This commit is contained in:
syuilo 2023-05-29 19:56:17 +09:00
parent bd66a3f148
commit 19b96ff650
1 changed files with 117 additions and 147 deletions

View File

@ -1,9 +1,9 @@
<template> <template>
<div class="yfudmmck"> <div :class="$style.root">
<nav> <nav :class="$style.nav">
<div class="path" @contextmenu.prevent.stop="() => {}"> <div :class="$style.navPath" @contextmenu.prevent.stop="() => {}">
<XNavFolder <XNavFolder
:class="{ current: folder == null }" :class="[$style.navPathItem, { [$style.navCurrent]: folder == null }]"
:parentFolder="folder" :parentFolder="folder"
@move="move" @move="move"
@upload="upload" @upload="upload"
@ -11,37 +11,38 @@
@removeFolder="removeFolder" @removeFolder="removeFolder"
/> />
<template v-for="f in hierarchyFolders"> <template v-for="f in hierarchyFolders">
<span class="separator"><i class="ti ti-chevron-right"></i></span> <span :class="[$style.navPathItem, $style.navSeparator]"><i class="ti ti-chevron-right"></i></span>
<XNavFolder <XNavFolder
:folder="f" :folder="f"
:parentFolder="folder" :parentFolder="folder"
:class="[$style.navPathItem]"
@move="move" @move="move"
@upload="upload" @upload="upload"
@removeFile="removeFile" @removeFile="removeFile"
@removeFolder="removeFolder" @removeFolder="removeFolder"
/> />
</template> </template>
<span v-if="folder != null" class="separator"><i class="ti ti-chevron-right"></i></span> <span v-if="folder != null" :class="[$style.navPathItem, $style.navSeparator]"><i class="ti ti-chevron-right"></i></span>
<span v-if="folder != null" class="folder current">{{ folder.name }}</span> <span v-if="folder != null" :class="[$style.navPathItem, $style.navCurrent]">{{ folder.name }}</span>
</div> </div>
<button class="menu _button" @click="showMenu"><i class="ti ti-dots"></i></button> <button class="_button" :class="$style.navMenu" @click="showMenu"><i class="ti ti-dots"></i></button>
</nav> </nav>
<div <div
ref="main" class="main" ref="main"
:class="{ uploading: uploadings.length > 0, fetching }" :class="[$style.main, { [$style.uploading]: uploadings.length > 0, [$style.fetching]: fetching }]"
@dragover.prevent.stop="onDragover" @dragover.prevent.stop="onDragover"
@dragenter="onDragenter" @dragenter="onDragenter"
@dragleave="onDragleave" @dragleave="onDragleave"
@drop.prevent.stop="onDrop" @drop.prevent.stop="onDrop"
@contextmenu.stop="onContextmenu" @contextmenu.stop="onContextmenu"
> >
<div ref="contents" class="contents"> <div ref="contents">
<div v-show="folders.length > 0" ref="foldersContainer" class="folders"> <div v-show="folders.length > 0" ref="foldersContainer" :class="$style.folders">
<XFolder <XFolder
v-for="(f, i) in folders" v-for="(f, i) in folders"
:key="f.id" :key="f.id"
v-anim="i" v-anim="i"
class="folder" :class="$style.folder"
:folder="f" :folder="f"
:selectMode="select === 'folder'" :selectMode="select === 'folder'"
:isSelected="selectedFolders.some(x => x.id === f.id)" :isSelected="selectedFolders.some(x => x.id === f.id)"
@ -54,15 +55,15 @@
@dragend="isDragSource = false" @dragend="isDragSource = false"
/> />
<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid --> <!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
<div v-for="(n, i) in 16" :key="i" class="padding"></div> <div v-for="(n, i) in 16" :key="i" :class="$style.padding"></div>
<MkButton v-if="moreFolders" ref="moreFolders">{{ i18n.ts.loadMore }}</MkButton> <MkButton v-if="moreFolders" ref="moreFolders">{{ i18n.ts.loadMore }}</MkButton>
</div> </div>
<div v-show="files.length > 0" ref="filesContainer" class="files"> <div v-show="files.length > 0" ref="filesContainer" :class="$style.files">
<XFile <XFile
v-for="(file, i) in files" v-for="(file, i) in files"
:key="file.id" :key="file.id"
v-anim="i" v-anim="i"
class="file" :class="$style.file"
:file="file" :file="file"
:selectMode="select === 'file'" :selectMode="select === 'file'"
:isSelected="selectedFiles.some(x => x.id === file.id)" :isSelected="selectedFiles.some(x => x.id === file.id)"
@ -71,19 +72,19 @@
@dragend="isDragSource = false" @dragend="isDragSource = false"
/> />
<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid --> <!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
<div v-for="(n, i) in 16" :key="i" class="padding"></div> <div v-for="(n, i) in 16" :key="i" :class="$style.padding"></div>
<MkButton v-show="moreFiles" ref="loadMoreFiles" @click="fetchMoreFiles">{{ i18n.ts.loadMore }}</MkButton> <MkButton v-show="moreFiles" ref="loadMoreFiles" @click="fetchMoreFiles">{{ i18n.ts.loadMore }}</MkButton>
</div> </div>
<div v-if="files.length == 0 && folders.length == 0 && !fetching" class="empty"> <div v-if="files.length == 0 && folders.length == 0 && !fetching" :class="$style.empty">
<p v-if="draghover">{{ i18n.t('empty-draghover') }}</p> <div v-if="draghover">{{ i18n.t('empty-draghover') }}</div>
<p v-if="!draghover && folder == null"><strong>{{ i18n.ts.emptyDrive }}</strong><br/>{{ i18n.t('empty-drive-description') }}</p> <div v-if="!draghover && folder == null"><strong>{{ i18n.ts.emptyDrive }}</strong><br/>{{ i18n.t('empty-drive-description') }}</div>
<p v-if="!draghover && folder != null">{{ i18n.ts.emptyFolder }}</p> <div v-if="!draghover && folder != null">{{ i18n.ts.emptyFolder }}</div>
</div> </div>
</div> </div>
<MkLoading v-if="fetching"/> <MkLoading v-if="fetching"/>
</div> </div>
<div v-if="draghover" class="dropzone"></div> <div v-if="draghover" :class="$style.dropzone"></div>
<input ref="fileInput" type="file" accept="*/*" multiple tabindex="-1" @change="onChangeFileInput"/> <input ref="fileInput" style="display: none;" type="file" accept="*/*" multiple tabindex="-1" @change="onChangeFileInput"/>
</div> </div>
</template> </template>
@ -658,13 +659,14 @@ onBeforeUnmount(() => {
}); });
</script> </script>
<style lang="scss" scoped> <style lang="scss" module>
.yfudmmck { .root {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
}
> nav { .nav {
display: flex; display: flex;
z-index: 2; z-index: 2;
width: 100%; width: 100%;
@ -673,33 +675,28 @@ onBeforeUnmount(() => {
overflow: auto; overflow: auto;
font-size: 0.9em; font-size: 0.9em;
box-shadow: 0 1px 0 var(--divider); box-shadow: 0 1px 0 var(--divider);
&, * {
user-select: none; user-select: none;
} }
> .path { .navPath {
display: inline-block; display: inline-block;
vertical-align: bottom; vertical-align: bottom;
line-height: 42px; line-height: 42px;
white-space: nowrap; white-space: nowrap;
}
> * { .navPathItem {
display: inline-block; display: inline-block;
margin: 0; margin: 0;
padding: 0 8px; padding: 0 8px;
line-height: 42px; line-height: 42px;
cursor: pointer; cursor: pointer;
* {
pointer-events: none;
}
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
&.current { &.navCurrent {
font-weight: bold; font-weight: bold;
cursor: default; cursor: default;
@ -708,86 +705,64 @@ onBeforeUnmount(() => {
} }
} }
&.separator { &.navSeparator {
margin: 0; margin: 0;
padding: 0; padding: 0;
opacity: 0.5; opacity: 0.5;
cursor: default; cursor: default;
> i {
margin: 0;
}
}
} }
} }
> .menu { .navMenu {
margin-left: auto; margin-left: auto;
padding: 0 12px; padding: 0 12px;
} }
}
> .main { .main {
flex: 1; flex: 1;
overflow: auto; overflow: auto;
padding: var(--margin); padding: var(--margin);
&, * {
user-select: none; user-select: none;
}
&.fetching { &.fetching {
cursor: wait !important; cursor: wait !important;
* {
pointer-events: none;
}
> .contents {
opacity: 0.5; opacity: 0.5;
} pointer-events: none;
} }
&.uploading { &.uploading {
height: calc(100% - 38px - 100px); height: calc(100% - 38px - 100px);
} }
}
> .contents { .folders,
.files {
> .folders,
> .files {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
}
> .folder, .folder,
> .file { .file {
flex-grow: 1; flex-grow: 1;
width: 128px; width: 128px;
margin: 4px; margin: 4px;
box-sizing: border-box; box-sizing: border-box;
} }
> .padding { .padding {
flex-grow: 1; flex-grow: 1;
pointer-events: none; pointer-events: none;
width: 128px + 8px; width: 128px + 8px;
} }
}
> .empty { .empty {
padding: 16px; padding: 16px;
text-align: center; text-align: center;
pointer-events: none; pointer-events: none;
opacity: 0.5; opacity: 0.5;
> p {
margin: 0;
}
}
}
} }
> .dropzone { .dropzone {
position: absolute; position: absolute;
left: 0; left: 0;
top: 38px; top: 38px;
@ -796,9 +771,4 @@ onBeforeUnmount(() => {
border: dashed 2px var(--focus); border: dashed 2px var(--focus);
pointer-events: none; pointer-events: none;
} }
> input {
display: none;
}
}
</style> </style>