diff options
Diffstat (limited to 'src/site')
| -rw-r--r-- | src/site/components/grid/Grid.vue | 62 | ||||
| -rw-r--r-- | src/site/pages/a/_identifier.vue | 112 | ||||
| -rw-r--r-- | src/site/pages/dashboard/account.vue | 7 | ||||
| -rw-r--r-- | src/site/pages/dashboard/admin/file/_id.vue | 12 | ||||
| -rw-r--r-- | src/site/pages/dashboard/admin/settings.vue | 16 | ||||
| -rw-r--r-- | src/site/pages/dashboard/admin/statistics.vue | 11 | ||||
| -rw-r--r-- | src/site/pages/dashboard/admin/user/_id.vue | 59 | ||||
| -rw-r--r-- | src/site/pages/dashboard/admin/users.vue | 12 | ||||
| -rw-r--r-- | src/site/pages/dashboard/albums/_id.vue | 4 | ||||
| -rw-r--r-- | src/site/pages/dashboard/albums/index.vue | 11 | ||||
| -rw-r--r-- | src/site/pages/dashboard/index.vue | 6 | ||||
| -rw-r--r-- | src/site/plugins/handler.js | 12 | ||||
| -rw-r--r-- | src/site/plugins/nuxt-client-init.js | 3 | ||||
| -rw-r--r-- | src/site/static/logo.png | bin | 0 -> 13039 bytes | |||
| -rw-r--r-- | src/site/store/admin.js | 10 | ||||
| -rw-r--r-- | src/site/store/index.js | 3 |
16 files changed, 188 insertions, 152 deletions
diff --git a/src/site/components/grid/Grid.vue b/src/site/components/grid/Grid.vue index 9e1ce6f..3a0045b 100644 --- a/src/site/components/grid/Grid.vue +++ b/src/site/components/grid/Grid.vue @@ -227,17 +227,14 @@ export default { showList: 'displayTypeChange' }, created() { - // TODO: Create a middleware for this - this.getAlbums(); - this.getTags(); + if (!this.isPublic) { + this.$handler.executeAction('albums/getTinyDetails', null, false); + this.$handler.executeAction('tags/fetch', null, false); + } this.showList = this.images.showList; }, methods: { - async search() { - const data = await this.$search.do(this.searchTerm, ['name', 'original', 'type', 'albums:name']); - console.log('> Search result data', data); // eslint-disable-line no-console - }, deleteFile(file) { // this.$emit('delete', file); this.$buefy.dialog.confirm({ @@ -246,13 +243,7 @@ export default { confirmText: 'Delete File', type: 'is-danger', onConfirm: async () => { - try { - const response = await this.$store.dispatch('images/deleteFile', file.id); - - this.$buefy.toast.open(response.message); - } catch (e) { - this.$store.dispatch('alert/set', { text: e.message, error: true }, { root: true }); - } + await this.$handler.executeAction('images/deleteFile', file.id); } }); }, @@ -266,41 +257,17 @@ export default { this.showingModalForFile = file; this.showingModalForFile.albums = []; - try { - await this.$store.dispatch('images/getFileAlbums', id); - } catch (e) { - this.$store.dispatch('alert/set', { text: e.message, error: true }, { root: true }); - } + await this.$handler.executeAction('images/getFileAlbums', id, false); + this.showingModalForFile.albums = this.images.fileAlbumsMap[id]; this.isAlbumsModalActive = true; }, async albumCheckboxClicked(add, id) { - try { - let response; - if (add) { - response = await this.$store.dispatch('images/addToAlbum', { - albumId: id, - fileId: this.showingModalForFile.id - }); - } else { - response = await this.$store.dispatch('images/removeFromAlbum', { - albumId: id, - fileId: this.showingModalForFile.id - }); - } - - this.$buefy.toast.open(response.message); - } catch (e) { - this.$store.dispatch('alert/set', { text: e.message, error: true }, { root: true }); - } - }, - async getAlbums() { - try { - await this.$store.dispatch('albums/getTinyDetails'); - } catch (e) { - this.$store.dispatch('alert/set', { text: e.message, error: true }, { root: true }); - } + await this.$handler.executeAction(add ? 'images/addToAlbum' : 'images/removeFromAlbum', { + albumId: id, + fileId: this.showingModalForFile.id + }); }, async handleFileModal(file) { const { id } = file; @@ -316,13 +283,6 @@ export default { this.isAlbumsModalActive = true; }, - async getTags() { - try { - await this.$store.dispatch('tags/fetch'); - } catch (e) { - this.$store.dispatch('alert/set', { text: e.message, error: true }, { root: true }); - } - }, mouseOver(id) { const foundIndex = this.hoveredItems.indexOf(id); if (foundIndex > -1) return; diff --git a/src/site/pages/a/_identifier.vue b/src/site/pages/a/_identifier.vue index 7ffed35..d9abf0a 100644 --- a/src/site/pages/a/_identifier.vue +++ b/src/site/pages/a/_identifier.vue @@ -7,7 +7,7 @@ {{ name }} </h1> <h2 class="subtitle"> - Serving {{ files ? files.length : 0 }} files + Serving {{ totalFiles }} files </h2> <a v-if="downloadLink" @@ -23,7 +23,24 @@ :is-public="true" :width="200" :enable-search="false" - :enable-toolbar="false" /> + :enable-toolbar="false"> + <template v-slot:pagination> + <b-pagination + :total="totalFiles" + :per-page="limit" + :current.sync="current" + range-before="2" + range-after="2" + class="pagination-slot" + icon-prev="icon-interface-arrow-left" + icon-next="icon-interface-arrow-right" + icon-pack="icon" + aria-next-label="Next page" + aria-previous-label="Previous page" + aria-page-label="Page" + aria-current-label="Current page" /> + </template> + </Grid> </template> <template v-else> <div class="nsfw"> @@ -56,67 +73,103 @@ </template> <script> +import { mapGetters } from 'vuex'; import axios from 'axios'; import Grid from '~/components/grid/Grid.vue'; - +import logo from '~/assets/images/logo.png'; export default { components: { Grid }, data() { return { - nsfwConsent: false + nsfwConsent: false, + current: 1, + name: null, + downloadEnabled: false, + files: [], + downloadLink: null, + isNsfw: false, + totalFiles: 0 }; }, computed: { + ...mapGetters({ + limit: 'images/getLimit' + }), config() { return this.$store.state.config; } }, + watch: { + current: 'fetchPaginate' + }, async asyncData({ app, params, error }) { try { - const { data } = await axios.get(`${app.store.state.config.baseURL}/album/${params.identifier}`); + const { data } = await axios.get(`${app.store.state.config.baseURL}/album/${params.identifier}`, { params: { limit: 50, page: 1 } }); const downloadLink = data.downloadEnabled ? `${app.store.state.config.baseURL}/album/${params.identifier}/zip` : null; return { name: data.name, downloadEnabled: data.downloadEnabled, files: data.files, downloadLink, - isNsfw: data.isNsfw + isNsfw: data.isNsfw, + totalFiles: data.count }; } catch (err) { console.log('Error when retrieving album', err); error({ statusCode: 404, message: 'Album not found' }); } }, - metaInfo() { + methods: { + async fetch(page = 1) { + try { + const { data } = await axios.get( + `${this.$store.state.config.baseURL}/album/${this.$route.params.identifier}`, + { params: { limit: 50, page } } + ); + const downloadLink = data.downloadEnabled ? `${this.$store.state.config.baseURL}/album/${this.$route.params.identifier}/zip` : null; + + this.name = data.name; + this.downloadEnabled = data.downloadEnabled; + this.files = data.files; + this.downloadLink = downloadLink; + this.isNsfw = data.isNsfw; + this.totalFiles = data.count; + } catch (err) { + this.$notifier.error(err.message); + } + }, + async fetchPaginate() { + this.isLoading = true; + await this.fetch(this.current); + this.isLoading = false; + } + }, + head() { if (this.files) { + const image = this.isNsfw ? logo : this.files.length ? this.files[0].url : logo; + const title = this.name ? this.isNsfw ? `[NSFW] ${this.name}` : this.name : ''; + const description = `Files: ${this.totalFiles}`; return { - title: `${this.name ? this.name : ''}`, + title, meta: [ - { vmid: 'theme-color', name: 'theme-color', content: '#30a9ed' }, - { vmid: 'twitter:card', name: 'twitter:card', content: 'summary' }, - { vmid: 'twitter:title', name: 'twitter:title', content: `Album: ${this.name} | Files: ${this.files.length}` }, - { vmid: 'twitter:description', name: 'twitter:description', content: 'A modern and self-hosted file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind.' }, - { vmid: 'twitter:image', name: 'twitter:image', content: `${this.files.length > 0 ? this.files[0].thumbSquare : '/public/images/share.jpg'}` }, - { vmid: 'twitter:image:src', name: 'twitter:image:src', value: `${this.files.length > 0 ? this.files[0].thumbSquare : '/public/images/share.jpg'}` }, - - { vmid: 'og:url', property: 'og:url', content: `${this.config.URL}/a/${this.$route.params.identifier}` }, - { vmid: 'og:title', property: 'og:title', content: `Album: ${this.name} | Files: ${this.files.length}` }, - { vmid: 'og:description', property: 'og:description', content: 'A modern and self-hosted file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind.' }, - { vmid: 'og:image', property: 'og:image', content: `${this.files.length > 0 ? this.files[0].thumbSquare : '/public/images/share.jpg'}` }, - { vmid: 'og:image:secure_url', property: 'og:image:secure_url', content: `${this.files.length > 0 ? this.files[0].thumbSquare : '/public/images/share.jpg'}` } + { hid: 'twitter:card', name: 'twitter:card', content: 'summary' }, + { hid: 'twitter:title', name: 'twitter:title', content: title }, + { hid: 'twitter:image', name: 'twitter:image', content: image }, + { hid: 'twitter:label1', name: 'twitter:label1', value: 'Files' }, + { hid: 'twitter:data1', name: 'twitter:data1', value: this.totalFiles }, + { hid: 'twitter:description', name: 'twitter:description', content: description }, + { hid: 'og:description', property: 'og:description', content: description }, + { hid: 'og:url', property: 'og:url', content: `${this.config.URL}/a/${this.$route.params.identifier}` }, + { hid: 'og:title', property: 'og:title', content: title }, + { hid: 'og:image', property: 'og:image', content: image }, + { hid: 'og:image:secure_url', property: 'og:image:secure_url', content: image } ] }; } return { title: `${this.name ? this.name : ''}`, meta: [ - { vmid: 'theme-color', name: 'theme-color', content: '#30a9ed' }, - { vmid: 'twitter:card', name: 'twitter:card', content: 'summary' }, - { vmid: 'twitter:title', name: 'twitter:title', content: 'chibisafe' }, - { vmid: 'twitter:description', name: 'twitter:description', content: 'A modern and self-hosted file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind.' }, - { vmid: 'og:url', property: 'og:url', content: `${this.config.URL}/a/${this.$route.params.identifier}` }, - { vmid: 'og:title', property: 'og:title', content: 'chibisafe' }, - { vmid: 'og:description', property: 'og:description', content: 'A modern and self-hosted file upload service that can handle anything you throw at it. Fast uploads, file manager and sharing capabilities all crafted with a beautiful user experience in mind.' } + { hid: 'og:url', property: 'og:url', content: `${this.config.URL}/a/${this.$route.params.identifier}` } ] }; } @@ -151,3 +204,8 @@ export default { } } </style> +<style lang="scss"> + .pagination-slot > .pagination-previous, .pagination-slot > .pagination-next { + display: none !important; + } +</style> diff --git a/src/site/pages/dashboard/account.vue b/src/site/pages/dashboard/account.vue index 05b969b..5d5d775 100644 --- a/src/site/pages/dashboard/account.vue +++ b/src/site/pages/dashboard/account.vue @@ -104,9 +104,7 @@ export default { components: { Sidebar }, - middleware: ['auth', ({ store }) => { - store.dispatch('auth/fetchCurrentUser'); - }], + middleware: ['auth'], data() { return { password: '', @@ -120,6 +118,9 @@ export default { user: state => state.auth.user }) }, + async asyncData({ app }) { + await app.store.dispatch('auth/fetchCurrentUser'); + }, methods: { ...mapActions({ getUserSetttings: 'auth/fetchCurrentUser' diff --git a/src/site/pages/dashboard/admin/file/_id.vue b/src/site/pages/dashboard/admin/file/_id.vue index 135d066..2d7607f 100644 --- a/src/site/pages/dashboard/admin/file/_id.vue +++ b/src/site/pages/dashboard/admin/file/_id.vue @@ -129,15 +129,11 @@ export default { components: { Sidebar }, - middleware: ['auth', 'admin', ({ route, store }) => { - try { - store.dispatch('admin/fetchFile', route.params.id); - } catch (e) { - // eslint-disable-next-line no-console - console.error(e); - } - }], + middleware: ['auth', 'admin'], computed: mapState(['admin', 'auth']), + async asyncData({ app, params }) { + await app.store.dispatch('admin/fetchFile', params.id); + }, methods: { promptDisableUser() { this.$buefy.dialog.confirm({ diff --git a/src/site/pages/dashboard/admin/settings.vue b/src/site/pages/dashboard/admin/settings.vue index bd23b1c..3b2e99b 100644 --- a/src/site/pages/dashboard/admin/settings.vue +++ b/src/site/pages/dashboard/admin/settings.vue @@ -41,16 +41,7 @@ export default { Sidebar, JoiObject }, - middleware: ['auth', 'admin', ({ store }) => { - try { - store.dispatch('admin/fetchSettings'); - // TODO: Implement merging fields with values from the db (no endpoint to fetch settings yet) - store.dispatch('admin/getSettingsSchema'); - } catch (e) { - // eslint-disable-next-line no-console - console.error(e); - } - }], + middleware: ['auth', 'admin'], computed: { ...mapState({ settings: state => state.admin.settings, @@ -71,6 +62,11 @@ export default { }, {}); } }, + async asyncData({ app }) { + await app.store.dispatch('admin/fetchSettings'); + // TODO: Implement merging fields with values from the db (no endpoint to fetch settings yet) + await app.store.dispatch('admin/getSettingsSchema'); + }, methods: { promptRestartService() { this.$buefy.dialog.confirm({ diff --git a/src/site/pages/dashboard/admin/statistics.vue b/src/site/pages/dashboard/admin/statistics.vue index c1e79fc..1b951fc 100644 --- a/src/site/pages/dashboard/admin/statistics.vue +++ b/src/site/pages/dashboard/admin/statistics.vue @@ -78,16 +78,13 @@ export default { detailed, generic }, - middleware: ['auth', 'admin', ({ store }) => { - try { - store.dispatch('admin/fetchStatistics'); - } catch (e) { - console.error(e); - } - }], + middleware: ['auth', 'admin'], computed: mapState({ stats: state => state.admin.statistics }), + async asyncData({ app }) { + await app.store.dispatch('admin/fetchStatistics'); + }, methods: { refresh(category) { try { diff --git a/src/site/pages/dashboard/admin/user/_id.vue b/src/site/pages/dashboard/admin/user/_id.vue index 0ed3e86..7e0b182 100644 --- a/src/site/pages/dashboard/admin/user/_id.vue +++ b/src/site/pages/dashboard/admin/user/_id.vue @@ -61,7 +61,24 @@ <Grid v-if="user.files.length" - :files="user.files" /> + :files="user.files"> + <template v-slot:pagination> + <b-pagination + :total="user.totalFiles" + :per-page="limit" + :current.sync="current" + range-before="2" + range-after="2" + class="pagination-slot" + icon-prev="icon-interface-arrow-left" + icon-next="icon-interface-arrow-right" + icon-pack="icon" + aria-next-label="Next page" + aria-previous-label="Previous page" + aria-page-label="Page" + aria-current-label="Current page" /> + </template> + </Grid> </div> </div> </div> @@ -69,7 +86,7 @@ </template> <script> -import { mapState } from 'vuex'; +import { mapState, mapGetters, mapActions } from 'vuex'; import Sidebar from '~/components/sidebar/Sidebar.vue'; import Grid from '~/components/grid/Grid.vue'; @@ -78,23 +95,37 @@ export default { Sidebar, Grid }, - middleware: ['auth', 'admin', ({ route, store }) => { - try { - store.dispatch('admin/fetchUser', route.params.id); - } catch (e) { - // eslint-disable-next-line no-console - console.error(e); - } - }], + middleware: ['auth', 'admin'], data() { return { - options: {} + options: {}, + current: 1, + isLoading: false }; }, - computed: mapState({ - user: state => state.admin.user - }), + computed: { + ...mapGetters({ + limit: 'images/getLimit' + }), + ...mapState({ + user: state => state.admin.user + }) + }, + watch: { + current: 'fetchPaginate' + }, + async asyncData({ app, params }) { + await app.store.dispatch('admin/fetchUser', { id: params.id }); + }, methods: { + ...mapActions({ + fetch: 'admin/fetchUser' + }), + async fetchPaginate() { + this.isLoading = true; + await this.fetch({ id: this.$route.params.id, page: this.current }); + this.isLoading = false; + }, promptDisableUser() { this.$buefy.dialog.confirm({ type: 'is-danger', diff --git a/src/site/pages/dashboard/admin/users.vue b/src/site/pages/dashboard/admin/users.vue index 5195e5d..556049d 100644 --- a/src/site/pages/dashboard/admin/users.vue +++ b/src/site/pages/dashboard/admin/users.vue @@ -143,14 +143,7 @@ export default { components: { Sidebar }, - middleware: ['auth', 'admin', ({ route, store }) => { - try { - store.dispatch('admin/fetchUsers', route.params.id); - } catch (e) { - // eslint-disable-next-line no-console - console.error(e); - } - }], + middleware: ['auth', 'admin'], data() { return { isCreateUserOpen: false, @@ -163,6 +156,9 @@ export default { users: state => state.admin.users, config: state => state.config }), + async asyncData({ app, params }) { + await app.store.dispatch('admin/fetchUsers', params.id); + }, methods: { async changeEnabledStatus(row) { if (row.enabled) { diff --git a/src/site/pages/dashboard/albums/_id.vue b/src/site/pages/dashboard/albums/_id.vue index faaf27c..446d3ac 100644 --- a/src/site/pages/dashboard/albums/_id.vue +++ b/src/site/pages/dashboard/albums/_id.vue @@ -76,7 +76,6 @@ export default { }, middleware: ['auth', ({ route, store }) => { store.commit('images/resetState'); - store.dispatch('images/fetchByAlbumId', { id: route.params.id }); }], data() { return { @@ -101,6 +100,9 @@ export default { watch: { current: 'fetchPaginate' }, + async asyncData({ app, params }) { + await app.store.dispatch('images/fetchByAlbumId', { id: params.id }); + }, methods: { ...mapActions({ fetch: 'images/fetchByAlbumId' diff --git a/src/site/pages/dashboard/albums/index.vue b/src/site/pages/dashboard/albums/index.vue index 2ebfb3f..686edc3 100644 --- a/src/site/pages/dashboard/albums/index.vue +++ b/src/site/pages/dashboard/albums/index.vue @@ -55,13 +55,7 @@ export default { Sidebar, AlbumEntry }, - middleware: ['auth', ({ store }) => { - try { - store.dispatch('albums/fetch'); - } catch (e) { - this.alert({ text: e.message, error: true }); - } - }], + middleware: ['auth'], data() { return { newAlbumName: null, @@ -69,6 +63,9 @@ export default { }; }, computed: mapState(['config', 'albums']), + async asyncData({ app }) { + await app.store.dispatch('albums/fetch'); + }, methods: { ...mapActions({ alert: 'alert/set' diff --git a/src/site/pages/dashboard/index.vue b/src/site/pages/dashboard/index.vue index 4877e15..bd7b745 100644 --- a/src/site/pages/dashboard/index.vue +++ b/src/site/pages/dashboard/index.vue @@ -68,7 +68,6 @@ export default { }, middleware: ['auth', ({ store }) => { store.commit('images/resetState'); - store.dispatch('images/fetch'); }], data() { return { @@ -88,7 +87,10 @@ export default { watch: { current: 'fetchPaginate' }, - created() { + async asyncData({ app }) { + await app.store.dispatch('images/fetch'); + }, + mounted() { this.filteredHints = this.hints; // fixes the issue where on pageload, suggestions wont load }, methods: { diff --git a/src/site/plugins/handler.js b/src/site/plugins/handler.js index 7933eab..f4be79c 100644 --- a/src/site/plugins/handler.js +++ b/src/site/plugins/handler.js @@ -2,14 +2,16 @@ import AlertTypes from '~/constants/alertTypes'; export default ({ store }, inject) => { inject('handler', { - async executeAction(action, param) { + async executeAction(action, param, showSuccess = true) { try { const response = await store.dispatch(action, param); - store.commit('alert/set', { - message: response?.message ?? 'Executed sucesfully', - type: AlertTypes.SUCCESS - }); + if (showSuccess) { + store.commit('alert/set', { + message: response?.message ?? 'Executed sucesfully', + type: AlertTypes.SUCCESS + }); + } return response; } catch (e) { diff --git a/src/site/plugins/nuxt-client-init.js b/src/site/plugins/nuxt-client-init.js deleted file mode 100644 index 4b10dcd..0000000 --- a/src/site/plugins/nuxt-client-init.js +++ /dev/null @@ -1,3 +0,0 @@ -export default async ctx => { - await ctx.store.dispatch('nuxtClientInit', ctx); -}; diff --git a/src/site/static/logo.png b/src/site/static/logo.png Binary files differnew file mode 100644 index 0000000..500445b --- /dev/null +++ b/src/site/static/logo.png diff --git a/src/site/store/admin.js b/src/site/store/admin.js index 72cd919..4f814b5 100644 --- a/src/site/store/admin.js +++ b/src/site/store/admin.js @@ -45,9 +45,10 @@ export const actions = { return response; }, - async fetchUser({ commit }, id) { - const response = await this.$axios.$get(`admin/users/${id}`); - commit('setUserInfo', response); + async fetchUser({ commit }, { id, page }) { + page = page || 1; + const response = await this.$axios.$get(`admin/users/${id}`, { params: { limit: 50, page } }); + commit('setUserInfo', { ...response, page }); return response; }, @@ -120,9 +121,10 @@ export const mutations = { setUsers(state, { users }) { state.users = users; }, - setUserInfo(state, { user, files }) { + setUserInfo(state, { user, files, count }) { state.user = { ...state.user, ...user }; state.user.files = files || []; + state.user.totalFiles = count; }, setFile(state, { file }) { state.file = file || {}; diff --git a/src/site/store/index.js b/src/site/store/index.js index 94d673f..b94a336 100644 --- a/src/site/store/index.js +++ b/src/site/store/index.js @@ -1,9 +1,8 @@ import config from '../../../dist/config.json'; export const actions = { - async nuxtClientInit({ commit, dispatch }) { + async nuxtServerInit({ commit, dispatch }) { commit('config/set', config); - const cookies = this.$cookies.getAll(); if (!cookies.token) return dispatch('auth/logout'); |