added basic UI for file transfer
This commit is contained in:
parent
ec69eb2dcb
commit
fa45619dbb
194
client/src/components/files.vue
Normal file
194
client/src/components/files.vue
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
<template>
|
||||||
|
<div class="files">
|
||||||
|
<div class="files-cwd">
|
||||||
|
<p>{{ cwd }}</p>
|
||||||
|
<i class="fas fa-rotate-right refresh" @click="refresh" />
|
||||||
|
</div>
|
||||||
|
<div class="files-list">
|
||||||
|
<div v-for="item in files" :key="item.name" class="files-list-item">
|
||||||
|
<i :class="fileIcon(item)" />
|
||||||
|
<p>{{ item.name }}</p>
|
||||||
|
<i class="fas fa-download download" @click="() => download(item)" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="files-transfer" @dragover.prevent @drop.prevent="onFileDrop">
|
||||||
|
<i class="fas fa-file-arrow-up" />
|
||||||
|
<p>Drag files here to upload</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.files {
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
display: flex;
|
||||||
|
max-width: 100%;
|
||||||
|
|
||||||
|
.files-cwd {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
margin: 10px 10px 0px 10px;
|
||||||
|
padding: 0.5em;
|
||||||
|
font-weight: 600;
|
||||||
|
background-color: rgba($color: #fff, $alpha: 0.05);
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.files-list {
|
||||||
|
margin: 10px 10px 10px 10px;
|
||||||
|
background-color: rgba($color: #fff, $alpha: 0.05);
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow-y: scroll;
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: $background-tertiary transparent;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-track {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background-color: $background-tertiary;
|
||||||
|
border: 2px solid $background-primary;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb:hover {
|
||||||
|
background-color: $background-floating;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.files-list-item {
|
||||||
|
padding: 0.5em;
|
||||||
|
border-bottom: 2px solid rgba($color: #fff, $alpha: 0.10);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-icon {
|
||||||
|
width: 14px;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.files-list-item:last-child {
|
||||||
|
border-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh, .download {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh:hover, .download:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.files-transfer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: auto 10px 10px 10px;
|
||||||
|
background-color: rgba($color: #fff, $alpha: 0.05);
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.files-transfer > i {
|
||||||
|
font-size: 4em;
|
||||||
|
margin: 10px 10px 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.files-transfer > p {
|
||||||
|
margin: 0px 10px 10px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
|
||||||
|
import { Component, Vue } from 'vue-property-decorator'
|
||||||
|
import { onMounted, onUnmounted } from 'vue'
|
||||||
|
|
||||||
|
import Markdown from './markdown'
|
||||||
|
import Content from './context.vue'
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
name: 'neko-files',
|
||||||
|
components: {
|
||||||
|
'neko-markdown': Markdown,
|
||||||
|
'neko-context': Content,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
export default class extends Vue {
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
cwd: '~/Downloads',
|
||||||
|
files: [
|
||||||
|
{
|
||||||
|
name: 'a.txt',
|
||||||
|
type: 'file'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'b',
|
||||||
|
type: 'dir'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'c.mkv',
|
||||||
|
type: 'file'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'd.mp3',
|
||||||
|
type: 'file'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
refresh() {
|
||||||
|
console.log('refresh')
|
||||||
|
}
|
||||||
|
|
||||||
|
download(item: any) {
|
||||||
|
console.log(item.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
fileIcon(file: any) {
|
||||||
|
let className = 'file-icon fas '
|
||||||
|
if (file.type === 'dir') {
|
||||||
|
className += 'fa-folder'
|
||||||
|
return className
|
||||||
|
}
|
||||||
|
const parts = file.name.split('.')
|
||||||
|
if (!parts) {
|
||||||
|
className += 'fa-file'
|
||||||
|
return className
|
||||||
|
}
|
||||||
|
const ext = parts[parts.length - 1]
|
||||||
|
switch (ext) {
|
||||||
|
case 'mp3':
|
||||||
|
case 'flac':
|
||||||
|
className += 'fa-music'
|
||||||
|
break;
|
||||||
|
case 'webm':
|
||||||
|
case 'mp4':
|
||||||
|
case 'mkv':
|
||||||
|
className += 'fa-film'
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
className += 'fa-file'
|
||||||
|
}
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
|
||||||
|
onFileDrop(e: any) {
|
||||||
|
console.log('file dropped', e)
|
||||||
|
console.log(e.dataTransfer.files)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
@ -6,6 +6,10 @@
|
|||||||
<i class="fas fa-comment-alt" />
|
<i class="fas fa-comment-alt" />
|
||||||
<span>{{ $t('side.chat') }}</span>
|
<span>{{ $t('side.chat') }}</span>
|
||||||
</li>
|
</li>
|
||||||
|
<li :class="{ active: tab === 'files' }" @click.stop.prevent="change('files')">
|
||||||
|
<i class="fas fa-file" />
|
||||||
|
<span>{{ $t('side.files') }}</span>
|
||||||
|
</li>
|
||||||
<li :class="{ active: tab === 'settings' }" @click.stop.prevent="change('settings')">
|
<li :class="{ active: tab === 'settings' }" @click.stop.prevent="change('settings')">
|
||||||
<i class="fas fa-sliders-h" />
|
<i class="fas fa-sliders-h" />
|
||||||
<span>{{ $t('side.settings') }}</span>
|
<span>{{ $t('side.settings') }}</span>
|
||||||
@ -14,6 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<neko-chat v-if="tab === 'chat'" />
|
<neko-chat v-if="tab === 'chat'" />
|
||||||
|
<neko-files v-if="tab === 'files'" />
|
||||||
<neko-settings v-if="tab === 'settings'" />
|
<neko-settings v-if="tab === 'settings'" />
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
@ -78,12 +83,14 @@
|
|||||||
|
|
||||||
import Settings from '~/components/settings.vue'
|
import Settings from '~/components/settings.vue'
|
||||||
import Chat from '~/components/chat.vue'
|
import Chat from '~/components/chat.vue'
|
||||||
|
import Files from '~/components/files.vue'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
name: 'neko',
|
name: 'neko',
|
||||||
components: {
|
components: {
|
||||||
'neko-settings': Settings,
|
'neko-settings': Settings,
|
||||||
'neko-chat': Chat,
|
'neko-chat': Chat,
|
||||||
|
'neko-files': Files
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class extends Vue {
|
export default class extends Vue {
|
||||||
|
@ -7,6 +7,7 @@ export const send_a_message = 'Send a message'
|
|||||||
|
|
||||||
export const side = {
|
export const side = {
|
||||||
chat: 'Chat',
|
chat: 'Chat',
|
||||||
|
files: 'Files',
|
||||||
settings: 'Settings',
|
settings: 'Settings',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user