Merge branch 'master' into feature/enhancement

This commit is contained in:
Pietro Tamburini 2024-05-03 18:03:19 +02:00 committed by GitHub
commit 76cd0f8788
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 292 additions and 177 deletions

View File

@ -12,6 +12,7 @@
:data-type="type" :data-type="type"
:aria-label="name" :aria-label="name"
:aria-selected="isSelected" :aria-selected="isSelected"
:data-ext="getExtension(name).toLowerCase()"
> >
<div> <div>
<img <img
@ -209,8 +210,10 @@ const drop = async (event: Event) => {
const itemClick = (event: Event | KeyboardEvent) => { const itemClick = (event: Event | KeyboardEvent) => {
if ( if (
!((event as KeyboardEvent).ctrlKey || (event as KeyboardEvent).metaKey) &&
singleClick.value && singleClick.value &&
!(event as KeyboardEvent).ctrlKey &&
!(event as KeyboardEvent).metaKey &&
!(event as KeyboardEvent).shiftKey &&
!fileStore.multiple !fileStore.multiple
) )
open(); open();
@ -270,4 +273,14 @@ const click = (event: Event | KeyboardEvent) => {
const open = () => { const open = () => {
router.push({ path: props.url }); router.push({ path: props.url });
}; };
const getExtension = (fileName: string): string => {
const lastDotIndex = fileName.lastIndexOf('.');
if (lastDotIndex === -1) {
return fileName;
}
return fileName.substring(lastDotIndex );
};
</script> </script>

View File

@ -1,14 +1,8 @@
<template> <template>
<video ref="videoPlayer" class="video-max video-js" controls> <video ref="videoPlayer" class="video-max video-js" controls preload="auto">
<source :src="source" /> <source />
<track <track kind="subtitles" v-for="(sub, index) in subtitles" :key="index" :src="sub" :label="subLabel(sub)"
kind="subtitles" :default="index === 0" />
v-for="(sub, index) in subtitles"
:key="index"
:src="sub"
:label="subLabel(sub)"
:default="index === 0"
/>
<p class="vjs-no-js"> <p class="vjs-no-js">
Sorry, your browser doesn't support embedded videos, but don't worry, you Sorry, your browser doesn't support embedded videos, but don't worry, you
can <a :href="source">download it</a> can <a :href="source">download it</a>
@ -18,18 +12,18 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted, onBeforeUnmount } from "vue"; import { ref, onMounted, onBeforeUnmount, nextTick, } from "vue";
import videojs from "video.js"; import videojs from "video.js";
import type Player from "video.js/dist/types/player"; import type Player from "video.js/dist/types/player";
import "videojs-mobile-ui"; import "videojs-mobile-ui";
import "videojs-hotkeys"; import "videojs-hotkeys";
import "video.js/dist/video-js.min.css"; import "video.js/dist/video-js.min.css";
import "videojs-mobile-ui/dist/videojs-mobile-ui.css"; import "videojs-mobile-ui/dist/videojs-mobile-ui.css";
const videoPlayer = ref<HTMLElement | null>(null); const videoPlayer = ref<HTMLElement | null>(null);
const player = ref<Player | null>(null); const player = ref<Player | null>(null);
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
source: string; source: string;
@ -41,33 +35,14 @@ const props = withDefaults(
} }
); );
onMounted(() => { const source = ref(props.source)
player.value = videojs( const sourceType = ref("")
videoPlayer.value!,
{ nextTick(() => {
html5: { initVideoPlayer()
// needed for customizable subtitles })
// TODO: add to user settings
nativeTextTracks: false, onMounted(() => { });
},
plugins: {
hotkeys: {
volumeStep: 0.1,
seekStep: 10,
enableModifiersForNumbers: false,
},
},
...props.options,
},
// onReady callback
async () => {
// player.value!.log("onPlayerReady", this);
}
);
// TODO: need to test on mobile
// @ts-ignore
player.value!.mobileUi();
});
onBeforeUnmount(() => { onBeforeUnmount(() => {
if (player.value) { if (player.value) {
@ -76,6 +51,67 @@ onBeforeUnmount(() => {
} }
}); });
const initVideoPlayer = async () => {
try {
const lang = document.documentElement.lang;
const languagePack = await (languageImports[lang] || languageImports.en)?.();
videojs.addLanguage('videoPlayerLocal', languagePack.default);
sourceType.value = ""
//
sourceType.value = getSourceType(source.value);
const srcOpt = { sources: { src: props.source, type: sourceType.value } }
//Supporting localized language display.
const langOpt = { language: "videoPlayerLocal" }
// support for playback at different speeds.
const playbackRatesOpt = { playbackRates: [0.5, 1, 1.5, 2, 2.5, 3] }
let options = getOptions(props.options, langOpt, srcOpt, playbackRatesOpt)
player.value = videojs(videoPlayer.value!, options, () => {
});
// TODO: need to test on mobile
// @ts-ignore
player.value!.mobileUi();
} catch (error) {
console.error("Error initializing video player:", error);
}
}
const getOptions = (...srcOpt: any[]) => {
const options = {
controlBar: {
skipButtons: {
forward: 5,
backward: 5
}
},
html5: {
nativeTextTracks: false,
},
plugins: {
hotkeys: {
volumeStep: 0.1,
seekStep: 10,
enableModifiersForNumbers: false,
},
},
};
return videojs.obj.merge(options, ...srcOpt);
}
// Attempting to fix the issue of being unable to play .MKV format video files
const getSourceType = (source: string) => {
const fileExtension = source ? source.split("?")[0].split(".").pop() : "";
if (fileExtension?.toLowerCase() === "mkv") {
return "video/mp4";
}
return "";
};
const subLabel = (subUrl: string) => { const subLabel = (subUrl: string) => {
let url: URL; let url: URL;
try { try {
@ -95,6 +131,36 @@ const subLabel = (subUrl: string) => {
return label; return label;
}; };
interface LanguageImports {
[key: string]: () => Promise<any>;
}
const languageImports: LanguageImports = {
'he': () => import('video.js/dist/lang/he.json'),
'hu': () => import('video.js/dist/lang/hu.json'),
'ar': () => import('video.js/dist/lang/ar.json'),
'de': () => import('video.js/dist/lang/de.json'),
'el': () => import('video.js/dist/lang/el.json'),
'en': () => import('video.js/dist/lang/en.json'),
'es': () => import('video.js/dist/lang/es.json'),
'fr': () => import('video.js/dist/lang/fr.json'),
'it': () => import('video.js/dist/lang/it.json'),
'ja': () => import('video.js/dist/lang/ja.json'),
'ko': () => import('video.js/dist/lang/ko.json'),
'nl-be': () => import('video.js/dist/lang/nl.json'),
'pl': () => import('video.js/dist/lang/pl.json'),
'pt-br': () => import('video.js/dist/lang/pt-BR.json'),
'pt': () => import('video.js/dist/lang/pt-PT.json'),
'ro': () => import('video.js/dist/lang/ro.json'),
'ru': () => import('video.js/dist/lang/ru.json'),
'sk': () => import('video.js/dist/lang/sk.json'),
'tr': () => import('video.js/dist/lang/tr.json'),
'uk': () => import('video.js/dist/lang/uk.json'),
'zh-cn': () => import('video.js/dist/lang/zh-CN.json'),
'zh-tw': () => import('video.js/dist/lang/zh-TW.json'),
};
</script> </script>
<style scoped> <style scoped>
.video-max { .video-max {

View File

@ -33,117 +33,118 @@
/* #f90 - Image */ /* #f90 - Image */
.file-icons [aria-label$=".ai"] i::before, .file-icons [data-ext=".ai"] i::before,
.file-icons [aria-label$=".odg"] i::before, .file-icons [data-ext=".odg"] i::before,
.file-icons [aria-label$=".xcf"] i::before { .file-icons [data-ext=".xcf"] i::before {
content: "image"; content: "image";
} }
/* #f90 - Presentation */ /* #f90 - Presentation */
.file-icons [aria-label$=".odp"] i::before, .file-icons [data-ext=".odp"] i::before,
.file-icons [aria-label$=".ppt"] i::before, .file-icons [data-ext=".ppt"] i::before,
.file-icons [aria-label$=".pptx"] i::before { .file-icons [data-ext=".pptx"] i::before {
content: "slideshow"; content: "slideshow";
} }
/* #0f0 - Spreadsheet/Database */ /* #0f0 - Spreadsheet/Database */
.file-icons [aria-label$=".csv"] i::before, .file-icons [data-ext=".csv"] i::before,
.file-icons [aria-label$=".db"] i::before, .file-icons [data-ext=".db"] i::before,
.file-icons [aria-label$=".odb"] i::before, .file-icons [data-ext=".odb"] i::before,
.file-icons [aria-label$=".ods"] i::before, .file-icons [data-ext=".ods"] i::before,
.file-icons [aria-label$=".xls"] i::before, .file-icons [data-ext=".xls"] i::before,
.file-icons [aria-label$=".xlsx"] i::before { .file-icons [data-ext=".xlsx"] i::before {
content: "border_all"; content: "border_all";
} }
/* #00f - Document */ /* #00f - Document */
.file-icons [aria-label$=".doc"] i::before, .file-icons [data-ext=".doc"] i::before,
.file-icons [aria-label$=".docx"] i::before, .file-icons [data-ext=".docx"] i::before,
.file-icons [aria-label$=".log"] i::before, .file-icons [data-ext=".log"] i::before,
.file-icons [aria-label$=".odt"] i::before, .file-icons [data-ext=".odt"] i::before,
.file-icons [aria-label$=".rtf"] i::before { .file-icons [data-ext=".rtf"] i::before {
content: "description"; content: "description";
} }
/* #999 - Code */ /* #999 - Code */
.file-icons [aria-label$=".c"] i::before, .file-icons [data-ext=".c"] i::before,
.file-icons [aria-label$=".cpp"] i::before, .file-icons [data-ext=".cpp"] i::before,
.file-icons [aria-label$=".cs"] i::before, .file-icons [data-ext=".cs"] i::before,
.file-icons [aria-label$=".css"] i::before, .file-icons [data-ext=".css"] i::before,
.file-icons [aria-label$=".go"] i::before, .file-icons [data-ext=".go"] i::before,
.file-icons [aria-label$=".h"] i::before, .file-icons [data-ext=".h"] i::before,
.file-icons [aria-label$=".html"] i::before, .file-icons [data-ext=".html"] i::before,
.file-icons [aria-label$=".java"] i::before, .file-icons [data-ext=".java"] i::before,
.file-icons [aria-label$=".js"] i::before, .file-icons [data-ext=".js"] i::before,
.file-icons [aria-label$=".json"] i::before, .file-icons [data-ext=".json"] i::before,
.file-icons [aria-label$=".kt"] i::before, .file-icons [data-ext=".kt"] i::before,
.file-icons [aria-label$=".php"] i::before, .file-icons [data-ext=".php"] i::before,
.file-icons [aria-label$=".py"] i::before, .file-icons [data-ext=".py"] i::before,
.file-icons [aria-label$=".rb"] i::before, .file-icons [data-ext=".rb"] i::before,
.file-icons [aria-label$=".rs"] i::before, .file-icons [data-ext=".rs"] i::before,
.file-icons [aria-label$=".vue"] i::before, .file-icons [data-ext=".vue"] i::before,
.file-icons [aria-label$=".xml"] i::before, .file-icons [data-ext=".xml"] i::before,
.file-icons [aria-label$=".yml"] i::before { .file-icons [data-ext=".yml"] i::before {
content: "code"; content: "code";
} }
/* #999 - Executable */ /* #999 - Executable */
.file-icons [aria-label$=".apk"] i::before, .file-icons [data-ext=".apk"] i::before,
.file-icons [aria-label$=".bat"] i::before, .file-icons [data-ext=".bat"] i::before,
.file-icons [aria-label$=".exe"] i::before, .file-icons [data-ext=".exe"] i::before,
.file-icons [aria-label$=".jar"] i::before, .file-icons [data-ext=".jar"] i::before,
.file-icons [aria-label$=".ps1"] i::before, .file-icons [data-ext=".ps1"] i::before,
.file-icons [aria-label$=".sh"] i::before { .file-icons [data-ext=".sh"] i::before {
content: "web_asset"; content: "web_asset";
} }
/* #999 - Installer */ /* #999 - Installer */
.file-icons [aria-label$=".deb"] i::before, .file-icons [data-ext=".deb"] i::before,
.file-icons [aria-label$=".msi"] i::before, .file-icons [data-ext=".msi"] i::before,
.file-icons [aria-label$=".pkg"] i::before, .file-icons [data-ext=".pkg"] i::before,
.file-icons [aria-label$=".rpm"] i::before { .file-icons [data-ext=".rpm"] i::before {
content: "archive"; content: "archive";
} }
/* #999 - Compressed */ /* #999 - Compressed */
.file-icons [aria-label$=".7z"] i::before, .file-icons [data-ext=".7z"] i::before,
.file-icons [aria-label$=".bz2"] i::before, .file-icons [data-ext=".bz2"] i::before,
.file-icons [aria-label$=".cab"] i::before, .file-icons [data-ext=".cab"] i::before,
.file-icons [aria-label$=".gz"] i::before, .file-icons [data-ext=".gz"] i::before,
.file-icons [aria-label$=".rar"] i::before, .file-icons [data-ext=".rar"] i::before,
.file-icons [aria-label$=".tar"] i::before, .file-icons [data-ext=".tar"] i::before,
.file-icons [aria-label$=".xz"] i::before, .file-icons [data-ext=".xz"] i::before,
.file-icons [aria-label$=".zip"] i::before, .file-icons [data-ext=".zip"] i::before,
.file-icons [aria-label$=".zst"] i::before { .file-icons [data-ext=".zst"] i::before {
content: "folder_zip"; content: "folder_zip";
} }
/* #999 - Disk */ /* #999 - Disk */
.file-icons [aria-label$=".ccd"] i::before, .file-icons [data-ext=".ccd"] i::before,
.file-icons [aria-label$=".dmg"] i::before, .file-icons [data-ext=".dmg"] i::before,
.file-icons [aria-label$=".iso"] i::before, .file-icons [data-ext=".iso"] i::before,
.file-icons [aria-label$=".mdf"] i::before, .file-icons [data-ext=".mdf"] i::before,
.file-icons [aria-label$=".vdi"] i::before, .file-icons [data-ext=".vdi"] i::before,
.file-icons [aria-label$=".vhd"] i::before, .file-icons [data-ext=".vhd"] i::before,
.file-icons [aria-label$=".vmdk"] i::before, .file-icons [data-ext=".vmdk"] i::before,
.file-icons [aria-label$=".wim"] i::before { .file-icons [data-ext=".wim"] i::before {
content: "album"; content: "album";
} }
/* #999 - Font */ /* #999 - Font */
.file-icons [aria-label$=".otf"] i::before, .file-icons [data-ext=".otf"] i::before,
.file-icons [aria-label$=".ttf"] i::before, .file-icons [data-ext=".ttf"] i::before,
.file-icons [aria-label$=".woff"] i::before, .file-icons [data-ext=".woff"] i::before,
.file-icons [aria-label$=".woff2"] i::before { .file-icons [data-ext=".woff2"] i::before {
content: "font_download"; content: "font_download";
} }
@ -151,92 +152,93 @@
/* General */ /* General */
.file-icons [data-type="audio"] i { .file-icons [data-ext="audio"] i {
color: var(--icon-yellow); color: var(--icon-yellow);
} }
.file-icons [data-type="image"] i { .file-icons [data-ext="image"] i {
color: var(--icon-orange); color: var(--icon-orange);
} }
.file-icons [data-type="video"] i { .file-icons [data-ext="video"] i {
color: var(--icon-violet); color: var(--icon-violet);
} }
.file-icons [data-type="invalid_link"] i { .file-icons [data-ext="invalid_link"] i {
color: var(--icon-red); color: var(--icon-red);
} }
/* #f00 - Adobe/Oracle */ /* #f00 - Adobe/Oracle */
.file-icons [aria-label$=".ai"] i, .file-icons [data-ext=".ai"] i,
.file-icons [aria-label$=".java"] i, .file-icons [data-ext=".java"] i,
.file-icons [aria-label$=".jar"] i, .file-icons [data-ext=".jar"] i,
.file-icons [aria-label$=".psd"] i, .file-icons [data-ext=".psd"] i,
.file-icons [aria-label$=".rb"] i, .file-icons [data-ext=".rb"] i,
.file-icons [data-type="pdf"] i { .file-icons [data-ext="pdf"] i {
color: var(--icon-red); color: var(--icon-red);
} }
/* #f90 - Image/Presentation */ /* #f90 - Image/Presentation */
.file-icons [aria-label$=".html"] i, .file-icons [data-ext=".html"] i,
.file-icons [aria-label$=".odg"] i, .file-icons [data-ext=".odg"] i,
.file-icons [aria-label$=".odp"] i, .file-icons [data-ext=".odp"] i,
.file-icons [aria-label$=".ppt"] i, .file-icons [data-ext=".ppt"] i,
.file-icons [aria-label$=".pptx"] i, .file-icons [data-ext=".pptx"] i,
.file-icons [aria-label$=".vue"] i, .file-icons [data-ext=".vue"] i,
.file-icons [aria-label$=".xcf"] i { .file-icons [data-ext=".xcf"] i {
color: var(--icon-orange); color: var(--icon-orange);
} }
/* #ff0 - Various */ /* #ff0 - Various */
.file-icons [aria-label$=".css"] i, .file-icons [data-ext=".css"] i,
.file-icons [aria-label$=".js"] i, .file-icons [data-ext=".js"] i,
.file-icons [aria-label$=".json"] i, .file-icons [data-ext=".json"] i,
.file-icons [aria-label$=".zip"] i { .file-icons [data-ext=".zip"] i {
color: var(--icon-yellow); color: var(--icon-yellow);
} }
/* #0f0 - Spreadsheet/Google */ /* #0f0 - Spreadsheet/Google */
.file-icons [aria-label$=".apk"] i, .file-icons [data-ext=".apk"] i,
.file-icons [aria-label$=".dex"] i, .file-icons [data-ext=".dex"] i,
.file-icons [aria-label$=".go"] i, .file-icons [data-ext=".go"] i,
.file-icons [aria-label$=".ods"] i, .file-icons [data-ext=".ods"] i,
.file-icons [aria-label$=".xls"] i, .file-icons [data-ext=".xls"] i,
.file-icons [aria-label$=".xlsx"] i { .file-icons [data-ext=".xlsx"] i ,
.file-icons [data-ext="xlsx"] i::before{
color: var(--icon-green); color: var(--icon-green);
} }
/* #00f - Document/Microsoft/Apple/Closed */ /* #00f - Document/Microsoft/Apple/Closed */
.file-icons [aria-label$=".aac"] i, .file-icons [data-ext=".aac"] i,
.file-icons [aria-label$=".bat"] i, .file-icons [data-ext=".bat"] i,
.file-icons [aria-label$=".cab"] i, .file-icons [data-ext=".cab"] i,
.file-icons [aria-label$=".cs"] i, .file-icons [data-ext=".cs"] i,
.file-icons [aria-label$=".dmg"] i, .file-icons [data-ext=".dmg"] i,
.file-icons [aria-label$=".doc"] i, .file-icons [data-ext=".doc"] i,
.file-icons [aria-label$=".docx"] i, .file-icons [data-ext=".docx"] i,
.file-icons [aria-label$=".emf"] i, .file-icons [data-ext=".emf"] i,
.file-icons [aria-label$=".exe"] i, .file-icons [data-ext=".exe"] i,
.file-icons [aria-label$=".ico"] i, .file-icons [data-ext=".ico"] i,
.file-icons [aria-label$=".mp2"] i, .file-icons [data-ext=".mp2"] i,
.file-icons [aria-label$=".mp3"] i, .file-icons [data-ext=".mp3"] i,
.file-icons [aria-label$=".mp4"] i, .file-icons [data-ext=".mp4"] i,
.file-icons [aria-label$=".mpg"] i, .file-icons [data-ext=".mpg"] i,
.file-icons [aria-label$=".msi"] i, .file-icons [data-ext=".msi"] i,
.file-icons [aria-label$=".odt"] i, .file-icons [data-ext=".odt"] i,
.file-icons [aria-label$=".ps1"] i, .file-icons [data-ext=".ps1"] i,
.file-icons [aria-label$=".rtf"] i, .file-icons [data-ext=".rtf"] i,
.file-icons [aria-label$=".vob"] i, .file-icons [data-ext=".vob"] i,
.file-icons [aria-label$=".wim"] i { .file-icons [data-ext=".wim"] i {
color: var(--icon-blue); color: var(--icon-blue);
} }
/* #60f - Various */ /* #60f - Various */
.file-icons [aria-label$=".iso"] i, .file-icons [data-ext=".iso"] i,
.file-icons [aria-label$=".php"] i, .file-icons [data-ext=".php"] i,
.file-icons [aria-label$=".rar"] i { .file-icons [data-ext=".rar"] i {
color: var(--icon-violet); color: var(--icon-violet);
} }

View File

@ -39,7 +39,9 @@
"update": "更新", "update": "更新",
"upload": "上传", "upload": "上传",
"openFile": "打开文件", "openFile": "打开文件",
"continue": "继续" "continue": "继续",
"fullScreen": "切换全屏",
"discardChanges": "放弃更改"
}, },
"download": { "download": {
"downloadFile": "下载文件", "downloadFile": "下载文件",
@ -136,7 +138,9 @@
"uploadFiles": "正在上传 {files} ...", "uploadFiles": "正在上传 {files} ...",
"uploadMessage": "选择上传选项。", "uploadMessage": "选择上传选项。",
"optionalPassword": "密码(选填,不填即无密码)", "optionalPassword": "密码(选填,不填即无密码)",
"resolution": "分辨率" "resolution": "分辨率",
"deleteUser": "你确定要删除这个用户吗?",
"discardEditorChanges": "你确定要放弃所做的更改吗?"
}, },
"search": { "search": {
"images": "图像", "images": "图像",
@ -218,6 +222,7 @@
"shareDeleted": "分享已删除!", "shareDeleted": "分享已删除!",
"singleClick": "使用单击来打开文件和文件夹", "singleClick": "使用单击来打开文件和文件夹",
"themes": { "themes": {
"default": "系统默认",
"dark": "深色", "dark": "深色",
"light": "浅色", "light": "浅色",
"title": "主题" "title": "主题"

View File

@ -6,10 +6,13 @@
"copy": "複製", "copy": "複製",
"copyFile": "複製檔案", "copyFile": "複製檔案",
"copyToClipboard": "複製到剪貼簿", "copyToClipboard": "複製到剪貼簿",
"copyDownloadLinkToClipboard": "複製到剪貼簿",
"create": "建立", "create": "建立",
"delete": "刪除", "delete": "刪除",
"download": "下載", "download": "下載",
"hideDotfiles": "", "file": "檔案",
"folder": "資料夾",
"hideDotfiles": "隱藏隱藏檔案",
"info": "資訊", "info": "資訊",
"more": "更多", "more": "更多",
"move": "移動", "move": "移動",
@ -30,20 +33,29 @@
"selectMultiple": "選擇多個", "selectMultiple": "選擇多個",
"share": "分享", "share": "分享",
"shell": "切換 shell", "shell": "切換 shell",
"submit": "提交",
"switchView": "切換顯示方式", "switchView": "切換顯示方式",
"toggleSidebar": "切換側邊欄", "toggleSidebar": "切換側邊欄",
"update": "更新", "update": "更新",
"upload": "上傳" "upload": "上傳",
"openFile": "開啟檔案",
"continue": "繼續",
"fullScreen": "切換全螢幕",
"discardChanges": "放棄變更"
}, },
"download": { "download": {
"downloadFile": "下載檔案", "downloadFile": "下載檔案",
"downloadFolder": "下載資料夾", "downloadFolder": "下載資料夾",
"downloadSelected": "" "downloadSelected": "下載已選擇"
},
"upload": {
"abortUpload": "你確定要中止嗎?"
}, },
"errors": { "errors": {
"forbidden": "您無權訪問。", "forbidden": "您無權訪問。",
"internal": "伺服器出了點問題。", "internal": "伺服器出了點問題。",
"notFound": "找不到檔案。" "notFound": "找不到檔案。",
"connection": "無法連接到伺服器。"
}, },
"files": { "files": {
"body": "内容", "body": "内容",
@ -60,7 +72,8 @@
"size": "大小", "size": "大小",
"sortByLastModified": "按最後修改時間排序", "sortByLastModified": "按最後修改時間排序",
"sortByName": "按名稱排序", "sortByName": "按名稱排序",
"sortBySize": "按大小排序" "sortBySize": "按大小排序",
"noPreview": "此檔案無法預覽。"
}, },
"help": { "help": {
"click": "選擇檔案或目錄", "click": "選擇檔案或目錄",
@ -95,6 +108,7 @@
"currentlyNavigating": "目前目錄:", "currentlyNavigating": "目前目錄:",
"deleteMessageMultiple": "你確定要刪除這 {count} 個檔案嗎?", "deleteMessageMultiple": "你確定要刪除這 {count} 個檔案嗎?",
"deleteMessageSingle": "你確定要刪除這個檔案/資料夾嗎?", "deleteMessageSingle": "你確定要刪除這個檔案/資料夾嗎?",
"deleteMessageShare": "你確定要刪除這個分享({path})嗎?",
"deleteTitle": "刪除檔案", "deleteTitle": "刪除檔案",
"displayName": "名稱:", "displayName": "名稱:",
"download": "下載檔案", "download": "下載檔案",
@ -117,11 +131,16 @@
"replace": "替換", "replace": "替換",
"replaceMessage": "您嘗試上傳的檔案中有一個與現有檔案的名稱存在衝突。是否取代現有的同名檔案?", "replaceMessage": "您嘗試上傳的檔案中有一個與現有檔案的名稱存在衝突。是否取代現有的同名檔案?",
"schedule": "計畫", "schedule": "計畫",
"scheduleMessage": "請選擇發佈這篇貼文的日期。", "scheduleMessage": "請選擇發佈這篇貼文的日期與時間。",
"show": "顯示", "show": "顯示",
"size": "大小", "size": "大小",
"upload": "上傳", "upload": "上傳",
"uploadMessage": "選擇上傳項。" "uploadFiles": "正在上傳 {files} ...",
"uploadMessage": "選擇上傳項。",
"optionalPassword": "密碼(選填,不填即無密碼)",
"resolution": "解析度",
"deleteUser": "你確定要刪除這個使用者嗎?",
"discardEditorChanges": "你確定要放棄所做的變更嗎?"
}, },
"search": { "search": {
"images": "影像", "images": "影像",
@ -138,10 +157,10 @@
"administrator": "管理員", "administrator": "管理員",
"allowCommands": "執行命令", "allowCommands": "執行命令",
"allowEdit": "編輯、重命名或刪除檔案/目錄", "allowEdit": "編輯、重命名或刪除檔案/目錄",
"allowNew": "建新檔案和目錄", "allowNew": "新檔案和目錄",
"allowPublish": "發佈新的貼文與頁面", "allowPublish": "發佈新的貼文與頁面",
"allowSignup": "允許使用者註冊", "allowSignup": "允許使用者註冊",
"avoidChanges": "(留空以避免更改)", "avoidChanges": "(留空以避免更改)",
"branding": "品牌", "branding": "品牌",
"brandingDirectoryPath": "品牌資訊資料夾路徑", "brandingDirectoryPath": "品牌資訊資料夾路徑",
"brandingHelp": "您可以通過改變例項名稱更換Logo加入自定義樣式甚至禁用到Github的外部連結來自定義File Browser的外觀和給人的感覺。\n想獲得更多資訊請檢視 {0} 。", "brandingHelp": "您可以通過改變例項名稱更換Logo加入自定義樣式甚至禁用到Github的外部連結來自定義File Browser的外觀和給人的感覺。\n想獲得更多資訊請檢視 {0} 。",
@ -150,17 +169,24 @@
"commandRunnerHelp": "在這裡你可以設定在下面的事件中執行的命令。每行必須寫一條命令。可以在命令中使用環境變數 {0} 和 {1}。關於此功能和可用環境變數的更多資訊,請閱讀{2}.", "commandRunnerHelp": "在這裡你可以設定在下面的事件中執行的命令。每行必須寫一條命令。可以在命令中使用環境變數 {0} 和 {1}。關於此功能和可用環境變數的更多資訊,請閱讀{2}.",
"commandsUpdated": "命令已更新!", "commandsUpdated": "命令已更新!",
"createUserDir": "在新增新使用者的同時自動建立使用者的個人目錄", "createUserDir": "在新增新使用者的同時自動建立使用者的個人目錄",
"customStylesheet": "自定義樣式表", "tusUploads": "分塊上傳",
"tusUploadsHelp": "File Browser 支援分塊上傳,在不佳的網絡環境下也可進行高效、可靠、可續的檔案上傳",
"tusUploadsChunkSize": "分塊上傳大小,例如 10MB 或 1GB",
"tusUploadsRetryCount": "分塊上傳失敗時的重試次數",
"userHomeBasePath": "使用者主目錄的路徑",
"userScopeGenerationPlaceholder": "自動生成目錄範圍",
"createUserHomeDirectory": "建立使用者主目錄",
"customStylesheet": "自定義樣式表CSS",
"defaultUserDescription": "這些是新使用者的預設設定。", "defaultUserDescription": "這些是新使用者的預設設定。",
"disableExternalLinks": "禁止外部連結(幫助文件除外)", "disableExternalLinks": "禁止外部連結(幫助文件除外)",
"disableUsedDiskPercentage": "Disable used disk percentage graph", "disableUsedDiskPercentage": "停用已使用磁碟空間百分比圖",
"documentation": "幫助文件", "documentation": "幫助文件",
"examples": "範例", "examples": "範例",
"executeOnShell": "在Shell中執行", "executeOnShell": "在Shell中執行",
"executeOnShellDescription": "預設情況下File Browser通過直接呼叫命令的二進位制包來執行命令如果想在shell中執行如Bash、PowerShell你可以在這裡定義所使用的shell和參數。如果設定了這個選項所執行的命令會作為參數追加在後面。本選項對使用者命令和事件鉤子都生效。", "executeOnShellDescription": "預設情況下File Browser通過直接呼叫命令的二進位制包來執行命令如果想在shell中執行如Bash、PowerShell你可以在這裡定義所使用的shell和參數。如果設定了這個選項所執行的命令會作為參數追加在後面。本選項對使用者命令和事件鉤子都生效。",
"globalRules": "這是全局允許與禁止規則。它們作用於所有使用者。您可以給每個使用者定義單獨的特殊規則來覆蓋全局規則。", "globalRules": "這是全局允許與禁止規則。它們作用於所有使用者。您可以給每個使用者定義單獨的特殊規則來覆蓋全局規則。",
"globalSettings": "全域設定", "globalSettings": "全域設定",
"hideDotfiles": "", "hideDotfiles": "隱藏隱藏檔案",
"insertPath": "插入路徑", "insertPath": "插入路徑",
"insertRegex": "插入正規表示式", "insertRegex": "插入正規表示式",
"instanceName": "例項名稱", "instanceName": "例項名稱",
@ -171,7 +197,7 @@
"newUser": "建立使用者", "newUser": "建立使用者",
"password": "密碼", "password": "密碼",
"passwordUpdated": "密碼已更新!", "passwordUpdated": "密碼已更新!",
"path": "", "path": "路徑",
"perm": { "perm": {
"create": "建立檔案和資料夾", "create": "建立檔案和資料夾",
"delete": "刪除檔案和資料夾", "delete": "刪除檔案和資料夾",
@ -189,18 +215,21 @@
"rules": "規則", "rules": "規則",
"rulesHelp": "您可以為該使用者製定一組黑名單或白名單式的規則,被屏蔽的檔案將不會顯示在清單中,使用者也無權限存取,支持相對於目錄範圍的路徑。", "rulesHelp": "您可以為該使用者製定一組黑名單或白名單式的規則,被屏蔽的檔案將不會顯示在清單中,使用者也無權限存取,支持相對於目錄範圍的路徑。",
"scope": "目錄範圍", "scope": "目錄範圍",
"setDateFormat": "顯示精確的日期格式",
"settingsUpdated": "設定已更新!", "settingsUpdated": "設定已更新!",
"shareDuration": "", "shareDuration": "分享期限",
"shareManagement": "", "shareManagement": "分享管理",
"singleClick": "", "shareDeleted": "分享已刪除!",
"singleClick": "使用單擊開啟檔案和目錄",
"themes": { "themes": {
"default": "系統預設",
"dark": "深色", "dark": "深色",
"light": "淺色", "light": "淺色",
"title": "主題" "title": "主題"
}, },
"user": "使用者", "user": "使用者",
"userCommands": "使用者命令", "userCommands": "使用者命令Shell 命令)",
"userCommandsHelp": "指定該使用者可以執行的命令,用空格分隔。例如:", "userCommandsHelp": "指定該使用者可以執行的命令Shell 命令),用空格分隔。例如:",
"userCreated": "使用者已建立!", "userCreated": "使用者已建立!",
"userDefaults": "使用者預設選項", "userDefaults": "使用者預設選項",
"userDeleted": "使用者已刪除!", "userDeleted": "使用者已刪除!",
@ -211,7 +240,7 @@
}, },
"sidebar": { "sidebar": {
"help": "幫助", "help": "幫助",
"hugoNew": "Hugo New", "hugoNew": "Hugo 新建",
"login": "登入", "login": "登入",
"logout": "登出", "logout": "登出",
"myFiles": "我的檔案", "myFiles": "我的檔案",