From 720ffaf0083564c85a07d66a6d303f34706add41 Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Thu, 2 Jul 2020 02:50:55 +0300 Subject: feat: start refactoring the code to actually use vuex This includes creating multiple stores as needed for components and removing all complex states from components (since all those states should be stored in vuex) --- src/site/store/alert.js | 26 ++++++++++++++++++++ src/site/store/auth.js | 61 +++++++++++++++++++++++++++++++++++++++++++++++ src/site/store/config.js | 19 +++++++++++++++ src/site/store/images.js | 56 +++++++++++++++++++++++++++++++++++++++++++ src/site/store/index.js | 62 +++++++----------------------------------------- 5 files changed, 170 insertions(+), 54 deletions(-) create mode 100644 src/site/store/alert.js create mode 100644 src/site/store/auth.js create mode 100644 src/site/store/config.js create mode 100644 src/site/store/images.js (limited to 'src/site/store') diff --git a/src/site/store/alert.js b/src/site/store/alert.js new file mode 100644 index 0000000..78c0eaf --- /dev/null +++ b/src/site/store/alert.js @@ -0,0 +1,26 @@ +/* eslint-disable no-shadow */ +const getDefaultState = () => ({ + text: null, + error: false +}); + +export const state = getDefaultState; + +export const actions = { + set({ commit }, data) { + commit('set', data); + }, + clear({ commit }) { + commit('clear'); + } +}; + +export const mutations = { + set(state, { text, error }) { + state.text = text; + state.error = error; + }, + clear(state) { + Object.assign(state, getDefaultState()); + } +}; diff --git a/src/site/store/auth.js b/src/site/store/auth.js new file mode 100644 index 0000000..a62a6ec --- /dev/null +++ b/src/site/store/auth.js @@ -0,0 +1,61 @@ +/* eslint-disable no-shadow */ +// only used so I could keep the convention of naming the first param as "state" in mutations +const getDefaultState = () => ({ + loggedIn: false, + isLoading: false, + user: null, + token: null +}); + +export const state = getDefaultState; + +export const getters = { + isLoggedIn: state => state.loggedIn +}; + +export const actions = { + async verify({ commit, dispatch }) { + try { + const response = await this.$axios.$get('verify'); + commit('loginSuccess', response); + } catch (e) { + dispatch('alert/set', { text: e.message, error: true }, { root: true }); + } + }, + async login({ commit, dispatch }, { username, password }) { + commit('loginRequest'); + + try { + const data = await this.$axios.$post(`auth/login`, { username, password }); + this.$axios.setToken(data.token, 'Bearer'); + + commit('setToken', data.token); + commit('loginSuccess', { token: data.token, user: data.user }); + } catch (e) { + dispatch('alert/set', { text: e.message, error: true }, { root: true }); + } + }, + logout({ commit }) { + commit('logout'); + } +}; + +export const mutations = { + setToken(state, token) { + state.token = token; + }, + loginRequest(state) { + state.isLoading = true; + }, + loginSuccess(state, { user }) { + this.$cookies.set('token', state.token); + state.user = user; + state.loggedIn = true; + state.isLoading = false; + }, + logout(state) { + this.$cookies.remove('token'); + // reset state to default + Object.assign(state, getDefaultState()); + } +}; diff --git a/src/site/store/config.js b/src/site/store/config.js new file mode 100644 index 0000000..6202f84 --- /dev/null +++ b/src/site/store/config.js @@ -0,0 +1,19 @@ +/* eslint-disable no-shadow */ +export const state = () => ({ + development: true, + version: '4.0.0', + URL: 'http://localhost:8080', + baseURL: 'http://localhost:8080/api', + serviceName: '', + maxFileSize: 100, + chunkSize: 90, + maxLinksPerAlbum: 5, + publicMode: false, + userAccounts: false +}); + +export const mutations = { + set(state, config) { + Object.assign(state, config); + } +}; diff --git a/src/site/store/images.js b/src/site/store/images.js new file mode 100644 index 0000000..e87dac1 --- /dev/null +++ b/src/site/store/images.js @@ -0,0 +1,56 @@ +/* eslint-disable no-shadow */ +export const state = () => ({ + files: [], + isLoading: false, + pagination: { + page: 1, + limit: 30, + totalFiles: 0 + } +}); + +export const getters = { + getTotalFiles: state => state.pagination.totalFiles, + getFetchedCount: state => state.files.length, + shouldPaginate: ({ pagination }) => pagination.totalFiles > pagination.limit, + getLimit: ({ pagination }) => pagination.limit +}; + +export const actions = { + async fetch({ commit, dispatch, state }, page) { + commit('setIsLoading'); + + page = page || 1; + + try { + const response = await this.$axios.$get(`files`, { params: { limit: state.pagination.limit, page } }); + + commit('updateFiles', { files: response.files }); + commit('updatePaginationMeta', { totalFiles: response.count, page }); + } catch (e) { + dispatch('alert/set', { text: e.message, error: true }, { root: true }); + } + }, + async fetchById({ commit, dispatch }) { + try { + const response = await this.$axios.$get('verify'); + commit('loginSuccess', response); + } catch (e) { + dispatch('alert/set', { text: e.message, error: true }, { root: true }); + } + } +}; + +export const mutations = { + setIsLoading(state) { + state.isLoading = true; + }, + updateFiles(state, { files }) { + state.files = files || []; + state.isLoading = false; + }, + updatePaginationMeta(state, { page, totalFiles }) { + state.pagination.page = page || 1; + state.pagination.totalFiles = totalFiles || 0; + } +}; diff --git a/src/site/store/index.js b/src/site/store/index.js index 1fc2272..8f910ae 100644 --- a/src/site/store/index.js +++ b/src/site/store/index.js @@ -1,66 +1,20 @@ import config from '../../../dist/config.json'; -export const state = () => ({ - loggedIn: false, - user: null, - token: null, - config: null, - alert: null -}); - -/* eslint-disable no-shadow */ -export const mutations = { - loggedIn(state, payload) { - state.loggedIn = payload; - }, - user(state, payload) { - state.user = payload; - }, - token(state, payload) { - state.token = payload; - }, - config(state, payload) { - state.config = payload; - }, - alert(state, payload) { - state.alert = payload; - } -}; export const actions = { - async nuxtClientInit({ commit, dispatch }, { app, req }) { - commit('config', config); + async nuxtClientInit({ commit, dispatch }) { + commit('config/set', config); const cookies = this.$cookies.getAll(); - if (!cookies.token) return dispatch('logout'); + if (!cookies.token) return dispatch('auth/logout'); - commit('token', cookies.token); - try { - const response = await this.$axios.$get('verify'); - dispatch('login', { - token: cookies.token, - user: response.user - }); - } catch (error) { - // dispatch('logout'); - } - }, - login({ commit }, { token, user }) { - this.$cookies.set('token', token); - commit('token', token); - commit('user', user); - commit('loggedIn', true); - }, - logout({ commit }) { - this.$cookies.remove('token'); - commit('token', null); - commit('user', null); - commit('loggedIn', false); - }, - alert({ commit }, payload) { + commit('auth/setToken', cookies.token); + await dispatch('auth/verify'); + } + /* alert({ commit }, payload) { if (!payload) return commit('alert', null); commit('alert', { text: payload.text, error: payload.error }); - } + } */ }; -- cgit v1.2.3 From c2dbbe6396540ee9d76991a00f5028b49d221d0c Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Thu, 2 Jul 2020 23:42:02 +0300 Subject: feat: refactor account to use vuex, fix small presentational components --- src/site/store/auth.js | 39 ++++++++++++++++++++++++++++++++++++++- src/site/store/images.js | 4 ++-- 2 files changed, 40 insertions(+), 3 deletions(-) (limited to 'src/site/store') diff --git a/src/site/store/auth.js b/src/site/store/auth.js index a62a6ec..73976d6 100644 --- a/src/site/store/auth.js +++ b/src/site/store/auth.js @@ -10,7 +10,8 @@ const getDefaultState = () => ({ export const state = getDefaultState; export const getters = { - isLoggedIn: state => state.loggedIn + isLoggedIn: state => state.loggedIn, + getApiKey: state => state.user?.apiKey }; export const actions = { @@ -35,6 +36,36 @@ export const actions = { dispatch('alert/set', { text: e.message, error: true }, { root: true }); } }, + async fetchCurrentUser({ commit, dispatch }) { + try { + const data = await this.$axios.$get(`users/me`); + commit('setUser', data.user); + } catch (e) { + dispatch('alert/set', { text: e.message, error: true }, { root: true }); + } + }, + async changePassword({ dispatch }, { password, newPassword }) { + try { + const response = await this.$axios.$post(`user/password/change`, { + password, + newPassword + }); + + return response; + } catch (e) { + dispatch('alert/set', { text: e.message, error: true }, { root: true }); + } + }, + async requestAPIKey({ commit, dispatch }) { + try { + const response = await this.$axios.$post(`user/apikey/change`); + commit('setApiKey', response.apiKey); + + return response; + } catch (e) { + dispatch('alert/set', { text: e.message, error: true }, { root: true }); + } + }, logout({ commit }) { commit('logout'); } @@ -44,6 +75,12 @@ export const mutations = { setToken(state, token) { state.token = token; }, + setApiKey(state, apiKey) { + state.user.apiKey = apiKey; + }, + setUser(state, user) { + state.user = user; + }, loginRequest(state) { state.isLoading = true; }, diff --git a/src/site/store/images.js b/src/site/store/images.js index e87dac1..f6dae1b 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -10,8 +10,8 @@ export const state = () => ({ }); export const getters = { - getTotalFiles: state => state.pagination.totalFiles, - getFetchedCount: state => state.files.length, + getTotalFiles: ({ pagination }) => pagination.totalFiles, + getFetchedCount: ({ files }) => files.length, shouldPaginate: ({ pagination }) => pagination.totalFiles > pagination.limit, getLimit: ({ pagination }) => pagination.limit }; -- cgit v1.2.3 From 7581d13d1cdbd190009dea11549669cfa5cc00ad Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Fri, 3 Jul 2020 00:35:09 +0300 Subject: feat: separate album view into multiple components and use vuex --- src/site/store/albums.js | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/site/store/albums.js (limited to 'src/site/store') diff --git a/src/site/store/albums.js b/src/site/store/albums.js new file mode 100644 index 0000000..a33181c --- /dev/null +++ b/src/site/store/albums.js @@ -0,0 +1,56 @@ +/* eslint-disable no-shadow */ +export const state = () => ({ + list: [], + isListLoading: false, + albumDetails: {}, + expandedAlbums: [] +}); + +export const getters = { + isExpanded: state => id => state.expandedAlbums.indexOf(id) > -1, + getDetails: state => id => state.albumDetails[id] || {} +}; + +export const actions = { + async fetch({ commit, dispatch }) { + try { + commit('albumsRequest'); + const response = await this.$axios.$get(`albums/mini`); + + commit('setAlbums', response.albums); + } catch (e) { + dispatch('alert/set', { text: e.message, error: true }, { root: true }); + } + }, + async fetchDetails({ commit }, albumId) { + const response = await this.$axios.$get(`album/${albumId}/links`); + + commit('setDetails', { + id: albumId, + details: { + links: response.links + } + }); + } +}; + +export const mutations = { + albumsRequest(state) { + state.isLoading = true; + }, + setAlbums(state, albums) { + state.list = albums; + state.isLoading = false; + }, + setDetails(state, { id, details }) { + state.albumDetails[id] = details; + }, + toggleExpandedState(state, id) { + const foundIndex = state.expandedAlbums.indexOf(id); + if (foundIndex > -1) { + state.expandedAlbums.splice(foundIndex, 1); + } else { + state.expandedAlbums.push(id); + } + } +}; -- cgit v1.2.3 From 92be4504ccb8f6d918013e5c33870858cd22376a Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Sat, 4 Jul 2020 03:26:35 +0300 Subject: feat: refactor most of the album components to use store for presentation and actions --- src/site/store/album.js | 0 src/site/store/albums.js | 75 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/site/store/album.js (limited to 'src/site/store') diff --git a/src/site/store/album.js b/src/site/store/album.js new file mode 100644 index 0000000..e69de29 diff --git a/src/site/store/albums.js b/src/site/store/albums.js index a33181c..d5d45ce 100644 --- a/src/site/store/albums.js +++ b/src/site/store/albums.js @@ -1,4 +1,6 @@ /* eslint-disable no-shadow */ +import Vue from 'vue'; + export const state = () => ({ list: [], isListLoading: false, @@ -18,10 +20,13 @@ export const actions = { const response = await this.$axios.$get(`albums/mini`); commit('setAlbums', response.albums); + + return response; } catch (e) { dispatch('alert/set', { text: e.message, error: true }, { root: true }); } }, + async fetchDetails({ commit }, albumId) { const response = await this.$axios.$get(`album/${albumId}/links`); @@ -31,6 +36,52 @@ export const actions = { links: response.links } }); + + return response; + }, + + async createAlbum({ commit }, name) { + const response = await this.$axios.$post(`album/new`, { name }); + + commit('addAlbum', response.data); + + return response; + }, + + async deleteAlbum({ commit }, albumId) { + const response = await this.$axios.$delete(`album/${albumId}`); + + commit('removeAlbum', albumId); + + return response; + }, + + async createLink({ commit }, albumId) { + const response = await this.$axios.$post(`album/link/new`, { albumId }); + + commit('addAlbumLink', { albumId, data: response.data }); + + return response; + }, + + async updateLinkOptions({ commit }, { albumId, linkOpts }) { + const response = await this.$axios.$post(`album/link/edit`, { + identifier: linkOpts.identifier, + enableDownload: linkOpts.enableDownload, + enabled: linkOpts.enabled + }); + + commit('updateAlbumLinkOpts', { albumId, linkOpts: response.data }); + + return response; + }, + + async deleteLink({ commit }, { albumId, identifier }) { + const response = await this.$axios.$delete(`album/link/delete/${identifier}`); + + commit('removeAlbumLink', { albumId, identifier }); + + return response; } }; @@ -42,8 +93,30 @@ export const mutations = { state.list = albums; state.isLoading = false; }, + addAlbum(state, album) { + state.list.unshift(album); + }, + removeAlbum(state, albumId) { + // state.list = state.list.filter(({ id }) => id !== albumId); + const foundIndex = state.list.findIndex(({ id }) => id === albumId); + state.list.splice(foundIndex, 1); + }, setDetails(state, { id, details }) { - state.albumDetails[id] = details; + Vue.set(state.albumDetails, id, details); + }, + addAlbumLink(state, { albumId, data }) { + state.albumDetails[albumId].links.push(data); + }, + updateAlbumLinkOpts(state, { albumId, linkOpts }) { + const foundIndex = state.albumDetails[albumId].links.findIndex( + ({ identifier }) => identifier === linkOpts.identifier + ); + const link = state.albumDetails[albumId].links[foundIndex]; + state.albumDetails[albumId].links[foundIndex] = { ...link, ...linkOpts }; + }, + removeAlbumLink(state, { albumId, identifier }) { + const foundIndex = state.albumDetails[albumId].links.findIndex(({ identifier: id }) => id === identifier); + state.albumDetails[albumId].links.splice(foundIndex, 1); }, toggleExpandedState(state, id) { const foundIndex = state.expandedAlbums.indexOf(id); -- cgit v1.2.3 From 04fdd63cee5327f49e5e11d5837a9031027c34ef Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Sun, 5 Jul 2020 04:17:09 +0300 Subject: feat: refactor single album page to use vuex --- src/site/store/album.js | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ src/site/store/albums.js | 38 +++++++++++++++------------------- 2 files changed, 71 insertions(+), 21 deletions(-) (limited to 'src/site/store') diff --git a/src/site/store/album.js b/src/site/store/album.js index e69de29..f7c88c9 100644 --- a/src/site/store/album.js +++ b/src/site/store/album.js @@ -0,0 +1,54 @@ +/* eslint-disable no-shadow */ +export const state = () => ({ + files: [], + name: null, + isLoading: false, + pagination: { + page: 1, + limit: 30, + totalFiles: 0, + }, + downloadEnabled: false, +}); + +export const getters = { + getTotalFiles: ({ pagination }) => pagination.totalFiles, + getFetchedCount: ({ files }) => files.length, + shouldPaginate: ({ pagination }) => pagination.totalFiles > pagination.limit, + getLimit: ({ pagination }) => pagination.limit, + getName: ({ name }) => name, +}; + +export const actions = { + async fetchById({ commit, dispatch, state }, { id, page }) { + commit('setIsLoading'); + + page = page || 1; + + try { + const response = await this.$axios.$get(`album/${id}/full`, { + params: { limit: state.pagination.limit, page }, + }); + + commit('setFiles', response); + commit('updatePaginationMeta', { totalFiles: response.count, page }); + } catch (e) { + dispatch('alert/set', { text: e.message, error: true }, { root: true }); + } + }, +}; + +export const mutations = { + setIsLoading(state) { + state.isLoading = true; + }, + setFiles(state, { files, name }) { + state.files = files || []; + state.name = name; + state.isLoading = false; + }, + updatePaginationMeta(state, { page, totalFiles }) { + state.pagination.page = page || 1; + state.pagination.totalFiles = totalFiles || 0; + }, +}; diff --git a/src/site/store/albums.js b/src/site/store/albums.js index d5d45ce..f3d7bcf 100644 --- a/src/site/store/albums.js +++ b/src/site/store/albums.js @@ -5,26 +5,22 @@ export const state = () => ({ list: [], isListLoading: false, albumDetails: {}, - expandedAlbums: [] + expandedAlbums: [], }); export const getters = { - isExpanded: state => id => state.expandedAlbums.indexOf(id) > -1, - getDetails: state => id => state.albumDetails[id] || {} + isExpanded: (state) => (id) => state.expandedAlbums.indexOf(id) > -1, + getDetails: (state) => (id) => state.albumDetails[id] || {}, }; export const actions = { - async fetch({ commit, dispatch }) { - try { - commit('albumsRequest'); - const response = await this.$axios.$get(`albums/mini`); + async fetch({ commit }) { + commit('albumsRequest'); + const response = await this.$axios.$get('albums/mini'); - commit('setAlbums', response.albums); + commit('setAlbums', response.albums); - return response; - } catch (e) { - dispatch('alert/set', { text: e.message, error: true }, { root: true }); - } + return response; }, async fetchDetails({ commit }, albumId) { @@ -33,15 +29,15 @@ export const actions = { commit('setDetails', { id: albumId, details: { - links: response.links - } + links: response.links, + }, }); return response; }, async createAlbum({ commit }, name) { - const response = await this.$axios.$post(`album/new`, { name }); + const response = await this.$axios.$post('album/new', { name }); commit('addAlbum', response.data); @@ -57,7 +53,7 @@ export const actions = { }, async createLink({ commit }, albumId) { - const response = await this.$axios.$post(`album/link/new`, { albumId }); + const response = await this.$axios.$post('album/link/new', { albumId }); commit('addAlbumLink', { albumId, data: response.data }); @@ -65,10 +61,10 @@ export const actions = { }, async updateLinkOptions({ commit }, { albumId, linkOpts }) { - const response = await this.$axios.$post(`album/link/edit`, { + const response = await this.$axios.$post('album/link/edit', { identifier: linkOpts.identifier, enableDownload: linkOpts.enableDownload, - enabled: linkOpts.enabled + enabled: linkOpts.enabled, }); commit('updateAlbumLinkOpts', { albumId, linkOpts: response.data }); @@ -82,7 +78,7 @@ export const actions = { commit('removeAlbumLink', { albumId, identifier }); return response; - } + }, }; export const mutations = { @@ -109,7 +105,7 @@ export const mutations = { }, updateAlbumLinkOpts(state, { albumId, linkOpts }) { const foundIndex = state.albumDetails[albumId].links.findIndex( - ({ identifier }) => identifier === linkOpts.identifier + ({ identifier }) => identifier === linkOpts.identifier, ); const link = state.albumDetails[albumId].links[foundIndex]; state.albumDetails[albumId].links[foundIndex] = { ...link, ...linkOpts }; @@ -125,5 +121,5 @@ export const mutations = { } else { state.expandedAlbums.push(id); } - } + }, }; -- cgit v1.2.3 From 766e74cc51138b32482f65f0f2647eb9d943103e Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Sun, 5 Jul 2020 04:18:08 +0300 Subject: feat: add video preview on hover to dashboard and apply new linter rules to some of the files --- src/site/store/auth.js | 20 ++++++++++---------- src/site/store/images.js | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/site/store') diff --git a/src/site/store/auth.js b/src/site/store/auth.js index 73976d6..55009ce 100644 --- a/src/site/store/auth.js +++ b/src/site/store/auth.js @@ -4,14 +4,14 @@ const getDefaultState = () => ({ loggedIn: false, isLoading: false, user: null, - token: null + token: null, }); export const state = getDefaultState; export const getters = { - isLoggedIn: state => state.loggedIn, - getApiKey: state => state.user?.apiKey + isLoggedIn: (state) => state.loggedIn, + getApiKey: (state) => state.user?.apiKey, }; export const actions = { @@ -27,7 +27,7 @@ export const actions = { commit('loginRequest'); try { - const data = await this.$axios.$post(`auth/login`, { username, password }); + const data = await this.$axios.$post('auth/login', { username, password }); this.$axios.setToken(data.token, 'Bearer'); commit('setToken', data.token); @@ -38,7 +38,7 @@ export const actions = { }, async fetchCurrentUser({ commit, dispatch }) { try { - const data = await this.$axios.$get(`users/me`); + const data = await this.$axios.$get('users/me'); commit('setUser', data.user); } catch (e) { dispatch('alert/set', { text: e.message, error: true }, { root: true }); @@ -46,9 +46,9 @@ export const actions = { }, async changePassword({ dispatch }, { password, newPassword }) { try { - const response = await this.$axios.$post(`user/password/change`, { + const response = await this.$axios.$post('user/password/change', { password, - newPassword + newPassword, }); return response; @@ -58,7 +58,7 @@ export const actions = { }, async requestAPIKey({ commit, dispatch }) { try { - const response = await this.$axios.$post(`user/apikey/change`); + const response = await this.$axios.$post('user/apikey/change'); commit('setApiKey', response.apiKey); return response; @@ -68,7 +68,7 @@ export const actions = { }, logout({ commit }) { commit('logout'); - } + }, }; export const mutations = { @@ -94,5 +94,5 @@ export const mutations = { this.$cookies.remove('token'); // reset state to default Object.assign(state, getDefaultState()); - } + }, }; diff --git a/src/site/store/images.js b/src/site/store/images.js index f6dae1b..14f475a 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -25,7 +25,7 @@ export const actions = { try { const response = await this.$axios.$get(`files`, { params: { limit: state.pagination.limit, page } }); - commit('updateFiles', { files: response.files }); + commit('setFiles', { files: response.files }); commit('updatePaginationMeta', { totalFiles: response.count, page }); } catch (e) { dispatch('alert/set', { text: e.message, error: true }, { root: true }); @@ -45,7 +45,7 @@ export const mutations = { setIsLoading(state) { state.isLoading = true; }, - updateFiles(state, { files }) { + setFiles(state, { files }) { state.files = files || []; state.isLoading = false; }, -- cgit v1.2.3 From 15f296a7805b7623f56eab67b74ab0bf93a038e1 Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Tue, 7 Jul 2020 02:02:37 +0300 Subject: chore: eslint stores feat: merge album and images --- src/site/store/.eslintrc.json | 5 +++++ src/site/store/admin.js | 0 src/site/store/album.js | 5 ++++- src/site/store/albums.js | 1 - src/site/store/alert.js | 7 +++---- src/site/store/auth.js | 17 +++++----------- src/site/store/config.js | 5 ++--- src/site/store/images.js | 45 ++++++++++++++++++++++++------------------- src/site/store/index.js | 5 +++-- 9 files changed, 47 insertions(+), 43 deletions(-) create mode 100644 src/site/store/.eslintrc.json create mode 100644 src/site/store/admin.js (limited to 'src/site/store') diff --git a/src/site/store/.eslintrc.json b/src/site/store/.eslintrc.json new file mode 100644 index 0000000..052e3ef --- /dev/null +++ b/src/site/store/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "rules": { + "no-shadow": ["error", { "allow": ["state"] }] + } +} diff --git a/src/site/store/admin.js b/src/site/store/admin.js new file mode 100644 index 0000000..e69de29 diff --git a/src/site/store/album.js b/src/site/store/album.js index f7c88c9..d8ffacc 100644 --- a/src/site/store/album.js +++ b/src/site/store/album.js @@ -1,4 +1,3 @@ -/* eslint-disable no-shadow */ export const state = () => ({ files: [], name: null, @@ -36,6 +35,10 @@ export const actions = { dispatch('alert/set', { text: e.message, error: true }, { root: true }); } }, + // TODO: Fix duplicate code between this store and files store + deleteFile({ commit }, fileId) { + + }, }; export const mutations = { diff --git a/src/site/store/albums.js b/src/site/store/albums.js index f3d7bcf..2b4ac60 100644 --- a/src/site/store/albums.js +++ b/src/site/store/albums.js @@ -1,4 +1,3 @@ -/* eslint-disable no-shadow */ import Vue from 'vue'; export const state = () => ({ diff --git a/src/site/store/alert.js b/src/site/store/alert.js index 78c0eaf..ff38e09 100644 --- a/src/site/store/alert.js +++ b/src/site/store/alert.js @@ -1,7 +1,6 @@ -/* eslint-disable no-shadow */ const getDefaultState = () => ({ text: null, - error: false + error: false, }); export const state = getDefaultState; @@ -12,7 +11,7 @@ export const actions = { }, clear({ commit }) { commit('clear'); - } + }, }; export const mutations = { @@ -22,5 +21,5 @@ export const mutations = { }, clear(state) { Object.assign(state, getDefaultState()); - } + }, }; diff --git a/src/site/store/auth.js b/src/site/store/auth.js index 55009ce..69de9ec 100644 --- a/src/site/store/auth.js +++ b/src/site/store/auth.js @@ -1,8 +1,5 @@ -/* eslint-disable no-shadow */ -// only used so I could keep the convention of naming the first param as "state" in mutations const getDefaultState = () => ({ loggedIn: false, - isLoading: false, user: null, token: null, }); @@ -23,18 +20,14 @@ export const actions = { dispatch('alert/set', { text: e.message, error: true }, { root: true }); } }, - async login({ commit, dispatch }, { username, password }) { + async login({ commit }, { username, password }) { commit('loginRequest'); - try { - const data = await this.$axios.$post('auth/login', { username, password }); - this.$axios.setToken(data.token, 'Bearer'); + const data = await this.$axios.$post('auth/login', { username, password }); + this.$axios.setToken(data.token, 'Bearer'); - commit('setToken', data.token); - commit('loginSuccess', { token: data.token, user: data.user }); - } catch (e) { - dispatch('alert/set', { text: e.message, error: true }, { root: true }); - } + commit('setToken', data.token); + commit('loginSuccess', { token: data.token, user: data.user }); }, async fetchCurrentUser({ commit, dispatch }) { try { diff --git a/src/site/store/config.js b/src/site/store/config.js index 6202f84..f52fc0f 100644 --- a/src/site/store/config.js +++ b/src/site/store/config.js @@ -1,4 +1,3 @@ -/* eslint-disable no-shadow */ export const state = () => ({ development: true, version: '4.0.0', @@ -9,11 +8,11 @@ export const state = () => ({ chunkSize: 90, maxLinksPerAlbum: 5, publicMode: false, - userAccounts: false + userAccounts: false, }); export const mutations = { set(state, config) { Object.assign(state, config); - } + }, }; diff --git a/src/site/store/images.js b/src/site/store/images.js index 14f475a..d02219f 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -1,19 +1,21 @@ -/* eslint-disable no-shadow */ export const state = () => ({ files: [], isLoading: false, pagination: { page: 1, limit: 30, - totalFiles: 0 - } + totalFiles: 0, + }, + name: null, + downloadEnabled: false, }); export const getters = { getTotalFiles: ({ pagination }) => pagination.totalFiles, getFetchedCount: ({ files }) => files.length, shouldPaginate: ({ pagination }) => pagination.totalFiles > pagination.limit, - getLimit: ({ pagination }) => pagination.limit + getLimit: ({ pagination }) => pagination.limit, + getName: ({ name }) => name, }; export const actions = { @@ -23,34 +25,37 @@ export const actions = { page = page || 1; try { - const response = await this.$axios.$get(`files`, { params: { limit: state.pagination.limit, page } }); + const response = await this.$axios.$get('files', { params: { limit: state.pagination.limit, page } }); - commit('setFiles', { files: response.files }); - commit('updatePaginationMeta', { totalFiles: response.count, page }); + commit('setFilesAndMeta', { ...response, page }); } catch (e) { dispatch('alert/set', { text: e.message, error: true }, { root: true }); } }, - async fetchById({ commit, dispatch }) { - try { - const response = await this.$axios.$get('verify'); - commit('loginSuccess', response); - } catch (e) { - dispatch('alert/set', { text: e.message, error: true }, { root: true }); - } - } + async fetchByAlbumId({ commit, dispatch, state }, { id, page }) { + commit('setIsLoading'); + + page = page || 1; + + const response = await this.$axios.$get(`album/${id}/full`, { + params: { limit: state.pagination.limit, page }, + }); + + commit('setFilesAndMeta', { ...response, page }); + }, }; export const mutations = { setIsLoading(state) { state.isLoading = true; }, - setFiles(state, { files }) { + setFilesAndMeta(state, { + files, name, page, count, + }) { state.files = files || []; + state.name = name ?? null; state.isLoading = false; - }, - updatePaginationMeta(state, { page, totalFiles }) { state.pagination.page = page || 1; - state.pagination.totalFiles = totalFiles || 0; - } + state.pagination.totalFiles = count || 0; + }, }; diff --git a/src/site/store/index.js b/src/site/store/index.js index 8f910ae..c0faffb 100644 --- a/src/site/store/index.js +++ b/src/site/store/index.js @@ -1,5 +1,6 @@ import config from '../../../dist/config.json'; +// eslint-disable-next-line import/prefer-default-export export const actions = { async nuxtClientInit({ commit, dispatch }) { commit('config/set', config); @@ -8,8 +9,8 @@ export const actions = { if (!cookies.token) return dispatch('auth/logout'); commit('auth/setToken', cookies.token); - await dispatch('auth/verify'); - } + return dispatch('auth/verify'); + }, /* alert({ commit }, payload) { if (!payload) return commit('alert', null); commit('alert', { -- cgit v1.2.3 From 1a8b6602e094289a4f477c33e432e0f5e1587b45 Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Wed, 8 Jul 2020 03:13:51 +0300 Subject: refactor: change uploader component to use vuex --- src/site/store/albums.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'src/site/store') diff --git a/src/site/store/albums.js b/src/site/store/albums.js index 2b4ac60..8441182 100644 --- a/src/site/store/albums.js +++ b/src/site/store/albums.js @@ -5,6 +5,7 @@ export const state = () => ({ isListLoading: false, albumDetails: {}, expandedAlbums: [], + tinyDetails: [], }); export const getters = { @@ -21,7 +22,6 @@ export const actions = { return response; }, - async fetchDetails({ commit }, albumId) { const response = await this.$axios.$get(`album/${albumId}/links`); @@ -34,7 +34,6 @@ export const actions = { return response; }, - async createAlbum({ commit }, name) { const response = await this.$axios.$post('album/new', { name }); @@ -42,7 +41,6 @@ export const actions = { return response; }, - async deleteAlbum({ commit }, albumId) { const response = await this.$axios.$delete(`album/${albumId}`); @@ -50,7 +48,6 @@ export const actions = { return response; }, - async createLink({ commit }, albumId) { const response = await this.$axios.$post('album/link/new', { albumId }); @@ -58,7 +55,6 @@ export const actions = { return response; }, - async updateLinkOptions({ commit }, { albumId, linkOpts }) { const response = await this.$axios.$post('album/link/edit', { identifier: linkOpts.identifier, @@ -70,12 +66,18 @@ export const actions = { return response; }, - async deleteLink({ commit }, { albumId, identifier }) { const response = await this.$axios.$delete(`album/link/delete/${identifier}`); commit('removeAlbumLink', { albumId, identifier }); + return response; + }, + async getTinyDetails({ commit }) { + const response = await this.$axios.$get('albums/dropdown'); + + commit('setTinyDetails', response); + return response; }, }; @@ -111,7 +113,7 @@ export const mutations = { }, removeAlbumLink(state, { albumId, identifier }) { const foundIndex = state.albumDetails[albumId].links.findIndex(({ identifier: id }) => id === identifier); - state.albumDetails[albumId].links.splice(foundIndex, 1); + if (foundIndex > -1) state.albumDetails[albumId].links.splice(foundIndex, 1); }, toggleExpandedState(state, id) { const foundIndex = state.expandedAlbums.indexOf(id); @@ -121,4 +123,7 @@ export const mutations = { state.expandedAlbums.push(id); } }, + setTinyDetails(state, { albums }) { + state.tinyDetails = albums; + }, }; -- cgit v1.2.3 From 15266378810d81704f8c9ece6ecf919526efacae Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Wed, 8 Jul 2020 03:15:07 +0300 Subject: feat: add new sidebar with mdi icons and active reactivity --- src/site/store/auth.js | 1 + 1 file changed, 1 insertion(+) (limited to 'src/site/store') diff --git a/src/site/store/auth.js b/src/site/store/auth.js index 69de9ec..286d321 100644 --- a/src/site/store/auth.js +++ b/src/site/store/auth.js @@ -9,6 +9,7 @@ export const state = getDefaultState; export const getters = { isLoggedIn: (state) => state.loggedIn, getApiKey: (state) => state.user?.apiKey, + getToken: (state) => state.token, }; export const actions = { -- cgit v1.2.3 From b519b6ccb469e874c783b995ddf0ab6fabdb5a0e Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Wed, 8 Jul 2020 03:37:50 +0300 Subject: refactor: refactor grid to use vuex for every action --- src/site/store/album.js | 57 --------------------------------------- src/site/store/images.js | 69 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 67 insertions(+), 59 deletions(-) delete mode 100644 src/site/store/album.js (limited to 'src/site/store') diff --git a/src/site/store/album.js b/src/site/store/album.js deleted file mode 100644 index d8ffacc..0000000 --- a/src/site/store/album.js +++ /dev/null @@ -1,57 +0,0 @@ -export const state = () => ({ - files: [], - name: null, - isLoading: false, - pagination: { - page: 1, - limit: 30, - totalFiles: 0, - }, - downloadEnabled: false, -}); - -export const getters = { - getTotalFiles: ({ pagination }) => pagination.totalFiles, - getFetchedCount: ({ files }) => files.length, - shouldPaginate: ({ pagination }) => pagination.totalFiles > pagination.limit, - getLimit: ({ pagination }) => pagination.limit, - getName: ({ name }) => name, -}; - -export const actions = { - async fetchById({ commit, dispatch, state }, { id, page }) { - commit('setIsLoading'); - - page = page || 1; - - try { - const response = await this.$axios.$get(`album/${id}/full`, { - params: { limit: state.pagination.limit, page }, - }); - - commit('setFiles', response); - commit('updatePaginationMeta', { totalFiles: response.count, page }); - } catch (e) { - dispatch('alert/set', { text: e.message, error: true }, { root: true }); - } - }, - // TODO: Fix duplicate code between this store and files store - deleteFile({ commit }, fileId) { - - }, -}; - -export const mutations = { - setIsLoading(state) { - state.isLoading = true; - }, - setFiles(state, { files, name }) { - state.files = files || []; - state.name = name; - state.isLoading = false; - }, - updatePaginationMeta(state, { page, totalFiles }) { - state.pagination.page = page || 1; - state.pagination.totalFiles = totalFiles || 0; - }, -}; diff --git a/src/site/store/images.js b/src/site/store/images.js index d02219f..3019d85 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -1,4 +1,6 @@ -export const state = () => ({ +import Vue from 'vue'; + +export const getDefaultState = () => ({ files: [], isLoading: false, pagination: { @@ -8,8 +10,11 @@ export const state = () => ({ }, name: null, downloadEnabled: false, + filesAlbums: {}, }); +export const state = getDefaultState; + export const getters = { getTotalFiles: ({ pagination }) => pagination.totalFiles, getFetchedCount: ({ files }) => files.length, @@ -28,11 +33,15 @@ export const actions = { const response = await this.$axios.$get('files', { params: { limit: state.pagination.limit, page } }); commit('setFilesAndMeta', { ...response, page }); + + return response; } catch (e) { dispatch('alert/set', { text: e.message, error: true }, { root: true }); } + + return null; }, - async fetchByAlbumId({ commit, dispatch, state }, { id, page }) { + async fetchByAlbumId({ commit, state }, { id, page }) { commit('setIsLoading'); page = page || 1; @@ -42,6 +51,36 @@ export const actions = { }); commit('setFilesAndMeta', { ...response, page }); + + return response; + }, + async getFileAlbums({ commit }, fileId) { + const response = await this.$axios.$get(`file/${fileId}/albums`); + + commit('setFileAlbums', { ...response, fileId }); + + return response; + }, + async addToAlbum({ commit }, { fileId, albumId }) { + const response = await this.$axios.$post('file/album/add', { fileId, albumId }); + + commit('addAlbumToFile', { fileId, albumId, ...response.data }); + + return response; + }, + async removeFromAlbum({ commit }, { fileId, albumId }) { + const response = await this.$axios.$post('file/album/del', { fileId, albumId }); + + commit('removeAlbumFromFile', { fileId, albumId }); + + return response; + }, + async deleteFile({ commit }, fileId) { + const response = await this.$axios.$delete(`file/${fileId}`); + + commit('removeFile', fileId); + + return response; }, }; @@ -58,4 +97,30 @@ export const mutations = { state.pagination.page = page || 1; state.pagination.totalFiles = count || 0; }, + removeFile(state, fileId) { + const foundIndex = state.files.findIndex(({ id }) => id === fileId); + if (foundIndex > -1) { + state.files.splice(foundIndex, 1); + state.pagination.totalFiles -= 1; + } + }, + setFileAlbums(state, { fileId, albums }) { + Vue.set(state.filesAlbums, fileId, albums); + }, + addAlbumToFile(state, { fileId, album }) { + if (!state.filesAlbums[fileId]) return; + + state.filesAlbums[fileId].push(album); + }, + removeAlbumFromFile(state, { fileId, albumId }) { + if (!state.filesAlbums[fileId]) return; + + const foundIndex = state.filesAlbums[fileId].findIndex(({ id }) => id === albumId); + if (foundIndex > -1) { + state.filesAlbums[fileId].splice(foundIndex, 1); + } + }, + resetState(state) { + Object.assign(state, getDefaultState()); + }, }; -- cgit v1.2.3 From ad852de51a0d2dd5d29c08838d5a430c58849e74 Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Wed, 8 Jul 2020 04:00:12 +0300 Subject: chore: linter the entire project using the new rules --- src/site/store/auth.js | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/site/store') diff --git a/src/site/store/auth.js b/src/site/store/auth.js index 286d321..fcc051b 100644 --- a/src/site/store/auth.js +++ b/src/site/store/auth.js @@ -49,6 +49,8 @@ export const actions = { } catch (e) { dispatch('alert/set', { text: e.message, error: true }, { root: true }); } + + return null; }, async requestAPIKey({ commit, dispatch }) { try { @@ -59,6 +61,8 @@ export const actions = { } catch (e) { dispatch('alert/set', { text: e.message, error: true }, { root: true }); } + + return null; }, logout({ commit }) { commit('logout'); -- cgit v1.2.3 From fd3f6de51a082dcd72c2ef557747e031ef7b9c4a Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Thu, 9 Jul 2020 02:24:40 +0300 Subject: refactor: refactor most of the admin pages to use the store instead of internal states --- src/site/store/admin.js | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ src/site/store/alert.js | 18 +++++++--- src/site/store/auth.js | 10 ++++-- src/site/store/images.js | 2 +- 4 files changed, 115 insertions(+), 8 deletions(-) (limited to 'src/site/store') diff --git a/src/site/store/admin.js b/src/site/store/admin.js index e69de29..2586a18 100644 --- a/src/site/store/admin.js +++ b/src/site/store/admin.js @@ -0,0 +1,93 @@ +export const state = () => ({ + users: [], + user: { + id: null, + username: null, + enabled: false, + createdAt: null, + editedAt: null, + apiKeyEditedAt: null, + isAdmin: null, + files: [], + }, + file: {}, + settings: {}, +}); + +export const actions = { + async fetchUsers({ commit }) { + const response = await this.$axios.$get('admin/users'); + commit('setUsers', response); + + return response; + }, + async fetchUser({ commit }, id) { + const response = await this.$axios.$get(`/admin/users/${id}`); + commit('setUserInfo', response); + + return response; + }, + async enableUser({ commit }, id) { + const response = await this.$axios.$post('admin/users/enable', { id }); + + commit('changeUserState', { userId: id, enabled: true }); + + return response; + }, + async disableUser({ commit }, id) { + const response = await this.$axios.$post('admin/users/disable', { id }); + + commit('changeUserState', { userId: id, enabled: false }); + + return response; + }, + async promoteUser({ commit }, id) { + const response = await this.$axios.$post('admin/users/promote', { id }); + + commit('changeUserState', { userId: id, isAdmin: true }); + + return response; + }, + async demoteUser({ commit }, id) { + const response = await this.$axios.$post('admin/users/demote', { id }); + + commit('changeUserState', { userId: id, isAdmin: false }); + + return response; + }, + async purgeUserFiles(_, id) { + const response = await this.$axios.$post('admin/users/purge', { id }); + + return response; + }, +}; + +export const mutations = { + setUsers(state, { users }) { + state.users = users; + }, + setUserInfo(state, { user, files }) { + state.user = { ...state.user, ...user }; + state.user.files = files || []; + }, + changeUserState(state, { userId, enabled, isAdmin }) { + const foundIndex = state.users.findIndex(({ id }) => id === userId); + if (foundIndex > -1) { + if (enabled !== undefined) { + state.users[foundIndex].enabled = enabled; + } + if (isAdmin !== undefined) { + state.users[foundIndex].isAdmin = isAdmin; + } + } + + if (state.user.id === userId) { + if (enabled !== undefined) { + state.user.enabled = enabled; + } + if (isAdmin !== undefined) { + state.user.isAdmin = isAdmin; + } + } + }, +}; diff --git a/src/site/store/alert.js b/src/site/store/alert.js index ff38e09..580dcc8 100644 --- a/src/site/store/alert.js +++ b/src/site/store/alert.js @@ -1,12 +1,19 @@ +import AlertTypes from '~/constants/alertTypes'; + const getDefaultState = () => ({ - text: null, - error: false, + message: null, + type: null, + snackbar: false, }); export const state = getDefaultState; export const actions = { set({ commit }, data) { + // Only exists for backwards compatibility, remove one day + if (data.error === true) data.type = AlertTypes.ERROR; + if (data.text !== undefined) data.message = data.text; + commit('set', data); }, clear({ commit }) { @@ -15,9 +22,10 @@ export const actions = { }; export const mutations = { - set(state, { text, error }) { - state.text = text; - state.error = error; + set(state, { message, type, snackbar }) { + state.message = message; + state.type = type; + state.snackbar = snackbar || false; }, clear(state) { Object.assign(state, getDefaultState()); diff --git a/src/site/store/auth.js b/src/site/store/auth.js index fcc051b..465de7d 100644 --- a/src/site/store/auth.js +++ b/src/site/store/auth.js @@ -30,6 +30,12 @@ export const actions = { commit('setToken', data.token); commit('loginSuccess', { token: data.token, user: data.user }); }, + async register(_, { username, password }) { + return this.$axios.$post('auth/register', { + username, + password, + }); + }, async fetchCurrentUser({ commit, dispatch }) { try { const data = await this.$axios.$get('users/me'); @@ -83,13 +89,13 @@ export const mutations = { state.isLoading = true; }, loginSuccess(state, { user }) { - this.$cookies.set('token', state.token); + this.$cookies.set('token', state.token, { path: '/' }); state.user = user; state.loggedIn = true; state.isLoading = false; }, logout(state) { - this.$cookies.remove('token'); + this.$cookies.remove('token', { path: '/' }); // reset state to default Object.assign(state, getDefaultState()); }, diff --git a/src/site/store/images.js b/src/site/store/images.js index 3019d85..a7581e0 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -10,7 +10,7 @@ export const getDefaultState = () => ({ }, name: null, downloadEnabled: false, - filesAlbums: {}, + filesAlbums: {}, // map of file ids with a list of album objects the file is in }); export const state = getDefaultState; -- cgit v1.2.3 From 0f66d807035d3e32a66c7dc9bf55fb3be99aedac Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Fri, 10 Jul 2020 01:13:51 +0300 Subject: refactor: finish refactoring all the components to use vuex --- src/site/store/admin.js | 31 ++++++++++++++++++++++++++++++- src/site/store/auth.js | 6 +++++- src/site/store/images.js | 15 ++++++++------- 3 files changed, 43 insertions(+), 9 deletions(-) (limited to 'src/site/store') diff --git a/src/site/store/admin.js b/src/site/store/admin.js index 2586a18..b31c446 100644 --- a/src/site/store/admin.js +++ b/src/site/store/admin.js @@ -15,6 +15,12 @@ export const state = () => ({ }); export const actions = { + async fetchSettings({ commit }) { + const response = await this.$axios.$get('service/config'); + commit('setSettings', response); + + return response; + }, async fetchUsers({ commit }) { const response = await this.$axios.$get('admin/users'); commit('setUsers', response); @@ -22,11 +28,23 @@ export const actions = { return response; }, async fetchUser({ commit }, id) { - const response = await this.$axios.$get(`/admin/users/${id}`); + const response = await this.$axios.$get(`admin/users/${id}`); + commit('setUserInfo', response); + + return response; + }, + async fetchFile({ commit }, id) { + const response = await this.$axios.$get(`file/${id}`); + commit('setFile', response); commit('setUserInfo', response); return response; }, + async banIP(_, ip) { + const response = await this.$axios.$post('admin/ban/ip', { ip }); + + return response; + }, async enableUser({ commit }, id) { const response = await this.$axios.$post('admin/users/enable', { id }); @@ -58,11 +76,19 @@ export const actions = { async purgeUserFiles(_, id) { const response = await this.$axios.$post('admin/users/purge', { id }); + return response; + }, + async restartService() { + const response = await this.$axios.$post('service/restart'); + return response; }, }; export const mutations = { + setSettings(state, { config }) { + state.settings = config; + }, setUsers(state, { users }) { state.users = users; }, @@ -70,6 +96,9 @@ export const mutations = { state.user = { ...state.user, ...user }; state.user.files = files || []; }, + setFile(state, { file }) { + state.file = file || {}; + }, changeUserState(state, { userId, enabled, isAdmin }) { const foundIndex = state.users.findIndex(({ id }) => id === userId); if (foundIndex > -1) { diff --git a/src/site/store/auth.js b/src/site/store/auth.js index 465de7d..96631e2 100644 --- a/src/site/store/auth.js +++ b/src/site/store/auth.js @@ -1,6 +1,10 @@ const getDefaultState = () => ({ loggedIn: false, - user: null, + user: { + id: null, + isAdmin: false, + username: null, + }, token: null, }); diff --git a/src/site/store/images.js b/src/site/store/images.js index a7581e0..acac286 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -10,7 +10,8 @@ export const getDefaultState = () => ({ }, name: null, downloadEnabled: false, - filesAlbums: {}, // map of file ids with a list of album objects the file is in + fileAlbumsMap: {}, // map of file ids with a list of album objects the file is in + filesTags: {}, // map of file ids with a list of tag objects for the file }); export const state = getDefaultState; @@ -105,19 +106,19 @@ export const mutations = { } }, setFileAlbums(state, { fileId, albums }) { - Vue.set(state.filesAlbums, fileId, albums); + Vue.set(state.fileAlbumsMap, fileId, albums); }, addAlbumToFile(state, { fileId, album }) { - if (!state.filesAlbums[fileId]) return; + if (!state.fileAlbumsMap[fileId]) return; - state.filesAlbums[fileId].push(album); + state.fileAlbumsMap[fileId].push(album); }, removeAlbumFromFile(state, { fileId, albumId }) { - if (!state.filesAlbums[fileId]) return; + if (!state.fileAlbumsMap[fileId]) return; - const foundIndex = state.filesAlbums[fileId].findIndex(({ id }) => id === albumId); + const foundIndex = state.fileAlbumsMap[fileId].findIndex(({ id }) => id === albumId); if (foundIndex > -1) { - state.filesAlbums[fileId].splice(foundIndex, 1); + state.fileAlbumsMap[fileId].splice(foundIndex, 1); } }, resetState(state) { -- cgit v1.2.3 From c93ddb09008c45942544b13bbb03319c367f9cd8 Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Sun, 19 Jul 2020 22:27:11 +0300 Subject: feat: Start working on a new album/tags/image info modal --- src/site/store/admin.js | 2 +- src/site/store/images.js | 27 ++++++++++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) (limited to 'src/site/store') diff --git a/src/site/store/admin.js b/src/site/store/admin.js index b31c446..04ad980 100644 --- a/src/site/store/admin.js +++ b/src/site/store/admin.js @@ -34,7 +34,7 @@ export const actions = { return response; }, async fetchFile({ commit }, id) { - const response = await this.$axios.$get(`file/${id}`); + const response = await this.$axios.$get(`admin/file/${id}`); commit('setFile', response); commit('setUserInfo', response); diff --git a/src/site/store/images.js b/src/site/store/images.js index acac286..0d5e82a 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -8,10 +8,11 @@ export const getDefaultState = () => ({ limit: 30, totalFiles: 0, }, - name: null, - downloadEnabled: false, + albumName: null, + albumDownloadEnabled: false, + fileExtraInfoMap: {}, // information about the selected file fileAlbumsMap: {}, // map of file ids with a list of album objects the file is in - filesTags: {}, // map of file ids with a list of tag objects for the file + fileTagsMap: {}, // map of file ids with a list of tag objects for the file }); export const state = getDefaultState; @@ -55,6 +56,15 @@ export const actions = { return response; }, + async fetchFileMeta({ commit }, fileId) { + const response = await this.$axios.$get(`file/${fileId}`); + + commit('setFileAlbums', { ...response, fileId }); + commit('setFileTags', { ...response, fileId }); + commit('setFileExtraInfo', { ...response, fileId }); + + return response; + }, async getFileAlbums({ commit }, fileId) { const response = await this.$axios.$get(`file/${fileId}/albums`); @@ -90,10 +100,11 @@ export const mutations = { state.isLoading = true; }, setFilesAndMeta(state, { - files, name, page, count, + files, name, page, count, downloadEnabled, }) { state.files = files || []; - state.name = name ?? null; + state.albumName = name ?? null; + state.downloadEnabled = downloadEnabled ?? false; state.isLoading = false; state.pagination.page = page || 1; state.pagination.totalFiles = count || 0; @@ -108,6 +119,12 @@ export const mutations = { setFileAlbums(state, { fileId, albums }) { Vue.set(state.fileAlbumsMap, fileId, albums); }, + setFileTags(state, { fileId, tags }) { + Vue.set(state.fileTagsMap, fileId, tags); + }, + setFileExtraInfo(state, { fileId, file }) { + Vue.set(state.fileExtraInfoMap, fileId, file); + }, addAlbumToFile(state, { fileId, album }) { if (!state.fileAlbumsMap[fileId]) return; -- cgit v1.2.3 From 18bb451f793677a5bbfdc2c14128bae33c66dfde Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Mon, 20 Jul 2020 23:01:45 +0300 Subject: feat: implement all-in-one file detail viewer, tag editor and album selection modal --- src/site/store/images.js | 27 +++++++++++++++++++++++++++ src/site/store/tags.js | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) create mode 100644 src/site/store/tags.js (limited to 'src/site/store') diff --git a/src/site/store/images.js b/src/site/store/images.js index 0d5e82a..be04c8a 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -91,6 +91,20 @@ export const actions = { commit('removeFile', fileId); + return response; + }, + async addTag({ commit }, { fileId, tagName }) { + const response = await this.$axios.$post('file/tag/add', { fileId, tagName }); + + commit('addTagToFile', response.data); + + return response; + }, + async removeTag({ commit }, { fileId, tagName }) { + const response = await this.$axios.$post('file/tag/del', { fileId, tagName }); + + commit('removeTagFromFile', response.data); + return response; }, }; @@ -138,6 +152,19 @@ export const mutations = { state.fileAlbumsMap[fileId].splice(foundIndex, 1); } }, + addTagToFile(state, { fileId, tag }) { + if (!state.fileTagsMap[fileId]) return; + + state.fileTagsMap[fileId].push(tag); + }, + removeTagFromFile(state, { fileId, tag }) { + if (!state.fileTagsMap[fileId]) return; + + const foundIndex = state.fileTagsMap[fileId].findIndex(({ id }) => id === tag.id); + if (foundIndex > -1) { + state.fileTagsMap[fileId].splice(foundIndex, 1); + } + }, resetState(state) { Object.assign(state, getDefaultState()); }, diff --git a/src/site/store/tags.js b/src/site/store/tags.js new file mode 100644 index 0000000..c06b741 --- /dev/null +++ b/src/site/store/tags.js @@ -0,0 +1,40 @@ +export const state = () => ({ + tagsList: [], +}); + +export const actions = { + async fetch({ commit }) { + const response = await this.$axios.$get('tags'); + + commit('setTags', response.tags); + + return response; + }, + async createTag({ commit }, name) { + const response = await this.$axios.$post('tag/new', { name }); + + commit('addTag', response.data); + + return response; + }, + async deleteTag({ commit }, tagId) { + const response = await this.$axios.$delete(`tag/${tagId}`); + + commit('deleteTag', response.data); + + return response; + }, +}; + +export const mutations = { + setTags(state, tags) { + state.tagsList = tags; + }, + addTag(state, tag) { + state.tagsList.unshift(tag); + }, + deleteTag(state, { id: tagId }) { + const foundIndex = state.tagsList.findIndex(({ id }) => id === tagId); + state.tagsList.splice(foundIndex, 1); + }, +}; -- cgit v1.2.3 From 279234a081e5ea772978732ae5d2e45d8adcd741 Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Wed, 22 Jul 2020 02:14:06 +0300 Subject: feat: add new search input For now, it clones the autocomplete from buefy, untill a PR or resolution to the opened issue about not being able to manipulate how the suggestions are applied is found --- src/site/store/images.js | 1 + 1 file changed, 1 insertion(+) (limited to 'src/site/store') diff --git a/src/site/store/images.js b/src/site/store/images.js index be04c8a..4737c26 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -8,6 +8,7 @@ export const getDefaultState = () => ({ limit: 30, totalFiles: 0, }, + search: '', albumName: null, albumDownloadEnabled: false, fileExtraInfoMap: {}, // information about the selected file -- cgit v1.2.3 From 39e9941ded8de4e41048781daa80de0838c01c19 Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Thu, 23 Jul 2020 04:08:31 +0300 Subject: feat: Add hiding to recommendations as a prop fix: change some of the regexes to remove , and ; as separator support because the query parser doesn't understad them and I don't feel like dealing with all the edge cases introduces by it --- src/site/store/images.js | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/site/store') diff --git a/src/site/store/images.js b/src/site/store/images.js index 4737c26..0488573 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -106,6 +106,12 @@ export const actions = { commit('removeTagFromFile', response.data); + return response; + }, + async search({ commit }, { q, albumId }) { + const optionalAlbum = albumId ? `&albumId=${albumId}` : ''; + const response = await this.$axios.$get(`search/?q=${encodeURI(q)}${optionalAlbum}`); + return response; }, }; -- cgit v1.2.3 From 151c360740aac5733759888220d91a1d3713b6e1 Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Fri, 2 Oct 2020 22:16:34 +0300 Subject: feat: allow administrators to create custom links for albums --- src/site/store/albums.js | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/site/store') diff --git a/src/site/store/albums.js b/src/site/store/albums.js index 8441182..c1ff696 100644 --- a/src/site/store/albums.js +++ b/src/site/store/albums.js @@ -55,6 +55,13 @@ export const actions = { return response; }, + async createCustomLink({ commit }, { albumId, value }) { + const response = await this.$axios.$post('album/link/new', { albumId, identifier: value }); + + commit('addAlbumLink', { albumId, data: response.data }); + + return response; + }, async updateLinkOptions({ commit }, { albumId, linkOpts }) { const response = await this.$axios.$post('album/link/edit', { identifier: linkOpts.identifier, -- cgit v1.2.3 From 90001c2df56d58e69fd199a518ae7f3e4ed327fc Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Thu, 24 Dec 2020 10:40:50 +0200 Subject: chore: remove trailing commas --- src/site/store/admin.js | 8 ++++---- src/site/store/albums.js | 16 ++++++++-------- src/site/store/alert.js | 6 +++--- src/site/store/auth.js | 14 +++++++------- src/site/store/config.js | 4 ++-- src/site/store/images.js | 14 +++++++------- src/site/store/index.js | 2 +- src/site/store/tags.js | 6 +++--- 8 files changed, 35 insertions(+), 35 deletions(-) (limited to 'src/site/store') diff --git a/src/site/store/admin.js b/src/site/store/admin.js index 04ad980..58b63b5 100644 --- a/src/site/store/admin.js +++ b/src/site/store/admin.js @@ -8,10 +8,10 @@ export const state = () => ({ editedAt: null, apiKeyEditedAt: null, isAdmin: null, - files: [], + files: [] }, file: {}, - settings: {}, + settings: {} }); export const actions = { @@ -82,7 +82,7 @@ export const actions = { const response = await this.$axios.$post('service/restart'); return response; - }, + } }; export const mutations = { @@ -118,5 +118,5 @@ export const mutations = { state.user.isAdmin = isAdmin; } } - }, + } }; diff --git a/src/site/store/albums.js b/src/site/store/albums.js index c1ff696..4f796a1 100644 --- a/src/site/store/albums.js +++ b/src/site/store/albums.js @@ -5,12 +5,12 @@ export const state = () => ({ isListLoading: false, albumDetails: {}, expandedAlbums: [], - tinyDetails: [], + tinyDetails: [] }); export const getters = { isExpanded: (state) => (id) => state.expandedAlbums.indexOf(id) > -1, - getDetails: (state) => (id) => state.albumDetails[id] || {}, + getDetails: (state) => (id) => state.albumDetails[id] || {} }; export const actions = { @@ -28,8 +28,8 @@ export const actions = { commit('setDetails', { id: albumId, details: { - links: response.links, - }, + links: response.links + } }); return response; @@ -66,7 +66,7 @@ export const actions = { const response = await this.$axios.$post('album/link/edit', { identifier: linkOpts.identifier, enableDownload: linkOpts.enableDownload, - enabled: linkOpts.enabled, + enabled: linkOpts.enabled }); commit('updateAlbumLinkOpts', { albumId, linkOpts: response.data }); @@ -86,7 +86,7 @@ export const actions = { commit('setTinyDetails', response); return response; - }, + } }; export const mutations = { @@ -113,7 +113,7 @@ export const mutations = { }, updateAlbumLinkOpts(state, { albumId, linkOpts }) { const foundIndex = state.albumDetails[albumId].links.findIndex( - ({ identifier }) => identifier === linkOpts.identifier, + ({ identifier }) => identifier === linkOpts.identifier ); const link = state.albumDetails[albumId].links[foundIndex]; state.albumDetails[albumId].links[foundIndex] = { ...link, ...linkOpts }; @@ -132,5 +132,5 @@ export const mutations = { }, setTinyDetails(state, { albums }) { state.tinyDetails = albums; - }, + } }; diff --git a/src/site/store/alert.js b/src/site/store/alert.js index 580dcc8..cbd6359 100644 --- a/src/site/store/alert.js +++ b/src/site/store/alert.js @@ -3,7 +3,7 @@ import AlertTypes from '~/constants/alertTypes'; const getDefaultState = () => ({ message: null, type: null, - snackbar: false, + snackbar: false }); export const state = getDefaultState; @@ -18,7 +18,7 @@ export const actions = { }, clear({ commit }) { commit('clear'); - }, + } }; export const mutations = { @@ -29,5 +29,5 @@ export const mutations = { }, clear(state) { Object.assign(state, getDefaultState()); - }, + } }; diff --git a/src/site/store/auth.js b/src/site/store/auth.js index 96631e2..85e3a39 100644 --- a/src/site/store/auth.js +++ b/src/site/store/auth.js @@ -3,9 +3,9 @@ const getDefaultState = () => ({ user: { id: null, isAdmin: false, - username: null, + username: null }, - token: null, + token: null }); export const state = getDefaultState; @@ -13,7 +13,7 @@ export const state = getDefaultState; export const getters = { isLoggedIn: (state) => state.loggedIn, getApiKey: (state) => state.user?.apiKey, - getToken: (state) => state.token, + getToken: (state) => state.token }; export const actions = { @@ -37,7 +37,7 @@ export const actions = { async register(_, { username, password }) { return this.$axios.$post('auth/register', { username, - password, + password }); }, async fetchCurrentUser({ commit, dispatch }) { @@ -52,7 +52,7 @@ export const actions = { try { const response = await this.$axios.$post('user/password/change', { password, - newPassword, + newPassword }); return response; @@ -76,7 +76,7 @@ export const actions = { }, logout({ commit }) { commit('logout'); - }, + } }; export const mutations = { @@ -102,5 +102,5 @@ export const mutations = { this.$cookies.remove('token', { path: '/' }); // reset state to default Object.assign(state, getDefaultState()); - }, + } }; diff --git a/src/site/store/config.js b/src/site/store/config.js index f52fc0f..c17632d 100644 --- a/src/site/store/config.js +++ b/src/site/store/config.js @@ -8,11 +8,11 @@ export const state = () => ({ chunkSize: 90, maxLinksPerAlbum: 5, publicMode: false, - userAccounts: false, + userAccounts: false }); export const mutations = { set(state, config) { Object.assign(state, config); - }, + } }; diff --git a/src/site/store/images.js b/src/site/store/images.js index 0488573..7cf25ce 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -6,14 +6,14 @@ export const getDefaultState = () => ({ pagination: { page: 1, limit: 30, - totalFiles: 0, + totalFiles: 0 }, search: '', albumName: null, albumDownloadEnabled: false, fileExtraInfoMap: {}, // information about the selected file fileAlbumsMap: {}, // map of file ids with a list of album objects the file is in - fileTagsMap: {}, // map of file ids with a list of tag objects for the file + fileTagsMap: {} // map of file ids with a list of tag objects for the file }); export const state = getDefaultState; @@ -23,7 +23,7 @@ export const getters = { getFetchedCount: ({ files }) => files.length, shouldPaginate: ({ pagination }) => pagination.totalFiles > pagination.limit, getLimit: ({ pagination }) => pagination.limit, - getName: ({ name }) => name, + getName: ({ name }) => name }; export const actions = { @@ -50,7 +50,7 @@ export const actions = { page = page || 1; const response = await this.$axios.$get(`album/${id}/full`, { - params: { limit: state.pagination.limit, page }, + params: { limit: state.pagination.limit, page } }); commit('setFilesAndMeta', { ...response, page }); @@ -113,7 +113,7 @@ export const actions = { const response = await this.$axios.$get(`search/?q=${encodeURI(q)}${optionalAlbum}`); return response; - }, + } }; export const mutations = { @@ -121,7 +121,7 @@ export const mutations = { state.isLoading = true; }, setFilesAndMeta(state, { - files, name, page, count, downloadEnabled, + files, name, page, count, downloadEnabled }) { state.files = files || []; state.albumName = name ?? null; @@ -174,5 +174,5 @@ export const mutations = { }, resetState(state) { Object.assign(state, getDefaultState()); - }, + } }; diff --git a/src/site/store/index.js b/src/site/store/index.js index c0faffb..c5d9a23 100644 --- a/src/site/store/index.js +++ b/src/site/store/index.js @@ -10,7 +10,7 @@ export const actions = { commit('auth/setToken', cookies.token); return dispatch('auth/verify'); - }, + } /* alert({ commit }, payload) { if (!payload) return commit('alert', null); commit('alert', { diff --git a/src/site/store/tags.js b/src/site/store/tags.js index c06b741..a28c2ad 100644 --- a/src/site/store/tags.js +++ b/src/site/store/tags.js @@ -1,5 +1,5 @@ export const state = () => ({ - tagsList: [], + tagsList: [] }); export const actions = { @@ -23,7 +23,7 @@ export const actions = { commit('deleteTag', response.data); return response; - }, + } }; export const mutations = { @@ -36,5 +36,5 @@ export const mutations = { deleteTag(state, { id: tagId }) { const foundIndex = state.tagsList.findIndex(({ id }) => id === tagId); state.tagsList.splice(foundIndex, 1); - }, + } }; -- cgit v1.2.3 From 587f7d69e80cfa1d94cc4730dc26834c389f574d Mon Sep 17 00:00:00 2001 From: Zephyrrus Date: Thu, 24 Dec 2020 13:57:09 +0200 Subject: bug: fix showlist resetting itself every time the page is changed bug: fix store not commiting search results --- src/site/store/images.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src/site/store') diff --git a/src/site/store/images.js b/src/site/store/images.js index 7cf25ce..69b4f5e 100644 --- a/src/site/store/images.js +++ b/src/site/store/images.js @@ -9,6 +9,7 @@ export const getDefaultState = () => ({ totalFiles: 0 }, search: '', + showList: false, albumName: null, albumDownloadEnabled: false, fileExtraInfoMap: {}, // information about the selected file @@ -108,11 +109,22 @@ export const actions = { return response; }, - async search({ commit }, { q, albumId }) { + async search({ commit, dispatch }, { q, albumId, page }) { const optionalAlbum = albumId ? `&albumId=${albumId}` : ''; - const response = await this.$axios.$get(`search/?q=${encodeURI(q)}${optionalAlbum}`); - return response; + page = page || 1; + + try { + const response = await this.$axios.$get(`search/?q=${encodeURI(q)}${optionalAlbum}`); + + commit('setFilesAndMeta', { ...response, page }); + + return response; + } catch (e) { + dispatch('alert/set', { text: e.message, error: true }, { root: true }); + } + + return null; } }; @@ -172,6 +184,9 @@ export const mutations = { state.fileTagsMap[fileId].splice(foundIndex, 1); } }, + setShowList(state, showList) { + state.showList = showList; + }, resetState(state) { Object.assign(state, getDefaultState()); } -- cgit v1.2.3