mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-28 19:10:40 +00:00
Shared pages refactoring part 1
This commit is contained in:
@@ -95,6 +95,10 @@ return [
|
|||||||
'name' => 'app_color',
|
'name' => 'app_color',
|
||||||
'value' => '#00BC7E',
|
'value' => '#00BC7E',
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'name' => 'allowed_adsense',
|
||||||
|
'value' => 0,
|
||||||
|
],
|
||||||
],
|
],
|
||||||
'extended' => [
|
'extended' => [
|
||||||
[
|
[
|
||||||
@@ -177,6 +181,10 @@ return [
|
|||||||
'name' => 'app_color',
|
'name' => 'app_color',
|
||||||
'value' => '#00BC7E',
|
'value' => '#00BC7E',
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'name' => 'allowed_adsense',
|
||||||
|
'value' => 0,
|
||||||
|
],
|
||||||
|
|
||||||
// Subscription
|
// Subscription
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
<span class="text-theme dark-text-theme absolute z-10 mx-auto mt-1 inline-block w-7 overflow-hidden text-ellipsis text-center text-tiny font-semibold lg:text-xs">
|
<span class="text-theme absolute z-10 mx-auto mt-1 inline-block w-7 overflow-hidden text-ellipsis text-center font-semibold text-[9px]">
|
||||||
{{ entry.data.attributes.mimetype }}
|
{{ entry.data.attributes.mimetype }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
:class="{ 'bg-light-background dark:bg-dark-foreground': isClicked }"
|
:class="{
|
||||||
class="relative z-0 flex h-48 select-none flex-wrap items-center justify-center rounded-lg border-2 border-dashed border-transparent px-1 pt-2 text-center dark:hover:bg-dark-foreground sm:h-56 lg:h-60 lg:hover:bg-light-background"
|
'bg-light-background dark:bg-dark-foreground': isClicked,
|
||||||
|
'dark:hover:bg-dark-foreground lg:hover:bg-light-background': canHover
|
||||||
|
}"
|
||||||
|
class="relative z-0 flex h-48 select-none flex-wrap items-center justify-center rounded-lg border-2 border-dashed border-transparent px-1 pt-2 text-center sm:h-56 lg:h-60"
|
||||||
:draggable="canDrag"
|
:draggable="canDrag"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
>
|
>
|
||||||
@@ -50,7 +53,8 @@
|
|||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<!--Item Title-->
|
<!--Item Title-->
|
||||||
<b
|
<b
|
||||||
class="tracking-tigh inline-block w-full overflow-hidden text-ellipsis whitespace-nowrap text-sm leading-3 hover:underline md:px-6"
|
class="tracking-tight inline-block w-full overflow-hidden text-ellipsis whitespace-nowrap text-sm leading-3 md:px-6"
|
||||||
|
:class="{'hover:underline': canEditName}"
|
||||||
ref="name"
|
ref="name"
|
||||||
@input="renameItem"
|
@input="renameItem"
|
||||||
@keydown.delete.stop
|
@keydown.delete.stop
|
||||||
@@ -63,7 +67,7 @@
|
|||||||
<!--Item sub line-->
|
<!--Item sub line-->
|
||||||
<div class="flex items-center justify-center">
|
<div class="flex items-center justify-center">
|
||||||
<!--Shared Icon-->
|
<!--Shared Icon-->
|
||||||
<div v-if="$checkPermission('master') && entry.data.relationships.shared">
|
<div v-if="canShowLinkIcon">
|
||||||
<link-icon size="12" class="text-theme dark-text-theme vue-feather mr-1.5" />
|
<link-icon size="12" class="text-theme dark-text-theme vue-feather mr-1.5" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -106,7 +110,7 @@ import { mapGetters } from 'vuex'
|
|||||||
import { events } from '../../bus'
|
import { events } from '../../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ItemList',
|
name: 'ItemGrid',
|
||||||
components: {
|
components: {
|
||||||
FileIconThumbnail,
|
FileIconThumbnail,
|
||||||
MoreHorizontalIcon,
|
MoreHorizontalIcon,
|
||||||
@@ -117,7 +121,7 @@ export default {
|
|||||||
EyeIcon,
|
EyeIcon,
|
||||||
Emoji,
|
Emoji,
|
||||||
},
|
},
|
||||||
props: ['mobileHandler', 'entry'],
|
props: ['mobileHandler', 'entry', 'canHover'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
mobileMultiSelect: false,
|
mobileMultiSelect: false,
|
||||||
@@ -154,9 +158,8 @@ export default {
|
|||||||
canEditName() {
|
canEditName() {
|
||||||
return (
|
return (
|
||||||
!this.$isMobile() &&
|
!this.$isMobile() &&
|
||||||
!this.$isThisRoute(this.$route, ['Trash']) &&
|
!this.$isThisRoute(this.$route, ['Trash', 'SharedSingleFile']) &&
|
||||||
!this.$checkPermission('visitor') &&
|
!this.$checkPermission('visitor')
|
||||||
!(this.sharedDetail && this.sharedDetail.attributes.type === 'file')
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
folderItems() {
|
folderItems() {
|
||||||
@@ -165,6 +168,9 @@ export default {
|
|||||||
canShowAuthor() {
|
canShowAuthor() {
|
||||||
return this.$isThisRoute(this.$route, ['SharedWithMe', 'TeamFolders']) && !this.isFolder && this.user.data.id !== this.entry.data.relationships.owner.data.id
|
return this.$isThisRoute(this.$route, ['SharedWithMe', 'TeamFolders']) && !this.isFolder && this.user.data.id !== this.entry.data.relationships.owner.data.id
|
||||||
},
|
},
|
||||||
|
canShowLinkIcon() {
|
||||||
|
return this.entry.data.relationships.shared && !this.$isThisRoute(this.$route, ['SharedSingleFile'])
|
||||||
|
},
|
||||||
canDrag() {
|
canDrag() {
|
||||||
return !this.isDeleted && this.$checkPermission(['master', 'editor'])
|
return !this.isDeleted && this.$checkPermission(['master', 'editor'])
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
:entry="item"
|
:entry="item"
|
||||||
:highlight="true"
|
:highlight="true"
|
||||||
:mobile-handler="true"
|
:mobile-handler="true"
|
||||||
|
:can-hover="true"
|
||||||
@mouseup.stop.native="clickFilter"
|
@mouseup.stop.native="clickFilter"
|
||||||
@dragstart.native="$emit('dragstart')"
|
@dragstart.native="$emit('dragstart')"
|
||||||
@drop.native="drop()"
|
@drop.native="drop()"
|
||||||
|
|||||||
+2
-3
@@ -267,16 +267,15 @@ const FunctionHelpers = {
|
|||||||
|
|
||||||
Vue.prototype.$downloadFile = function (url, filename) {
|
Vue.prototype.$downloadFile = function (url, filename) {
|
||||||
// Show alert message when download is disabled
|
// Show alert message when download is disabled
|
||||||
if (!store.getters.user.data.meta.restrictions.canDownload) {
|
if (store.getters.user && !store.getters.user.data.meta.restrictions.canDownload) {
|
||||||
Vue.prototype.$temporarilyDisabledDownload()
|
Vue.prototype.$temporarilyDisabledDownload()
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var anchor = document.createElement('a')
|
let anchor = document.createElement('a')
|
||||||
|
|
||||||
anchor.href = url
|
anchor.href = url
|
||||||
|
|
||||||
anchor.download = filename
|
anchor.download = filename
|
||||||
|
|
||||||
document.body.appendChild(anchor)
|
document.body.appendChild(anchor)
|
||||||
|
|||||||
Vendored
+1
-1
@@ -38,7 +38,7 @@ const itemHelpers = {
|
|||||||
|
|
||||||
Vue.prototype.$downloadSelection = function (item = undefined) {
|
Vue.prototype.$downloadSelection = function (item = undefined) {
|
||||||
// Show alert message when download is disabled
|
// Show alert message when download is disabled
|
||||||
if (!store.getters.user.data.meta.restrictions.canDownload) {
|
if (store.getters.user && !store.getters.user.data.meta.restrictions.canDownload) {
|
||||||
Vue.prototype.$temporarilyDisabledDownload()
|
Vue.prototype.$temporarilyDisabledDownload()
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|||||||
Vendored
+5
-5
@@ -10,15 +10,17 @@ const routesShared = [
|
|||||||
{
|
{
|
||||||
name: 'Public',
|
name: 'Public',
|
||||||
path: '/share/:token/files/:id?',
|
path: '/share/:token/files/:id?',
|
||||||
component: () => import(/* webpackChunkName: "chunks/shared/files" */ '../views/FileView/Public'),
|
component: () => import(/* webpackChunkName: "chunks/shared/browser" */ '../views/FileView/Public'),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: false,
|
requiresAuth: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'SharedSingleFile',
|
name: 'SharedSingleFile',
|
||||||
path: '/share/:token/file',
|
path: '/share/:token/file',
|
||||||
component: () => import(/* webpackChunkName: "chunks/shared/single-file" */ '../views/Shared/SharedSingleFile'),
|
component: () => import(/* webpackChunkName: "chunks/shared/single-file" */ '../views/SharedSingleFile'),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: false,
|
requiresAuth: false,
|
||||||
},
|
},
|
||||||
@@ -26,13 +28,11 @@ const routesShared = [
|
|||||||
{
|
{
|
||||||
name: 'SharedAuthentication',
|
name: 'SharedAuthentication',
|
||||||
path: '/share/:token/authenticate',
|
path: '/share/:token/authenticate',
|
||||||
component: () => import(/* webpackChunkName: "chunks/shared/authenticate" */ '../views/Shared/SharedAuthentication'),
|
component: () => import(/* webpackChunkName: "chunks/shared/authenticate" */ '../views/SharedAuthentication'),
|
||||||
meta: {
|
meta: {
|
||||||
requiresAuth: false,
|
requiresAuth: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
export default routesShared
|
export default routesShared
|
||||||
|
|||||||
-5
@@ -47,11 +47,6 @@ const actions = {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getSingleFile: ({ commit }) => {
|
|
||||||
axios.get(`/api/browse/file/${router.currentRoute.params.token}`).then((response) => {
|
|
||||||
commit('STORE_SHARED_FILE', response.data)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getShareDetail: ({ commit, state }, token) => {
|
getShareDetail: ({ commit, state }, token) => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axios
|
axios
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ import ContentGroup from '../components/Sidebar/ContentGroup'
|
|||||||
import ContentSidebar from '../components/Sidebar/ContentSidebar'
|
import ContentSidebar from '../components/Sidebar/ContentSidebar'
|
||||||
import SidebarNavigation from '../components/Sidebar/SidebarNavigation'
|
import SidebarNavigation from '../components/Sidebar/SidebarNavigation'
|
||||||
import Spotlight from '../components/Spotlight/Spotlight'
|
import Spotlight from '../components/Spotlight/Spotlight'
|
||||||
import MobileNavigationToolbar from './MobileNavigationToolbar'
|
import MobileNavigationToolbar from '../components/Mobile/MobileNavigationToolbar'
|
||||||
import {
|
import {
|
||||||
BoxIcon,
|
BoxIcon,
|
||||||
CreditCardIcon,
|
CreditCardIcon,
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<AuthContentWrapper ref="auth">
|
<AuthContentWrapper ref="auth" class="h-screen">
|
||||||
<AuthContent :visible="true">
|
<AuthContent :visible="true">
|
||||||
<Headline :title="$t('page_shared_404.title')" :description="$t('page_shared_404.subtitle')" />
|
<Headline :title="$t('page_shared_404.title')" :description="$t('page_shared_404.subtitle')" />
|
||||||
<span class="additional-link"
|
<span class="additional-link"
|
||||||
>{{ $t('page_registration.have_an_account') }}
|
>{{ $t('page_registration.have_an_account') }}
|
||||||
<router-link :to="{ name: 'SignIn' }">
|
<router-link :to="{ name: 'SignIn' }" class="text-theme font-bold">
|
||||||
{{ $t('page_forgotten_password.password_remember_button') }}
|
{{ $t('page_forgotten_password.password_remember_button') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ import Spinner from '../components/FilesView/Spinner'
|
|||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import CardNavigation from '../components/Admin/CardNavigation'
|
import CardNavigation from '../components/Admin/CardNavigation'
|
||||||
import ConfirmPassword from '../components/Others/ConfirmPassword'
|
import ConfirmPassword from '../components/Others/ConfirmPassword'
|
||||||
import MobileNavigationToolbar from './MobileNavigationToolbar'
|
import MobileNavigationToolbar from '../components/Mobile/MobileNavigationToolbar'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Settings',
|
name: 'Settings',
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="sm:flex md:h-screen md:overflow-hidden">
|
<div class="lg:flex lg:h-screen lg:overflow-hidden">
|
||||||
<!--Loading Spinner-->
|
|
||||||
<Spinner v-if="isLoading" />
|
|
||||||
|
|
||||||
<!--File preview window-->
|
<!--File preview window-->
|
||||||
<FilePreview />
|
<FilePreview />
|
||||||
<Spotlight />
|
<Spotlight />
|
||||||
@@ -23,54 +20,47 @@
|
|||||||
<DragUI />
|
<DragUI />
|
||||||
<Alert />
|
<Alert />
|
||||||
|
|
||||||
<NavigationSharePanel v-if="sharedDetail && $router.currentRoute.name === 'Public'" />
|
<NavigationSharePanel />
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@contextmenu.prevent.capture="contextMenu($event, undefined)"
|
@contextmenu.prevent.capture="contextMenu($event, undefined)"
|
||||||
class="transition-transform duration-300 sm:flex-grow sm:px-3.5 md:grid md:content-start"
|
class="transition-transform duration-200 lg:grid lg:flex-grow lg:content-start lg:px-3.5"
|
||||||
:class="{ 'origin-center scale-97 transform': isScaledDown }"
|
|
||||||
>
|
>
|
||||||
<DesktopToolbar />
|
<DesktopToolbar />
|
||||||
|
|
||||||
<MobileToolbar />
|
<MobileToolbar />
|
||||||
|
|
||||||
<!--File list & info sidebar-->
|
<!--Google Adsense banner-->
|
||||||
<div class="flex space-x-6 md:h-full md:overflow-hidden">
|
<div v-if="config.allowedAdsense" v-html="config.adsenseBanner01" class="mb-5 min-h-[120px]"></div>
|
||||||
<router-view
|
|
||||||
id="file-view"
|
|
||||||
:class="{
|
|
||||||
'w-full md:w-4/6 2xl:w-5/6': isVisibleSidebar,
|
|
||||||
'w-full': !isVisibleSidebar,
|
|
||||||
}"
|
|
||||||
class="relative"
|
|
||||||
:key="$route.fullPath"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<InfoSidebar v-if="isVisibleSidebar" class="hidden h-screen w-2/6 overflow-y-auto overflow-x-hidden md:block 2xl:w-72" />
|
<!--File list & info sidebar-->
|
||||||
|
<div class="flex space-x-3 lg:overflow-hidden">
|
||||||
|
<router-view id="file-view" class="relative w-full" :key="$route.fullPath" />
|
||||||
|
|
||||||
|
<InfoSidebar v-if="isVisibleSidebar" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MobileToolbar from '../components/FilesView/MobileToolbar'
|
|
||||||
import InfoSidebar from '../components/FilesView/InfoSidebar'
|
|
||||||
import MobileMultiSelectToolbar from '../components/FilesView/MobileMultiSelectToolbar'
|
import MobileMultiSelectToolbar from '../components/FilesView/MobileMultiSelectToolbar'
|
||||||
|
import NavigationSharePanel from './FileView/Components/NavigationSharePanel'
|
||||||
import FileSortingMobile from '../components/FilesView/FileSortingMobile'
|
import FileSortingMobile from '../components/FilesView/FileSortingMobile'
|
||||||
import CreateFolderPopup from '../components/Others/CreateFolderPopup'
|
import CreateFolderPopup from '../components/Others/CreateFolderPopup'
|
||||||
import ProcessingPopup from '../components/FilesView/ProcessingPopup'
|
import ProcessingPopup from '../components/FilesView/ProcessingPopup'
|
||||||
import NavigationSharePanel from './FileView/Components/NavigationSharePanel'
|
import DesktopToolbar from '../components/FilesView/DesktopToolbar'
|
||||||
import RenameItemPopup from '../components/Others/RenameItemPopup'
|
import RenameItemPopup from '../components/Others/RenameItemPopup'
|
||||||
|
import MobileToolbar from '../components/FilesView/MobileToolbar'
|
||||||
import FilePreview from '../components/FilePreview/FilePreview'
|
import FilePreview from '../components/FilePreview/FilePreview'
|
||||||
import MoveItemPopup from '../components/Others/MoveItemPopup'
|
import MoveItemPopup from '../components/Others/MoveItemPopup'
|
||||||
import DesktopToolbar from '../components/FilesView/DesktopToolbar'
|
import InfoSidebar from '../components/FilesView/InfoSidebar'
|
||||||
import Spinner from '../components/FilesView/Spinner'
|
import Spotlight from '../components/Spotlight/Spotlight'
|
||||||
import Vignette from '../components/Others/Vignette'
|
import Vignette from '../components/Others/Vignette'
|
||||||
import DragUI from '../components/FilesView/DragUI'
|
import DragUI from '../components/FilesView/DragUI'
|
||||||
import Alert from '../components/FilesView/Alert'
|
import Alert from '../components/FilesView/Alert'
|
||||||
import Spotlight from '../components/Spotlight/Spotlight'
|
|
||||||
import { events } from '../bus'
|
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
|
import { events } from '../bus'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Shared',
|
name: 'Shared',
|
||||||
@@ -88,7 +78,6 @@ export default {
|
|||||||
FilePreview,
|
FilePreview,
|
||||||
Spotlight,
|
Spotlight,
|
||||||
Vignette,
|
Vignette,
|
||||||
Spinner,
|
|
||||||
DragUI,
|
DragUI,
|
||||||
Alert,
|
Alert,
|
||||||
},
|
},
|
||||||
@@ -97,51 +86,18 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isLoading: true,
|
|
||||||
isScaledDown: false,
|
isScaledDown: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
spotlightListener(e) {
|
|
||||||
if (e.key === 'k' && e.metaKey) {
|
|
||||||
events.$emit('spotlight:show')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
contextMenu(event, item) {
|
contextMenu(event, item) {
|
||||||
events.$emit('context-menu:show', event, item)
|
events.$emit('context-menu:show', event, item)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
// TODO: new scaledown effect
|
||||||
events.$on('mobile-menu:show', () => (this.isScaledDown = true))
|
events.$on('mobile-menu:show', () => (this.isScaledDown = true))
|
||||||
|
events.$on('mobile-menu:hide', () => (this.isScaledDown = false))
|
||||||
this.$store.dispatch('getShareDetail', this.$route.params.token).then((response) => {
|
|
||||||
this.isLoading = false
|
|
||||||
|
|
||||||
let type = response.data.data.attributes.type
|
|
||||||
let routeName = this.$router.currentRoute.name
|
|
||||||
let isProtected = response.data.data.attributes.protected
|
|
||||||
|
|
||||||
// Show public file browser
|
|
||||||
if (type === 'folder' && !isProtected && routeName !== 'Public') {
|
|
||||||
this.$router.replace({
|
|
||||||
name: 'Public',
|
|
||||||
params: {
|
|
||||||
token: this.$route.params.token,
|
|
||||||
id: response.data.data.attributes.item_id,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show public single file
|
|
||||||
if (type !== 'folder' && !isProtected && routeName !== 'SharedSingleFile') {
|
|
||||||
this.$router.push({ name: 'SharedSingleFile' })
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show authentication page
|
|
||||||
if (isProtected && routeName !== 'SharedAuthentication') {
|
|
||||||
this.$router.push({ name: 'SharedAuthentication' })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,45 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="flex h-screen items-center justify-center">
|
|
||||||
<div class="w-full text-center">
|
|
||||||
<ItemGrid v-if="sharedFile" :entry="sharedFile" :highlight="true" :mobile-handler="true" />
|
|
||||||
|
|
||||||
<ButtonBase @click.native="download" button-style="theme" class="mx-auto">
|
|
||||||
{{ $t('page_shared.download_file') }}
|
|
||||||
</ButtonBase>
|
|
||||||
|
|
||||||
<!--Google Adsense banner-->
|
|
||||||
<div v-if="config.allowedAdsense" v-html="config.adsenseBanner01" class="min-h-[120px] mt-5"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import ButtonBase from '../../components/FilesView/ButtonBase'
|
|
||||||
import ItemGrid from '../../components/FilesView/ItemGrid'
|
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'SharedSingleItem',
|
|
||||||
components: {
|
|
||||||
ButtonBase,
|
|
||||||
ItemGrid,
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapGetters(['sharedDetail', 'sharedFile', 'config']),
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
download() {
|
|
||||||
this.$downloadFile(this.sharedFile.data.attributes.file_url, this.sharedFile.data.attributes.name + '.' + this.sharedFile.data.attributes.mimetype)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
if (!this.sharedDetail) {
|
|
||||||
this.$store.dispatch('getShareDetail', this.$route.params.token).then(() => {
|
|
||||||
this.$store.dispatch('getSingleFile')
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.$store.dispatch('getSingleFile')
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
+22
-9
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<AuthContentWrapper>
|
<AuthContentWrapper class="h-screen">
|
||||||
<AuthContent name="password" :visible="true">
|
<AuthContent name="password" :visible="true">
|
||||||
<Headline :title="$t('page_shared.title')" :description="$t('page_shared.subtitle')" />
|
<Headline :title="$t('page_shared.title')" :description="$t('page_shared.subtitle')" />
|
||||||
<ValidationObserver
|
<ValidationObserver
|
||||||
@@ -9,7 +9,14 @@
|
|||||||
tag="form"
|
tag="form"
|
||||||
class="mb-12 items-start space-y-4 md:flex md:space-x-4 md:space-y-0"
|
class="mb-12 items-start space-y-4 md:flex md:space-x-4 md:space-y-0"
|
||||||
>
|
>
|
||||||
<ValidationProvider tag="div" mode="passive" class="w-full text-left" name="Password" rules="required" v-slot="{ errors }">
|
<ValidationProvider
|
||||||
|
tag="div"
|
||||||
|
mode="passive"
|
||||||
|
class="w-full text-left"
|
||||||
|
name="Password"
|
||||||
|
rules="required"
|
||||||
|
v-slot="{ errors }"
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
v-model="password"
|
v-model="password"
|
||||||
:placeholder="$t('page_shared.placeholder_pass')"
|
:placeholder="$t('page_shared.placeholder_pass')"
|
||||||
@@ -19,7 +26,13 @@
|
|||||||
/>
|
/>
|
||||||
<span class="text-left text-xs text-red-600" v-if="errors[0]">{{ errors[0] }}</span>
|
<span class="text-left text-xs text-red-600" v-if="errors[0]">{{ errors[0] }}</span>
|
||||||
</ValidationProvider>
|
</ValidationProvider>
|
||||||
<AuthButton class="w-full justify-center md:w-min" icon="chevron-right" :text="$t('page_shared.submit')" :loading="isLoading" :disabled="isLoading" />
|
<AuthButton
|
||||||
|
class="w-full justify-center md:w-min"
|
||||||
|
icon="chevron-right"
|
||||||
|
:text="$t('page_shared.submit')"
|
||||||
|
:loading="isLoading"
|
||||||
|
:disabled="isLoading"
|
||||||
|
/>
|
||||||
</ValidationObserver>
|
</ValidationObserver>
|
||||||
</AuthContent>
|
</AuthContent>
|
||||||
</AuthContentWrapper>
|
</AuthContentWrapper>
|
||||||
@@ -27,10 +40,10 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
|
import { ValidationProvider, ValidationObserver } from 'vee-validate/dist/vee-validate.full'
|
||||||
import AuthContentWrapper from '../../components/Auth/AuthContentWrapper'
|
import AuthContentWrapper from '../components/Auth/AuthContentWrapper'
|
||||||
import AuthContent from '../../components/Auth/AuthContent'
|
import AuthContent from '../components/Auth/AuthContent'
|
||||||
import AuthButton from '../../components/Auth/AuthButton'
|
import AuthButton from '../components/Auth/AuthButton'
|
||||||
import Headline from '../Auth/Headline'
|
import Headline from './Auth/Headline'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
@@ -70,7 +83,7 @@ export default {
|
|||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
// Show file browser
|
// Show file browser
|
||||||
if (response.data.data.attributes.type === 'folder' && this.$router.currentRoute.name !== 'Public') {
|
if ( response.data.data.attributes.type === 'folder' ) {
|
||||||
this.$router.replace({
|
this.$router.replace({
|
||||||
name: 'Public',
|
name: 'Public',
|
||||||
params: {
|
params: {
|
||||||
@@ -81,7 +94,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show single file
|
// Show single file
|
||||||
if (response.data.data.attributes.type !== 'folder' && this.$router.currentRoute.name !== 'SharedSingleFile') {
|
if ( response.data.data.attributes.type !== 'folder' ) {
|
||||||
this.$router.push({ name: 'SharedSingleFile' })
|
this.$router.push({ name: 'SharedSingleFile' })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
<template>
|
||||||
|
<div class="flex h-screen items-center justify-center">
|
||||||
|
<div v-if="file" class="w-full text-center">
|
||||||
|
<ItemGrid :entry="file" :mobile-handler="false" />
|
||||||
|
|
||||||
|
<ButtonBase @click.native="$downloadSelection(file)" button-style="theme" class="mx-auto">
|
||||||
|
{{ $t('page_shared.download_file') }}
|
||||||
|
</ButtonBase>
|
||||||
|
|
||||||
|
<!--Google Adsense banner-->
|
||||||
|
<div v-if="config.allowedAdsense" v-html="config.adsenseBanner01" class="mt-5 min-h-[120px]"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ButtonBase from '../components/FilesView/ButtonBase'
|
||||||
|
import ItemGrid from '../components/FilesView/ItemGrid'
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SharedSingleItem',
|
||||||
|
components: {
|
||||||
|
ButtonBase,
|
||||||
|
ItemGrid,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['config']),
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
file: undefined,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
axios
|
||||||
|
.get(`/api/browse/file/${this.$router.currentRoute.params.token}`)
|
||||||
|
.then((response) => {
|
||||||
|
this.file = response.data
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (error.response.status === 403)
|
||||||
|
this.$router.push({ name: 'SharedAuthentication' })
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<AuthContentWrapper ref="auth">
|
<AuthContentWrapper ref="auth" class="h-screen">
|
||||||
<!--Invitation info-->
|
<!--Invitation info-->
|
||||||
<AuthContent name="invitation" :visible="false">
|
<AuthContent name="invitation" :visible="false">
|
||||||
<Headline
|
<Headline
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<AuthContentWrapper ref="auth">
|
<AuthContentWrapper ref="auth" class="h-screen">
|
||||||
<AuthContent :visible="true">
|
<AuthContent :visible="true">
|
||||||
<Headline :title="$t('Temporary Unavailable')" :description="$t('Unfortunately, this shared link is temporary unavailable. Please try it later.')" />
|
<Headline :title="$t('Temporary Unavailable')" :description="$t('Unfortunately, this shared link is temporary unavailable. Please try it later.')" />
|
||||||
|
|
||||||
<span class="additional-link"
|
<span class="additional-link"
|
||||||
>{{ $t('page_registration.have_an_account') }}
|
>{{ $t('page_registration.have_an_account') }}
|
||||||
<router-link :to="{ name: 'SignIn' }">
|
<router-link :to="{ name: 'SignIn' }" class="text-theme font-bold">
|
||||||
{{ $t('page_forgotten_password.password_remember_button') }}
|
{{ $t('page_forgotten_password.password_remember_button') }}
|
||||||
</router-link>
|
</router-link>
|
||||||
</span>
|
</span>
|
||||||
@@ -16,20 +16,14 @@
|
|||||||
<script>
|
<script>
|
||||||
import AuthContentWrapper from '../components/Auth/AuthContentWrapper'
|
import AuthContentWrapper from '../components/Auth/AuthContentWrapper'
|
||||||
import AuthContent from '../components/Auth/AuthContent'
|
import AuthContent from '../components/Auth/AuthContent'
|
||||||
import AuthButton from '../components/Auth/AuthButton'
|
|
||||||
import Headline from './Auth/Headline'
|
import Headline from './Auth/Headline'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'NotFound',
|
name: 'TemporaryUnavailable',
|
||||||
components: {
|
components: {
|
||||||
AuthContentWrapper,
|
AuthContentWrapper,
|
||||||
AuthContent,
|
AuthContent,
|
||||||
AuthButton,
|
|
||||||
Headline,
|
Headline,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
|
||||||
@import '../../sass/vuefilemanager/auth';
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -144,7 +144,7 @@
|
|||||||
isGithubLoginConfigured: {{ env('GITHUB_CLIENT_ID') ? 1 : 0 }},
|
isGithubLoginConfigured: {{ env('GITHUB_CLIENT_ID') ? 1 : 0 }},
|
||||||
|
|
||||||
// Adsense
|
// Adsense
|
||||||
allowedAdsense: {{ $settings->allowed_adsense ?? 0 }},
|
allowedAdsense: {{ $settings?->allowed_adsense ?? 0 }},
|
||||||
adsenseClientId: '{{ $settings->adsense_client_id ?? '' }}',
|
adsenseClientId: '{{ $settings->adsense_client_id ?? '' }}',
|
||||||
adsenseBanner01: `{!! $settings->adsense_banner_01 ?? '' !!}`,
|
adsenseBanner01: `{!! $settings->adsense_banner_01 ?? '' !!}`,
|
||||||
adsenseBanner02: `{!! $settings->adsense_banner_02 ?? '' !!}`,
|
adsenseBanner02: `{!! $settings->adsense_banner_02 ?? '' !!}`,
|
||||||
@@ -182,7 +182,7 @@
|
|||||||
@endif
|
@endif
|
||||||
|
|
||||||
{{--Adsense code--}}
|
{{--Adsense code--}}
|
||||||
@if($settings->allowed_adsense)
|
@if(optional($settings)->allowed_adsense)
|
||||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client={{ $settings->adsense_client_id }}" crossorigin="anonymous"></script>
|
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client={{ $settings->adsense_client_id }}" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Domain\Homepage\Controllers;
|
namespace Domain\Homepage\Controllers;
|
||||||
|
|
||||||
use Illuminate\View\View;
|
use Illuminate\Contracts\Foundation\Application;
|
||||||
|
use Illuminate\Contracts\View\Factory;
|
||||||
use Domain\Pages\Models\Page;
|
use Domain\Pages\Models\Page;
|
||||||
use Doctrine\DBAL\Driver\PDOException;
|
use Doctrine\DBAL\Driver\PDOException;
|
||||||
|
use Illuminate\Contracts\View\View;
|
||||||
|
|
||||||
class IndexController
|
class IndexController
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Show index page
|
* Show index page
|
||||||
*/
|
*/
|
||||||
public function __invoke(): View
|
public function __invoke(): Application|Factory|View
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// Try to connect to database
|
// Try to connect to database
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ class SharePublicIndexController extends Controller
|
|||||||
public function __invoke(
|
public function __invoke(
|
||||||
Share $share,
|
Share $share,
|
||||||
): View | StreamedResponse | RedirectResponse {
|
): View | StreamedResponse | RedirectResponse {
|
||||||
|
|
||||||
// Check if user can see shared record
|
// Check if user can see shared record
|
||||||
if (! $share->user->canVisitShared()) {
|
if (! $share->user->canVisitShared()) {
|
||||||
return redirect('/temporary-unavailable');
|
return redirect('/temporary-unavailable');
|
||||||
@@ -31,30 +32,29 @@ class SharePublicIndexController extends Controller
|
|||||||
// Delete share_session if exist
|
// Delete share_session if exist
|
||||||
if ($share->is_protected) {
|
if ($share->is_protected) {
|
||||||
cookie()->queue('share_session', '', -1);
|
cookie()->queue('share_session', '', -1);
|
||||||
|
|
||||||
|
return redirect("/share/$share->token/authenticate");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if shared is image file and then show it
|
// Check if shared is image file and then show it
|
||||||
if ($share->type === 'file' && ! $share->is_protected) {
|
if ($share->type === 'file') {
|
||||||
$image = File::whereUserId($share->user_id)
|
|
||||||
->whereType('image')
|
|
||||||
->whereId($share->item_id)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($image) {
|
// Get file
|
||||||
// Get image filesize
|
$file = File::whereUserId($share->user_id)
|
||||||
$fileSize = (int) $image->getRawOriginal('filesize');
|
->where('type', 'image')
|
||||||
|
->where('id', $share->item_id);
|
||||||
|
|
||||||
// Store user download size
|
// Return raw image
|
||||||
($this->recordDownload)($fileSize, $share->user->id);
|
if ($file->exists()) {
|
||||||
|
return $this->get_single_image($file->first(), $share->user_id);
|
||||||
return $this->get_single_image($image, $share->user_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return view('index')
|
// Return file download page
|
||||||
->with('status_check', [])
|
return redirect("/share/$share->token/file");
|
||||||
->with('installation', 'setup-done')
|
}
|
||||||
->with('settings', get_settings_in_json() ?? null);
|
|
||||||
|
// Return folder items
|
||||||
|
return redirect("/share/$share->token/files/$share->item_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,6 +62,9 @@ class SharePublicIndexController extends Controller
|
|||||||
*/
|
*/
|
||||||
private function get_single_image(File $file, string $user_id): StreamedResponse
|
private function get_single_image(File $file, string $user_id): StreamedResponse
|
||||||
{
|
{
|
||||||
|
// Store user download size
|
||||||
|
($this->recordDownload)($file->getRawOriginal('filesize'), $user_id);
|
||||||
|
|
||||||
// Get file path
|
// Get file path
|
||||||
$path = "/files/$user_id/$file->basename";
|
$path = "/files/$user_id/$file->basename";
|
||||||
|
|
||||||
|
|||||||
@@ -181,6 +181,6 @@ class DefaultRestrictionsTest extends TestCase
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$this->get("/share/$share->token")
|
$this->get("/share/$share->token")
|
||||||
->assertViewIs('index');
|
->assertRedirect("/share/$share->token/files/$share->item_id");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -220,6 +220,6 @@ class FixedBillingRestrictionsTest extends TestCase
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$this->get("/share/$share->token")
|
$this->get("/share/$share->token")
|
||||||
->assertViewIs('index');
|
->assertRedirect("/share/$share->token/files/$share->item_id");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ class VisitorAccessToItemsTest extends TestCase
|
|||||||
|
|
||||||
$this->withCookies($cookie)
|
$this->withCookies($cookie)
|
||||||
->get("/share/$share->token")
|
->get("/share/$share->token")
|
||||||
->assertStatus(200);
|
->assertRedirect("/share/$share->token/authenticate");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! $is_protected) {
|
if (! $is_protected) {
|
||||||
|
|||||||
@@ -55,8 +55,7 @@ class VisitorBrowseTest extends TestCase
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$this->get("/share/$share->token")
|
$this->get("/share/$share->token")
|
||||||
->assertViewIs('index')
|
->assertRedirect("/share/$share->token/files/$share->item_id");
|
||||||
->assertStatus(200);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user