Archived
2
0

lint fix.

This commit is contained in:
Miroslav Šedivý 2022-11-19 16:01:57 +01:00
parent 04cd943eb4
commit fac8700192
21 changed files with 160 additions and 144 deletions

View File

@ -9,8 +9,7 @@
<i :class="fileIcon(item)" /> <i :class="fileIcon(item)" />
<p>{{ item.name }}</p> <p>{{ item.name }}</p>
<p class="file-size">{{ fileSize(item.size) }}</p> <p class="file-size">{{ fileSize(item.size) }}</p>
<i v-if="item.type !== 'dir'" class="fas fa-download download" <i v-if="item.type !== 'dir'" class="fas fa-download download" @click="() => download(item)" />
@click="() => download(item)" />
</div> </div>
</div> </div>
<div class="transfer-area"> <div class="transfer-area">
@ -18,29 +17,51 @@
<p v-if="downloads.length > 0">{{ $t('files.downloads') }}</p> <p v-if="downloads.length > 0">{{ $t('files.downloads') }}</p>
<div v-for="download in downloads" :key="download.id" class="transfers-list-item"> <div v-for="download in downloads" :key="download.id" class="transfers-list-item">
<div class="transfer-info"> <div class="transfer-info">
<i class="fas transfer-status" :class="{ 'fa-arrows-rotate': download.status !== 'completed', 'fa-check': download.status === 'completed' }"></i> <i
class="fas transfer-status"
:class="{
'fa-arrows-rotate': download.status !== 'completed',
'fa-check': download.status === 'completed',
}"
></i>
<p>{{ download.name }}</p> <p>{{ download.name }}</p>
<p class="file-size">{{ Math.min(100, Math.round(download.progress / download.size * 100))}}%</p> <p class="file-size">{{ Math.min(100, Math.round((download.progress / download.size) * 100)) }}%</p>
<i class="fas fa-xmark remove-transfer" @click="() => removeTransfer(download)"></i> <i class="fas fa-xmark remove-transfer" @click="() => removeTransfer(download)"></i>
</div> </div>
<progress class="transfer-progress" :aria-label="download.name + ' progress'" :value="download.progress" <progress
:max="download.size"></progress> class="transfer-progress"
:aria-label="download.name + ' progress'"
:value="download.progress"
:max="download.size"
></progress>
</div> </div>
<p v-if="uploads.length > 0">{{ $t('files.uploads' )}}</p> <p v-if="uploads.length > 0">{{ $t('files.uploads') }}</p>
<div v-for="upload in uploads" :key="upload.id" class="transfers-list-item"> <div v-for="upload in uploads" :key="upload.id" class="transfers-list-item">
<div class="transfer-info"> <div class="transfer-info">
<i class="fas transfer-status" :class="{ 'fa-arrows-rotate': upload.status !== 'completed', 'fa-check': upload.status === 'completed' }"></i> <i
class="fas transfer-status"
:class="{ 'fa-arrows-rotate': upload.status !== 'completed', 'fa-check': upload.status === 'completed' }"
></i>
<p>{{ upload.name }}</p> <p>{{ upload.name }}</p>
<p class="file-size">{{ Math.min(100, Math.round(upload.progress / upload.size * 100))}}%</p> <p class="file-size">{{ Math.min(100, Math.round((upload.progress / upload.size) * 100)) }}%</p>
<i class="fas fa-xmark remove-transfer" @click="() => removeTransfer(upload)"></i> <i class="fas fa-xmark remove-transfer" @click="() => removeTransfer(upload)"></i>
</div> </div>
<progress class="transfer-progress" :aria-label="upload.name + ' progress'" :value="upload.progress" <progress
:max="upload.size"></progress> class="transfer-progress"
:aria-label="upload.name + ' progress'"
:value="upload.progress"
:max="upload.size"
></progress>
</div> </div>
</div> </div>
<div class="upload-area" :class="{ 'upload-area-drag': uploadAreaDrag }" <div
@dragover.prevent="() => uploadAreaDrag = true" @dragleave.prevent="() => uploadAreaDrag = false" class="upload-area"
@drop.prevent="(e) => upload(e.dataTransfer)" @click="openFileBrowser"> :class="{ 'upload-area-drag': uploadAreaDrag }"
@dragover.prevent="() => (uploadAreaDrag = true)"
@dragleave.prevent="() => (uploadAreaDrag = false)"
@drop.prevent="(e) => upload(e.dataTransfer)"
@click="openFileBrowser"
>
<i class="fas fa-file-arrow-up" /> <i class="fas fa-file-arrow-up" />
<p>{{ $t('files.upload_here') }}</p> <p>{{ $t('files.upload_here') }}</p>
</div> </div>
@ -94,12 +115,13 @@
.files-list-item { .files-list-item {
padding: 0.5em; padding: 0.5em;
border-bottom: 2px solid rgba($color: #fff, $alpha: 0.10); border-bottom: 2px solid rgba($color: #fff, $alpha: 0.1);
display: flex; display: flex;
flex-direction: row; flex-direction: row;
} }
.file-icon, .transfer-status { .file-icon,
.transfer-status {
width: 14px; width: 14px;
margin-right: 0.5em; margin-right: 0.5em;
} }
@ -115,10 +137,12 @@
.file-size { .file-size {
margin-left: auto; margin-left: auto;
margin-right: 0.5em; margin-right: 0.5em;
color: rgba($color: #fff, $alpha: 0.40); color: rgba($color: #fff, $alpha: 0.4);
} }
.refresh:hover, .download:hover, .remove-transfer:hover { .refresh:hover,
.download:hover,
.remove-transfer:hover {
cursor: pointer; cursor: pointer;
} }
@ -186,8 +210,9 @@
cursor: pointer; cursor: pointer;
} }
.upload-area-drag, .upload-area:hover { .upload-area-drag,
background-color: rgba($color: #fff, $alpha: 0.10); .upload-area:hover {
background-color: rgba($color: #fff, $alpha: 0.1);
} }
.upload-area > i { .upload-area > i {
@ -198,12 +223,10 @@
.upload-area > p { .upload-area > p {
margin: 0px 10px 10px 10px; margin: 0px 10px 10px 10px;
} }
} }
</style> </style>
<script lang="ts"> <script lang="ts">
import { Component, Vue } from 'vue-property-decorator' import { Component, Vue } from 'vue-property-decorator'
import Markdown from './markdown' import Markdown from './markdown'
@ -215,11 +238,10 @@
components: { components: {
'neko-markdown': Markdown, 'neko-markdown': Markdown,
'neko-context': Content, 'neko-context': Content,
} },
}) })
export default class extends Vue { export default class extends Vue {
public uploadAreaDrag: boolean = false
public uploadAreaDrag: boolean = false;
get cwd() { get cwd() {
return this.$accessor.files.cwd return this.$accessor.files.cwd
@ -234,13 +256,13 @@
} }
get downloads() { get downloads() {
return this.$accessor.files.transfers.filter((t => t.direction === 'download')) return this.$accessor.files.transfers.filter((t) => t.direction === 'download')
} }
get uploads() { get uploads() {
return this.$accessor.files.transfers.filter((t => t.direction === 'upload')) return this.$accessor.files.transfers.filter((t) => t.direction === 'upload')
} }
refresh() { refresh() {
this.$accessor.files.refresh() this.$accessor.files.refresh()
} }
@ -261,39 +283,41 @@
progress: 0, progress: 0,
status: 'pending', status: 'pending',
axios: null, axios: null,
abortController: null abortController: null,
} }
transfer.abortController = new AbortController() transfer.abortController = new AbortController()
transfer.axios = this.$http.get(url, { transfer.axios = this.$http
responseType: 'blob', .get(url, {
signal: transfer.abortController.signal, responseType: 'blob',
onDownloadProgress: (x) => { signal: transfer.abortController.signal,
transfer.progress = x.loaded onDownloadProgress: (x) => {
transfer.progress = x.loaded
if (x.lengthComputable && transfer.size !== x.total) { if (x.lengthComputable && transfer.size !== x.total) {
transfer.size = x.total transfer.size = x.total
} }
if (transfer.progress === transfer.size) { if (transfer.progress === transfer.size) {
transfer.status = 'completed' transfer.status = 'completed'
} else if (transfer.status !== 'inprogress') { } else if (transfer.status !== 'inprogress') {
transfer.status = 'inprogress' transfer.status = 'inprogress'
} }
} },
}).then((res) => { })
const url = window.URL .then((res) => {
.createObjectURL(new Blob([res.data])) const url = window.URL.createObjectURL(new Blob([res.data]))
const link = document.createElement('a') const link = document.createElement('a')
link.href = url link.href = url
link.setAttribute('download', item.name) link.setAttribute('download', item.name)
document.body.appendChild(link) document.body.appendChild(link)
link.click() link.click()
document.body.removeChild(link) document.body.removeChild(link)
transfer.progress = transfer.size transfer.progress = transfer.size
transfer.status = 'completed' transfer.status = 'completed'
}).catch((err) => { })
this.$log.error(err) .catch((err) => {
}) this.$log.error(err)
})
this.$accessor.files.addTransfer(transfer) this.$accessor.files.addTransfer(transfer)
} }
@ -302,7 +326,7 @@
for (const file of dt.files) { for (const file of dt.files) {
const formdata = new FormData() const formdata = new FormData()
formdata.append("files", file, file.name) formdata.append('files', file, file.name)
const url = `/file?pwd=${this.$accessor.password}` const url = `/file?pwd=${this.$accessor.password}`
let transfer: FileTransfer = { let transfer: FileTransfer = {
@ -313,25 +337,27 @@
progress: 0, progress: 0,
status: 'pending', status: 'pending',
axios: null, axios: null,
abortController: null abortController: null,
} }
transfer.abortController = new AbortController() transfer.abortController = new AbortController()
this.$http.post(url, formdata, { this.$http
onUploadProgress: (x: any) => { .post(url, formdata, {
transfer.progress = x.loaded onUploadProgress: (x: any) => {
transfer.progress = x.loaded
if (transfer.size !== x.total) { if (transfer.size !== x.total) {
transfer.size = x.total transfer.size = x.total
} }
if (transfer.progress === transfer.size) { if (transfer.progress === transfer.size) {
transfer.status = 'completed' transfer.status = 'completed'
} else if (transfer.status !== 'inprogress') { } else if (transfer.status !== 'inprogress') {
transfer.status = 'inprogress' transfer.status = 'inprogress'
} }
} },
}).catch((err) => { })
this.$log.error(err) .catch((err) => {
}) this.$log.error(err)
})
this.$accessor.files.addTransfer(transfer) this.$accessor.files.addTransfer(transfer)
} }
} }
@ -399,7 +425,7 @@
case 'tiff': case 'tiff':
case 'webp': case 'webp':
className += 'fa-image' className += 'fa-image'
break; break
default: default:
className += 'fa-file' className += 'fa-file'
} }
@ -421,7 +447,5 @@
} }
return `${(size / 1000 ** 4).toFixed(3)} tb` return `${(size / 1000 ** 4).toFixed(3)} tb`
} }
} }
</script> </script>

View File

@ -385,7 +385,7 @@
} }
set file_transfer(value: boolean) { set file_transfer(value: boolean) {
this.$accessor.settings.setGlobalFileTransferStatus({ admin: value, unpriv: false }) this.$accessor.settings.setRemoteFileTransferStatus({ admin: value, unpriv: false })
} }
get unpriv_file_transfer() { get unpriv_file_transfer() {
@ -393,7 +393,7 @@
} }
set unpriv_file_transfer(value: boolean) { set unpriv_file_transfer(value: boolean) {
this.$accessor.settings.setGlobalFileTransferStatus({ admin: this.file_transfer, unpriv: value }) this.$accessor.settings.setRemoteFileTransferStatus({ admin: this.file_transfer, unpriv: value })
} }
get broadcast_is_active() { get broadcast_is_active() {

View File

@ -79,7 +79,7 @@
</style> </style>
<script lang="ts"> <script lang="ts">
import { Vue, Component } from 'vue-property-decorator' import { Vue, Component, Watch } from 'vue-property-decorator'
import Settings from '~/components/settings.vue' import Settings from '~/components/settings.vue'
import Chat from '~/components/chat.vue' import Chat from '~/components/chat.vue'
@ -90,28 +90,29 @@
components: { components: {
'neko-settings': Settings, 'neko-settings': Settings,
'neko-chat': Chat, 'neko-chat': Chat,
'neko-files': Files 'neko-files': Files,
}, },
}) })
export default class extends Vue { export default class extends Vue {
constructor() {
super()
if (this.tab === 'files' && (!this.$accessor.settings.file_transfer ||
!this.$accessor.user.admin && this.$accessor.settings.unpriv_file_transfer)) {
this.change('chat')
}
}
get filetransferAllowed() { get filetransferAllowed() {
return this.$accessor.user.admin && this.$accessor.settings.file_transfer || return (
(this.$accessor.user.admin && this.$accessor.settings.file_transfer) ||
this.$accessor.settings.unpriv_file_transfer this.$accessor.settings.unpriv_file_transfer
)
} }
get tab() { get tab() {
return this.$accessor.client.tab return this.$accessor.client.tab
} }
@Watch('tab', { immediate: true })
onTabChange() {
// do not show the files tab if file transfer is disabled
if (this.tab === 'files' && !this.filetransferAllowed) {
this.change('chat')
}
}
change(tab: string) { change(tab: string) {
this.$accessor.client.setTab(tab) this.$accessor.client.setTab(tab)
} }

View File

@ -38,9 +38,9 @@ const exportMixin = {
$accessor() { $accessor() {
return neko return neko
}, },
$client () { $client() {
return window.$client return window.$client
} },
}, },
} }
@ -52,15 +52,8 @@ const plugini18n: PluginObject<undefined> = {
}, },
} }
function extend (component: any) { function extend(component: any) {
return component return component.use(plugini18n).use(Logger).use(Axios).use(Swal).use(Anime).use(Client).extend(exportMixin)
.use(plugini18n)
.use(Logger)
.use(Axios)
.use(Swal)
.use(Anime)
.use(Client)
.extend(exportMixin)
} }
export const NekoConnect = extend(Connect) export const NekoConnect = extend(Connect)

View File

@ -115,5 +115,5 @@ export const notifications = {
export const files = { export const files = {
downloads: 'Herunterladen', downloads: 'Herunterladen',
uploads: 'Hochladen', uploads: 'Hochladen',
upload_here: 'Klicken oder ziehen Sie Dateien zum Hochladen hierher' upload_here: 'Klicken oder ziehen Sie Dateien zum Hochladen hierher',
} }

View File

@ -117,5 +117,5 @@ export const notifications = {
export const files = { export const files = {
downloads: 'Downloads', downloads: 'Downloads',
uploads: 'Uploads', uploads: 'Uploads',
upload_here: 'Click or drag files here to upload' upload_here: 'Click or drag files here to upload',
} }

View File

@ -124,5 +124,5 @@ export const notifications = {
export const files = { export const files = {
downloads: 'Descargas', downloads: 'Descargas',
uploads: 'Cargar', uploads: 'Cargar',
upload_here: 'Haga clic o arrastre los archivos aquí para cargarlos' upload_here: 'Haga clic o arrastre los archivos aquí para cargarlos',
} }

View File

@ -117,5 +117,5 @@ export const notifications = {
export const files = { export const files = {
downloads: 'Lataukset', downloads: 'Lataukset',
uploads: 'Lataa', uploads: 'Lataa',
upload_here: 'Klikkaa tai vedä tiedostoja tähän ladataksesi' upload_here: 'Klikkaa tai vedä tiedostoja tähän ladataksesi',
} }

View File

@ -85,7 +85,7 @@ export const setting = {
chat_sound: 'Jouer le son du tchat', chat_sound: 'Jouer le son du tchat',
keyboard_layout: 'Langue du clavier', keyboard_layout: 'Langue du clavier',
file_transfer: 'Transfert de fichiers', file_transfer: 'Transfert de fichiers',
unpriv_file_transfer: 'Transfert de fichiers d\'utilisateurs', unpriv_file_transfer: "Transfert de fichiers d'utilisateurs",
// TODO // TODO
//broadcast_title: 'Live Broadcast', //broadcast_title: 'Live Broadcast',
} }
@ -124,5 +124,5 @@ export const notifications = {
export const files = { export const files = {
downloads: 'Téléchargements', downloads: 'Téléchargements',
uploads: 'Télécharger', uploads: 'Télécharger',
upload_here: 'Cliquez ou faites glisser les fichiers ici pour les télécharger' upload_here: 'Cliquez ou faites glisser les fichiers ici pour les télécharger',
} }

View File

@ -115,5 +115,5 @@ export const notifications = {
export const files = { export const files = {
downloads: '다운로드', downloads: '다운로드',
uploads: '업로드', uploads: '업로드',
upload_here: '업로드할 파일을 여기로 클릭하거나 드래그하세요.' upload_here: '업로드할 파일을 여기로 클릭하거나 드래그하세요.',
} }

View File

@ -124,5 +124,5 @@ export const notifications = {
export const files = { export const files = {
downloads: 'Overførsler', downloads: 'Overførsler',
uploads: 'Overfør', uploads: 'Overfør',
upload_here: 'Klik eller træk filer her for at uploade' upload_here: 'Klik eller træk filer her for at uploade',
} }

View File

@ -117,5 +117,5 @@ export const notifications = {
export const files = { export const files = {
downloads: 'Загрузки', downloads: 'Загрузки',
uploads: 'Загрузить', uploads: 'Загрузить',
upload_here: 'Нажмите или перетащите сюда файлы для загрузки' upload_here: 'Нажмите или перетащите сюда файлы для загрузки',
} }

View File

@ -120,5 +120,5 @@ export const notifications = {
export const files = { export const files = {
downloads: 'Stiahnutia', downloads: 'Stiahnutia',
uploads: 'Nahrávanie', uploads: 'Nahrávanie',
upload_here: 'Kliknutím alebo pretiahnutím súborov sem ich môžete nahrať' upload_here: 'Kliknutím alebo pretiahnutím súborov sem ich môžete nahrať',
} }

View File

@ -124,5 +124,5 @@ export const notifications = {
export const files = { export const files = {
downloads: 'Nedladdningar', downloads: 'Nedladdningar',
uploads: 'Ladda upp', uploads: 'Ladda upp',
upload_here: 'Klicka eller dra filer hit för att ladda upp dem' upload_here: 'Klicka eller dra filer hit för att ladda upp dem',
} }

View File

@ -117,5 +117,5 @@ export const notifications = {
export const files = { export const files = {
downloads: '下载', downloads: '下载',
uploads: '上传', uploads: '上传',
upload_here: '点击或拖动文件到这里来上传' upload_here: '点击或拖动文件到这里来上传',
} }

View File

@ -41,7 +41,7 @@ export const EVENT = {
FILETRANSFER: { FILETRANSFER: {
STATUS: 'filetransfer/status', STATUS: 'filetransfer/status',
LIST: 'filetransfer/list', LIST: 'filetransfer/list',
REFRESH: 'filetransfer/refresh' REFRESH: 'filetransfer/refresh',
}, },
SCREEN: { SCREEN: {
CONFIGURATIONS: 'screen/configurations', CONFIGURATIONS: 'screen/configurations',

View File

@ -10,12 +10,7 @@ import {
AdminEvents, AdminEvents,
FileTransferEvents, FileTransferEvents,
} from './events' } from './events'
import { import { FileListItem, Member, ScreenConfigurations, ScreenResolution } from './types'
FileListItem,
Member,
ScreenConfigurations,
ScreenResolution
} from './types'
export type WebSocketMessages = export type WebSocketMessages =
| WebSocketMessage | WebSocketMessage
@ -199,12 +194,15 @@ export interface EmojiSendPayload {
emote: string emote: string
} }
// file transfer enabled /*
FILE TRANSFER PAYLOADS
*/
export interface FileTransferStatusMessage extends WebSocketMessage, FileTransferStatusPayload { export interface FileTransferStatusMessage extends WebSocketMessage, FileTransferStatusPayload {
event: typeof EVENT.FILETRANSFER.STATUS event: typeof EVENT.FILETRANSFER.STATUS
} }
export interface FileTransferStatusPayload { export interface FileTransferStatusPayload {
admin: boolean, admin: boolean
unpriv: boolean unpriv: boolean
} }
@ -212,8 +210,9 @@ export interface FileTransferStatusPayload {
export interface FileTransferListMessage extends WebSocketMessage, FileTransferListPayload { export interface FileTransferListMessage extends WebSocketMessage, FileTransferListPayload {
event: FileTransferEvents event: FileTransferEvents
} }
export interface FileTransferListPayload { export interface FileTransferListPayload {
cwd: string, cwd: string
files: FileListItem[] files: FileListItem[]
} }
@ -240,11 +239,11 @@ export interface ScreenConfigurationsPayload {
BROADCAST PAYLOADS BROADCAST PAYLOADS
*/ */
export interface BroadcastCreatePayload { export interface BroadcastCreatePayload {
url: string url: string
} }
export interface BroadcastStatusPayload { export interface BroadcastStatusPayload {
url: string url: string
isActive: boolean isActive: boolean
} }

View File

@ -24,18 +24,18 @@ export interface ScreenResolution {
} }
export interface FileListItem { export interface FileListItem {
name: string, name: string
type: 'file' | 'dir', type: 'file' | 'dir'
size: number size: number
} }
export interface FileTransfer { export interface FileTransfer {
id: number, id: number
name: string, name: string
direction: 'upload' | 'download', direction: 'upload' | 'download'
size: number, size: number
progress: number, progress: number
status: 'pending' | 'inprogress' | 'completed', status: 'pending' | 'inprogress' | 'completed'
axios: Promise<void> | null, axios: Promise<void> | null
abortController: AbortController | null abortController: AbortController | null
} }

View File

@ -6,7 +6,7 @@ import { accessor } from '~/store'
export const state = () => ({ export const state = () => ({
cwd: '', cwd: '',
files: [] as FileListItem[], files: [] as FileListItem[],
transfers: [] as FileTransfer[] transfers: [] as FileTransfer[],
}) })
export const getters = getterTree(state, { export const getters = getterTree(state, {
@ -28,7 +28,7 @@ export const mutations = mutationTree(state, {
_removeTransfer(state, transfer: FileTransfer) { _removeTransfer(state, transfer: FileTransfer) {
state.transfers = state.transfers.filter((t) => t.id !== transfer.id) state.transfers = state.transfers.filter((t) => t.id !== transfer.id)
} },
}) })
export const actions = actionTree( export const actions = actionTree(
@ -67,6 +67,6 @@ export const actions = actionTree(
return return
} }
$client.sendMessage(EVENT.FILETRANSFER.REFRESH) $client.sendMessage(EVENT.FILETRANSFER.REFRESH)
} },
} },
) )

View File

@ -94,16 +94,15 @@ export const actions = actionTree(
accessor.settings.setFileTransfer(admin) accessor.settings.setFileTransfer(admin)
accessor.settings.setUnprivFileTransfer(unpriv) accessor.settings.setUnprivFileTransfer(unpriv)
if (!admin || !accessor.user.admin && !unpriv) { if (!admin || (!accessor.user.admin && !unpriv)) {
accessor.files.cancelAllTransfers() accessor.files.cancelAllTransfers()
} }
if (accessor.client.tab === 'files' && !unpriv) { if (accessor.client.tab === 'files' && !unpriv) {
accessor.client.setTab('chat') accessor.client.setTab('chat')
} }
}, },
setRemoteFileTransferStatus({ getters }, { admin, unpriv }) {
setGlobalFileTransferStatus({ getters}, { admin, unpriv }) {
$client.sendMessage(EVENT.FILETRANSFER.STATUS, { admin, unpriv }) $client.sendMessage(EVENT.FILETRANSFER.STATUS, { admin, unpriv })
}, },

View File

@ -23,5 +23,5 @@ module.exports = {
}, },
devServer: { devServer: {
disableHostCheck: true, disableHostCheck: true,
} },
} }