diff --git a/config/vuefilemanager.php b/config/vuefilemanager.php index 928897b6..6dfff8d1 100644 --- a/config/vuefilemanager.php +++ b/config/vuefilemanager.php @@ -60,4 +60,8 @@ return [ ], ], ], + + 'paginate' => [ + 'perPage' => 50 + ] ]; diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 05ada352..eb14b871 100644 --- a/public/mix-manifest.json +++ b/public/mix-manifest.json @@ -1,75 +1,75 @@ { "/js/main.js": "/js/main.js", - "/chunks/request.js": "/chunks/request.js?id=37e3e34fbcc98d4c", - "/chunks/request-upload.js": "/chunks/request-upload.js?id=2a6d910114ffb8d2", - "/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=3c2fc454c3fce8d2", - "/chunks/status-check.js": "/chunks/status-check.js?id=783c6143db13e6c0", - "/chunks/purchase-code.js": "/chunks/purchase-code.js?id=c1df85c34d7e9521", - "/chunks/database.js": "/chunks/database.js?id=d4f38bfdef26b0d9", - "/chunks/environment-setup.js": "/chunks/environment-setup.js?id=21e576c9c8183e42", - "/chunks/app-setup.js": "/chunks/app-setup.js?id=647bf9cdc907e83c", - "/chunks/admin-account.js": "/chunks/admin-account.js?id=d21b66f2b6e1638e", - "/chunks/shared.js": "/chunks/shared.js?id=52ff66b9c01f84ef", - "/chunks/shared/browser.js": "/chunks/shared/browser.js?id=a9710655d75c8079", - "/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=c013d98f7386c448", - "/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=ca8cc89fe5982782", - "/chunks/not-found.js": "/chunks/not-found.js?id=4cb8d3a7a2212c3c", - "/chunks/temporary-unavailable.js": "/chunks/temporary-unavailable.js?id=c71981d946a9ca71", - "/chunks/admin.js": "/chunks/admin.js?id=4c86279cd6e85aa5", - "/chunks/dashboard.js": "/chunks/dashboard.js?id=d8740b43db79abfe", - "/chunks/invoices.js": "/chunks/invoices.js?id=70fb9a603be2f554", - "/chunks/subscriptions.js": "/chunks/subscriptions.js?id=94e96e1bb505ae59", - "/chunks/pages.js": "/chunks/pages.js?id=d1f5d211e9dfc4ae", - "/chunks/page-edit.js": "/chunks/page-edit.js?id=184547a95a64a121", - "/chunks/plans.js": "/chunks/plans.js?id=f6e9d2f34fac6d79", - "/chunks/users.js": "/chunks/users.js?id=651b8af7afecc88e", - "/chunks/user-create.js": "/chunks/user-create.js?id=d24c5037b91a2fa2", - "/chunks/plan-create/fixed.js": "/chunks/plan-create/fixed.js?id=20a6ee217157864f", - "/chunks/plan-create/metered.js": "/chunks/plan-create/metered.js?id=617982724a144a43", - "/chunks/user.js": "/chunks/user.js?id=dae4ac26750f99d0", - "/chunks/user-detail.js": "/chunks/user-detail.js?id=d56437755ba2c6cc", - "/chunks/user-storage.js": "/chunks/user-storage.js?id=c26b370f6f4323fe", - "/chunks/user-subscription.js": "/chunks/user-subscription.js?id=6d7d1235d1ae5bf2", - "/chunks/user-password.js": "/chunks/user-password.js?id=acd9b49cca55d161", - "/chunks/user-delete.js": "/chunks/user-delete.js?id=47d44b2f8e4e620c", - "/chunks/plan.js": "/chunks/plan.js?id=d8ffa85dc9b68966", - "/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=3010ddb4ba7419e9", - "/chunks/plan-settings.js": "/chunks/plan-settings.js?id=d3c236e167831f25", - "/chunks/plan-delete.js": "/chunks/plan-delete.js?id=44ad905bfe1ae983", - "/chunks/payments.js": "/chunks/payments.js?id=051e8246e2b5c9d0", - "/chunks/payments/billings.js": "/chunks/payments/billings.js?id=7ec4ad9b9755b2b8", - "/chunks/payments/settings.js": "/chunks/payments/settings.js?id=6644b642875c732f", - "/chunks/app-settings.js": "/chunks/app-settings.js?id=692d3291fb9d2cf7", - "/chunks/app-appearance.js": "/chunks/app-appearance.js?id=27652021b725b9e7", - "/chunks/app-index.js": "/chunks/app-index.js?id=968d5378d871f070", - "/chunks/app-environment.js": "/chunks/app-environment.js?id=09a06687b64b4246", - "/chunks/app-others.js": "/chunks/app-others.js?id=2c024715a619858e", - "/chunks/app-sign-in-out.js": "/chunks/app-sign-in-out.js?id=ea65b443a513ad8c", - "/chunks/app-adsense.js": "/chunks/app-adsense.js?id=c4c4cda03202a49a", - "/chunks/app-server.js": "/chunks/app-server.js?id=307fce5c9d192bf3", - "/chunks/app-language.js": "/chunks/app-language.js?id=51c79c7bdb8f9382", - "/chunks/homepage.js": "/chunks/homepage.js?id=b45798483b942ac1", - "/chunks/dynamic-page.js": "/chunks/dynamic-page.js?id=e110e8923b6ca22f", - "/chunks/contact-us.js": "/chunks/contact-us.js?id=54d3469e6d46cef6", - "/chunks/successfully-email-verified.js": "/chunks/successfully-email-verified.js?id=3153532f0d2273c8", - "/chunks/successfully-email-send.js": "/chunks/successfully-email-send.js?id=d630ed9f6f558509", - "/chunks/sign-in.js": "/chunks/sign-in.js?id=73e0fd17a1b1677d", - "/chunks/sign-up.js": "/chunks/sign-up.js?id=920ebe5b86e59c09", - "/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=9c62b8573fbdd567", - "/chunks/create-new-password.js": "/chunks/create-new-password.js?id=926b35b6745d99ba", - "/chunks/settings.js": "/chunks/settings.js?id=a1244ef9a4054cdf", - "/chunks/profile.js": "/chunks/profile.js?id=e92af0c70da9aa83", - "/chunks/settings-password.js": "/chunks/settings-password.js?id=080d3133ed6bc14c", - "/chunks/settings-storage.js": "/chunks/settings-storage.js?id=736118b6409186cc", - "/chunks/billing.js": "/chunks/billing.js?id=e4e8b9c2f7fa6cd2", - "/chunks/platform.js": "/chunks/platform.js?id=dd458bc66dd8cb51", - "/chunks/files.js": "/chunks/files.js?id=5d6eb9b9f9ecd296", - "/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=827d3a5dcce159b5", - "/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=2a4e4e0db02cbcbb", - "/chunks/trash.js": "/chunks/trash.js?id=8362aa0f91231350", - "/chunks/team-folders.js": "/chunks/team-folders.js?id=0a46fecf35a23406", - "/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=77a33583775c6d8f", - "/chunks/invitation.js": "/chunks/invitation.js?id=64a211c90b505767", + "/chunks/request.js": "/chunks/request.js?id=e12cca6ff4d753a0", + "/chunks/request-upload.js": "/chunks/request-upload.js?id=6162439c4476a9fb", + "/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=e8b9ac5e5a0854bf", + "/chunks/status-check.js": "/chunks/status-check.js?id=4c7482ca1bc4806d", + "/chunks/purchase-code.js": "/chunks/purchase-code.js?id=95910a6098545b18", + "/chunks/database.js": "/chunks/database.js?id=f075fa5bd4011705", + "/chunks/environment-setup.js": "/chunks/environment-setup.js?id=6a2f88cf2e1c8c42", + "/chunks/app-setup.js": "/chunks/app-setup.js?id=fac96a371fa057a9", + "/chunks/admin-account.js": "/chunks/admin-account.js?id=f207f8887394310d", + "/chunks/shared.js": "/chunks/shared.js?id=cdfbac570212aaba", + "/chunks/shared/browser.js": "/chunks/shared/browser.js?id=eb7d18bbc0ac131a", + "/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=fda3ee1897218fb4", + "/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=a68c497e91a6fadb", + "/chunks/not-found.js": "/chunks/not-found.js?id=cbcb2fcb42696af3", + "/chunks/temporary-unavailable.js": "/chunks/temporary-unavailable.js?id=8b78c188c3ef58cc", + "/chunks/admin.js": "/chunks/admin.js?id=23b353c5fba8f97b", + "/chunks/dashboard.js": "/chunks/dashboard.js?id=c265489f6698ba44", + "/chunks/invoices.js": "/chunks/invoices.js?id=4888dcbcb1371d33", + "/chunks/subscriptions.js": "/chunks/subscriptions.js?id=c754f2735eefc4c9", + "/chunks/pages.js": "/chunks/pages.js?id=d7fa7d4e7183174e", + "/chunks/page-edit.js": "/chunks/page-edit.js?id=3bd81e19fcce81aa", + "/chunks/plans.js": "/chunks/plans.js?id=d69f27e0eef6cd1a", + "/chunks/users.js": "/chunks/users.js?id=89c6cffd734c97b0", + "/chunks/user-create.js": "/chunks/user-create.js?id=200db7025d533298", + "/chunks/plan-create/fixed.js": "/chunks/plan-create/fixed.js?id=9d40af67b3f3eb25", + "/chunks/plan-create/metered.js": "/chunks/plan-create/metered.js?id=47674b7d5dd105e6", + "/chunks/user.js": "/chunks/user.js?id=b9b5caf4720670e9", + "/chunks/user-detail.js": "/chunks/user-detail.js?id=ae8139dee6bc9148", + "/chunks/user-storage.js": "/chunks/user-storage.js?id=415f9f91492ec6eb", + "/chunks/user-subscription.js": "/chunks/user-subscription.js?id=2e485797f12f64c8", + "/chunks/user-password.js": "/chunks/user-password.js?id=30e1861f3b9f4e2b", + "/chunks/user-delete.js": "/chunks/user-delete.js?id=61995898ac991620", + "/chunks/plan.js": "/chunks/plan.js?id=d8cdd722694b202d", + "/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=a264bff3e18fbb1c", + "/chunks/plan-settings.js": "/chunks/plan-settings.js?id=aaaf30d34d941711", + "/chunks/plan-delete.js": "/chunks/plan-delete.js?id=385d94cbf75154cd", + "/chunks/payments.js": "/chunks/payments.js?id=26aa71dcfe9109fb", + "/chunks/payments/billings.js": "/chunks/payments/billings.js?id=c2edc02c0261af92", + "/chunks/payments/settings.js": "/chunks/payments/settings.js?id=72383895b3bfb5a4", + "/chunks/app-settings.js": "/chunks/app-settings.js?id=a6b8202457054e7c", + "/chunks/app-appearance.js": "/chunks/app-appearance.js?id=8a139759c507aab3", + "/chunks/app-index.js": "/chunks/app-index.js?id=0237d25f5fec22f8", + "/chunks/app-environment.js": "/chunks/app-environment.js?id=5cdd3a4a5276b300", + "/chunks/app-others.js": "/chunks/app-others.js?id=8c9ef45b8163b98e", + "/chunks/app-sign-in-out.js": "/chunks/app-sign-in-out.js?id=bdd9ab8b100e63e9", + "/chunks/app-adsense.js": "/chunks/app-adsense.js?id=916521e9750df132", + "/chunks/app-server.js": "/chunks/app-server.js?id=daa05ca55f05276e", + "/chunks/app-language.js": "/chunks/app-language.js?id=3dc649491be91954", + "/chunks/homepage.js": "/chunks/homepage.js?id=8d839489cb2670b7", + "/chunks/dynamic-page.js": "/chunks/dynamic-page.js?id=0b84c5e06b3f1202", + "/chunks/contact-us.js": "/chunks/contact-us.js?id=c2f9beea77a7109b", + "/chunks/successfully-email-verified.js": "/chunks/successfully-email-verified.js?id=d080d93ce30187d1", + "/chunks/successfully-email-send.js": "/chunks/successfully-email-send.js?id=5d0042e9619ed73e", + "/chunks/sign-in.js": "/chunks/sign-in.js?id=379b9147d37291d5", + "/chunks/sign-up.js": "/chunks/sign-up.js?id=d1bcad80748579ae", + "/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=7e713217b427cc06", + "/chunks/create-new-password.js": "/chunks/create-new-password.js?id=094a12eb5ba69c9f", + "/chunks/settings.js": "/chunks/settings.js?id=7ef82be482dcf31d", + "/chunks/profile.js": "/chunks/profile.js?id=d280577d80754c91", + "/chunks/settings-password.js": "/chunks/settings-password.js?id=4f56d97ef76cff6e", + "/chunks/settings-storage.js": "/chunks/settings-storage.js?id=e6866a6ffd9c3a80", + "/chunks/billing.js": "/chunks/billing.js?id=ce81cf6583d26d4c", + "/chunks/platform.js": "/chunks/platform.js?id=8899666aebaf9db4", + "/chunks/files.js": "/chunks/files.js?id=5f981e4f05062e30", + "/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=3469cce1ee71c03c", + "/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=2f712e064ac8e575", + "/chunks/trash.js": "/chunks/trash.js?id=2df58d71ed9f7ea2", + "/chunks/team-folders.js": "/chunks/team-folders.js?id=7bda1a54e372f0de", + "/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=f8eec4a942b431a0", + "/chunks/invitation.js": "/chunks/invitation.js?id=3220065b746aa8fe", "/css/tailwind.css": "/css/tailwind.css", "/css/app.css": "/css/app.css" } diff --git a/resources/js/components/FilesView/FileBrowser.vue b/resources/js/components/FilesView/FileBrowser.vue index 0318686a..14c451af 100644 --- a/resources/js/components/FilesView/FileBrowser.vue +++ b/resources/js/components/FilesView/FileBrowser.vue @@ -11,6 +11,7 @@ @dragover="dragEnter" @dragleave="dragLeave" @dragover.prevent + @scroll="infiniteScroll" tabindex="-1" @click.self="deselect" > @@ -24,6 +25,14 @@ :key="item.data.id" :item="item" /> + + +
+ +
@@ -31,14 +40,16 @@ import ItemHandler from './ItemHandler' import { events } from '../../bus' import { mapGetters } from 'vuex' +import Spinner from './Spinner' export default { name: 'FileBrowser', components: { ItemHandler, + Spinner }, computed: { - ...mapGetters(['isVisibleSidebar', 'currentFolder', 'itemViewType', 'clipboard', 'entries', 'config']), + ...mapGetters(['isVisibleSidebar', 'currentFolder', 'itemViewType', 'clipboard', 'entries', 'config', 'paginate']), draggedItems() { // Set opacity for dragged items if (!this.clipboard.includes(this.draggingId)) { @@ -49,14 +60,46 @@ export default { return this.clipboard } }, + continueInfiniteScroll() { + if(this.paginate) + return this.paginate.paginate.currentPage !== this.paginate.paginate.lastPage + }, + showInfiniteLoadSpinner() { + return this.continueInfiniteScroll && this.entries.length !== 0 && config.itemsPerPage <= this.entries.length + }, }, data() { return { draggingId: undefined, isDragging: false, + infiniteScrollLoad: false, } }, methods: { + infiniteScroll() { + + if( this.continueInfiniteScroll && this.elementInViewport() ) { + + if(! this.infiniteScrollLoad) { + this.infiniteScrollLoad = true + + this.$getDataByLocation(this.paginate.paginate.currentPage + 1).then(() => { + this.infiniteScrollLoad = false + }) + } + } + }, + elementInViewport() { + var item = document.getElementById('infinite-loader') + var rect = item.getBoundingClientRect() + + return ( + rect.bottom > 0 && + rect.right > 0 && + rect.left < (window.innerWidth || document.documentElement.clientWidth) && + rect.top < (window.innerHeight || document.documentElement.clientHeight) + ); + }, deleteItems() { if ((this.clipboard.length > 0 && this.$checkPermission('master')) || this.$checkPermission('editor')) { this.$store.dispatch('deleteItem') @@ -133,6 +176,9 @@ export default { }, }, created() { + if(this.$isMobile()) + document.addEventListener('scroll', this.infiniteScroll, true) + events.$on('drop', () => { this.isDragging = false diff --git a/resources/js/components/Spotlight/Spotlight.vue b/resources/js/components/Spotlight/Spotlight.vue index b3a85276..14abe3ec 100644 --- a/resources/js/components/Spotlight/Spotlight.vue +++ b/resources/js/components/Spotlight/Spotlight.vue @@ -839,13 +839,13 @@ export default { .then((response) => { // Show user result if (this.activeFilter === 'users') { - this.results = response.data.data + this.results = response.data } // Show file result if (!this.activeFilter) { - let files = response.data.files.data - let folders = response.data.folders.data + let files = response.data.files + let folders = response.data.folders this.results = folders.concat(files) } diff --git a/resources/js/helpers/functionHelpers.js b/resources/js/helpers/functionHelpers.js index ad528370..86ff803c 100644 --- a/resources/js/helpers/functionHelpers.js +++ b/resources/js/helpers/functionHelpers.js @@ -325,19 +325,19 @@ const FunctionHelpers = { }[this.$router.currentRoute.name] } - Vue.prototype.$getDataByLocation = function () { + Vue.prototype.$getDataByLocation = async function (page) { let routes = { - RequestUpload: ['getUploadRequestFolder', router.currentRoute.params.id || undefined ], - Public: ['getSharedFolder', router.currentRoute.params.id || undefined], - Files: ['getFolder', router.currentRoute.params.id || undefined], - RecentUploads: ['getRecentUploads'], - MySharedItems: ['getMySharedItems'], - Trash: ['getTrash', router.currentRoute.params.id || undefined], - TeamFolders: ['getTeamFolder', router.currentRoute.params.id || undefined], - SharedWithMe: ['getSharedWithMeFolder', router.currentRoute.params.id || undefined], + RequestUpload: ['getUploadRequestFolder', {page:page, id:router.currentRoute.params.id || undefined} ], + Public: ['getSharedFolder', {page:page, id:router.currentRoute.params.id || undefined}], + Files: ['getFolder', {page:page, id:router.currentRoute.params.id || undefined}], + RecentUploads: ['getRecentUploads', page], + MySharedItems: ['getMySharedItems', page], + Trash: ['getTrash', {page:page , id:router.currentRoute.params.id || undefined}], + TeamFolders: ['getTeamFolder',{page:page, id:router.currentRoute.params.id || undefined}], + SharedWithMe: ['getSharedWithMeFolder',{page:page, id:router.currentRoute.params.id || undefined}], } - store.dispatch(...routes[router.currentRoute.name]) + await store.dispatch(...routes[router.currentRoute.name]) } Vue.prototype.$getPaymentLogo = function (driver) { diff --git a/resources/js/helpers/itemHelpers.js b/resources/js/helpers/itemHelpers.js index 635272d0..da1dcaa5 100644 --- a/resources/js/helpers/itemHelpers.js +++ b/resources/js/helpers/itemHelpers.js @@ -17,7 +17,7 @@ const itemHelpers = { } Vue.prototype.$toggleFavourites = function (entry) { - let favourites = store.getters.user.data.relationships.favourites.data + let favourites = store.getters.user.data.relationships.favourites // Check if folder is in favourites and then add/remove from favourites if (favourites && !favourites.find((el) => el.data.id === entry.data.id)) { diff --git a/resources/js/store/modules/fileBrowser.js b/resources/js/store/modules/fileBrowser.js index 487dfe6e..be98fb3e 100644 --- a/resources/js/store/modules/fileBrowser.js +++ b/resources/js/store/modules/fileBrowser.js @@ -12,93 +12,150 @@ const defaultState = { isLoading: true, clipboard: [], entries: [], + paginate: undefined, } const actions = { - getFolder: ({ commit, getters }, id) => { - commit('LOADING_STATE', { loading: true, data: [] }) + getFolder: ({ commit, getters },{page, id}) => { + return new Promise ((resolve, reject) => { - axios - .get(`${getters.api}/browse/folders/${id}/${getters.sorting.URI}`) - .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data + if( !page) + commit('LOADING_STATE', { loading: true, data: [] }) - commit('LOADING_STATE', { - loading: false, - data: folders.concat(files), - }) - commit('SET_CURRENT_FOLDER', response.data.root) + let currentPage = page || 1 - events.$emit('scrollTop') - }) - .catch((error) => { - // Redirect if unauthenticated - if ([401, 403].includes(error.response.status)) { - commit('SET_AUTHORIZED', false) - router.push({ name: 'SignIn' }) - } else { - // Show error message - events.$emit('alert:open', { - title: i18n.t('popup_error.title'), - message: i18n.t('popup_error.message'), + axios + .get(`${getters.api}/browse/folders/${id}/${getters.sorting.URI}&page=${currentPage}`) + .then((response) => { + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate }) - } - }) - }, - getRecentUploads: ({ commit, getters }) => { - commit('LOADING_STATE', { loading: true, data: [] }) - axios - .get(getters.api + '/browse/latest') - .then((response) => { - commit('LOADING_STATE', { - loading: false, - data: response.data.files.data, + commit('LOADING_STATE', { + loading: false, + data: response.data.data, + }) + commit('SET_CURRENT_FOLDER', response.data.meta.root) + + events.$emit('scrollTop') + + resolve(true); }) - commit('SET_CURRENT_FOLDER', undefined) + .catch((error) => { + // Redirect if unauthenticated + if ([401, 403].includes(error.response.status)) { + commit('SET_AUTHORIZED', false) + router.push({ name: 'SignIn' }) + } else { + // Show error message + events.$emit('alert:open', { + title: i18n.t('popup_error.title'), + message: i18n.t('popup_error.message'), + }) + } - events.$emit('scrollTop') - }) - .catch(() => Vue.prototype.$isSomethingWrong()) - }, - getMySharedItems: ({ commit, getters }) => { - commit('LOADING_STATE', { loading: true, data: [] }) - - axios - .get(getters.api + '/browse/share' + getters.sorting.URI) - .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data - - commit('LOADING_STATE', { - loading: false, - data: folders.concat(files), + reject(error) }) - commit('SET_CURRENT_FOLDER', undefined) - - events.$emit('scrollTop') - }) - .catch(() => Vue.prototype.$isSomethingWrong()) + }) }, - getTrash: ({ commit, getters }, id) => { - commit('LOADING_STATE', { loading: true, data: [] }) + getRecentUploads: ({ commit, getters }, page) => { + return new Promise ((resolve, reject) => { - axios - .get(`${getters.api}/browse/trash/${id}/${getters.sorting.URI}`) - .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data + if(! page) + commit('LOADING_STATE', { loading: true, data: [] }) + + let currentPage = page || 1 + + axios + .get(getters.api + `/browse/latest?page=${currentPage}`) + .then((response) => { + + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate + }) + + commit('LOADING_STATE', { + loading: false, + data: response.data.data, + }) + commit('SET_CURRENT_FOLDER', undefined) + + events.$emit('scrollTop') - commit('LOADING_STATE', { - loading: false, - data: folders.concat(files), + resolve(true) }) - commit('SET_CURRENT_FOLDER', response.data.root) + .catch((error) => { + Vue.prototype.$isSomethingWrong() - events.$emit('scrollTop') - }) - .catch(() => Vue.prototype.$isSomethingWrong()) + reject(error) + }) + }) + + }, + getMySharedItems: ({ commit, getters }, page) => { + return new Promise ((resolve, reject) => { + if(! page) + commit('LOADING_STATE', { loading: true, data: [] }) + + let currentPage = page || 1 + + axios + .get(`${getters.api}/browse/share${getters.sorting.URI}&page=${currentPage}`) + .then((response) => { + + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate + }) + + commit('LOADING_STATE', { + loading: false, + data: response.data.data, + }) + commit('SET_CURRENT_FOLDER', undefined) + + events.$emit('scrollTop') + + resolve(true) + }) + .catch((error) => { + Vue.prototype.$isSomethingWrong() + + reject(error) + }) + }) + + }, + getTrash: ({ commit, getters },{page, id}) => { + return new Promise ((resolve, reject) => { + if(! page) + commit('LOADING_STATE', { loading: true, data: [] }) + + let currentPage = page || 1 + + axios + .get(`${getters.api}/browse/trash/${id}/${getters.sorting.URI}&page=${currentPage}`) + .then((response) => { + + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate + }) + + commit('LOADING_STATE', { + loading: false, + data: response.data.data, + }) + commit('SET_CURRENT_FOLDER', response.data.meta.root) + + events.$emit('scrollTop') + + resolve(true) + }) + .catch((error) => { + Vue.prototype.$isSomethingWrong() + + reject(error) + }) + }) }, getFolderTree: ({ commit, getters }) => { return new Promise((resolve, reject) => { @@ -116,17 +173,24 @@ const actions = { commit('UPDATE_FOLDER_TREE', response.data) }) .catch((error) => { - reject(error) - Vue.prototype.$isSomethingWrong() + + reject(error) }) }) }, } const mutations = { + SET_PAGINATE(state, payload) { + state.paginate = payload + }, LOADING_STATE(state, payload) { - state.entries = payload.data + if(payload.data.length === 0) { + state.entries = [] + } else { + state.entries.push(...payload.data) + } state.isLoading = payload.loading }, SET_CURRENT_FOLDER(state, folder) { @@ -221,6 +285,7 @@ const getters = { clipboard: (state) => state.clipboard, isLoading: (state) => state.isLoading, entries: (state) => state.entries, + paginate: (state) => state.paginate } export default { diff --git a/resources/js/store/modules/sharing.js b/resources/js/store/modules/sharing.js index 81b3ead6..fa4e9203 100644 --- a/resources/js/store/modules/sharing.js +++ b/resources/js/store/modules/sharing.js @@ -20,21 +20,26 @@ const defaultState = { sharedFile: undefined, } const actions = { - getSharedFolder: ({ commit, getters }, id) => { - commit('LOADING_STATE', { loading: true, data: [] }) + getSharedFolder: ({ commit, getters }, {page, id}) => { + + if(! page) + commit('LOADING_STATE', { loading: true, data: [] }) + + let currentPage = page || 1 return new Promise((resolve, reject) => { axios - .get(`/api/browse/folders/${id}/${router.currentRoute.params.token}${getters.sorting.URI}`) + .get(`/api/browse/folders/${id}/${router.currentRoute.params.token}${getters.sorting.URI}&page=${currentPage}`) .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate + }) commit('LOADING_STATE', { loading: false, - data: folders.concat(files), + data: response.data.data, }) - commit('SET_CURRENT_FOLDER', response.data.root) + commit('SET_CURRENT_FOLDER', response.data.meta.root) events.$emit('scrollTop') diff --git a/resources/js/store/modules/teams.js b/resources/js/store/modules/teams.js index 4cac8427..41df857c 100644 --- a/resources/js/store/modules/teams.js +++ b/resources/js/store/modules/teams.js @@ -9,89 +9,111 @@ const defaultState = { } const actions = { - getTeamFolder: ({ commit, getters }, id) => { - commit('LOADING_STATE', { loading: true, data: [] }) + getTeamFolder: ({ commit, getters }, {page, id}) => { + return new Promise ((resolve, reject) => { - if (typeof id === 'undefined') { - commit('SET_CURRENT_TEAM_FOLDER', null) - } + if(! page) + commit('LOADING_STATE', { loading: true, data: [] }) + + if (typeof id === 'undefined') { + commit('SET_CURRENT_TEAM_FOLDER', null) + } - axios - .get(`${getters.api}/teams/folders/${id}/${getters.sorting.URI}`) - .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data - - commit('LOADING_STATE', { - loading: false, - data: folders.concat(files), - }) - commit('SET_CURRENT_FOLDER', response.data.root) - - if ( - !getters.currentTeamFolder || - getters.currentTeamFolder.data.id !== response.data.teamFolder.data.id - ) { - commit('SET_CURRENT_TEAM_FOLDER', response.data.teamFolder) - } - - events.$emit('scrollTop') - }) - .catch((error) => { - // Redirect if unauthenticated - if ([401, 403].includes(error.response.status)) { - commit('SET_AUTHORIZED', false) - router.push({ name: 'SignIn' }) - } else { - // Show error message - events.$emit('alert:open', { - title: i18n.t('popup_error.title'), - message: i18n.t('popup_error.message'), + let currentPage = page || 1 + + axios + .get(`${getters.api}/teams/folders/${id}/${getters.sorting.URI}&page=${currentPage}`) + .then((response) => { + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate }) - } - }) + + commit('LOADING_STATE', { + loading: false, + data:response.data.data, + }) + commit('SET_CURRENT_FOLDER', response.data.meta.root) + + if ( + !getters.currentTeamFolder || + getters.currentTeamFolder.data.id !== response.data.teamFolder.data.id + ) { + commit('SET_CURRENT_TEAM_FOLDER', response.data.teamFolder) + } + + events.$emit('scrollTop') + + resolve(true) + }) + .catch((error) => { + // Redirect if unauthenticated + if ([401, 403].includes(error.response.status)) { + commit('SET_AUTHORIZED', false) + router.push({ name: 'SignIn' }) + } else { + // Show error message + events.$emit('alert:open', { + title: i18n.t('popup_error.title'), + message: i18n.t('popup_error.message'), + }) + } + + reject(error) + }) + }) }, - getSharedWithMeFolder: ({ commit, getters }, id) => { - commit('LOADING_STATE', { loading: true, data: [] }) + getSharedWithMeFolder: ({ commit, getters }, {page, id}) => { + return new Promise ((resolve, reject) => { + + if(! page) + commit('LOADING_STATE', { loading: true, data: [] }) + + if (typeof id === 'undefined') { + commit('SET_CURRENT_TEAM_FOLDER', null) + } - if (typeof id === 'undefined') { - commit('SET_CURRENT_TEAM_FOLDER', null) - } - - axios - .get(`${getters.api}/teams/shared-with-me/${id}/${getters.sorting.URI}`) - .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data - - commit('LOADING_STATE', { - loading: false, - data: folders.concat(files), - }) - commit('SET_CURRENT_FOLDER', response.data.root) - - if ( - !getters.currentTeamFolder || - getters.currentTeamFolder.data.id !== response.data.teamFolder.data.id - ) { - commit('SET_CURRENT_TEAM_FOLDER', response.data.teamFolder) - } - - events.$emit('scrollTop') - }) - .catch((error) => { - // Redirect if unauthenticated - if ([401, 403].includes(error.response.status)) { - commit('SET_AUTHORIZED', false) - router.push({ name: 'SignIn' }) - } else { - // Show error message - events.$emit('alert:open', { - title: i18n.t('popup_error.title'), - message: i18n.t('popup_error.message'), + let currentPage = page || 1 + + axios + .get(`${getters.api}/teams/shared-with-me/${id}/${getters.sorting.URI}&page=${currentPage}`) + .then((response) => { + commit('SET_PAGINATE', { + paginate: response.data.meta.paginate }) - } - }) + + commit('LOADING_STATE', { + loading: false, + data: response.data.data, + }) + commit('SET_CURRENT_FOLDER', response.data.meta.root) + + if ( + !getters.currentTeamFolder || + getters.currentTeamFolder.data.id !== response.data.teamFolder.data.id + ) { + commit('SET_CURRENT_TEAM_FOLDER', response.data.teamFolder) + } + + events.$emit('scrollTop') + + resolve(true) + }) + .catch((error) => { + // Redirect if unauthenticated + if ([401, 403].includes(error.response.status)) { + commit('SET_AUTHORIZED', false) + router.push({ name: 'SignIn' }) + } else { + // Show error message + events.$emit('alert:open', { + title: i18n.t('popup_error.title'), + message: i18n.t('popup_error.message'), + }) + } + + reject(error) + }) + }) }, getTeamFolderTree: ({ commit, getters }) => { return new Promise((resolve, reject) => { diff --git a/resources/js/store/modules/uploadRequest.js b/resources/js/store/modules/uploadRequest.js index eeafcef7..0c2a18da 100644 --- a/resources/js/store/modules/uploadRequest.js +++ b/resources/js/store/modules/uploadRequest.js @@ -15,8 +15,8 @@ const actions = { axios .get(`/api/upload-request/${router.currentRoute.params.token}/browse/${id}${getters.sorting.URI}`) .then((response) => { - let folders = response.data.folders.data - let files = response.data.files.data + let folders = response.data.folders + let files = response.data.files commit('LOADING_STATE', { loading: false, @@ -52,6 +52,11 @@ const actions = { commit('SET_CURRENT_FOLDER', response.data.data.relationships.folder) } }) + .catch((error) => { + Vue.prototype.$isSomethingWrong() + + reject(error) + }) }) }, closeUploadRequest: ({ commit }) => { diff --git a/resources/js/store/modules/userAuth.js b/resources/js/store/modules/userAuth.js index 60d5ec06..f8e3db14 100644 --- a/resources/js/store/modules/userAuth.js +++ b/resources/js/store/modules/userAuth.js @@ -75,7 +75,7 @@ const actions = { items.forEach((item) => { if (item.data.type === 'folder') { if ( - context.getters.user.data.relationships.favourites.data.find((folder) => folder.id === item.data.id) + context.getters.user.data.relationships.favourites.find((folder) => folder.id === item.data.id) ) return @@ -92,7 +92,7 @@ const actions = { // Check is favorites already don't include some of pushed folders items.map((item) => { - if (!context.getters.user.data.relationships.favourites.data.find((folder) => folder.data.id === item.id)) { + if (!context.getters.user.data.relationships.favourites.find((folder) => folder.data.id === item.id)) { pushToFavorites.push(item) } }) @@ -152,7 +152,7 @@ const mutations = { }, ADD_TO_FAVOURITES(state, folder) { folder.forEach((item) => { - state.user.data.relationships.favourites.data.push(item) + state.user.data.relationships.favourites.push(item) }) }, UPDATE_FIRST_NAME(state, name) { @@ -169,12 +169,12 @@ const mutations = { } }, REMOVE_ITEM_FROM_FAVOURITES(state, item) { - state.user.data.relationships.favourites.data = state.user.data.relationships.favourites.data.filter( + state.user.data.relationships.favourites = state.user.data.relationships.favourites.filter( (folder) => folder.data.id !== item.data.id ) }, UPDATE_NAME_IN_FAVOURITES(state, data) { - state.user.data.relationships.favourites.data.find((folder) => { + state.user.data.relationships.favourites.find((folder) => { if (folder.id === data.id) { folder.name = data.name } diff --git a/resources/js/views/FileView/Components/NavigationSharePanel.vue b/resources/js/views/FileView/Components/NavigationSharePanel.vue index 83ee0add..0bd5c594 100644 --- a/resources/js/views/FileView/Components/NavigationSharePanel.vue +++ b/resources/js/views/FileView/Components/NavigationSharePanel.vue @@ -115,7 +115,7 @@ export default { 'isDarkMode', ]), favourites() { - return this.user.data.relationships.favourites.data.attributes.folders + return this.user.data.relationships.favourites.attributes.folders }, storage() { return this.$store.getters.user.data.attributes.storage diff --git a/resources/js/views/FileView/Components/PanelNavigationFiles.vue b/resources/js/views/FileView/Components/PanelNavigationFiles.vue index 89dc148a..c950cde2 100644 --- a/resources/js/views/FileView/Components/PanelNavigationFiles.vue +++ b/resources/js/views/FileView/Components/PanelNavigationFiles.vue @@ -132,7 +132,7 @@ export default { computed: { ...mapGetters(['isVisibleNavigationBars', 'navigation', 'clipboard', 'config', 'user']), favourites() { - return this.user.data.relationships.favourites.data + return this.user.data.relationships.favourites }, storage() { return this.$store.getters.user.data.attributes.storage diff --git a/resources/js/views/FileView/Files.vue b/resources/js/views/FileView/Files.vue index d51dc283..1a4e4b5a 100644 --- a/resources/js/views/FileView/Files.vue +++ b/resources/js/views/FileView/Files.vue @@ -251,7 +251,7 @@ export default { return this.item && this.item.data.type === 'folder' }, isInFavourites() { - return this.user.data.relationships.favourites.data.find((el) => el.data.id === this.item.data.id) + return this.user.data.relationships.favourites.find((el) => el.data.id === this.item.data.id) }, hasFile() { return this.clipboard.find((item) => item.data.type !== 'folder') @@ -263,7 +263,7 @@ export default { } }, created() { - this.$store.dispatch('getFolder', this.$route.params.id) + this.$store.dispatch('getFolder', {page:null, id:this.$route.params.id}) events.$on('context-menu:show', (event, item) => (this.item = item)) events.$on('context-menu:current-folder', (folder) => (this.item = folder)) diff --git a/resources/js/views/FileView/MySharedItems.vue b/resources/js/views/FileView/MySharedItems.vue index 44b7a2d6..2e4920b3 100644 --- a/resources/js/views/FileView/MySharedItems.vue +++ b/resources/js/views/FileView/MySharedItems.vue @@ -152,7 +152,7 @@ export default { return this.item && this.item.type === 'folder' }, isInFavourites() { - return this.user.data.relationships.favourites.data.find((el) => el.id === this.item.id) + return this.user.data.relationships.favourites.find((el) => el.id === this.item.id) }, hasFile() { return this.clipboard.find((item) => item.type !== 'folder') diff --git a/resources/js/views/FileView/Public.vue b/resources/js/views/FileView/Public.vue index 3cf722e6..57db6df8 100644 --- a/resources/js/views/FileView/Public.vue +++ b/resources/js/views/FileView/Public.vue @@ -228,7 +228,7 @@ export default { }, }, created() { - this.$store.dispatch('getSharedFolder', this.$route.params.id) + this.$store.dispatch('getSharedFolder', {page:null, id:this.$route.params.id}) events.$on('context-menu:show', (event, item) => (this.item = item)) events.$on('mobile-context-menu:show', (item) => (this.item = item)) diff --git a/resources/js/views/FileView/SharedWithMe.vue b/resources/js/views/FileView/SharedWithMe.vue index 24af38a2..0e76cea7 100644 --- a/resources/js/views/FileView/SharedWithMe.vue +++ b/resources/js/views/FileView/SharedWithMe.vue @@ -234,7 +234,7 @@ export default { }, }, mounted() { - this.$store.dispatch('getSharedWithMeFolder', this.$route.params.id) + this.$store.dispatch('getSharedWithMeFolder',{page:null, id:this.$route.params.id}) events.$on('context-menu:show', (event, item) => (this.item = item)) events.$on('mobile-context-menu:show', (item) => (this.item = item)) @@ -249,7 +249,7 @@ export default { if (this.$route.params.id) { this.$router.push({ name: 'SharedWithMe' }) } else { - this.$store.dispatch('getSharedWithMeFolder', undefined) + this.$store.dispatch('getSharedWithMeFolder',{page:null, id:undefined}) } events.$emit('toaster', { diff --git a/resources/js/views/FileView/TeamFolders.vue b/resources/js/views/FileView/TeamFolders.vue index c17715b8..23206851 100644 --- a/resources/js/views/FileView/TeamFolders.vue +++ b/resources/js/views/FileView/TeamFolders.vue @@ -275,7 +275,7 @@ export default { return this.item && this.item.data.type === 'folder' }, isInFavourites() { - return this.user.data.relationships.favourites.data.find((el) => el.id === this.item.id) + return this.user.data.relationships.favourites.find((el) => el.id === this.item.id) }, hasFile() { return this.clipboard.find((item) => item.type !== 'folder') @@ -287,7 +287,7 @@ export default { } }, mounted() { - this.$store.dispatch('getTeamFolder', this.$route.params.id) + this.$store.dispatch('getTeamFolder', {page:null, id:this.$route.params.id}) events.$on('context-menu:show', (event, item) => (this.item = item)) events.$on('mobile-context-menu:show', (item) => (this.item = item)) diff --git a/resources/js/views/FileView/Trash.vue b/resources/js/views/FileView/Trash.vue index 5faed522..7dfbfc1e 100644 --- a/resources/js/views/FileView/Trash.vue +++ b/resources/js/views/FileView/Trash.vue @@ -146,7 +146,7 @@ export default { } }, created() { - this.$store.dispatch('getTrash', this.$route.params.id) + this.$store.dispatch('getTrash', {page:null, id:this.$route.params.id}) events.$on('context-menu:show', (event, item) => (this.item = item)) events.$on('mobile-context-menu:show', (item) => (this.item = item)) diff --git a/resources/views/index.blade.php b/resources/views/index.blade.php index a9a93617..d4ede93f 100644 --- a/resources/views/index.blade.php +++ b/resources/views/index.blade.php @@ -180,6 +180,7 @@ // App settings userRegistration: {{ $settings->registration ?? 1 }}, userVerification: {{ $settings->user_verification ?? 0 }}, + itemsPerPage: {{ config('vuefilemanager.paginate.perPage') }}, } diff --git a/src/App/Users/Models/User.php b/src/App/Users/Models/User.php index 7003cca3..b5edb88b 100644 --- a/src/App/Users/Models/User.php +++ b/src/App/Users/Models/User.php @@ -159,8 +159,7 @@ class User extends Authenticatable implements MustVerifyEmail ->with([ 'parent:id,name', 'shared:token,id,item_id,permission,is_protected,expire_in', - ]) - ->take(40); + ]); } /** diff --git a/src/Domain/Browsing/Controllers/BrowseFolderController.php b/src/Domain/Browsing/Controllers/BrowseFolderController.php index 0baf51bb..0d42c906 100644 --- a/src/Domain/Browsing/Controllers/BrowseFolderController.php +++ b/src/Domain/Browsing/Controllers/BrowseFolderController.php @@ -6,9 +6,7 @@ use Illuminate\Http\Request; use Domain\Files\Models\File; use Domain\Folders\Models\Folder; use Illuminate\Support\Facades\Auth; -use Domain\Files\Resources\FilesCollection; use Domain\Folders\Resources\FolderResource; -use Domain\Folders\Resources\FolderCollection; class BrowseFolderController { @@ -31,11 +29,15 @@ class BrowseFolderController ->sortable() ->get(); - // Collect folders and files to single array + list($data, $paginate, $links) = groupPaginate($request, $folders, $files); + return [ - 'folders' => new FolderCollection($folders), - 'files' => new FilesCollection($files), - 'root' => $root_id ? new FolderResource(Folder::findOrFail($root_id)) : null, + 'data' => $data, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => $root_id ? new FolderResource(Folder::findOrFail($root_id)) : null, + ] ]; } } diff --git a/src/Domain/Browsing/Controllers/BrowseLatestFilesController.php b/src/Domain/Browsing/Controllers/BrowseLatestFilesController.php index 1f1eb085..556f50fb 100644 --- a/src/Domain/Browsing/Controllers/BrowseLatestFilesController.php +++ b/src/Domain/Browsing/Controllers/BrowseLatestFilesController.php @@ -3,11 +3,11 @@ namespace Domain\Browsing\Controllers; use App\Users\Models\User; use Illuminate\Support\Facades\Auth; -use Domain\Files\Resources\FilesCollection; +use Illuminate\Http\Request; class BrowseLatestFilesController { - public function __invoke(): array + public function __invoke(Request $request): array { $user = User::with([ 'latestUploads' => fn ($query) => $query->sortable(['created_at' => 'desc']), @@ -15,9 +15,15 @@ class BrowseLatestFilesController ->where('id', Auth::id()) ->first(); + list($data, $paginate, $links) = groupPaginate($request, null, $user->latestUploads); + return [ - 'files' => new FilesCollection($user->latestUploads), - 'root' => null, + 'data' => $data, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => null, + ] ]; } } diff --git a/src/Domain/Browsing/Controllers/BrowseSharedItemsController.php b/src/Domain/Browsing/Controllers/BrowseSharedItemsController.php index 902af769..0dc73125 100644 --- a/src/Domain/Browsing/Controllers/BrowseSharedItemsController.php +++ b/src/Domain/Browsing/Controllers/BrowseSharedItemsController.php @@ -5,12 +5,11 @@ use Domain\Files\Models\File; use Domain\Sharing\Models\Share; use Domain\Folders\Models\Folder; use Illuminate\Support\Facades\Auth; -use Domain\Files\Resources\FilesCollection; -use Domain\Folders\Resources\FolderCollection; +use Illuminate\Http\Request; class BrowseSharedItemsController { - public function __invoke(): array + public function __invoke(Request $request): array { $user_id = Auth::id(); @@ -36,11 +35,16 @@ class BrowseSharedItemsController ->sortable() ->get(); + list($data, $paginate, $links) = groupPaginate($request, $folders, $files); + // Collect folders and files to single array return [ - 'folders' => new FolderCollection($folders), - 'files' => new FilesCollection($files), - 'root' => null, + 'data' => $data, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => null, + ] ]; } } diff --git a/src/Domain/Browsing/Controllers/BrowseTrashContentController.php b/src/Domain/Browsing/Controllers/BrowseTrashContentController.php index 994ac075..06428057 100644 --- a/src/Domain/Browsing/Controllers/BrowseTrashContentController.php +++ b/src/Domain/Browsing/Controllers/BrowseTrashContentController.php @@ -4,12 +4,11 @@ namespace Domain\Browsing\Controllers; use Domain\Files\Models\File; use Domain\Folders\Models\Folder; use Illuminate\Support\Facades\Auth; -use Domain\Files\Resources\FilesCollection; -use Domain\Folders\Resources\FolderCollection; +use Illuminate\Http\Request; class BrowseTrashContentController { - public function __invoke(string $id): array + public function __invoke(Request $request, string $id): array { $user_id = Auth::id(); $root_id = $id === 'undefined' ? null : $id; @@ -29,43 +28,43 @@ class BrowseTrashContentController ->sortable() ->get(); - // Collect folders and files to single array - return [ - 'folders' => new FolderCollection($folders), - 'files' => new FilesCollection($files), - 'root' => $requestedFolder, - ]; - } - // Get folders and files - $folders_trashed = Folder::onlyTrashed() + } else { + // Get folders and files + $folders_trashed = Folder::onlyTrashed() ->with(['trashedFolders', 'parent']) ->where('user_id', $user_id) ->get(['parent_id', 'id', 'name']); - $folders = Folder::onlyTrashed() - ->with(['parent']) - ->where('user_id', $user_id) - ->whereIn('id', filter_folders_ids($folders_trashed)) - ->sortable() - ->get(); + $folders = Folder::onlyTrashed() + ->with(['parent']) + ->where('user_id', $user_id) + ->whereIn('id', filter_folders_ids($folders_trashed)) + ->sortable() + ->get(); - // Get files trashed - $files_trashed = File::onlyTrashed() - ->with(['parent']) - ->where('user_id', $user_id) - ->where(function ($query) use ($folders_trashed) { - $query->whereNull('parent_id'); - $query->orWhereNotIn('parent_id', array_values(array_unique(recursiveFind($folders_trashed->toArray(), 'id')))); - }) - ->sortable() - ->get(); + // Get files trashed + $files = File::onlyTrashed() + ->with(['parent']) + ->where('user_id', $user_id) + ->where(function ($query) use ($folders_trashed) { + $query->whereNull('parent_id'); + $query->orWhereNotIn('parent_id', array_values(array_unique(recursiveFind($folders_trashed->toArray(), 'id')))); + }) + ->sortable() + ->get(); + } + + list($data, $paginate, $links) = groupPaginate($request, $folders, $files); // Collect folders and files to single array return [ - 'folders' => new FolderCollection($folders), - 'files' => new FilesCollection($files_trashed), - 'root' => $requestedFolder, + 'data' => $data, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => $requestedFolder, + ] ]; } } diff --git a/src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php b/src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php index fc0ddaad..db32ca9f 100644 --- a/src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php +++ b/src/Domain/Browsing/Controllers/VisitorBrowseFolderController.php @@ -4,11 +4,10 @@ namespace Domain\Browsing\Controllers; use Domain\Files\Models\File; use Domain\Sharing\Models\Share; use Domain\Folders\Models\Folder; -use Domain\Files\Resources\FilesCollection; use Domain\Folders\Resources\FolderResource; -use Domain\Folders\Resources\FolderCollection; use Domain\Sharing\Actions\ProtectShareRecordAction; use Domain\Sharing\Actions\VerifyAccessToItemAction; +use Illuminate\Http\Request; /** * Browse shared folder @@ -24,6 +23,7 @@ class VisitorBrowseFolderController public function __invoke( string $id, Share $shared, + Request $request, ): array { // Check ability to access protected share record ($this->protectShareRecord)($shared); @@ -48,10 +48,15 @@ class VisitorBrowseFolderController // Set thumbnail links for public files $files->map(fn ($file) => $file->setSharedPublicUrl($shared->token)); + list($data, $paginate, $links) = groupPaginate($request, $folders, $files); + return [ - 'folders' => new FolderCollection($folders), - 'files' => new FilesCollection($files), - 'root' => new FolderResource($requestedFolder), + 'data' => $data, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => new FolderResource($requestedFolder), + ] ]; } } diff --git a/src/Domain/Files/Resources/FilesCollection.php b/src/Domain/Files/Resources/FilesCollection.php index 28f265a5..e2c50f93 100644 --- a/src/Domain/Files/Resources/FilesCollection.php +++ b/src/Domain/Files/Resources/FilesCollection.php @@ -1,16 +1,15 @@ $this->collection, - ]; + return $this->collection; } } diff --git a/src/Domain/Folders/Resources/FolderCollection.php b/src/Domain/Folders/Resources/FolderCollection.php index 5b00fcf3..4fd429c4 100644 --- a/src/Domain/Folders/Resources/FolderCollection.php +++ b/src/Domain/Folders/Resources/FolderCollection.php @@ -1,16 +1,15 @@ $this->collection, - ]; + return $this->collection; } } diff --git a/src/Domain/Teams/Controllers/BrowseSharedWithMeController.php b/src/Domain/Teams/Controllers/BrowseSharedWithMeController.php index 50cad2c0..4602528c 100644 --- a/src/Domain/Teams/Controllers/BrowseSharedWithMeController.php +++ b/src/Domain/Teams/Controllers/BrowseSharedWithMeController.php @@ -3,17 +3,16 @@ namespace Domain\Teams\Controllers; use Str; use Gate; +use Illuminate\Http\Request; use Domain\Files\Models\File; use Domain\Folders\Models\Folder; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Auth; -use Domain\Files\Resources\FilesCollection; use Domain\Folders\Resources\FolderResource; -use Domain\Folders\Resources\FolderCollection; class BrowseSharedWithMeController { - public function __invoke($id): array + public function __invoke(Request $request, $id): array { $id = Str::isUuid($id) ? $id : null; @@ -46,11 +45,16 @@ class BrowseSharedWithMeController ->get(); } + list($data, $paginate, $links) = groupPaginate($request, $folders, $files ?? null); + return [ - 'root' => $id ? new FolderResource(Folder::findOrFail($id)) : null, - 'folders' => new FolderCollection($folders), - 'files' => isset($files) ? new FilesCollection($files) : new FilesCollection([]), + 'data' => $data, 'teamFolder' => $id ? new FolderResource($teamFolder) : null, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => $id ? new FolderResource(Folder::findOrFail($id)) : null + ] ]; } } diff --git a/src/Domain/Teams/Controllers/TeamFoldersController.php b/src/Domain/Teams/Controllers/TeamFoldersController.php index cc3f20f0..93d7b620 100644 --- a/src/Domain/Teams/Controllers/TeamFoldersController.php +++ b/src/Domain/Teams/Controllers/TeamFoldersController.php @@ -2,6 +2,7 @@ namespace Domain\Teams\Controllers; use Illuminate\Support\Str; +use Illuminate\Http\Request; use Domain\Files\Models\File; use Illuminate\Http\Response; use Domain\Folders\Models\Folder; @@ -10,10 +11,8 @@ use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Auth; use Domain\Teams\Models\TeamFolderMember; use Domain\Teams\DTO\CreateTeamFolderData; -use Domain\Files\Resources\FilesCollection; use Domain\Folders\Resources\FolderResource; use Domain\Teams\Actions\UpdateMembersAction; -use Domain\Folders\Resources\FolderCollection; use Domain\Teams\Actions\UpdateInvitationsAction; use Illuminate\Contracts\Routing\ResponseFactory; use Domain\Teams\Requests\CreateTeamFolderRequest; @@ -29,7 +28,7 @@ class TeamFoldersController extends Controller ) { } - public function show($id): array + public function show(Request $request, $id): array { $id = Str::isUuid($id) ? $id : null; @@ -52,12 +51,17 @@ class TeamFoldersController extends Controller ->get(); } + list($data, $paginate, $links) = groupPaginate($request, $folders, $files ?? null); + // Collect folders and files to single array return [ - 'folders' => new FolderCollection($folders), - 'files' => isset($files) ? new FilesCollection($files) : new FilesCollection([]), - 'root' => $id ? new FolderResource(Folder::findOrFail($id)) : null, + 'data' => $data, 'teamFolder' => $id ? new FolderResource(Folder::findOrFail($id)->getLatestParent()) : null, + 'links' => $links, + 'meta' => [ + 'paginate' => $paginate, + 'root' => $id ? new FolderResource(Folder::findOrFail($id)) : null, + ] ]; } diff --git a/src/Support/helpers.php b/src/Support/helpers.php index f2a0ee1c..56263598 100644 --- a/src/Support/helpers.php +++ b/src/Support/helpers.php @@ -5,6 +5,7 @@ use ByteUnits\Metric; use App\Users\Models\User; use Illuminate\Support\Arr; use Illuminate\Support\Str; +use Illuminate\Http\Request; use Domain\Files\Models\File; use Domain\Sharing\Models\Share; use Domain\Folders\Models\Folder; @@ -15,6 +16,8 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Database\QueryException; use Illuminate\Support\Facades\Storage; use Domain\Localization\Models\Language; +use Domain\Files\Resources\FilesCollection; +use Domain\Folders\Resources\FolderCollection; use Intervention\Image\ImageManagerStatic as Image; use Illuminate\Database\Eloquent\ModelNotFoundException; @@ -1148,4 +1151,52 @@ if (! function_exists('replace_occurrence')) { return "{$degrees}°$minutes'$seconds\"$ref"; } } + + if(! function_exists('groupPaginate')) { + /** + * Group paginate of Foldes and Files + */ + function groupPaginate( + Request $request, + ?Collection $folders = null, + ?Collection $files = null + ) : array { + + $perPage = config('vuefilemanager.paginate.perPage'); + $currentPage = $request->get('page'); + + // Collect Folders with Files + $entries = collect([ + $folders ? json_decode((new FolderCollection($folders))->toJson(), true) : null, + $files ? json_decode((new FilesCollection($files))->toJson(), true) : null, + ])->collapse(); + + // Paginate grouped Folders and Files + $groupPaginate = $entries->forPage($currentPage, $perPage)->values(); + + $uri = $request->fullUrl(); + + $lastPage = ceil(count($entries) / $perPage); + + return [ + $groupPaginate, + [ + 'currentPage' => (int)$currentPage, + 'from' => 1, + 'lastPage' => $lastPage, + 'path' => $uri, + 'perPage' => $perPage, + 'to' => $perPage, + 'total' => count($entries), + ], + [ + 'first' => $uri . '&page=' . 1, + 'last' => $uri . '&page=' . $lastPage, + 'next' => $currentPage == $lastPage ? null : $uri . '&page=' . $currentPage + 1, + 'prev' => $currentPage == 1 ? null : $uri . '&page=' . $currentPage -1, + ] + ]; + } + } + }