vue frontend update

This commit is contained in:
carodej
2020-04-17 11:33:06 +02:00
parent ae4353cc4b
commit 506c39896a
45 changed files with 2366 additions and 784 deletions

View File

@@ -1,13 +1,16 @@
<template>
<button class="button-base" :class="buttonStyle" type="button">
<slot></slot>
<span v-if="loading" class="icon">
<FontAwesomeIcon icon="sync-alt" class="sync-alt"/>
</span>
<slot v-if="! loading"></slot>
</button>
</template>
<script>
export default {
name: 'ButtonBase',
props: ['buttonStyle']
props: ['buttonStyle', 'loading']
}
</script>
@@ -38,12 +41,30 @@
background: rgba($danger, .1);
}
&.danger-solid {
color: white;
background: $danger;
}
&.secondary {
color: $text;
background: $light_background;
}
}
.sync-alt {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
@media (prefers-color-scheme: dark) {
.button-base {

View File

@@ -1,34 +1,60 @@
<template>
<div
ref="contextmenu"
class="contextmenu"
:style="{ top: positionY + 'px', left: positionX + 'px' }"
@click="closeAndResetContextMenu"
class="contextmenu"
v-show="isVisible"
ref="contextmenu"
>
<ul class="menu-options" id="menu-options-list" ref="list" @click="closeAndResetContextMenu">
<!--ContextMenu for trash location-->
<ul v-if="$isTrashLocation()" class="menu-options" ref="list">
<li class="menu-option" @click="removeItem" v-if="item">
{{ $t('context_menu.delete') }}
</li>
<li class="menu-option" @click="$store.dispatch('restoreItem', item)" v-if="item">
{{ $t('context_menu.restore') }}
</li>
<li class="menu-option" @click="$store.dispatch('emptyTrash')">
{{ $t('context_menu.empty_trash') }}
</li>
<li class="menu-option" @click="ItemDetail" v-if="item">
{{ $t('context_menu.detail') }}
</li>
<li class="menu-option" @click="downloadItem" v-if="! isFolder && item">
{{ $t('context_menu.download') }}
</li>
</ul>
<!--View-->
<li class="menu-option" @click="addToFavourites" v-if="! $isTrashLocation() && item && isFolder">{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}</li>
<li class="menu-option" @click="createFolder" v-if="! $isTrashLocation()">{{ $t('context_menu.create_folder') }}</li>
<!--Edits-->
<li class="menu-option" @click="removeItem" v-if="! $isTrashLocation() && item">{{ $t('context_menu.delete') }}</li>
<li class="menu-option" @click="moveItem" v-if="! $isTrashLocation() && item">{{ $t('context_menu.move') }}</li>
<!--Trash-->
<li class="menu-option" @click="$store.dispatch('restoreItem', item)" v-if="item && $isTrashLocation()">{{ $t('context_menu.restore') }}</li>
<li class="menu-option" @click="$store.dispatch('emptyTrash')" v-if="$isTrashLocation()">{{ $t('context_menu.empty_trash') }}</li>
<!--Others-->
<li class="menu-option" @click="ItemDetail" v-if="item">{{ $t('context_menu.detail') }}</li>
<li class="menu-option" @click="downloadItem" v-if="! isFolder && item">{{ $t('context_menu.download') }}</li>
<!--ContextMenu for Base location-->
<ul v-if="$isBaseLocation()" class="menu-options" ref="list">
<li class="menu-option" @click="addToFavourites" v-if="item && isFolder">
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
</li>
<li class="menu-option" @click="createFolder">
{{ $t('context_menu.create_folder') }}
</li>
<li class="menu-option" @click="removeItem" v-if="item">
{{ $t('context_menu.delete') }}
</li>
<li class="menu-option" @click="moveItem" v-if="item">
{{ $t('context_menu.move') }}
</li>
<li class="menu-option" @click="shareItem" v-if="item">
{{ $t('context_menu.share') }}
</li>
<li class="menu-option" @click="ItemDetail" v-if="item">
{{ $t('context_menu.detail') }}
</li>
<li class="menu-option" @click="downloadItem" v-if="! isFolder && item">
{{ $t('context_menu.download') }}
</li>
</ul>
</div>
</template>
<script>
import {events} from '@/bus'
import {mapGetters} from 'vuex'
import {events} from '@/bus'
export default {
name: 'ContextMenu',
@@ -57,10 +83,15 @@
},
methods: {
moveItem() {
// Move item fire popup
events.$emit('popup:move-item', this.item);
// Open move item popup
events.$emit('popup:open', {name: 'move', item: this.item})
},
shareItem() {
// Open share item popup
events.$emit('popup:open', {name: 'share-create', item: this.item})
},
addToFavourites() {
// Check if folder is in favourites and then add/remove from favourites
if (this.app.favourites && ! this.app.favourites.find(el => el.unique_id == this.item.unique_id)) {
this.$store.dispatch('addToFavourites', this.item)
} else {

View File

@@ -1,6 +1,7 @@
<template>
<div id="desktop-toolbar">
<div class="toolbar-wrapper">
<!-- Go back-->
<div class="toolbar-go-back" v-if="homeDirectory">
<div @click="goBack" class="go-back-button">
@@ -20,6 +21,7 @@
<div class="toolbar-button-wrapper">
<SearchBar/>
</div>
<div class="toolbar-button-wrapper">
<ToolbarButtonUpload source="upload" action="Upload file"/>
<ToolbarButton
@@ -33,6 +35,7 @@
action="Create folder"
/>
</div>
<div class="toolbar-button-wrapper">
<ToolbarButton
:source="preview"

View File

@@ -1,5 +1,5 @@
<template>
<div v-if="fileInfoDetail">
<div class="file-info-content" v-if="fileInfoDetail">
<div class="file-headline" spellcheck="false">
<FilePreview />
@@ -7,25 +7,20 @@
<!--File info-->
<div class="flex">
<div class="icon">
<div class="icon-preview" @dblclick="getItemAction">
<FontAwesomeIcon v-if="fileInfoDetail.type == 'folder'" icon="folder"></FontAwesomeIcon>
<FontAwesomeIcon v-if="fileInfoDetail.type == 'file'" icon="file"></FontAwesomeIcon>
<FontAwesomeIcon v-if="fileInfoDetail.type == 'image'" icon="file-image"></FontAwesomeIcon>
<FontAwesomeIcon v-if="fileInfoDetail.type == 'video'" icon="file-video"></FontAwesomeIcon>
<FontAwesomeIcon v-if="fileInfoDetail.type == 'audio'" icon="file-audio"></FontAwesomeIcon>
<div class="icon-preview">
<FontAwesomeIcon :icon="filePreviewIcon"></FontAwesomeIcon>
</div>
</div>
<div class="file-info">
<span ref="name" contenteditable="false" class="name">{{
fileInfoDetail.name
}}</span>
<span class="mimetype">{{ fileInfoDetail.mimetype }}</span>
<span ref="name" class="name">{{ fileInfoDetail.name }}</span>
<span class="mimetype" v-if="fileInfoDetail.mimetype">{{ fileInfoDetail.mimetype }}</span>
</div>
</div>
</div>
<!--Info list-->
<ul class="list-info">
<!--Filesize-->
<li v-if="fileInfoDetail.filesize" class="list-info-item">
<b>{{ $t('file_detail.size') }}</b>
@@ -33,7 +28,7 @@
</li>
<!--Latest change-->
<li v-if="fileInfoDetail.created_at" class="list-info-item">
<li class="list-info-item">
<b>{{ $t('file_detail.created_at') }}</b>
<span>{{ fileInfoDetail.created_at }}</span>
</li>
@@ -46,60 +41,69 @@
<span>{{ fileInfoDetail.parent ? fileInfoDetail.parent.name : $t('locations.home') }}</span>
</div>
</li>
<!--Parent-->
<li v-if="true" class="list-info-item">
<b>Shared</b>
<div class="action-button" @click="shareItemOptions">
<FontAwesomeIcon class="icon" icon="user-edit" />
<span>Can edit and upload files</span>
</div>
<CopyInput class="copy-sharelink" size="small" :value="shareLink" />
</li>
</ul>
</div>
</template>
<script>
import FilePreview from '@/components/VueFileManagerComponents/FilesView/FilePreview'
import CopyInput from '@/components/VueFileManagerComponents/Others/Forms/CopyInput'
import {mapGetters} from 'vuex'
import {debounce} from 'lodash'
import {events} from "@/bus"
export default {
name: 'FileInfoPanel',
components: {
FilePreview
FilePreview,
CopyInput,
},
computed: {
...mapGetters(['fileInfoDetail'])
...mapGetters(['fileInfoDetail']),
filePreviewIcon() {
switch (this.fileInfoDetail.type) {
case 'folder':
return 'folder'
break;
case 'file':
return 'file'
break;
case 'image':
return 'file-image'
break;
case 'video':
return 'file-video'
break;
case 'file':
return 'file-audio'
break;
}
}
},
data() {
return {
shareLink: 'http://192.168.1.131:8000/shared?token=3ZlQLIoCR8izoc0PemekHNq3UIMj6OrC0aQ2zowclfjFYa8P6go8fMKPnXTJomvz'
}
},
methods: {
shareItemOptions() {
// Open share item popup
events.$emit('popup:open', {name: 'share-edit', item: this.fileInfoDetail})
},
moveItem() {
// Move item fire popup
events.$emit('popup:move-item', this.fileInfoDetail);
},
getItemAction() {
// Open image on new tab
if (this.fileInfoDetail.type == 'image') {
this.$openImageOnNewTab(this.fileInfoDetail.file_url)
}
events.$emit('popup:open', {name: 'move', item: this.fileInfoDetail})
// Download file
if (this.fileInfoDetail.type == 'file') {
this.$downloadFile(
this.fileInfoDetail.file_url,
this.fileInfoDetail.name +
'.' +
this.fileInfoDetail.mimetype
)
}
// Open folder
if (this.fileInfoDetail.type == 'folder') {
// Todo: open folder
}
},
changeItemName: debounce(function (e) {
// Prevent submit empty string
if (e.target.innerText === '') return
this.$store.dispatch('changeItemName', {
unique_id: this.fileInfoDetail.unique_id,
type: this.fileInfoDetail.type,
name: e.target.innerText
})
}, 300)
}
}
}
</script>
@@ -107,6 +111,10 @@
<style scoped lang="scss">
@import "@assets/app.scss";
.file-info-content {
padding-bottom: 20px;
}
.file-headline {
background: $light_background;
padding: 12px;
@@ -156,6 +164,8 @@
.name {
@include font-size(14);
font-weight: 700;
line-height: 1.4;
display: block;
color: $text;
}
@@ -173,7 +183,7 @@
.list-info-item {
display: block;
padding-top: 20px;
padding-top: 15px;
&:first-child {
padding-top: 0;
@@ -183,9 +193,13 @@
cursor: pointer;
.icon {
@include font-size(11);
@include font-size(10);
display: inline-block;
margin-right: 2px;
path {
fill: $theme_light;
}
}
}
@@ -193,6 +207,7 @@
display: block;
@include font-size(13);
color: $theme;
margin-bottom: 2px;
}
span {
@@ -204,6 +219,10 @@
}
}
.copy-sharelink {
margin-top: 10px;
}
@media (prefers-color-scheme: dark) {
.file-headline {

View File

@@ -20,10 +20,11 @@
>
<!--Thumbnail for item-->
<div class="icon-item">
<!--If is file or image, then link item-->
<span v-if="isFile" class="file-icon-text">{{
data.mimetype
}}</span>
<span v-if="isFile" class="file-icon-text">
{{ data.mimetype }}
</span>
<!--Folder thumbnail-->
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file"/>
@@ -38,22 +39,30 @@
<!--Name-->
<div class="item-name">
<!--Name-->
<span
<b
ref="name"
@input="changeItemName"
:contenteditable="!$isMobile()"
class="name"
>{{ itemName }}</span
>
{{ itemName }}
</b>
<!--Other attributes-->
<span v-if="! isFolder" class="item-size">{{
data.filesize
}}</span>
<div class="item-info">
<!--Shared Icon-->
<div class="item-shared" v-if="true">
<FontAwesomeIcon class="shared-icon" icon="user-friends"/>
<span class="label">Shared, </span>
</div>
<span v-if="isFolder" class="item-length">
{{ folderItems == 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}
</span>
<!--Filesize-->
<span v-if="! isFolder" class="item-size">{{ data.filesize }}</span>
<!--Folder item counts-->
<span v-if="isFolder" class="item-length">
{{ folderItems == 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}
</span>
</div>
</div>
<span @click.stop="showItemActions" class="show-actions" v-if="$isMobile()">
@@ -220,19 +229,29 @@
@include font-size(12);
font-weight: 400;
color: $text-muted;
display: block;
display: inline-block;
}
.name {
.item-info {
display: block;
line-height: 1;
}
&[contenteditable] {
-webkit-user-select: text;
user-select: text;
.item-shared {
display: inline-block;
.label {
@include font-size(12);
font-weight: 400;
color: $theme;
}
&[contenteditable='true']:hover {
text-decoration: underline;
.shared-icon {
@include font-size(10);
path {
fill: $theme;
}
}
}
@@ -244,6 +263,15 @@
overflow: hidden;
text-overflow: ellipsis;
&[contenteditable] {
-webkit-user-select: text;
user-select: text;
}
&[contenteditable='true']:hover {
text-decoration: underline;
}
&.actived {
max-height: initial;
}
@@ -377,4 +405,6 @@
}
}
}
</style>

View File

@@ -20,9 +20,9 @@
<!--Thumbnail for item-->
<div class="icon-item">
<!--If is file or image, then link item-->
<span v-if="isFile" class="file-icon-text">{{
data.mimetype | limitCharacters
}}</span>
<span v-if="isFile" class="file-icon-text">
{{ data.mimetype | limitCharacters }}
</span>
<!--Folder thumbnail-->
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file"/>
@@ -37,19 +37,31 @@
<!--Name-->
<div class="item-name">
<!--Name-->
<span
<b
ref="name"
@input="changeItemName"
:contenteditable="!$isMobile() && !$isTrashLocation()"
class="name"
>{{ itemName }}</span>
>
{{ itemName }}
</b>
<!--Other attributes-->
<span v-if="! isFolder" class="item-size">{{ data.filesize }}, {{ timeStamp }}</span>
<div class="item-info">
<span v-if="isFolder" class="item-length">
{{ folderItems == 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ timeStamp }}
</span>
<!--Shared Icon-->
<div class="item-shared" v-if="true">
<FontAwesomeIcon class="shared-icon" icon="user-friends"/>
<span class="label">Shared,</span>
</div>
<!--Filesize and timestamp-->
<span v-if="! isFolder" class="item-size">{{ data.filesize }}, {{ timeStamp }}</span>
<!--Folder item counts-->
<span v-if="isFolder" class="item-length">
{{ folderItems == 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ timeStamp }}
</span>
</div>
</div>
<!--Go Next icon-->
@@ -233,12 +245,34 @@
text-overflow: ellipsis;
white-space: nowrap;
.item-info {
display: block;
line-height: 1;
}
.item-shared {
display: inline-block;
.label {
@include font-size(12);
font-weight: 400;
color: $theme;
}
.shared-icon {
@include font-size(10);
path {
fill: $theme;
}
}
}
.item-size,
.item-length {
@include font-size(12);
font-weight: 400;
color: $text-muted;
display: block;
}
.name {

View File

@@ -8,46 +8,38 @@
@click="closeAndResetContextMenu"
>
<div class="menu-wrapper">
<ul class="menu-options">
<li class="menu-option"
@click="addToFavourites"
v-if="! $isTrashLocation() && fileInfoDetail && isFolder"
>
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
</li>
<li class="menu-option"
@click="$store.dispatch('restoreItem', fileInfoDetail)"
v-if="fileInfoDetail && $isTrashLocation()"
>
<!--Mobile for trash location-->
<ul v-if="$isTrashLocation()" class="menu-options">
<li class="menu-option" @click="$store.dispatch('restoreItem', fileInfoDetail)" v-if="fileInfoDetail">
{{ $t('context_menu.restore') }}
</li>
<li
class="menu-option"
@click="renameItem"
v-if="fileInfoDetail"
>
{{ $t('context_menu.rename') }}
</li>
<li
class="menu-option"
@click="moveItem"
v-if="fileInfoDetail"
>
{{ $t('context_menu.move') }}
</li>
<li
class="menu-option"
@click="downloadItem"
v-if="! isFolder"
>
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
{{ $t('context_menu.download') }}
</li>
<li
class="menu-option delete"
@click="removeItem"
v-if="fileInfoDetail"
>
<li class="menu-option delete" @click="removeItem" v-if="fileInfoDetail">
{{ $t('context_menu.delete') }}
</li>
</ul>
<!--Mobile for Base location-->
<ul v-if="$isBaseLocation()" class="menu-options">
<li class="menu-option" @click="addToFavourites" v-if="fileInfoDetail && isFolder">
{{ isInFavourites ? $t('context_menu.remove_from_favourites') : $t('context_menu.add_to_favourites') }}
</li>
<li class="menu-option" @click="renameItem" v-if="fileInfoDetail">
{{ $t('context_menu.rename') }}
</li>
<li class="menu-option" @click="moveItem" v-if="fileInfoDetail">
{{ $t('context_menu.move') }}
</li>
<li class="menu-option" @click="shareItem" v-if="fileInfoDetail">
{{ $t('context_menu.share') }}
</li>
<li class="menu-option" @click="downloadItem" v-if="! isFolder">
{{ $t('context_menu.download') }}
</li>
<li class="menu-option delete" @click="removeItem" v-if="fileInfoDetail">
{{ $t('context_menu.delete') }}
</li>
</ul>
@@ -92,11 +84,16 @@
},
methods: {
moveItem() {
// Move item fire popup
events.$emit('popup:move-item', this.fileInfoDetail);
// Open move item popup
events.$emit('popup:open', {name: 'move', item: this.fileInfoDetail})
},
shareItem() {
// Open share item popup
events.$emit('popup:open', {name: 'share-create', item: this.fileInfoDetail})
},
addToFavourites() {
if (this.app.favourites && ! this.app.favourites.find(el => el.unique_id == this.fileInfoDetail.unique_id)) {
if (this.app.favourites && !this.app.favourites.find(el => el.unique_id == this.fileInfoDetail.unique_id)) {
this.$store.dispatch('addToFavourites', this.fileInfoDetail)
} else {
this.$store.dispatch('removeFromFavourites', this.fileInfoDetail)
@@ -130,7 +127,7 @@
this.$store.dispatch('changeItemName', item)
// Change item name if is mobile device or prompted
if ( this.$isMobile() ) {
if (this.$isMobile()) {
events.$emit('change:name', item)
}
}