mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-24 18:00:40 +00:00
v1.5-alpha.1
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<div class="content-group">
|
||||
<TextLabel>{{ title }}</TextLabel>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import TextLabel from '@/components/Others/TextLabel'
|
||||
|
||||
export default {
|
||||
name: 'ContentGroup',
|
||||
props: ['title'],
|
||||
components: {
|
||||
TextLabel,
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.content-group {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<section class="content-sidebar">
|
||||
<slot></slot>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ContentSidebar',
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@assets/vue-file-manager/_variables';
|
||||
@import '@assets/vue-file-manager/_mixins';
|
||||
|
||||
.content-sidebar {
|
||||
background: linear-gradient(0deg, rgba(246, 245, 241, 0.4) 0%, rgba(243, 244, 246, 0.4) 100%);
|
||||
user-select: none;
|
||||
padding-top: 25px;
|
||||
overflow-y: auto;
|
||||
flex: 0 0 225px;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
.content-sidebar {
|
||||
flex: 0 0 205px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 690px) {
|
||||
.content-sidebar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.content-sidebar {
|
||||
background: rgba($dark_mode_foreground, 0.2);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,183 +0,0 @@
|
||||
<template>
|
||||
<div class="file-item">
|
||||
|
||||
<!--Thumbnail for item-->
|
||||
<div class="icon-item">
|
||||
|
||||
<!--If is file or image, then link item-->
|
||||
<span v-if="isFile" class="file-icon-text">{{ file.mimetype }}</span>
|
||||
|
||||
<!--Folder thumbnail-->
|
||||
<FontAwesomeIcon v-if="isFile" class="file-icon" icon="file" />
|
||||
|
||||
<!--Image thumbnail-->
|
||||
<img v-if="isImage" class="image" :src="file.thumbnail" :alt="file.name" />
|
||||
|
||||
<!--Else show only folder icon-->
|
||||
<FontAwesomeIcon v-if="isFolder" class="folder-icon" icon="folder" />
|
||||
</div>
|
||||
|
||||
<!--Name-->
|
||||
<div class="item-name">
|
||||
|
||||
<!--Name-->
|
||||
<span class="name" >{{ file.name }}</span>
|
||||
|
||||
<!--Other attributes-->
|
||||
<span v-if="! isFolder" class="item-size">{{ file.filesize }}</span>
|
||||
|
||||
<span v-if="isFolder" class="item-length">{{ file.items == 0 ? $t('folder.empty') : $tc('folder.item_counts', folderItems) }}, {{ file.created_at }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'FileListItemThumbnail',
|
||||
props: ['file'],
|
||||
computed: {
|
||||
isFolder() {
|
||||
return this.file.type === 'folder'
|
||||
},
|
||||
isFile() {
|
||||
return this.file.type !== 'folder' && this.file.type !== 'image'
|
||||
},
|
||||
isImage() {
|
||||
return this.file.type === 'image'
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/app.scss";
|
||||
|
||||
.file-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 10px 15px;
|
||||
@include transition(150ms);
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: rgba($theme, .1);
|
||||
|
||||
.item-name .name {
|
||||
color: $theme;
|
||||
}
|
||||
}
|
||||
|
||||
.item-name {
|
||||
display: block;
|
||||
margin-left: 10px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
.item-size,
|
||||
.item-length {
|
||||
@include font-size(11);
|
||||
font-weight: 400;
|
||||
color: $text-muted;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.name {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.name {
|
||||
color: $text;
|
||||
@include font-size(14);
|
||||
font-weight: 700;
|
||||
max-height: 40px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-item {
|
||||
position: relative;
|
||||
min-width: 40px;
|
||||
text-align: center;
|
||||
line-height: 0;
|
||||
|
||||
.file-icon {
|
||||
@include font-size(35);
|
||||
|
||||
path {
|
||||
fill: #fafafc;
|
||||
stroke: #dfe0e8;
|
||||
stroke-width: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.file-icon-text {
|
||||
top: 40%;
|
||||
@include font-size(9);
|
||||
line-height: 1;
|
||||
margin: 0 auto;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
left: 0;
|
||||
right: 0;
|
||||
color: $theme;
|
||||
font-weight: 600;
|
||||
user-select: none;
|
||||
max-width: 20px;
|
||||
max-height: 20px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.image {
|
||||
object-fit: cover;
|
||||
user-select: none;
|
||||
max-width: 100%;
|
||||
border-radius: 5px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.file-item {
|
||||
|
||||
.icon-item .file-icon {
|
||||
|
||||
path {
|
||||
fill: $dark_mode_background;
|
||||
stroke: #2F3C54;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&.is-clicked {
|
||||
background: rgba($theme, .1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
.item-name .name {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 690px) and (prefers-color-scheme: dark){
|
||||
.file-item {
|
||||
|
||||
.icon-item .file-icon {
|
||||
|
||||
path {
|
||||
fill: $dark_mode_foreground;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,216 @@
|
||||
<template>
|
||||
<nav class="menu-bar" v-if="app">
|
||||
|
||||
<!--Navigation Icons-->
|
||||
<div class="icon-navigation menu">
|
||||
|
||||
<router-link :to="{name: 'Profile'}" class="icon-navigation-item user">
|
||||
<UserAvatar />
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{name: 'Files'}" :title="$t('locations.home')" class="icon-navigation-item home">
|
||||
<div class="button-icon">
|
||||
<hard-drive-icon size="19"></hard-drive-icon>
|
||||
</div>
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{name: 'SharedFiles'}" :title="$t('locations.shared')" class="icon-navigation-item shared">
|
||||
<div class="button-icon">
|
||||
<share-icon size="19"></share-icon>
|
||||
</div>
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{name: 'Trash'}" :title="$t('locations.trash')" class="icon-navigation-item trash">
|
||||
<div class="button-icon">
|
||||
<trash-2-icon size="19"></trash-2-icon>
|
||||
</div>
|
||||
</router-link>
|
||||
|
||||
<router-link :to="{name: 'Profile'}" :class="{'is-active': $isThisRoute($route, ['Password'])}" class="icon-navigation-item settings">
|
||||
<div class="button-icon">
|
||||
<settings-icon size="19"></settings-icon>
|
||||
</div>
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<!--User avatar & Logout-->
|
||||
<ul class="icon-navigation logout">
|
||||
<li @click="$store.dispatch('logOut')" class="icon-navigation-item">
|
||||
<div class="button-icon">
|
||||
<power-icon size="19"></power-icon>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserAvatar from '@/components/Others/UserAvatar'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {
|
||||
HardDriveIcon,
|
||||
SettingsIcon,
|
||||
Trash2Icon,
|
||||
PowerIcon,
|
||||
ShareIcon,
|
||||
} from 'vue-feather-icons'
|
||||
|
||||
export default {
|
||||
name: 'MenuBar',
|
||||
components: {
|
||||
HardDriveIcon,
|
||||
SettingsIcon,
|
||||
UserAvatar,
|
||||
Trash2Icon,
|
||||
PowerIcon,
|
||||
ShareIcon,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['app']),
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('getAppData')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@assets/vue-file-manager/_variables';
|
||||
@import '@assets/vue-file-manager/_mixins';
|
||||
|
||||
.menu-bar {
|
||||
background: linear-gradient(180deg, rgba(246, 245, 241, 0.8) 0%, rgba(243, 244, 246, 0.8) 100%);
|
||||
user-select: none;
|
||||
padding-top: 25px;
|
||||
display: grid;
|
||||
width: 72px;
|
||||
}
|
||||
|
||||
.icon-navigation {
|
||||
text-align: center;
|
||||
|
||||
&.menu {
|
||||
margin-bottom: auto;
|
||||
}
|
||||
|
||||
&.logout {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
.icon-navigation-item {
|
||||
display: block;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&.user {
|
||||
margin-bottom: 20px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
cursor: pointer;
|
||||
border-radius: 4px;
|
||||
padding: 12px;
|
||||
display: inline-block;
|
||||
line-height: 0;
|
||||
@include transition(150ms);
|
||||
|
||||
&:hover {
|
||||
background: darken($light_background, 5%);
|
||||
}
|
||||
|
||||
path, line, polyline, rect, circle {
|
||||
@include transition(150ms);
|
||||
stroke: black;
|
||||
}
|
||||
}
|
||||
|
||||
.router-link-active,
|
||||
.is-active {
|
||||
|
||||
&.home {
|
||||
.button-icon {
|
||||
background: rgba($theme, 0.1);
|
||||
|
||||
path, line, polyline, rect, circle {
|
||||
stroke: $theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.shared {
|
||||
.button-icon {
|
||||
background: rgba($yellow, 0.1);
|
||||
|
||||
path, line, polyline, rect, circle {
|
||||
stroke: $yellow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.trash {
|
||||
.button-icon {
|
||||
background: rgba($red, 0.1);
|
||||
|
||||
path, line, polyline, rect, circle {
|
||||
stroke: $red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.settings {
|
||||
.button-icon {
|
||||
background: rgba($purple, 0.1);
|
||||
|
||||
path, line, polyline, rect, circle {
|
||||
stroke: $purple;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
.menu-bar {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.icon-navigation {
|
||||
|
||||
.icon-navigation-item {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 690px) {
|
||||
.menu-bar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.icon-navigation {
|
||||
|
||||
.button-icon {
|
||||
&:hover {
|
||||
background: $dark_mode_background;
|
||||
}
|
||||
|
||||
path, line, polyline, rect, circle {
|
||||
stroke: $dark_mode_text_primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-bar {
|
||||
background: $dark_mode_foreground;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -1,460 +0,0 @@
|
||||
<template>
|
||||
<transition name="sidebar">
|
||||
<div id="sidebar" v-if="app && (isVisibleSidebar || ! isSmallAppSize)">
|
||||
|
||||
<!--User Headline-->
|
||||
<UserHeadline/>
|
||||
|
||||
<!--Content-->
|
||||
<div class="content-scroller">
|
||||
|
||||
<!--Locations-->
|
||||
<div class="menu-list-wrapper">
|
||||
<TextLabel>{{ $t('sidebar.locations') }}</TextLabel>
|
||||
<ul class="menu-list">
|
||||
<li class="menu-list-item" :class="{'is-active': isBaseLocation}" @click="goHome">
|
||||
<FontAwesomeIcon class="icon" icon="hdd"/>
|
||||
<span class="label">{{ $t('locations.home') }}</span>
|
||||
</li>
|
||||
<li class="menu-list-item" :class="{'is-active': isSharedLocation}" @click="getShared">
|
||||
<FontAwesomeIcon class="icon" icon="share"/>
|
||||
<span class="label">{{ $t('locations.shared') }}</span>
|
||||
</li>
|
||||
<li class="menu-list-item" :class="{'is-active': isTrashLocation}" @click="getTrash">
|
||||
<FontAwesomeIcon class="icon" icon="trash-alt"/>
|
||||
<span class="label">{{ $t('locations.trash') }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!--Favourites-->
|
||||
<div class="menu-list-wrapper favourites"
|
||||
@dragover.prevent="dragEnter"
|
||||
@dragleave="dragLeave"
|
||||
@drop="dragFinish($event)"
|
||||
:class="{ 'is-dragenter': area }"
|
||||
>
|
||||
<TextLabel>{{ $t('sidebar.favourites') }}</TextLabel>
|
||||
<transition-group tag="ul" class="menu-list" name="folder-item">
|
||||
<li class="empty-list" v-if="app.favourites.length == 0" :key="0">
|
||||
{{ $t('sidebar.favourites_empty') }}
|
||||
</li>
|
||||
|
||||
<li @click.stop="openFolder(folder)" class="menu-list-item" v-for="folder in app.favourites"
|
||||
:key="folder.unique_id">
|
||||
<div>
|
||||
<FontAwesomeIcon class="icon" icon="folder"/>
|
||||
<span class="label">{{ folder.name }}</span>
|
||||
</div>
|
||||
<FontAwesomeIcon @click.stop="removeFavourite(folder)" v-if="! $isMobile()" class="delete-icon" icon="times"/>
|
||||
</li>
|
||||
</transition-group>
|
||||
</div>
|
||||
|
||||
<!--Last Uploads-->
|
||||
<div class="menu-list-wrapper">
|
||||
<TextLabel>{{ $t('sidebar.latest') }}</TextLabel>
|
||||
|
||||
<p class="empty-list" v-if="app.latest_uploads.length == 0">{{ $t('sidebar.latest_empty') }}</p>
|
||||
|
||||
<FileListItemThumbnail @dblclick.native="downloadFile(item)" @click.native="showFileDetail(item)" :file="item" v-for="item in app.latest_uploads" :key="item.unique_id"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Storage Size Info-->
|
||||
<StorageSize v-if="config.storageLimit"/>
|
||||
|
||||
<!--Mobile logout button-->
|
||||
<div v-if="isSmallAppSize" class="log-out-button">
|
||||
<ButtonBase @click.native="$store.dispatch('logOut')" button-style="danger">{{ $t('context_menu.log_out') }}</ButtonBase>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FileListItemThumbnail from '@/components/Sidebar/FileListItemThumbnail'
|
||||
import UserHeadline from '@/components/Sidebar/UserHeadline'
|
||||
import ButtonBase from '@/components/FilesView/ButtonBase'
|
||||
import StorageSize from '@/components/Sidebar/StorageSize'
|
||||
import TextLabel from '@/components/Others/TextLabel'
|
||||
import {mapGetters} from 'vuex'
|
||||
import {events} from '@/bus'
|
||||
|
||||
export default {
|
||||
name: 'Sidebar',
|
||||
components: {
|
||||
FileListItemThumbnail,
|
||||
UserHeadline,
|
||||
StorageSize,
|
||||
ButtonBase,
|
||||
TextLabel,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['homeDirectory', 'app', 'appSize', 'config', 'currentFolder']),
|
||||
isTrashLocation() {
|
||||
return this.currentFolder && this.currentFolder.location === 'trash-root' || this.currentFolder && this.currentFolder.location === 'trash'
|
||||
},
|
||||
isBaseLocation() {
|
||||
return this.currentFolder && this.currentFolder.location === 'base'
|
||||
},
|
||||
isSharedLocation() {
|
||||
return this.currentFolder && this.currentFolder.location === 'shared'
|
||||
},
|
||||
isSmallAppSize() {
|
||||
return this.appSize === 'small'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
area: false,
|
||||
draggedItem: undefined,
|
||||
isVisibleSidebar: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getShared() {
|
||||
this.$store.dispatch('getShared')
|
||||
},
|
||||
getTrash() {
|
||||
this.$store.dispatch('getTrash')
|
||||
},
|
||||
goHome() {
|
||||
this.$store.commit('FLUSH_BROWSER_HISTORY')
|
||||
this.$store.dispatch('getFolder', [this.homeDirectory, true])
|
||||
},
|
||||
openFolder(folder) {
|
||||
|
||||
// Go to folder
|
||||
this.$store.dispatch('getFolder', [folder, false])
|
||||
},
|
||||
downloadFile(file) {
|
||||
|
||||
this.$downloadFile(file.file_url, file.name + '.' + file.mimetype)
|
||||
},
|
||||
showFileDetail(file) {
|
||||
// Dispatch load file info detail
|
||||
this.$store.dispatch('getFileDetail', file)
|
||||
|
||||
// Show panel if is not open
|
||||
this.$store.dispatch('fileInfoToggle', true)
|
||||
},
|
||||
dragEnter() {
|
||||
if (this.draggedItem && this.draggedItem.type !== 'folder') return
|
||||
|
||||
this.area = true
|
||||
},
|
||||
dragLeave() {
|
||||
this.area = false
|
||||
},
|
||||
dragFinish() {
|
||||
this.area = false
|
||||
|
||||
// Check if draged item is folder
|
||||
if (this.draggedItem && this.draggedItem.type !== 'folder') return
|
||||
|
||||
// Check if folder exist in favourites
|
||||
if (this.app.favourites.find(folder => folder.unique_id == this.draggedItem.unique_id)) return
|
||||
|
||||
// Store favourites folder
|
||||
this.$store.dispatch('addToFavourites', this.draggedItem)
|
||||
|
||||
},
|
||||
removeFavourite(folder) {
|
||||
|
||||
// Remove favourites folder
|
||||
this.$store.dispatch('removeFromFavourites', folder)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('getAppData')
|
||||
|
||||
// Listen for dragstart folder items
|
||||
events.$on('dragstart', (item) => this.draggedItem = item)
|
||||
|
||||
// Listen for show sidebar
|
||||
events.$on('show:sidebar', () => {
|
||||
this.isVisibleSidebar = !this.isVisibleSidebar
|
||||
})
|
||||
|
||||
// Listen for hide sidebar
|
||||
events.$on('show:content', () => {
|
||||
if (this.isVisibleSidebar) this.isVisibleSidebar = false
|
||||
})
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/app.scss";
|
||||
|
||||
#sidebar {
|
||||
position: relative;
|
||||
flex: 0 0 265px;
|
||||
background: $light_background;
|
||||
}
|
||||
|
||||
.content-scroller {
|
||||
bottom: 50px;
|
||||
position: absolute;
|
||||
top: 75px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
overflow-x: auto;
|
||||
|
||||
.menu-list-wrapper:first-of-type {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.text-label {
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-list-wrapper {
|
||||
margin-bottom: 20px;
|
||||
|
||||
.menu-list {
|
||||
|
||||
.menu-list-item {
|
||||
display: block;
|
||||
padding: 8px 15px 8px 25px;
|
||||
@include transition(150ms);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
|
||||
.icon {
|
||||
@include font-size(13);
|
||||
width: 15px;
|
||||
margin-right: 9px;
|
||||
vertical-align: middle;
|
||||
|
||||
path {
|
||||
fill: $text;
|
||||
}
|
||||
}
|
||||
|
||||
.delete-icon {
|
||||
display: none;
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 50%;
|
||||
@include transform(translateY(-50%));
|
||||
@include font-size(12);
|
||||
|
||||
path {
|
||||
fill: $text-muted;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
@include font-size(14);
|
||||
font-weight: 700;
|
||||
vertical-align: middle;
|
||||
white-space: nowrap;
|
||||
max-width: 210px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&.is-active {
|
||||
background: rgba($theme, .1);
|
||||
|
||||
.icon {
|
||||
path {
|
||||
fill: $theme;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
color: $theme;
|
||||
}
|
||||
|
||||
.delete-icon {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.favourites {
|
||||
|
||||
&.is-dragenter {
|
||||
|
||||
.menu-list {
|
||||
border: 2px dashed $theme;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-list {
|
||||
border: 2px dashed transparent;
|
||||
|
||||
.menu-list-item {
|
||||
padding: 8px 23px;
|
||||
|
||||
.icon {
|
||||
margin-right: 5px;
|
||||
@include font-size(14);
|
||||
width: 20px;
|
||||
|
||||
path {
|
||||
fill: $theme;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba($theme, .1);
|
||||
|
||||
.icon {
|
||||
path {
|
||||
fill: $theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-list {
|
||||
@include font-size(12);
|
||||
color: $text-muted;
|
||||
display: block;
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.log-out-button {
|
||||
margin-top: 15px;
|
||||
padding: 15px;
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1024px) {
|
||||
|
||||
#sidebar {
|
||||
flex: 0 0 265px;
|
||||
}
|
||||
|
||||
.menu-list-wrapper .menu-list .menu-list-item .label {
|
||||
max-width: 190px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 690px) {
|
||||
|
||||
.content-scroller {
|
||||
bottom: initial;
|
||||
position: relative;
|
||||
top: initial;
|
||||
overflow-x: initial;
|
||||
}
|
||||
|
||||
#sidebar {
|
||||
position: absolute;
|
||||
overflow-y: auto;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 99;
|
||||
bottom: 0;
|
||||
background: white;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.menu-list-wrapper {
|
||||
|
||||
&.favourites {
|
||||
|
||||
.menu-list .menu-list-item {
|
||||
padding: 10px 26px;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-list .menu-list-item {
|
||||
padding: 10px 26px;
|
||||
|
||||
.label {
|
||||
@include font-size(14);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.log-out-button {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
#sidebar {
|
||||
background: $dark_mode_background;
|
||||
}
|
||||
|
||||
.menu-list-wrapper {
|
||||
|
||||
.menu-list .menu-list-item {
|
||||
|
||||
.label {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
|
||||
.icon {
|
||||
|
||||
path {
|
||||
fill: lighten($dark_mode_foreground, 10%);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba($theme, .1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) and (max-width: 690px) {
|
||||
#sidebar {
|
||||
background: $dark_mode_background;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-enter-active {
|
||||
transition: all 300ms ease;
|
||||
}
|
||||
|
||||
.sidebar-enter /* .list-leave-active below version 2.1.8 */
|
||||
{
|
||||
opacity: 0;
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
// Transition
|
||||
.folder-item-move {
|
||||
transition: transform 300s ease;
|
||||
}
|
||||
|
||||
.folder-item-enter-active {
|
||||
transition: all 300ms ease;
|
||||
}
|
||||
|
||||
.folder-item-leave-active {
|
||||
transition: all 300ms;
|
||||
}
|
||||
|
||||
.folder-item-enter, .folder-item-leave-to /* .list-leave-active below version 2.1.8 */
|
||||
{
|
||||
opacity: 0;
|
||||
transform: translateX(30px);
|
||||
}
|
||||
|
||||
.folder-item-leave-active {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
@@ -24,7 +24,8 @@
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/app.scss";
|
||||
@import '@assets/vue-file-manager/_variables';
|
||||
@import '@assets/vue-file-manager/_mixins';
|
||||
|
||||
.storage-size {
|
||||
position: absolute;
|
||||
|
||||
@@ -1,26 +1,7 @@
|
||||
<template>
|
||||
<div class="user-headline-wrapper" v-if="app">
|
||||
<div class="user-headline" @click="openMenu">
|
||||
<div class="user-avatar">
|
||||
<img :src="app.user.avatar" :alt="app.user.name">
|
||||
</div>
|
||||
<div class="user-name">
|
||||
<b class="name">{{ app.user.name }}</b>
|
||||
<span class="email">{{ app.user.email }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<transition name="user-menu">
|
||||
<div class="user-menu" v-if="isOpenedMenu">
|
||||
<ul class="menu-options" @click="closeMenu">
|
||||
<li class="menu-option">
|
||||
<router-link :to="{name: 'Profile'}">
|
||||
{{ $t('context_menu.profile_settings') }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li class="menu-option" @click="$store.dispatch('logOut')">{{ $t('context_menu.log_out') }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</transition>
|
||||
<div class="user-meta" v-if="app">
|
||||
<b class="name">{{ app.user.name }}</b>
|
||||
<span class="email">{{ app.user.email }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -31,198 +12,36 @@
|
||||
export default {
|
||||
name: 'UserHeadline',
|
||||
computed: {
|
||||
...mapGetters(['app', 'appSize']),
|
||||
isSmallAppSize() {
|
||||
return this.appSize === 'small'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isOpenedMenu: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openMenu() {
|
||||
|
||||
// If is mobile, then go to user settings page, else, open menu
|
||||
if ( this.isSmallAppSize ) {
|
||||
|
||||
events.$emit('show:sidebar')
|
||||
this.$router.push({name: 'Profile'})
|
||||
|
||||
} else {
|
||||
|
||||
this.isOpenedMenu = !this.isOpenedMenu
|
||||
}
|
||||
|
||||
},
|
||||
closeMenu() {
|
||||
this.isOpenedMenu = !this.isOpenedMenu
|
||||
},
|
||||
...mapGetters(['app']),
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@assets/app.scss";
|
||||
@import '@assets/vue-file-manager/_variables';
|
||||
@import '@assets/vue-file-manager/_mixins';
|
||||
|
||||
.user-headline-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.user-headline {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 15px;
|
||||
padding: 5px;
|
||||
user-select: none;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
@include transition(150ms);
|
||||
background: darken($light_background, 3%);
|
||||
|
||||
&:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
.user-name {
|
||||
|
||||
.name, .email {
|
||||
white-space: nowrap;
|
||||
width: 180px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.user-meta {
|
||||
padding-left: 20px;
|
||||
|
||||
.name {
|
||||
display: block;
|
||||
@include font-size(17);
|
||||
line-height: 1;
|
||||
color: $text;
|
||||
@include font-size(18);
|
||||
}
|
||||
|
||||
.email {
|
||||
@include font-size(13);
|
||||
color: $theme;
|
||||
display: block;
|
||||
margin-top: 2px;
|
||||
@include font-size(12);
|
||||
color: $theme;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
line-height: 0;
|
||||
margin-right: 15px;
|
||||
|
||||
img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
object-fit: cover;
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-menu {
|
||||
position: absolute;
|
||||
top: 75px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 15px;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.menu-options {
|
||||
list-style: none;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-shadow: $shadow;
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
|
||||
.menu-option {
|
||||
font-weight: 700;
|
||||
@include font-size(15);
|
||||
padding: 15px 30px;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
color: $text;
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: $text;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $light_background;
|
||||
color: $theme;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 690px) {
|
||||
|
||||
.user-headline {
|
||||
position: relative;
|
||||
margin-bottom: 40px;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
|
||||
.user-headline {
|
||||
background: $dark_mode_background;
|
||||
padding: 0;
|
||||
|
||||
&:hover {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.user-name {
|
||||
|
||||
.name {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-options {
|
||||
background: $dark_mode_background;
|
||||
|
||||
.menu-option {
|
||||
color: $dark_mode_text_primary;
|
||||
|
||||
a {
|
||||
color: $dark_mode_text_primary;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $dark_mode_foreground;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transition
|
||||
.user-menu-enter-active {
|
||||
transition: all 150ms ease;
|
||||
}
|
||||
|
||||
.user-menu-leave-active {
|
||||
transition: all 150ms ease;
|
||||
}
|
||||
|
||||
.user-menu-enter,
|
||||
.user-menu-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(-35%);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user