mirror of
https://github.com/Kuingsmile/PicList.git
synced 2026-05-07 05:32:52 +08:00
🚧 WIP(custom): rewrite manage page
This commit is contained in:
@@ -1185,7 +1185,7 @@ small {
|
|||||||
/* Dark mode adjustments */
|
/* Dark mode adjustments */
|
||||||
:root.dark .image-process-settings,
|
:root.dark .image-process-settings,
|
||||||
:root.auto.dark .image-process-settings {
|
:root.auto.dark .image-process-settings {
|
||||||
background: var(--color-background-primary);
|
background: var(--color-background-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
:root.dark .settings-header,
|
:root.dark .settings-header,
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ const props = withDefaults(defineProps<{
|
|||||||
const containerRef = ref<HTMLElement | null>(null)
|
const containerRef = ref<HTMLElement | null>(null)
|
||||||
const containerHeight = ref<number>(props.pageMode ? 0 : props.height)
|
const containerHeight = ref<number>(props.pageMode ? 0 : props.height)
|
||||||
const containerWidth = ref<number>(0)
|
const containerWidth = ref<number>(0)
|
||||||
|
const parentScrollListeners = ref<HTMLElement[]>([])
|
||||||
|
|
||||||
const itemsRef = ref<Item[]>(props.items)
|
const itemsRef = ref<Item[]>(props.items)
|
||||||
watch(() => props.items, v => { itemsRef.value = v })
|
watch(() => props.items, v => { itemsRef.value = v })
|
||||||
@@ -124,7 +125,7 @@ const viewportStyle = computed(() => {
|
|||||||
const itemStyle = computed(() =>
|
const itemStyle = computed(() =>
|
||||||
isGridMode.value
|
isGridMode.value
|
||||||
? {}
|
? {}
|
||||||
: { height: `${props.itemHeight}px`, padding: `${props.itemPadding}px` }
|
: { height: `${props.itemHeight}px` }
|
||||||
)
|
)
|
||||||
|
|
||||||
function handleScroll () {
|
function handleScroll () {
|
||||||
@@ -133,7 +134,34 @@ function handleScroll () {
|
|||||||
updateScrollTop(c.scrollTop)
|
updateScrollTop(c.scrollTop)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handlePageScroll () {
|
||||||
|
if (!props.pageMode) return
|
||||||
|
// Throttle the scroll handler for better performance
|
||||||
|
const now = Date.now()
|
||||||
|
if (now - lastScrollTime.value < 16) return // ~60fps
|
||||||
|
lastScrollTime.value = now
|
||||||
|
|
||||||
|
updateContainerMetrics()
|
||||||
|
// When in page mode, recalculate visible items based on viewport intersection
|
||||||
|
const el = containerRef.value
|
||||||
|
if (!el) return
|
||||||
|
|
||||||
|
const rect = el.getBoundingClientRect()
|
||||||
|
const viewportHeight = window.innerHeight
|
||||||
|
|
||||||
|
// Calculate the intersection with the viewport
|
||||||
|
const intersectionTop = Math.max(0, -rect.top)
|
||||||
|
const intersectionBottom = Math.min(rect.height, viewportHeight - rect.top)
|
||||||
|
const intersectionHeight = Math.max(0, intersectionBottom - intersectionTop)
|
||||||
|
|
||||||
|
if (intersectionHeight > 0) {
|
||||||
|
// Update the virtual scroll position based on the intersection
|
||||||
|
updateScrollTop(intersectionTop)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let ro: ResizeObserver | null = null
|
let ro: ResizeObserver | null = null
|
||||||
|
const lastScrollTime = ref(0)
|
||||||
|
|
||||||
function updateContainerMetrics () {
|
function updateContainerMetrics () {
|
||||||
const el = containerRef.value
|
const el = containerRef.value
|
||||||
@@ -152,7 +180,20 @@ onMounted(() => {
|
|||||||
if (!el) return
|
if (!el) return
|
||||||
ro = new ResizeObserver(updateContainerMetrics)
|
ro = new ResizeObserver(updateContainerMetrics)
|
||||||
ro.observe(el)
|
ro.observe(el)
|
||||||
if (props.pageMode) ro.observe(document.documentElement)
|
if (props.pageMode) {
|
||||||
|
ro.observe(document.documentElement)
|
||||||
|
// Listen to scroll events on the window for page mode
|
||||||
|
window.addEventListener('scroll', handlePageScroll, { passive: true })
|
||||||
|
// Also listen to scroll events on potential scroll containers
|
||||||
|
let parent = el.parentElement
|
||||||
|
while (parent) {
|
||||||
|
if (parent.scrollHeight > parent.clientHeight) {
|
||||||
|
parent.addEventListener('scroll', handlePageScroll, { passive: true })
|
||||||
|
parentScrollListeners.value.push(parent)
|
||||||
|
}
|
||||||
|
parent = parent.parentElement
|
||||||
|
}
|
||||||
|
}
|
||||||
updateContainerMetrics()
|
updateContainerMetrics()
|
||||||
if (props.pageMode) {
|
if (props.pageMode) {
|
||||||
window.addEventListener('resize', updateContainerMetrics, { passive: true })
|
window.addEventListener('resize', updateContainerMetrics, { passive: true })
|
||||||
@@ -162,6 +203,14 @@ onMounted(() => {
|
|||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
if (ro) ro.disconnect()
|
if (ro) ro.disconnect()
|
||||||
window.removeEventListener('resize', updateContainerMetrics)
|
window.removeEventListener('resize', updateContainerMetrics)
|
||||||
|
if (props.pageMode) {
|
||||||
|
window.removeEventListener('scroll', handlePageScroll)
|
||||||
|
// Clean up parent scroll listeners
|
||||||
|
parentScrollListeners.value.forEach(parent => {
|
||||||
|
parent.removeEventListener('scroll', handlePageScroll)
|
||||||
|
})
|
||||||
|
parentScrollListeners.value = []
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function scrollTo (index: number) { scrollToItem(index) }
|
function scrollTo (index: number) { scrollToItem(index) }
|
||||||
@@ -178,6 +227,10 @@ function refresh () {
|
|||||||
if (containerRef.value) {
|
if (containerRef.value) {
|
||||||
updateScrollTop(containerRef.value.scrollTop)
|
updateScrollTop(containerRef.value.scrollTop)
|
||||||
}
|
}
|
||||||
|
// Also trigger page scroll calculation in page mode
|
||||||
|
if (props.pageMode) {
|
||||||
|
handlePageScroll()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ scrollTo, scrollToTop, scrollToBottom, setViewMode, toggleViewMode, refresh })
|
defineExpose({ scrollTo, scrollToTop, scrollToBottom, setViewMode, toggleViewMode, refresh })
|
||||||
@@ -203,9 +256,11 @@ defineExpose({ scrollTo, scrollToTop, scrollToBottom, setViewMode, toggleViewMod
|
|||||||
inset: 0 auto auto 0;
|
inset: 0 auto auto 0;
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
backface-visibility: hidden;
|
backface-visibility: hidden;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.virtual-scroller-viewport.is-grid {
|
.virtual-scroller-viewport.is-grid {
|
||||||
|
width: 100%;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(var(--items-per-row, 1), minmax(0, 1fr));
|
grid-template-columns: repeat(var(--items-per-row, 1), minmax(0, 1fr));
|
||||||
grid-auto-rows: var(--row-height, 1px);
|
grid-auto-rows: var(--row-height, 1px);
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
{
|
{
|
||||||
"app": { "title": "PicList" },
|
"app": { "title": "PicList" },
|
||||||
"titleBar": { "alwaysOnTop": "Always On Top", "close": "Close", "minimize": "Minimize", "miniWindow": "Mini Window" },
|
"titleBar": { "alwaysOnTop": "Always On Top", "close": "Close", "minimize": "Minimize", "miniWindow": "Mini Window" },
|
||||||
"common": { "confirm": "Confirm", "cancel": "Cancel", "close": "Close", "reset": "Reset", "import": "Import" },
|
"common": {
|
||||||
|
"confirm": "Confirm",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"close": "Close",
|
||||||
|
"reset": "Reset",
|
||||||
|
"import": "Import",
|
||||||
|
"submit": "Submit"
|
||||||
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"manage": "Manage",
|
"manage": "Manage",
|
||||||
@@ -695,74 +702,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"MANAGE_SETTING_TITLE": "Manage Setting",
|
|
||||||
"MANAGE_SETTING_ISAUTOREFRESH_TITLE": "Auto refresh file list when entering new directory",
|
|
||||||
"MANAGE_SETTING_ISAUTOREFRESH_TIPS": "Only applies to non-paginated mode, data is cached to indexdb to speed up loading speed",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_TITLE": "Clear file list cache database, currently in use:",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_FREE_TITLE": "Available:",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_TIPS": "After clearing, the file list will be reloaded when entering a new directory next time",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_PROMPT": "Are you sure you want to clear the file list cache database?",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_BUTTON": "Clear",
|
|
||||||
"MANAGE_SETTING_ISSHOWTHUMBNAIL_TITLE": "Display the original image instead of format icon (requires public access permissions)",
|
|
||||||
"MANAGE_SETTING_ISUSEPRESIGNEDURL_TITLE": "Use presigned URL for image display",
|
|
||||||
"MANAGE_SETTING_ISSHOWLIST_TITLE": "Default display mode for the file list",
|
|
||||||
"MANAGE_SETTING_ISSHOWLIST_ON": "List",
|
|
||||||
"MANAGE_SETTING_ISSHOWLIST_OFF": "Card",
|
|
||||||
"MANAGE_SETTING_ISFORCECUSTOMURLHTTPS_TITLE": "Force custom URL to use HTTPS",
|
|
||||||
"MANAGE_SETTING_ISFORCECUSTOMURLHTTPS_TIPS": "After enabling, all operations will automatically add the https prefix to custom domains",
|
|
||||||
"MANAGE_SETTING_ISUPLOADKEEPDIRSTRUCTURE_TITLE": "Preserve directory structure when uploading",
|
|
||||||
"MANAGE_SETTING_ISUPLOADKEEPDIRSTRUCTURE_TIPS": "After disabling, all files will be expanded to the specified directory",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_A": "Download",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_B": " File ",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_C": "will preserve the directory structure",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFOLDERKEEPDIRSTRUCTURE_TITLE_D": " Folder ",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TIPS": "After enabling, the original directory structure will be preserved",
|
|
||||||
"MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_TITLE": "Maximum number of files to download simultaneously (1-9999)",
|
|
||||||
"MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_TIPS": "Not work on Tencent",
|
|
||||||
"MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_INPUT_TIPS": "Please enter the maximum number of files to download simultaneously",
|
|
||||||
"MANAGE_SETTING_ISIGNORECASE_TITLE": "Should file search be case-insensitive",
|
|
||||||
"MANAGE_SETTING_ISIGNORECASE_TIPS": "After enabling, the search will be case-insensitive",
|
|
||||||
"MANAGE_SETTING_TIMESTAMPRENAME_TITLE": "Rename uploaded files with timestamp - (highest priority)",
|
|
||||||
"MANAGE_SETTING_TIMESTAMPRENAME_TIPS": "After enabling, the uploaded file will be renamed with the timestamp",
|
|
||||||
"MANAGE_SETTING_RANDOMSTRINGRENAME_TITLE": "Rename uploaded files with random strings - (medium priority)",
|
|
||||||
"MANAGE_SETTING_RANDOMSTRINGRENAME_TIPS": "Random string length is 20",
|
|
||||||
"MANAGE_SETTING_CUSTOMRENAME_TITLE": "Rename uploaded files with custom names - (lowest priority)",
|
|
||||||
"MANAGE_SETTING_CUSTOMRENAME_TIPS": "After enabling, the uploaded file will be renamed with the custom pattern",
|
|
||||||
"MANAGE_SETTING_CUSTOM_PATTERN_TITLE": "Custom rename format, placeholders can be freely combined, please refer to the table below",
|
|
||||||
"MANAGE_SETTING_CUSTOM_PATTERN_TIPS": "Please enter the custom rename format",
|
|
||||||
"MANAGE_SETTING_CUSTOM_PATTERN_TABLE_TITLE": "Placeholder",
|
|
||||||
"MANAGE_SETTING_CUSTOM_PATTERN_TABLE_TIPS": "Description",
|
|
||||||
"MANAGE_SETTING_PRESIGNED_URL_EXPIRE_TITLE": "Presigned URL expiration time (seconds)",
|
|
||||||
"MANAGE_SETTING_PRESIGNED_URL_EXPIRE_TIPS": "Please enter the presigned URL expiration time",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_TITLE": "Select default link format for copying",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_MARKDOWN": "Markdown",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_MARKDOWN_WITH_LINK": "Markdown with link",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_RAWURL": "Raw URL",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_HTML": "HTML",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_BBCODE": "BBCode",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_CUSTOM": "Custom",
|
|
||||||
"MANAGE_SETTING_CUSTOM_COPY_FORMAT_TITLE": "Custom link format($url -> raw url, $fileName -> raw fileName)",
|
|
||||||
"MANAGE_SETTING_CUSTOM_COPY_FORMAT_TIPS": "Please enter the custom link format",
|
|
||||||
"MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_TITLE": "Choose default download folder",
|
|
||||||
"MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_TIPS": "System default download directory",
|
|
||||||
"MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_BUTTON": "Choose folder",
|
|
||||||
"MANAGE_SETTING_COPY_MESSAGE": "Copied",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_SUCCESS": "Cleared successfully",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_FAILED": "Clear failed",
|
|
||||||
"MANAGE_SETTING_ISENCODEURL_TITLE": "Encode URL when copy",
|
|
||||||
"MANAGE_SETTING_ISENCODEURL_TIPS": "After enabling, the URL will be encoded when copying",
|
|
||||||
"MANAGE_NO_DATA": "No data",
|
|
||||||
"MANAGE_MAIN_PAGE_NEW_BUCKET": "New Bucket",
|
|
||||||
"MANAGE_MAIN_PAGE_BACK_TO_HOME": "Home",
|
|
||||||
"MANAGE_MAIN_PAGE_SWITCH_PICBED": "Switch",
|
|
||||||
"MANAGE_MAIN_PAGE_SETTING": "Setting",
|
|
||||||
"MANAGE_MAIN_PAGE_SUBMIT": "Submit",
|
|
||||||
"MANAGE_MAIN_PAGE_TIPS": "Tips",
|
|
||||||
"MANAGE_MAIN_PAGE_TIPS_SUCCESS": "Created successfully",
|
|
||||||
"MANAGE_MAIN_PAGE_TIPS_FAILED": "Create failed",
|
|
||||||
"MANAGE_MAIN_PAGE_BUCKET": "Bucket",
|
|
||||||
"MANAGE_MAIN_PAGE_GALLERY": "Album",
|
|
||||||
"MANAGE_MAIN_PAGE_REPOSITORY": "Repo",
|
|
||||||
"MANAGE_BUCKET_PAGE_LOADING_TEXT": "Loading...",
|
"MANAGE_BUCKET_PAGE_LOADING_TEXT": "Loading...",
|
||||||
"MANAGE_BUCKET_PAGE_CUSTOM_URL_SELECT_PLACEHOLDER": "Please select a custom domain",
|
"MANAGE_BUCKET_PAGE_CUSTOM_URL_SELECT_PLACEHOLDER": "Please select a custom domain",
|
||||||
"MANAGE_BUCKET_PAGE_CUSTOM_URL_INPUT_PLACEHOLDER": "Please enter a custom domain",
|
"MANAGE_BUCKET_PAGE_CUSTOM_URL_INPUT_PLACEHOLDER": "Please enter a custom domain",
|
||||||
@@ -774,6 +713,8 @@
|
|||||||
"MANAGE_BUCKET_PAGE_BATCH_COPY_URL_TOOLTIP": "Batch copy URL",
|
"MANAGE_BUCKET_PAGE_BATCH_COPY_URL_TOOLTIP": "Batch copy URL",
|
||||||
"MANAGE_BUCKET_PAGE_COPY_FILE_INFO_TOOLTIP": "Copy file information",
|
"MANAGE_BUCKET_PAGE_COPY_FILE_INFO_TOOLTIP": "Copy file information",
|
||||||
"MANAGE_BUCKET_PAGE_FORCE_REFRESH_TOOLTIP": "Force refresh file list",
|
"MANAGE_BUCKET_PAGE_FORCE_REFRESH_TOOLTIP": "Force refresh file list",
|
||||||
|
"MANAGE_BUCKET_PAGE_FULLSCREEN_TOOLTIP": "Enter fullscreen mode (F11)",
|
||||||
|
"MANAGE_BUCKET_PAGE_EXIT_FULLSCREEN_TOOLTIP": "Exit fullscreen mode (F11)",
|
||||||
"MANAGE_BUCKET_PAGE_SEARCH_PLACEHOLDER": "Search files",
|
"MANAGE_BUCKET_PAGE_SEARCH_PLACEHOLDER": "Search files",
|
||||||
"MANAGE_BUCKET_PAGE_ROOT_FOLDER": "Root folder",
|
"MANAGE_BUCKET_PAGE_ROOT_FOLDER": "Root folder",
|
||||||
"MANAGE_BUCKET_PAGE_FILE_NUMBER": "Number of files: ",
|
"MANAGE_BUCKET_PAGE_FILE_NUMBER": "Number of files: ",
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
{
|
{
|
||||||
"app": { "title": "PicList" },
|
"app": { "title": "PicList" },
|
||||||
"titleBar": { "alwaysOnTop": "置顶", "close": "关闭", "minimize": "最小化", "miniWindow": "迷你窗口" },
|
"titleBar": { "alwaysOnTop": "置顶", "close": "关闭", "minimize": "最小化", "miniWindow": "迷你窗口" },
|
||||||
"common": { "confirm": "确认", "cancel": "取消", "close": "关闭", "reset": "重置", "import": "导入" },
|
"common": {
|
||||||
|
"confirm": "确认",
|
||||||
|
"cancel": "取消",
|
||||||
|
"close": "关闭",
|
||||||
|
"reset": "重置",
|
||||||
|
"import": "导入",
|
||||||
|
"submit": "提交"
|
||||||
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"upload": "上传",
|
"upload": "上传",
|
||||||
"manage": "管理",
|
"manage": "管理",
|
||||||
@@ -481,6 +488,77 @@
|
|||||||
"copySuccess": "复制成功"
|
"copySuccess": "复制成功"
|
||||||
},
|
},
|
||||||
"manage": {
|
"manage": {
|
||||||
|
"main": {
|
||||||
|
"openPicBedUrl": "打开图床官网",
|
||||||
|
"newBucket": "新建存储桶",
|
||||||
|
"loading": "加载中...",
|
||||||
|
"backToHome": "首页",
|
||||||
|
"switchPicBed": "切换",
|
||||||
|
"settings": "设置",
|
||||||
|
"bucket": "存储桶",
|
||||||
|
"gallery": "相册",
|
||||||
|
"repo": "仓库",
|
||||||
|
"createSuccess": "创建成功",
|
||||||
|
"createFailed": "创建失败"
|
||||||
|
},
|
||||||
|
"empty": {
|
||||||
|
"noData": "暂无数据",
|
||||||
|
"noDataDesc": "请先创建存储桶或上传图片"
|
||||||
|
},
|
||||||
|
"setting": {
|
||||||
|
"clearCache": "清空文件列表缓存数据库,已使用 {size} 可用 {percent}%",
|
||||||
|
"clearCacheMsg": "确定要清空缓存吗?",
|
||||||
|
"isAutoRefreshTitle": "每次进入新目录时,是否自动刷新文件列表",
|
||||||
|
"isAutoRefreshTips": "仅对不分页模式有效,默认在加载过一次后自动缓存到数据库来加快下次加载速度",
|
||||||
|
"isShowThumbnailTitle": "图片显示为原图而非默认文件格式图标(需要存储桶可公开访问)",
|
||||||
|
"isUsePreSignedUrlTitle": "是否使用预签名URL预览图片",
|
||||||
|
"isForceCustomUrlHttpsTitle": "为自定义域名开启强制HTTPS",
|
||||||
|
"isForceCustomUrlHttpsTips": "开启后, 复制链接等操作将会自动为自定义域名添加https前缀",
|
||||||
|
"isEncodeUrlTitle": "复制链接时进行URL编码",
|
||||||
|
"isEncodeUrlTips": "根据平台选择是否开启",
|
||||||
|
"isUploadKeepDirStructureTitle": "上传时保持目录结构",
|
||||||
|
"isUploadKeepDirStructureTips": "关闭后会将所有文件展开到指定目录下",
|
||||||
|
"isIgnoreCaseTitle": "文件搜索时,是否忽略大小写",
|
||||||
|
"isIgnoreCaseTips": "建议开启",
|
||||||
|
"timestampRenameTitle": "上传文件时间戳重命名(最高优先级)",
|
||||||
|
"timestampRenameTips": "开启后,上传的文件将自动重命名为时间戳",
|
||||||
|
"randomStringRenameTitle": "上传文件随机字符串重命名(中优先级)",
|
||||||
|
"randomStringRenameTips": "20位随机字符",
|
||||||
|
"customRenameTitle": "上传文件自定义重命名(低优先级)",
|
||||||
|
"customRenameTips": "开启后填写命名格式",
|
||||||
|
"customRenameTableTitle": "自定义重命名格式参考表",
|
||||||
|
"customRenameTablePlaceholder": "请输入自定义重命名格式",
|
||||||
|
"placeholder": "占位符",
|
||||||
|
"description": "描述",
|
||||||
|
"copySuccess": "已复制 {name}",
|
||||||
|
"download": "下载",
|
||||||
|
"file": "文件",
|
||||||
|
"folder": "文件夹",
|
||||||
|
"keepDirStructure": "保持目录结构",
|
||||||
|
"keepDirStructureDesc": "开启后,下载时会保持原始目录结构",
|
||||||
|
"clearSuccess": "清空缓存成功",
|
||||||
|
"clearFailed": "清空缓存失败",
|
||||||
|
"notice": "通知",
|
||||||
|
"maxDownLoadFileLimit": "最大并行下载文件数",
|
||||||
|
"maxDownLoadFileLimitDesc": "建议根据网络情况调整",
|
||||||
|
"preSignedUrlExpire": "预签名URL过期时间(单位: 秒)",
|
||||||
|
"preSignedUrlExpireDesc": "建议根据实际需求调整",
|
||||||
|
"copyFormat": {
|
||||||
|
"title": "复制格式",
|
||||||
|
"markdown": "Markdown",
|
||||||
|
"rawurl": "原始URL",
|
||||||
|
"markdown-with-link": "Markdown(带链接)",
|
||||||
|
"html": "HTML格式",
|
||||||
|
"bbcode": "BBCode格式",
|
||||||
|
"custom": "自定义格式",
|
||||||
|
"customTitle": "自定义链接格式($url为链接,$fileName为文件名)",
|
||||||
|
"customTips": "请根据实际需求填写自定义格式"
|
||||||
|
},
|
||||||
|
"selectDownloadFolderTitle": "选择下载文件夹",
|
||||||
|
"selectDownloadFolderTips": "选择下载目录",
|
||||||
|
"defaultDownloadFolder": "系统默认下载文件夹",
|
||||||
|
"browse": "浏览"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"title": "图床管理",
|
"title": "图床管理",
|
||||||
"savedConfigs": "已保存配置",
|
"savedConfigs": "已保存配置",
|
||||||
@@ -690,74 +768,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"MANAGE_SETTING_TITLE": "管理页面设置",
|
|
||||||
"MANAGE_SETTING_ISAUTOREFRESH_TITLE": "每次进入新目录时,是否自动刷新文件列表",
|
|
||||||
"MANAGE_SETTING_ISAUTOREFRESH_TIPS": "仅对不分页模式有效,默认在加载过一次后自动缓存到数据库来加快下次加载速度",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_TITLE": "清空文件列表缓存数据库 已占用:",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_FREE_TITLE": "剩余可用:",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_TIPS": "清空后下次进入新目录时将会重新加载文件列表",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_PROMPT": "确定要清空文件列表缓存数据库吗?",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_BUTTON": "清空",
|
|
||||||
"MANAGE_SETTING_ISSHOWTHUMBNAIL_TITLE": "图片显示为原图而非默认文件格式图标(需要存储桶可公开访问)",
|
|
||||||
"MANAGE_SETTING_ISUSEPRESIGNEDURL_TITLE": "使用预签名URL预览图片",
|
|
||||||
"MANAGE_SETTING_ISSHOWLIST_TITLE": "文件列表默认显示方式",
|
|
||||||
"MANAGE_SETTING_ISSHOWLIST_ON": "列表",
|
|
||||||
"MANAGE_SETTING_ISSHOWLIST_OFF": "卡片",
|
|
||||||
"MANAGE_SETTING_ISFORCECUSTOMURLHTTPS_TITLE": "为自定义域名开启强制HTTPS",
|
|
||||||
"MANAGE_SETTING_ISFORCECUSTOMURLHTTPS_TIPS": "开启后, 复制链接等操作将会自动为自定义域名添加https前缀",
|
|
||||||
"MANAGE_SETTING_ISUPLOADKEEPDIRSTRUCTURE_TITLE": "上传时保留目录结构",
|
|
||||||
"MANAGE_SETTING_ISUPLOADKEEPDIRSTRUCTURE_TIPS": "关闭后会将所有文件展开到指定目录下",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_A": "下载",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_B": "文件",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_C": "时保留目录结构",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFOLDERKEEPDIRSTRUCTURE_TITLE_D": "文件夹",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TIPS": "开启后,下载时会保留原始目录结构",
|
|
||||||
"MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_TITLE": "最大同时下载文件数(1-9999)",
|
|
||||||
"MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_TIPS": "腾讯云由于后端实现不同,该设置不生效",
|
|
||||||
"MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_INPUT_TIPS": "请输入最大同时下载文件数",
|
|
||||||
"MANAGE_SETTING_ISIGNORECASE_TITLE": "文件搜索时,是否忽略大小写",
|
|
||||||
"MANAGE_SETTING_ISIGNORECASE_TIPS": "开启后,搜索时会忽略大小写",
|
|
||||||
"MANAGE_SETTING_TIMESTAMPRENAME_TITLE": "上传文件时间戳重命名--(优先级最高)",
|
|
||||||
"MANAGE_SETTING_TIMESTAMPRENAME_TIPS": "开启后,上传文件时会自动重命名为时间戳",
|
|
||||||
"MANAGE_SETTING_RANDOMSTRINGRENAME_TITLE": "上传文件随机字符串重命名--(优先级中)",
|
|
||||||
"MANAGE_SETTING_RANDOMSTRINGRENAME_TIPS": "随机字符串长度为20",
|
|
||||||
"MANAGE_SETTING_CUSTOMRENAME_TITLE": "上传文件自定义重命名--(优先级最低)",
|
|
||||||
"MANAGE_SETTING_CUSTOMRENAME_TIPS": "请填写自定义重命名格式",
|
|
||||||
"MANAGE_SETTING_CUSTOM_PATTERN_TITLE": "自定义重命名格式,占位符请参考下表,可自由组合",
|
|
||||||
"MANAGE_SETTING_CUSTOM_PATTERN_TIPS": "请填写自定义重命名格式",
|
|
||||||
"MANAGE_SETTING_CUSTOM_PATTERN_TABLE_TITLE": "占位符",
|
|
||||||
"MANAGE_SETTING_CUSTOM_PATTERN_TABLE_TIPS": "描述",
|
|
||||||
"MANAGE_SETTING_PRESIGNED_URL_EXPIRE_TITLE": "预签名URL过期时间(单位:秒)",
|
|
||||||
"MANAGE_SETTING_PRESIGNED_URL_EXPIRE_TIPS": "请填写预签名URL过期时间",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_TITLE": "选择默认复制的链接格式",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_MARKDOWN": "Markdown",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_MARKDOWN_WITH_LINK": "Markdown(带链接)",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_RAWURL": "原始链接",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_HTML": "HTML格式",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_BBCODE": "BBCode格式",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_CUSTOM": "自定义格式",
|
|
||||||
"MANAGE_SETTING_CUSTOM_COPY_FORMAT_TITLE": "自定义链接格式($url为链接,$fileName为文件名)",
|
|
||||||
"MANAGE_SETTING_CUSTOM_COPY_FORMAT_TIPS": "请填写自定义链接格式",
|
|
||||||
"MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_TITLE": "选择下载目录",
|
|
||||||
"MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_TIPS": "系统默认下载目录",
|
|
||||||
"MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_BUTTON": "选择目录",
|
|
||||||
"MANAGE_SETTING_COPY_MESSAGE": "已复制",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_SUCCESS": "清除成功",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_FAILED": "清除失败",
|
|
||||||
"MANAGE_SETTING_ISENCODEURL_TITLE": "复制链接时进行URL编码",
|
|
||||||
"MANAGE_SETTING_ISENCODEURL_TIPS": "根据平台选择是否开启",
|
|
||||||
"MANAGE_NO_DATA": "暂无数据",
|
|
||||||
"MANAGE_MAIN_PAGE_NEW_BUCKET": "新建存储桶",
|
|
||||||
"MANAGE_MAIN_PAGE_BACK_TO_HOME": "返回首页",
|
|
||||||
"MANAGE_MAIN_PAGE_SWITCH_PICBED": "切换图床",
|
|
||||||
"MANAGE_MAIN_PAGE_SETTING": "设置",
|
|
||||||
"MANAGE_MAIN_PAGE_SUBMIT": "提交",
|
|
||||||
"MANAGE_MAIN_PAGE_TIPS": "提示",
|
|
||||||
"MANAGE_MAIN_PAGE_TIPS_SUCCESS": "创建成功",
|
|
||||||
"MANAGE_MAIN_PAGE_TIPS_FAILED": "创建失败",
|
|
||||||
"MANAGE_MAIN_PAGE_BUCKET": "存储桶",
|
|
||||||
"MANAGE_MAIN_PAGE_GALLERY": "相册",
|
|
||||||
"MANAGE_MAIN_PAGE_REPOSITORY": "仓库",
|
|
||||||
"MANAGE_BUCKET_PAGE_LOADING_TEXT": "加载文件中...",
|
"MANAGE_BUCKET_PAGE_LOADING_TEXT": "加载文件中...",
|
||||||
"MANAGE_BUCKET_PAGE_CUSTOM_URL_SELECT_PLACEHOLDER": "请选择自定义域名",
|
"MANAGE_BUCKET_PAGE_CUSTOM_URL_SELECT_PLACEHOLDER": "请选择自定义域名",
|
||||||
"MANAGE_BUCKET_PAGE_CUSTOM_URL_INPUT_PLACEHOLDER": "请输入自定义域名",
|
"MANAGE_BUCKET_PAGE_CUSTOM_URL_INPUT_PLACEHOLDER": "请输入自定义域名",
|
||||||
@@ -769,6 +779,8 @@
|
|||||||
"MANAGE_BUCKET_PAGE_BATCH_COPY_URL_TOOLTIP": "批量复制URL",
|
"MANAGE_BUCKET_PAGE_BATCH_COPY_URL_TOOLTIP": "批量复制URL",
|
||||||
"MANAGE_BUCKET_PAGE_COPY_FILE_INFO_TOOLTIP": "复制文件信息",
|
"MANAGE_BUCKET_PAGE_COPY_FILE_INFO_TOOLTIP": "复制文件信息",
|
||||||
"MANAGE_BUCKET_PAGE_FORCE_REFRESH_TOOLTIP": "强制刷新文件列表",
|
"MANAGE_BUCKET_PAGE_FORCE_REFRESH_TOOLTIP": "强制刷新文件列表",
|
||||||
|
"MANAGE_BUCKET_PAGE_FULLSCREEN_TOOLTIP": "进入全屏模式 (F11)",
|
||||||
|
"MANAGE_BUCKET_PAGE_EXIT_FULLSCREEN_TOOLTIP": "退出全屏模式 (F11)",
|
||||||
"MANAGE_BUCKET_PAGE_SEARCH_PLACEHOLDER": "搜索文件",
|
"MANAGE_BUCKET_PAGE_SEARCH_PLACEHOLDER": "搜索文件",
|
||||||
"MANAGE_BUCKET_PAGE_ROOT_FOLDER": "根目录",
|
"MANAGE_BUCKET_PAGE_ROOT_FOLDER": "根目录",
|
||||||
"MANAGE_BUCKET_PAGE_FILE_NUMBER": "文件数: ",
|
"MANAGE_BUCKET_PAGE_FILE_NUMBER": "文件数: ",
|
||||||
|
|||||||
@@ -1,7 +1,14 @@
|
|||||||
{
|
{
|
||||||
"app": { "title": "PicList" },
|
"app": { "title": "PicList" },
|
||||||
"titleBar": { "alwaysOnTop": "置頂", "close": "關閉", "minimize": "最小化", "miniWindow": "迷你視窗" },
|
"titleBar": { "alwaysOnTop": "置頂", "close": "關閉", "minimize": "最小化", "miniWindow": "迷你視窗" },
|
||||||
"common": { "confirm": "確認", "cancel": "取消", "close": "關閉", "reset": "重置", "import": "匯入" },
|
"common": {
|
||||||
|
"confirm": "確認",
|
||||||
|
"cancel": "取消",
|
||||||
|
"close": "關閉",
|
||||||
|
"reset": "重置",
|
||||||
|
"import": "匯入",
|
||||||
|
"submit": "提交"
|
||||||
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"upload": "上傳",
|
"upload": "上傳",
|
||||||
"manage": "管理",
|
"manage": "管理",
|
||||||
@@ -690,74 +697,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"MANAGE_SETTING_TITLE": "管理設定",
|
|
||||||
"MANAGE_SETTING_ISAUTOREFRESH_TITLE": "每次進入新目錄時,是否自動重新整理檔案列表",
|
|
||||||
"MANAGE_SETTING_ISAUTOREFRESH_TIPS": "僅對不分頁模式有效,預設會在載入後自動快取至資料庫以提升下次載入速度",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_TITLE": "清空檔案列表快取資料庫 已佔用:",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_FREE_TITLE": "剩餘可用:",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_TIPS": "清空後下次進入新目錄時將會重新載入檔案列表",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_PROMPT": "確定要清空檔案列表快取資料庫嗎?",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_BUTTON": "清空",
|
|
||||||
"MANAGE_SETTING_ISSHOWTHUMBNAIL_TITLE": "顯示圖片的原始圖像而非預設的檔案格式圖示(需要存儲桶公開訪問權限)",
|
|
||||||
"MANAGE_SETTING_ISUSEPRESIGNEDURL_TITLE": "使用預簽名URL预览圖片",
|
|
||||||
"MANAGE_SETTING_ISSHOWLIST_TITLE": "檔案列表預設顯示方式",
|
|
||||||
"MANAGE_SETTING_ISSHOWLIST_ON": "列表",
|
|
||||||
"MANAGE_SETTING_ISSHOWLIST_OFF": "卡片",
|
|
||||||
"MANAGE_SETTING_ISFORCECUSTOMURLHTTPS_TITLE": "自定義域名啟用強制 HTTPS",
|
|
||||||
"MANAGE_SETTING_ISFORCECUSTOMURLHTTPS_TIPS": "開啟後,複製鏈結等操作將會自動為自定義域名添加 HTTPS 前綴",
|
|
||||||
"MANAGE_SETTING_ISUPLOADKEEPDIRSTRUCTURE_TITLE": "保留上傳時的目錄結構",
|
|
||||||
"MANAGE_SETTING_ISUPLOADKEEPDIRSTRUCTURE_TIPS": "停用後,所有文件將會展開到指定目錄下",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_A": "下載",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_B": "文件",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_C": "時保留目錄結構",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFOLDERKEEPDIRSTRUCTURE_TITLE_D": "目錄",
|
|
||||||
"MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TIPS": "啟用後,下載時會保留原始目錄結構",
|
|
||||||
"MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_TITLE": "最大同時下載檔案數量(1-9999)",
|
|
||||||
"MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_TIPS": "由於後端實現方式不同,此設定在腾讯云上不生效",
|
|
||||||
"MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_INPUT_TIPS": "請輸入最大同時下載檔案數量",
|
|
||||||
"MANAGE_SETTING_ISIGNORECASE_TITLE": "搜尋檔案時,是否忽略大小寫",
|
|
||||||
"MANAGE_SETTING_ISIGNORECASE_TIPS": "啟用後,搜尋時將會忽略大小寫",
|
|
||||||
"MANAGE_SETTING_TIMESTAMPRENAME_TITLE": "上傳檔案時間戳重新命名--(最高優先級)",
|
|
||||||
"MANAGE_SETTING_TIMESTAMPRENAME_TIPS": "啟用後,上傳檔案時將會使用時間戳重新命名",
|
|
||||||
"MANAGE_SETTING_RANDOMSTRINGRENAME_TITLE": "上傳檔案隨機字符串重新命名--(中優先級)",
|
|
||||||
"MANAGE_SETTING_RANDOMSTRINGRENAME_TIPS": "隨機字符串長度為20",
|
|
||||||
"MANAGE_SETTING_CUSTOMRENAME_TITLE": "上傳檔案自定義重新命名--(最低優先級)",
|
|
||||||
"MANAGE_SETTING_CUSTOMRENAME_TIPS": "啟用後,上傳檔案時將會使用自定義重新命名",
|
|
||||||
"MANAGE_SETTING_CUSTOM_PATTERN_TITLE": "自訂重新命名格式,占位符請參考下表,可自由組合",
|
|
||||||
"MANAGE_SETTING_CUSTOM_PATTERN_TIPS": "請輸入自訂重新命名格式",
|
|
||||||
"MANAGE_SETTING_CUSTOM_PATTERN_TABLE_TITLE": "占位符",
|
|
||||||
"MANAGE_SETTING_CUSTOM_PATTERN_TABLE_TIPS": "說明",
|
|
||||||
"MANAGE_SETTING_PRESIGNED_URL_EXPIRE_TITLE": "預設下載鏈結有效期(秒)",
|
|
||||||
"MANAGE_SETTING_PRESIGNED_URL_EXPIRE_TIPS": "請輸入下載鏈結有效期",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_TITLE": "選擇預設複製的連結格式",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_MARKDOWN": "Markdown",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_MARKDOWN_WITH_LINK": "Markdown(帶連結)",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_RAWURL": "原始鏈結",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_HTML": "HTML格式",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_BBCODE": "BBCode格式",
|
|
||||||
"MANAGE_SETTING_CHOOSE_COPY_FORMAT_CUSTOM": "自定義格式",
|
|
||||||
"MANAGE_SETTING_CUSTOM_COPY_FORMAT_TITLE": "自定義鏈結格式($url為原始鏈結,$fileName為檔案名稱)",
|
|
||||||
"MANAGE_SETTING_CUSTOM_COPY_FORMAT_TIPS": "請輸入自定義鏈結格式",
|
|
||||||
"MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_TITLE": "選擇下載目錄",
|
|
||||||
"MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_TIPS": "系統預設下載目錄",
|
|
||||||
"MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_BUTTON": "選擇目錄",
|
|
||||||
"MANAGE_SETTING_COPY_MESSAGE": "已複製",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_SUCCESS": "清除成功",
|
|
||||||
"MANAGE_SETTING_CLEAR_CACHE_FAILED": "清除失敗",
|
|
||||||
"MANAGE_SETTING_ISENCODEURL_TITLE": "複製鏈結時編碼",
|
|
||||||
"MANAGE_SETTING_ISENCODEURL_TIPS": "啟用後,複製鏈結時將會編碼",
|
|
||||||
"MANAGE_NO_DATA": "暫無數據",
|
|
||||||
"MANAGE_MAIN_PAGE_NEW_BUCKET": "新建存儲桶",
|
|
||||||
"MANAGE_MAIN_PAGE_BACK_TO_HOME": "返回首頁",
|
|
||||||
"MANAGE_MAIN_PAGE_SWITCH_PICBED": "切換圖床",
|
|
||||||
"MANAGE_MAIN_PAGE_SETTING": "設定",
|
|
||||||
"MANAGE_MAIN_PAGE_SUBMIT": "提交",
|
|
||||||
"MANAGE_MAIN_PAGE_TIPS": "提示",
|
|
||||||
"MANAGE_MAIN_PAGE_TIPS_SUCCESS": "創建成功",
|
|
||||||
"MANAGE_MAIN_PAGE_TIPS_FAILED": "創建失敗",
|
|
||||||
"MANAGE_MAIN_PAGE_BUCKET": "存儲桶",
|
|
||||||
"MANAGE_MAIN_PAGE_GALLERY": "圖庫",
|
|
||||||
"MANAGE_MAIN_PAGE_REPOSITORY": "倉庫",
|
|
||||||
"MANAGE_BUCKET_PAGE_LOADING_TEXT": "載入檔案中...",
|
"MANAGE_BUCKET_PAGE_LOADING_TEXT": "載入檔案中...",
|
||||||
"MANAGE_BUCKET_PAGE_CUSTOM_URL_SELECT_PLACEHOLDER": "請選擇自訂域名",
|
"MANAGE_BUCKET_PAGE_CUSTOM_URL_SELECT_PLACEHOLDER": "請選擇自訂域名",
|
||||||
"MANAGE_BUCKET_PAGE_CUSTOM_URL_INPUT_PLACEHOLDER": "請輸入自訂域名",
|
"MANAGE_BUCKET_PAGE_CUSTOM_URL_INPUT_PLACEHOLDER": "請輸入自訂域名",
|
||||||
@@ -769,6 +708,8 @@
|
|||||||
"MANAGE_BUCKET_PAGE_BATCH_COPY_URL_TOOLTIP": "批次複製 URL",
|
"MANAGE_BUCKET_PAGE_BATCH_COPY_URL_TOOLTIP": "批次複製 URL",
|
||||||
"MANAGE_BUCKET_PAGE_COPY_FILE_INFO_TOOLTIP": "複製檔案資訊",
|
"MANAGE_BUCKET_PAGE_COPY_FILE_INFO_TOOLTIP": "複製檔案資訊",
|
||||||
"MANAGE_BUCKET_PAGE_FORCE_REFRESH_TOOLTIP": "強制重新整理檔案列表",
|
"MANAGE_BUCKET_PAGE_FORCE_REFRESH_TOOLTIP": "強制重新整理檔案列表",
|
||||||
|
"MANAGE_BUCKET_PAGE_FULLSCREEN_TOOLTIP": "進入全螢幕模式 (F11)",
|
||||||
|
"MANAGE_BUCKET_PAGE_EXIT_FULLSCREEN_TOOLTIP": "退出全螢幕模式 (F11)",
|
||||||
"MANAGE_BUCKET_PAGE_SEARCH_PLACEHOLDER": "搜尋檔案",
|
"MANAGE_BUCKET_PAGE_SEARCH_PLACEHOLDER": "搜尋檔案",
|
||||||
"MANAGE_BUCKET_PAGE_ROOT_FOLDER": "根目錄",
|
"MANAGE_BUCKET_PAGE_ROOT_FOLDER": "根目錄",
|
||||||
"MANAGE_BUCKET_PAGE_FILE_NUMBER": "檔案數:",
|
"MANAGE_BUCKET_PAGE_FILE_NUMBER": "檔案數:",
|
||||||
|
|||||||
226
src/renderer/manage/components/CustomSwitch.vue
Normal file
226
src/renderer/manage/components/CustomSwitch.vue
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
<template>
|
||||||
|
<div class="switch-container">
|
||||||
|
<div class="switch-label-wrapper">
|
||||||
|
<span class="switch-label-text">
|
||||||
|
<span
|
||||||
|
v-for="(segment, index) in segments"
|
||||||
|
:key="index"
|
||||||
|
:style="segment.style"
|
||||||
|
>
|
||||||
|
{{ segment.text }}
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
v-if="tooltip"
|
||||||
|
class="tooltip-wrapper"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="info-icon"
|
||||||
|
@click="toggleTooltip"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
class="info-svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill-rule="evenodd"
|
||||||
|
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
|
||||||
|
clip-rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-show="showTooltip"
|
||||||
|
class="tooltip-content"
|
||||||
|
>
|
||||||
|
{{ tooltip }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="switch-control">
|
||||||
|
<label class="switch">
|
||||||
|
<input
|
||||||
|
v-model="value"
|
||||||
|
type="checkbox"
|
||||||
|
class="switch-input"
|
||||||
|
>
|
||||||
|
<span class="switch-slider">
|
||||||
|
<span class="switch-button" />
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
v-if="activeText || inactiveText"
|
||||||
|
class="switch-text"
|
||||||
|
>
|
||||||
|
{{ value ? activeText : inactiveText }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
tooltip?: string
|
||||||
|
activeText?: string
|
||||||
|
inactiveText?: string
|
||||||
|
segments?: { text: string; style: string }[]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const value = defineModel<boolean>()
|
||||||
|
const showTooltip = ref(false)
|
||||||
|
|
||||||
|
const toggleTooltip = () => {
|
||||||
|
showTooltip.value = !showTooltip.value
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.switch-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
padding: 1rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-label-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-label-text {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
border-radius: 50%;
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-icon:hover {
|
||||||
|
color: var(--color-accent);
|
||||||
|
background: rgba(0, 122, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-svg {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip-content {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
min-width: 200px;
|
||||||
|
max-width: 300px;
|
||||||
|
padding: 0.75rem;
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
box-shadow: var(--shadow-lg);
|
||||||
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-control {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 3rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input {
|
||||||
|
opacity: 0;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-slider {
|
||||||
|
position: absolute;
|
||||||
|
cursor: pointer;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: var(--color-border);
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
left: 2px;
|
||||||
|
width: 1.25rem;
|
||||||
|
height: 1.25rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input:checked + .switch-slider {
|
||||||
|
background: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input:checked + .switch-slider .switch-button {
|
||||||
|
transform: translateX(1.5rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input:focus + .switch-slider {
|
||||||
|
box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-text {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
min-width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input:checked ~ .switch-text {
|
||||||
|
color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode adjustments */
|
||||||
|
:root.dark .switch-slider,
|
||||||
|
:root.auto.dark .switch-slider {
|
||||||
|
background: var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.dark .tooltip-content,
|
||||||
|
:root.auto.dark .tooltip-content {
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
border-color: var(--color-border);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,61 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-empty :description="$t('MANAGE_NO_DATA')" />
|
<div class="empty-page">
|
||||||
|
<div class="empty-container">
|
||||||
|
<div class="empty-icon">
|
||||||
|
<FolderOpenIcon class="icon" />
|
||||||
|
</div>
|
||||||
|
<div class="empty-content">
|
||||||
|
<h3 class="empty-title">
|
||||||
|
{{ t('pages.manage.empty.noData') }}
|
||||||
|
</h3>
|
||||||
|
<p class="empty-description">
|
||||||
|
{{ t('pages.manage.empty.noDataDesc') }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { FolderOpenIcon } from 'lucide-vue-next'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
const { t } = useI18n()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.empty-page
|
||||||
|
height 100%
|
||||||
|
display flex
|
||||||
|
align-items center
|
||||||
|
justify-content center
|
||||||
|
padding 2rem
|
||||||
|
|
||||||
|
.empty-container
|
||||||
|
display flex
|
||||||
|
flex-direction column
|
||||||
|
align-items center
|
||||||
|
text-align center
|
||||||
|
max-width 400px
|
||||||
|
|
||||||
|
.empty-icon
|
||||||
|
margin-bottom 1.5rem
|
||||||
|
|
||||||
|
.icon
|
||||||
|
width 64px
|
||||||
|
height 64px
|
||||||
|
color var(--color-text-secondary)
|
||||||
|
|
||||||
|
.empty-content
|
||||||
|
.empty-title
|
||||||
|
font-size 1.25rem
|
||||||
|
font-weight 600
|
||||||
|
color var(--color-text-primary)
|
||||||
|
margin 0 0 0.5rem 0
|
||||||
|
|
||||||
|
.empty-description
|
||||||
|
font-size 0.875rem
|
||||||
|
color var(--color-text-secondary)
|
||||||
|
margin 0
|
||||||
|
line-height 1.5
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -1,288 +1,347 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="layout">
|
<div class="manage-container">
|
||||||
<div class="layout__menu">
|
<!-- Header Card -->
|
||||||
<div class="layout__menu__button">
|
<div class="manage-card header-card">
|
||||||
<span
|
<div class="card-header">
|
||||||
class="layout__menu__button__item"
|
<div class="header-content">
|
||||||
@click="openPicBedUrl"
|
<div class="header-icon">
|
||||||
>
|
<img
|
||||||
<img
|
:src="`/assets/${currentPagePicBedConfig.picBedName}.webp`"
|
||||||
:src="`/assets/${currentPagePicBedConfig.picBedName}.webp`"
|
class="header-icon-img"
|
||||||
class="layout__menu__button__item__icon"
|
>
|
||||||
|
</div>
|
||||||
|
<div class="header-text">
|
||||||
|
<h2 class="header-title">
|
||||||
|
{{ supportedPicBedList[currentPagePicBedConfig.picBedName].name }}
|
||||||
|
</h2>
|
||||||
|
<p class="header-subtitle">
|
||||||
|
{{ menuTitleMap[currentPicBedName] }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="header-actions">
|
||||||
|
<button
|
||||||
|
class="action-button secondary"
|
||||||
|
@click="openPicBedUrl"
|
||||||
>
|
>
|
||||||
{{ supportedPicBedList[currentPagePicBedConfig.picBedName].name }}
|
<ExternalLinkIcon class="button-icon" />
|
||||||
</span>
|
{{ t('pages.manage.main.openPicBedUrl') }}
|
||||||
</div>
|
</button>
|
||||||
<el-divider
|
<button
|
||||||
content-position="left"
|
|
||||||
class="layout__menu__button__divider"
|
|
||||||
border-style="none"
|
|
||||||
>
|
|
||||||
<span style="font-size: 14px; color: #909399">
|
|
||||||
{{ menuTitleMap[currentPicBedName] }}
|
|
||||||
<el-tooltip
|
|
||||||
v-if="showNewIconList.includes(currentPicBedName)"
|
v-if="showNewIconList.includes(currentPicBedName)"
|
||||||
effect="dark"
|
class="action-button primary"
|
||||||
:content="$t('MANAGE_MAIN_PAGE_NEW_BUCKET')"
|
@click="openNewBucketDrawer"
|
||||||
placement="right"
|
|
||||||
:persistent="false"
|
|
||||||
teleported
|
|
||||||
popper-class="layout__menu__button__divider__tooltip"
|
|
||||||
>
|
>
|
||||||
<el-icon
|
<PlusIcon class="button-icon" />
|
||||||
class="layout__menu__button__divider__icon"
|
{{ t('pages.manage.main.newBucket') }}
|
||||||
color="red"
|
</button>
|
||||||
style="top: 2px"
|
</div>
|
||||||
@click="openNewBucketDrawer()"
|
</div>
|
||||||
>
|
|
||||||
<CirclePlus />
|
|
||||||
</el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</span>
|
|
||||||
</el-divider>
|
|
||||||
<div />
|
|
||||||
<el-menu
|
|
||||||
v-loading="isLoadingBucketList"
|
|
||||||
class="layout__menu__list"
|
|
||||||
:default-active="getCurrentActiveBucket"
|
|
||||||
style="width: 120px"
|
|
||||||
active-text-color="#409EFF"
|
|
||||||
@select="handleSelectMenu"
|
|
||||||
>
|
|
||||||
<el-menu-item
|
|
||||||
v-for="item of bucketNameList"
|
|
||||||
:key="item"
|
|
||||||
:index="item"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="layout__menu__list__item"
|
|
||||||
:style="{
|
|
||||||
color: item === currentSelectedBucket ? '#409EFF' : '#606266'
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
<el-icon
|
|
||||||
v-if="currentSelectedBucket === item && currentPicBedName !== 'github'"
|
|
||||||
class="layout__menu__list__item__icon"
|
|
||||||
color="#409EFF"
|
|
||||||
style="top: 2px"
|
|
||||||
>
|
|
||||||
<FolderOpened />
|
|
||||||
</el-icon>
|
|
||||||
<el-icon
|
|
||||||
v-else-if="currentPicBedName !== 'github'"
|
|
||||||
class="layout__menu__list__item__icon"
|
|
||||||
color="#606266"
|
|
||||||
style="top: 2px"
|
|
||||||
>
|
|
||||||
<Folder />
|
|
||||||
</el-icon>
|
|
||||||
{{
|
|
||||||
currentPicBedName === 'tcyun'
|
|
||||||
? item.slice(0, item.length - 11)
|
|
||||||
: currentPicBedName === 'github'
|
|
||||||
? item.length > 10
|
|
||||||
? `${item.slice(0, 5)}..${item.slice(-5)}`
|
|
||||||
: item
|
|
||||||
: item
|
|
||||||
}}
|
|
||||||
</span>
|
|
||||||
</el-menu-item>
|
|
||||||
</el-menu>
|
|
||||||
<el-menu
|
|
||||||
class="layout__menu__setting"
|
|
||||||
style="width: 120px"
|
|
||||||
>
|
|
||||||
<el-menu-item
|
|
||||||
index="changePicBed"
|
|
||||||
style="height: 40px"
|
|
||||||
@click="switchPicBed('main')"
|
|
||||||
>
|
|
||||||
<span class="layout__menu__setting__item">
|
|
||||||
<el-icon class="layout__menu__setting__item__icon">
|
|
||||||
<HomeFilled />
|
|
||||||
</el-icon>
|
|
||||||
{{ $t('MANAGE_MAIN_PAGE_BACK_TO_HOME') }}
|
|
||||||
</span>
|
|
||||||
</el-menu-item>
|
|
||||||
<el-menu-item
|
|
||||||
index="changePicBed"
|
|
||||||
style="height: 40px"
|
|
||||||
@click="changePicBed"
|
|
||||||
>
|
|
||||||
<span class="layout__menu__setting__item">
|
|
||||||
<el-icon class="layout__menu__setting__item__icon">
|
|
||||||
<Switch />
|
|
||||||
</el-icon>
|
|
||||||
{{ $t('MANAGE_MAIN_PAGE_SWITCH_PICBED') }}
|
|
||||||
</span>
|
|
||||||
</el-menu-item>
|
|
||||||
<el-menu-item
|
|
||||||
index="bucketPageSetting"
|
|
||||||
style="height: 40px"
|
|
||||||
@click="openBucketPageSetting"
|
|
||||||
>
|
|
||||||
<span class="layout__menu__setting__item">
|
|
||||||
<el-icon class="layout__menu__setting__item__icon">
|
|
||||||
<Tools />
|
|
||||||
</el-icon>
|
|
||||||
{{ $t('MANAGE_MAIN_PAGE_SETTING') }}
|
|
||||||
</span>
|
|
||||||
</el-menu-item>
|
|
||||||
</el-menu>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Main Content Card -->
|
||||||
|
<div class="manage-card main-card">
|
||||||
|
<div class="main-layout">
|
||||||
|
<div class="sidebar">
|
||||||
|
<div class="sidebar-header">
|
||||||
|
<h3 class="sidebar-title">
|
||||||
|
{{ menuTitleMap[currentPicBedName] }}
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar-content">
|
||||||
|
<div
|
||||||
|
v-if="isLoadingBucketList"
|
||||||
|
class="loading-container"
|
||||||
|
>
|
||||||
|
<div class="loading-spinner" />
|
||||||
|
<span class="loading-text">{{ t('pages.manage.main.loading') }}</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="menu-list"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="item in bucketNameList"
|
||||||
|
:key="item"
|
||||||
|
class="menu-item"
|
||||||
|
:class="{ active: item === currentSelectedBucket }"
|
||||||
|
@click="handleSelectMenu(item)"
|
||||||
|
>
|
||||||
|
<FolderIcon
|
||||||
|
v-if="currentSelectedBucket === item && currentPicBedName !== 'github'"
|
||||||
|
class="menu-icon active"
|
||||||
|
/>
|
||||||
|
<FolderIcon
|
||||||
|
v-else-if="currentPicBedName !== 'github'"
|
||||||
|
class="menu-icon"
|
||||||
|
/>
|
||||||
|
<GitBranchIcon
|
||||||
|
v-else-if="currentPicBedName === 'github'"
|
||||||
|
class="menu-icon"
|
||||||
|
/>
|
||||||
|
<span class="menu-text">
|
||||||
|
{{
|
||||||
|
currentPicBedName === 'tcyun'
|
||||||
|
? item.slice(0, item.length - 11)
|
||||||
|
: currentPicBedName === 'github'
|
||||||
|
? item.length > 10
|
||||||
|
? `${item.slice(0, 5)}..${item.slice(-5)}`
|
||||||
|
: item
|
||||||
|
: item
|
||||||
|
}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar-footer">
|
||||||
|
<div class="footer-actions">
|
||||||
|
<button
|
||||||
|
class="footer-action-item"
|
||||||
|
@click="switchPicBed('main')"
|
||||||
|
>
|
||||||
|
<HomeIcon class="action-icon" />
|
||||||
|
<span class="action-text">{{ t('pages.manage.main.backToHome') }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="footer-action-item"
|
||||||
|
@click="changePicBed"
|
||||||
|
>
|
||||||
|
<ArrowLeftRightIcon class="action-icon" />
|
||||||
|
<span class="action-text">{{ t('pages.manage.main.switchPicBed') }}</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="footer-action-item"
|
||||||
|
@click="openBucketPageSetting"
|
||||||
|
>
|
||||||
|
<SettingsIcon class="action-icon" />
|
||||||
|
<span class="action-text">{{ t('pages.manage.main.settings') }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content-area">
|
||||||
|
<router-view />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- PicBed Switch Dialog -->
|
||||||
<div
|
<div
|
||||||
class="layout__content"
|
v-if="picBedSwitchDialogVisible"
|
||||||
style="height: 100%; background-color: transparent; flex: 1; width: 0"
|
class="dialog-overlay"
|
||||||
>
|
@click="picBedSwitchDialogVisible = false"
|
||||||
<router-view />
|
|
||||||
</div>
|
|
||||||
<el-dialog
|
|
||||||
v-model="picBedSwitchDialogVisible"
|
|
||||||
top="30vh"
|
|
||||||
append-to-body
|
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="choice-cos"
|
class="dialog-container"
|
||||||
style="display: flex; flex-direction: row; flex-wrap: wrap; justify-content: space-around"
|
@click.stop
|
||||||
>
|
>
|
||||||
<el-card shadow="hover">
|
<div class="dialog-header">
|
||||||
<div
|
<h3 class="dialog-title">
|
||||||
style="text-align: center; display: flex; flex-direction: column"
|
{{ t('pages.manage.main.switchPicBed') }}
|
||||||
@click="switchPicBed('main')"
|
</h3>
|
||||||
|
<button
|
||||||
|
class="dialog-close"
|
||||||
|
@click="picBedSwitchDialogVisible = false"
|
||||||
>
|
>
|
||||||
<el-icon
|
<XIcon class="close-icon" />
|
||||||
color="red"
|
</button>
|
||||||
size="25px"
|
</div>
|
||||||
style="margin: 0 auto"
|
<div class="dialog-content">
|
||||||
|
<div class="choice-cos">
|
||||||
|
<!-- Back to main card -->
|
||||||
|
<div
|
||||||
|
class="picbed-card main-card"
|
||||||
|
@click="switchPicBed('main')"
|
||||||
>
|
>
|
||||||
<ChromeFilled />
|
<div class="card-icon">
|
||||||
</el-icon>
|
<HomeIcon class="main-icon" />
|
||||||
<span style="font-size: 13px; margin-top: 5px; color: red">
|
</div>
|
||||||
{{ $t('MANAGE_MAIN_PAGE_BACK_TO_HOME') }}
|
<div class="card-content">
|
||||||
</span>
|
<div class="card-title main-title">
|
||||||
|
{{ $t('pages.manage.main.backToHome') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- PicBed cards -->
|
||||||
|
<div
|
||||||
|
v-for="(config, alias) in allPicBedConfigure"
|
||||||
|
:key="String(alias)"
|
||||||
|
class="picbed-card"
|
||||||
|
:class="{ active: String(alias) === currentAlias }"
|
||||||
|
@click="switchPicBed(String(alias))"
|
||||||
|
>
|
||||||
|
<div class="card-icon">
|
||||||
|
<img
|
||||||
|
:src="`/assets/${config.picBedName}.webp`"
|
||||||
|
class="picbed-icon"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="card-title">
|
||||||
|
{{ config.alias }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="String(alias) === currentAlias"
|
||||||
|
class="check-icon"
|
||||||
|
>
|
||||||
|
<CheckIcon />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</div>
|
||||||
<el-card
|
|
||||||
v-for="item in allPicBedConfigure"
|
|
||||||
:key="item"
|
|
||||||
shadow="hover"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style="text-align: center; display: flex; flex-direction: column"
|
|
||||||
@click="switchPicBed(item.alias)"
|
|
||||||
>
|
|
||||||
<el-image
|
|
||||||
:src="`/assets/${item.picBedName}.webp`"
|
|
||||||
class="layout__addNewBucket__icon"
|
|
||||||
style="width: 25px; height: 25px; margin: 0 auto"
|
|
||||||
/>
|
|
||||||
<span style="font-size: 13px; margin-top: 5px; color: cornflowerblue">
|
|
||||||
{{ item.alias }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</div>
|
||||||
<el-drawer
|
|
||||||
v-model="nweBucketDrawerVisible"
|
<!-- New Bucket Drawer -->
|
||||||
class="layout__addNewBucket"
|
<div
|
||||||
append-to-body
|
v-if="nweBucketDrawerVisible"
|
||||||
|
class="drawer-overlay"
|
||||||
|
@click="nweBucketDrawerVisible = false"
|
||||||
>
|
>
|
||||||
<el-form
|
<div
|
||||||
label-position="top"
|
class="drawer-container"
|
||||||
require-asterisk-position="right"
|
@click.stop
|
||||||
label-width="10vw"
|
|
||||||
size="default"
|
|
||||||
:model="newBucketConfigResult"
|
|
||||||
:rules="rules"
|
|
||||||
>
|
>
|
||||||
<div style="position: relative; height: 10vh; width: 100%">
|
<div class="drawer-header">
|
||||||
<el-image
|
<h3 class="drawer-title">
|
||||||
:src="`/assets/${currentPicBedName}.webp`"
|
{{ t('pages.manage.main.newBucket') }}
|
||||||
class="layout__addNewBucket__icon"
|
</h3>
|
||||||
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)"
|
<button
|
||||||
/>
|
class="drawer-close"
|
||||||
|
@click="nweBucketDrawerVisible = false"
|
||||||
|
>
|
||||||
|
<XIcon class="close-icon" />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<el-divider border-style="none" />
|
<div class="drawer-content">
|
||||||
<el-form-item
|
<form @submit.prevent="createNewBucket(currentPicBedName)">
|
||||||
v-for="option in newBucketConfig[currentPicBedName].options"
|
<div class="form-header">
|
||||||
:key="option"
|
<div class="form-icon">
|
||||||
:prop="currentPicBedName + '.' + option"
|
<img
|
||||||
:label="newBucketConfig[currentPicBedName].configOptions[option].description"
|
:src="`/assets/${currentPicBedName}.webp`"
|
||||||
>
|
class="picbed-form-icon"
|
||||||
<el-input
|
>
|
||||||
v-if="
|
</div>
|
||||||
newBucketConfig[currentPicBedName].configOptions[option].component === 'input' &&
|
</div>
|
||||||
currentPicBedName !== 'tcyun'
|
|
||||||
"
|
<div class="form-divider" />
|
||||||
v-model.trim="newBucketConfigResult[currentPicBedName + '.' + option]"
|
|
||||||
:placeholder="newBucketConfig[currentPicBedName].configOptions[option].placeholder"
|
<div
|
||||||
/>
|
v-for="option in newBucketConfig[currentPicBedName].options"
|
||||||
<el-input
|
:key="option"
|
||||||
v-if="
|
class="form-group"
|
||||||
currentPicBedName === 'tcyun' &&
|
>
|
||||||
newBucketConfig[currentPicBedName].configOptions[option].component === 'input'
|
<label class="form-label">
|
||||||
"
|
{{ newBucketConfig[currentPicBedName].configOptions[option].description }}
|
||||||
v-model.trim="newBucketConfigResult[currentPicBedName + '.' + option]"
|
</label>
|
||||||
:placeholder="newBucketConfig[currentPicBedName].configOptions[option].placeholder"
|
|
||||||
>
|
<!-- Input field -->
|
||||||
<template #append>
|
<input
|
||||||
{{ '-' + currentPagePicBedConfig.appId }}
|
v-if="newBucketConfig[currentPicBedName].configOptions[option].component === 'input' && currentPicBedName !== 'tcyun'"
|
||||||
</template>
|
v-model.trim="newBucketConfigResult[currentPicBedName + '.' + option]"
|
||||||
</el-input>
|
type="text"
|
||||||
<el-select
|
class="form-input"
|
||||||
v-if="newBucketConfig[currentPicBedName].configOptions[option].component === 'select'"
|
:placeholder="newBucketConfig[currentPicBedName].configOptions[option].placeholder"
|
||||||
v-model="newBucketConfigResult[currentPicBedName + '.' + option]"
|
>
|
||||||
size="large"
|
|
||||||
:persistent="false"
|
<!-- TCyun special input with append -->
|
||||||
teleported
|
<div
|
||||||
>
|
v-if="currentPicBedName === 'tcyun' && newBucketConfig[currentPicBedName].configOptions[option].component === 'input'"
|
||||||
<el-option
|
class="input-group"
|
||||||
v-for="item in Object.keys(newBucketConfig[currentPicBedName].configOptions[option].options)"
|
>
|
||||||
:key="item"
|
<input
|
||||||
:label="newBucketConfig[currentPicBedName].configOptions[option].options[item]"
|
v-model.trim="newBucketConfigResult[currentPicBedName + '.' + option]"
|
||||||
:value="item"
|
type="text"
|
||||||
/>
|
class="form-input group-input"
|
||||||
</el-select>
|
:placeholder="newBucketConfig[currentPicBedName].configOptions[option].placeholder"
|
||||||
<el-switch
|
>
|
||||||
v-if="newBucketConfig[currentPicBedName].configOptions[option].component === 'switch'"
|
<span class="input-append">{{ '-' + currentPagePicBedConfig.appId }}</span>
|
||||||
v-model="newBucketConfigResult[currentPicBedName + '.' + option]"
|
</div>
|
||||||
:active-value="true"
|
|
||||||
:inactive-value="false"
|
<!-- Select field -->
|
||||||
/>
|
<div
|
||||||
</el-form-item>
|
v-if="newBucketConfig[currentPicBedName].configOptions[option].component === 'select'"
|
||||||
<div style="position: relative; height: 10vh; width: 100%; z-index: 1">
|
class="select-wrapper"
|
||||||
<el-button
|
>
|
||||||
:icon="SuccessFilled"
|
<select
|
||||||
type="primary"
|
v-model="newBucketConfigResult[currentPicBedName + '.' + option]"
|
||||||
style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%)"
|
class="form-select"
|
||||||
@click="createNewBucket(currentPicBedName)"
|
>
|
||||||
>
|
<option
|
||||||
{{ $t('MANAGE_MAIN_PAGE_SUBMIT') }}
|
v-for="(label, value) in newBucketConfig[currentPicBedName].configOptions[option].options"
|
||||||
</el-button>
|
:key="value"
|
||||||
|
:value="value"
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<ChevronDownIcon class="select-arrow" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Switch field -->
|
||||||
|
<label
|
||||||
|
v-if="newBucketConfig[currentPicBedName].configOptions[option].component === 'switch'"
|
||||||
|
class="switch-label"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
v-model="newBucketConfigResult[currentPicBedName + '.' + option]"
|
||||||
|
type="checkbox"
|
||||||
|
class="switch-input"
|
||||||
|
:true-value="true"
|
||||||
|
:false-value="false"
|
||||||
|
>
|
||||||
|
<span class="switch-slider">
|
||||||
|
<span class="switch-button" />
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-actions">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="action-button secondary"
|
||||||
|
@click="nweBucketDrawerVisible = false"
|
||||||
|
>
|
||||||
|
{{ $t('common.cancel') }}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="action-button primary"
|
||||||
|
>
|
||||||
|
<CheckIcon class="button-icon" />
|
||||||
|
{{ t('common.submit') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</div>
|
||||||
</el-drawer>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ChromeFilled,
|
ArrowLeftRightIcon,
|
||||||
CirclePlus,
|
CheckIcon,
|
||||||
Folder,
|
ChevronDownIcon,
|
||||||
FolderOpened,
|
ExternalLinkIcon,
|
||||||
HomeFilled,
|
FolderIcon,
|
||||||
SuccessFilled,
|
GitBranchIcon,
|
||||||
Switch,
|
HomeIcon,
|
||||||
Tools
|
PlusIcon,
|
||||||
} from '@element-plus/icons-vue'
|
SettingsIcon,
|
||||||
import { ElNotification } from 'element-plus'
|
XIcon
|
||||||
import { computed, onBeforeMount, reactive, ref, watch } from 'vue'
|
} from 'lucide-vue-next'
|
||||||
|
import { onBeforeMount, reactive, ref, watch } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
|
|
||||||
|
import useMessage from '@/hooks/useMessage'
|
||||||
import { useManageStore } from '@/manage/store/manageStore'
|
import { useManageStore } from '@/manage/store/manageStore'
|
||||||
import { supportedPicBedList } from '@/manage/utils/constants'
|
import { supportedPicBedList } from '@/manage/utils/constants'
|
||||||
import { newBucketConfig } from '@/manage/utils/newBucketConfig'
|
import { newBucketConfig } from '@/manage/utils/newBucketConfig'
|
||||||
@@ -293,6 +352,7 @@ const { t } = useI18n()
|
|||||||
const manageStore = useManageStore() as any
|
const manageStore = useManageStore() as any
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const message = useMessage()
|
||||||
|
|
||||||
const currentAlias = ref(route.query.alias as string)
|
const currentAlias = ref(route.query.alias as string)
|
||||||
const currentPicBedName = ref(route.query.picBedName as string)
|
const currentPicBedName = ref(route.query.picBedName as string)
|
||||||
@@ -309,17 +369,16 @@ const isLoadingBucketList = ref(false)
|
|||||||
const nweBucketDrawerVisible = ref(false)
|
const nweBucketDrawerVisible = ref(false)
|
||||||
const picBedSwitchDialogVisible = ref(false)
|
const picBedSwitchDialogVisible = ref(false)
|
||||||
|
|
||||||
watch(route, async newRoute => {
|
watch(route, async (newRoute) => {
|
||||||
if (newRoute.fullPath.split('?')[0] === '/main-page/manage-main-page') {
|
if (newRoute.fullPath.split('?')[0] === '/main-page/manage-main-page') {
|
||||||
|
console.log('route changed')
|
||||||
currentAlias.value = newRoute.query.alias as string
|
currentAlias.value = newRoute.query.alias as string
|
||||||
currentPicBedName.value = newRoute.query.picBedName as string
|
currentPicBedName.value = newRoute.query.picBedName as string
|
||||||
allPicBedConfigure = JSON.parse(newRoute.query.allPicBedConfigure as string)
|
allPicBedConfigure = JSON.parse(newRoute.query.allPicBedConfigure as string)
|
||||||
currentPagePicBedConfig = reactive(JSON.parse(newRoute.query.config as string))
|
currentPagePicBedConfig = reactive(JSON.parse(newRoute.query.config as string))
|
||||||
await getBucketList()
|
await getBucketList()
|
||||||
}
|
}
|
||||||
})
|
}, { deep: true })
|
||||||
|
|
||||||
const getCurrentActiveBucket = computed(() => (bucketNameList.value.length === 0 ? '' : bucketNameList.value[0]))
|
|
||||||
|
|
||||||
const urlMap: IStringKeyMap = {
|
const urlMap: IStringKeyMap = {
|
||||||
aliyun: 'https://oss.console.aliyun.com',
|
aliyun: 'https://oss.console.aliyun.com',
|
||||||
@@ -337,9 +396,9 @@ const urlMap: IStringKeyMap = {
|
|||||||
|
|
||||||
const showNewIconList = ['aliyun', 'qiniu', 'tcyun', 's3plist']
|
const showNewIconList = ['aliyun', 'qiniu', 'tcyun', 's3plist']
|
||||||
|
|
||||||
const bucketT = t('MANAGE_MAIN_PAGE_BUCKET')
|
const bucketT = t('pages.manage.main.bucket')
|
||||||
const galleryT = t('MANAGE_MAIN_PAGE_GALLERY')
|
const galleryT = t('pages.manage.main.gallery')
|
||||||
const repositoryT = t('MANAGE_MAIN_PAGE_REPOSITORY')
|
const repositoryT = t('pages.manage.main.repo')
|
||||||
|
|
||||||
const menuTitleMap: IStringKeyMap = {
|
const menuTitleMap: IStringKeyMap = {
|
||||||
aliyun: bucketT,
|
aliyun: bucketT,
|
||||||
@@ -355,26 +414,8 @@ const menuTitleMap: IStringKeyMap = {
|
|||||||
local: ''
|
local: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const rules = ruleMap(newBucketConfig)
|
|
||||||
|
|
||||||
const openPicBedUrl = () => window.electron.sendRPC(IRPCActionType.OPEN_URL, urlMap[currentPagePicBedConfig.picBedName])
|
const openPicBedUrl = () => window.electron.sendRPC(IRPCActionType.OPEN_URL, urlMap[currentPagePicBedConfig.picBedName])
|
||||||
|
|
||||||
function ruleMap (options: IStringKeyMap) {
|
|
||||||
return Object.keys(options).reduce((result, key) => {
|
|
||||||
options[key].options.forEach((option: string) => {
|
|
||||||
const keyName = `${key}.${option}`
|
|
||||||
const configOption = options[key].configOptions[option]
|
|
||||||
if (configOption.rule) {
|
|
||||||
result[keyName] = configOption.rule
|
|
||||||
}
|
|
||||||
if (configOption.default) {
|
|
||||||
newBucketConfigResult[keyName] = configOption.default
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return result
|
|
||||||
}, {} as IStringKeyMap)
|
|
||||||
}
|
|
||||||
|
|
||||||
function openNewBucketDrawer () {
|
function openNewBucketDrawer () {
|
||||||
nweBucketDrawerVisible.value = true
|
nweBucketDrawerVisible.value = true
|
||||||
}
|
}
|
||||||
@@ -390,7 +431,7 @@ function createNewBucket (picBedName: string) {
|
|||||||
resultValue === '' && defaultValue !== undefined
|
resultValue === '' && defaultValue !== undefined
|
||||||
? defaultValue
|
? defaultValue
|
||||||
: resultValue === undefined
|
: resultValue === undefined
|
||||||
? defaultValue ?? ''
|
? ''
|
||||||
: resultValue
|
: resultValue
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -399,23 +440,17 @@ function createNewBucket (picBedName: string) {
|
|||||||
resultMap.BucketName = `${resultMap.BucketName}-${currentPagePicBedConfig.appId}`
|
resultMap.BucketName = `${resultMap.BucketName}-${currentPagePicBedConfig.appId}`
|
||||||
}
|
}
|
||||||
resultMap.endpoint = currentPagePicBedConfig.endpoint
|
resultMap.endpoint = currentPagePicBedConfig.endpoint
|
||||||
window.electron.triggerRPC(IRPCActionType.MANAGE_CREATE_BUCKET, currentAlias, resultMap).then((result: any) => {
|
window.electron.triggerRPC(IRPCActionType.MANAGE_CREATE_BUCKET, currentAlias.value, resultMap).then((result: any) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
ElNotification({
|
// Show success notification
|
||||||
title: t('MANAGE_MAIN_PAGE_TIPS'),
|
message.success(t('pages.manage.main.createSuccess'))
|
||||||
message: t('MANAGE_MAIN_PAGE_TIPS_SUCCESS'),
|
|
||||||
type: 'success'
|
|
||||||
})
|
|
||||||
nweBucketDrawerVisible.value = false
|
nweBucketDrawerVisible.value = false
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
getBucketList()
|
getBucketList()
|
||||||
}, 2000)
|
}, 2000)
|
||||||
} else {
|
} else {
|
||||||
ElNotification({
|
// Show error notification
|
||||||
title: t('MANAGE_MAIN_PAGE_TIPS'),
|
message.error(t('pages.manage.main.createFailed'))
|
||||||
message: t('MANAGE_MAIN_PAGE_TIPS_FAILED'),
|
|
||||||
type: 'error'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -427,7 +462,6 @@ async function getBucketList () {
|
|||||||
|
|
||||||
const result = await window.electron.triggerRPC<any>(IRPCActionType.MANAGE_GET_BUCKET_LIST, currentAlias.value)
|
const result = await window.electron.triggerRPC<any>(IRPCActionType.MANAGE_GET_BUCKET_LIST, currentAlias.value)
|
||||||
isLoadingBucketList.value = false
|
isLoadingBucketList.value = false
|
||||||
|
|
||||||
if (result.length > 0) {
|
if (result.length > 0) {
|
||||||
result.forEach((item: any) => {
|
result.forEach((item: any) => {
|
||||||
bucketList.value[item.Name] = item
|
bucketList.value[item.Name] = item
|
||||||
@@ -474,7 +508,11 @@ function handleSelectMenu (bucketName: string) {
|
|||||||
router.push({
|
router.push({
|
||||||
path: '/main-page/manage-main-page/manage-bucket-page',
|
path: '/main-page/manage-main-page/manage-bucket-page',
|
||||||
query: {
|
query: {
|
||||||
configMap: JSON.stringify(configMap)
|
configMap: JSON.stringify(configMap),
|
||||||
|
alias: currentAlias.value,
|
||||||
|
picBedName: currentPicBedName.value,
|
||||||
|
config: JSON.stringify(currentPagePicBedConfig),
|
||||||
|
allPicBedConfigure: JSON.stringify(allPicBedConfigure)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -515,8 +553,15 @@ function changePicBed () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function openBucketPageSetting () {
|
function openBucketPageSetting () {
|
||||||
|
console.log('Open Bucket Page Setting')
|
||||||
router.push({
|
router.push({
|
||||||
path: '/main-page/manage-main-page/manage-setting-page'
|
path: '/main-page/manage-main-page/manage-setting-page',
|
||||||
|
query: {
|
||||||
|
alias: currentAlias.value,
|
||||||
|
picBedName: currentPicBedName.value,
|
||||||
|
config: JSON.stringify(currentPagePicBedConfig),
|
||||||
|
allPicBedConfigure: JSON.stringify(allPicBedConfigure)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,74 +570,4 @@ onBeforeMount(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus">
|
<style src="./css/ManageMain.css" scoped></style>
|
||||||
.layout
|
|
||||||
height 100%
|
|
||||||
display flex
|
|
||||||
flex-direction row
|
|
||||||
&__menu
|
|
||||||
background: #fff
|
|
||||||
color: #fff
|
|
||||||
display: flex
|
|
||||||
flex-direction: column
|
|
||||||
border-bottom-right-radius: 4px
|
|
||||||
z-index 1
|
|
||||||
width: 130px
|
|
||||||
position: relative
|
|
||||||
&__button
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: left;
|
|
||||||
padding-left: 0px;
|
|
||||||
padding-top: 10px;
|
|
||||||
&__item
|
|
||||||
color:#2d8cf0
|
|
||||||
width: 100%
|
|
||||||
height: 100%
|
|
||||||
display: flex
|
|
||||||
align-items: center
|
|
||||||
justify-content: center
|
|
||||||
&:hover
|
|
||||||
cursor: pointer
|
|
||||||
color: orange
|
|
||||||
&__icon
|
|
||||||
width: 25px
|
|
||||||
height: 25px
|
|
||||||
&__divider
|
|
||||||
&__icon
|
|
||||||
&:hover
|
|
||||||
cursor: pointer
|
|
||||||
color: orange
|
|
||||||
&__list
|
|
||||||
flex: 1
|
|
||||||
overflow-y: auto
|
|
||||||
&__item
|
|
||||||
width: 100%
|
|
||||||
height: 100%
|
|
||||||
display: flex
|
|
||||||
color: #2d8cf0
|
|
||||||
align-items: center
|
|
||||||
justify-content: center
|
|
||||||
&:hover
|
|
||||||
cursor: pointer
|
|
||||||
color: orange
|
|
||||||
&__icon
|
|
||||||
width: 25px
|
|
||||||
height: 25px
|
|
||||||
&__setting
|
|
||||||
position relative
|
|
||||||
overflow hidden
|
|
||||||
&__item
|
|
||||||
width: 100%
|
|
||||||
display: flex
|
|
||||||
align-items: center
|
|
||||||
color: #000
|
|
||||||
justify-content: center
|
|
||||||
font-size: 12px
|
|
||||||
font-family: Arial, Helvetica, sans-serif
|
|
||||||
&:hover
|
|
||||||
cursor: pointer
|
|
||||||
color: orange
|
|
||||||
&__icon
|
|
||||||
width: 25px
|
|
||||||
height: 25px
|
|
||||||
</style>
|
|
||||||
|
|||||||
@@ -1,234 +1,253 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="manage-setting">
|
<div class="manage-setting-container">
|
||||||
<el-row
|
<!-- Cache Info Card -->
|
||||||
class="view-title"
|
<div class="setting-card content-card">
|
||||||
align="middle"
|
<div class="card-content">
|
||||||
justify="center"
|
<div class="setting-section">
|
||||||
style="font-size: 20px; color: black"
|
<div class="form-group">
|
||||||
>
|
<div class="form-control">
|
||||||
{{ $t('MANAGE_SETTING_TITLE') }}
|
<button
|
||||||
</el-row>
|
type="button"
|
||||||
<el-row class="setting-list">
|
class="action-button warning"
|
||||||
<el-col
|
@click="handleConfirmClearDb"
|
||||||
:span="20"
|
|
||||||
:offset="2"
|
|
||||||
>
|
|
||||||
<el-row style="width: 100%">
|
|
||||||
<el-form
|
|
||||||
label-position="left"
|
|
||||||
label-width="50%"
|
|
||||||
size="default"
|
|
||||||
style="position: relative; width: 100%"
|
|
||||||
>
|
|
||||||
<el-form-item>
|
|
||||||
<template #label>
|
|
||||||
<span style="position: absolute; left: 0">
|
|
||||||
<span>{{ $t('MANAGE_SETTING_CLEAR_CACHE_TITLE') }} </span>
|
|
||||||
<span style="color: #ff4949">{{ formatFileSize(dbSize) === '' ? 0 : formatFileSize(dbSize) }} </span>
|
|
||||||
<span> {{ $t('MANAGE_SETTING_CLEAR_CACHE_FREE_TITLE') }} </span>
|
|
||||||
<span style="color: #ff4949">{{ dbSizeAvailableRate }} %</span>
|
|
||||||
<el-tooltip
|
|
||||||
effect="dark"
|
|
||||||
:content="$t('MANAGE_SETTING_CLEAR_CACHE_TIPS')"
|
|
||||||
placement="right"
|
|
||||||
:persistent="false"
|
|
||||||
teleported
|
|
||||||
>
|
|
||||||
<el-icon>
|
|
||||||
<InfoFilled />
|
|
||||||
</el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<el-popconfirm
|
|
||||||
:title="$t('MANAGE_SETTING_CLEAR_CACHE_PROMPT')"
|
|
||||||
:confirm-button-text="$t('CONFIRM')"
|
|
||||||
:cancel-button-text="$t('CANCEL')"
|
|
||||||
hide-icon
|
|
||||||
:persistent="false"
|
|
||||||
teleported
|
|
||||||
@confirm="handleClearDb"
|
|
||||||
>
|
>
|
||||||
<template #reference>
|
<Trash2Icon :size="16" />
|
||||||
<el-button
|
{{ t('pages.manage.setting.clearCache', { percent: dbSizeAvailableRate, size: formatFileSize(dbSize) || 0 }) }}
|
||||||
type="primary"
|
</button>
|
||||||
plain
|
|
||||||
style="position: absolute; right: 0"
|
|
||||||
>
|
|
||||||
{{ $t('MANAGE_SETTING_CLEAR_CACHE_BUTTON') }}
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-popconfirm>
|
|
||||||
</el-form-item>
|
|
||||||
<DynamicSwitch
|
|
||||||
v-for="item in switchFieldsConfigList"
|
|
||||||
:key="item.configName"
|
|
||||||
v-model="form[item.configName]"
|
|
||||||
:segments="item.segments"
|
|
||||||
:tooltip="item.tooltip"
|
|
||||||
:config-name="item.configName"
|
|
||||||
:active-text="item.activeText"
|
|
||||||
:inactive-text="item.inactiveText"
|
|
||||||
/>
|
|
||||||
<el-link
|
|
||||||
v-if="form.customRename"
|
|
||||||
style="margin-top: 10px; margin-bottom: 10px; color: #409eff"
|
|
||||||
:underline="false"
|
|
||||||
>
|
|
||||||
{{ $t('MANAGE_SETTING_CUSTOM_PATTERN_TITLE') }}
|
|
||||||
</el-link>
|
|
||||||
<el-input
|
|
||||||
v-if="form.customRename"
|
|
||||||
v-model="form.customRenameFormat"
|
|
||||||
:placeholder="$t('MANAGE_SETTING_CUSTOM_PATTERN_TIPS')"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
<el-table
|
|
||||||
v-if="form.customRename"
|
|
||||||
:data="customRenameFormatTable"
|
|
||||||
style="width: 100%; margin-top: 10px; margin-left: 10%"
|
|
||||||
:header-cell-style="{ 'text-align': 'center' }"
|
|
||||||
:cell-style="{ 'text-align': 'center' }"
|
|
||||||
@cell-click="handleCellClick"
|
|
||||||
>
|
|
||||||
<el-table-column
|
|
||||||
v-for="prop in ['placeholder', 'description', 'placeholderB', 'descriptionB']"
|
|
||||||
:key="prop"
|
|
||||||
:prop="prop"
|
|
||||||
:label="$t('MANAGE_SETTING_CUSTOM_PATTERN_TABLE_TITLE' as any)"
|
|
||||||
width="150"
|
|
||||||
/>
|
|
||||||
</el-table>
|
|
||||||
<br v-if="form.customRename">
|
|
||||||
<DynamicSwitch
|
|
||||||
v-for="item in switchFieldsSpecialList"
|
|
||||||
:key="item.configName"
|
|
||||||
v-model="form[item.configName]"
|
|
||||||
:segments="item.segments"
|
|
||||||
:tooltip="item.tooltip"
|
|
||||||
:config-name="item.configName"
|
|
||||||
/>
|
|
||||||
<el-form-item>
|
|
||||||
<template #label>
|
|
||||||
<span style="position: absolute; left: 0">
|
|
||||||
{{ $t('MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_TITLE') }}
|
|
||||||
<el-tooltip
|
|
||||||
effect="dark"
|
|
||||||
:content="$t('MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_TIPS')"
|
|
||||||
placement="right"
|
|
||||||
:persistent="false"
|
|
||||||
teleported
|
|
||||||
>
|
|
||||||
<el-icon>
|
|
||||||
<InfoFilled />
|
|
||||||
</el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<el-input-number
|
|
||||||
v-model="form.maxDownloadFileCount"
|
|
||||||
style="position: absolute; right: 0"
|
|
||||||
:placeholder="$t('MANAGE_SETTING_MAX_DOWNLOAD_FILE_SIZE_INPUT_TIPS')"
|
|
||||||
:min="1"
|
|
||||||
:max="9999"
|
|
||||||
:step="1"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<template #label>
|
|
||||||
<span style="position: absolute; left: 0">
|
|
||||||
{{ $t('MANAGE_SETTING_PRESIGNED_URL_EXPIRE_TITLE') }}
|
|
||||||
<el-tooltip
|
|
||||||
effect="dark"
|
|
||||||
:content="$t('MANAGE_SETTING_PRESIGNED_URL_EXPIRE_TIPS')"
|
|
||||||
placement="right"
|
|
||||||
:persistent="false"
|
|
||||||
teleported
|
|
||||||
>
|
|
||||||
<el-icon>
|
|
||||||
<InfoFilled />
|
|
||||||
</el-icon>
|
|
||||||
</el-tooltip>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<el-input-number
|
|
||||||
v-model="form.PreSignedExpire"
|
|
||||||
style="position: absolute; right: 0"
|
|
||||||
:placeholder="$t('MANAGE_SETTING_PRESIGNED_URL_EXPIRE_TIPS')"
|
|
||||||
:min="1"
|
|
||||||
:step="1"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-link
|
|
||||||
style="margin-top: 10px; margin-bottom: 10px; color: #409eff"
|
|
||||||
:underline="false"
|
|
||||||
>
|
|
||||||
{{ $t('MANAGE_SETTING_CHOOSE_COPY_FORMAT_TITLE') }}
|
|
||||||
</el-link>
|
|
||||||
<br>
|
|
||||||
<el-radio-group v-model="form.pasteFormat">
|
|
||||||
<el-radio
|
|
||||||
v-for="item in pasteFormatList"
|
|
||||||
:key="item"
|
|
||||||
:value="item"
|
|
||||||
>
|
|
||||||
{{ $t(`MANAGE_SETTING_CHOOSE_COPY_FORMAT_${item.toUpperCase().replace(/-/g, '_')}` as any) }}
|
|
||||||
</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
<el-link
|
|
||||||
v-if="form.pasteFormat === 'custom'"
|
|
||||||
style="margin-top: 10px; margin-bottom: 10px; color: #409eff"
|
|
||||||
:underline="false"
|
|
||||||
>
|
|
||||||
{{ $t('MANAGE_SETTING_CUSTOM_COPY_FORMAT_TITLE') }}
|
|
||||||
</el-link>
|
|
||||||
<el-input
|
|
||||||
v-if="form.pasteFormat === 'custom'"
|
|
||||||
v-model="form.customPasteFormat"
|
|
||||||
:placeholder="$t('MANAGE_SETTING_CUSTOM_COPY_FORMAT_TIPS')"
|
|
||||||
style="width: 100%"
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
<el-link
|
|
||||||
style="margin-top: 10px; margin-bottom: 10px; color: #409eff"
|
|
||||||
:underline="false"
|
|
||||||
>
|
|
||||||
{{ $t('MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_TITLE') }}
|
|
||||||
</el-link>
|
|
||||||
</div>
|
</div>
|
||||||
<el-input
|
</div>
|
||||||
v-model="form.downloadDir"
|
</div>
|
||||||
disabled
|
</div>
|
||||||
:placeholder="$t('MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_TIPS')"
|
</div>
|
||||||
style="width: 100%; margin-top: 10px"
|
|
||||||
|
<!-- General Settings Card -->
|
||||||
|
<div class="setting-card content-card">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="setting-section">
|
||||||
|
<CustomSwitch
|
||||||
|
v-for="item in switchFieldsConfigList"
|
||||||
|
:key="item.configName"
|
||||||
|
v-model="form[item.configName]"
|
||||||
|
:segments="item.segments"
|
||||||
|
:tooltip="item.tooltip"
|
||||||
|
:active-text="item.activeText"
|
||||||
|
:inactive-text="item.inactiveText"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Custom Rename Pattern Card -->
|
||||||
|
<div
|
||||||
|
v-if="form.customRename"
|
||||||
|
class="setting-card content-card"
|
||||||
|
>
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="setting-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<h4 class="section-title">
|
||||||
|
{{ t('pages.manage.setting.customRenameTableTitle') }}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<input
|
||||||
|
v-model="form.customRenameFormat"
|
||||||
|
type="text"
|
||||||
|
class="form-input"
|
||||||
|
:placeholder="t('pages.manage.setting.customRenameTablePlaceholder')"
|
||||||
>
|
>
|
||||||
<template #append>
|
</div>
|
||||||
<el-button
|
|
||||||
type="primary"
|
<!-- Pattern Reference Table -->
|
||||||
@click="handleDownloadDirClick"
|
<div class="pattern-table-container">
|
||||||
|
<table class="pattern-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>{{ t('pages.manage.setting.placeholder') }}</th>
|
||||||
|
<th>{{ t('pages.manage.setting.description') }}</th>
|
||||||
|
<th>{{ t('pages.manage.setting.placeholder') }}</th>
|
||||||
|
<th>{{ t('pages.manage.setting.description') }}</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr
|
||||||
|
v-for="(row, index) in customRenameFormatTable"
|
||||||
|
:key="index"
|
||||||
>
|
>
|
||||||
<el-icon>
|
<td
|
||||||
<Folder />
|
class="clickable"
|
||||||
</el-icon>
|
@click="handleCellClick(row, { property: 'placeholder' })"
|
||||||
{{ $t('MANAGE_SETTING_CHOOSE_DOWNLOAD_FOLDER_BUTTON') }}
|
>
|
||||||
</el-button>
|
{{ row.placeholder }}
|
||||||
</template>
|
</td>
|
||||||
</el-input>
|
<td>{{ row.description }}</td>
|
||||||
</el-form>
|
<td
|
||||||
<el-divider border-style="none" />
|
class="clickable"
|
||||||
</el-row>
|
@click="handleCellClick(row, { property: 'placeholderB' })"
|
||||||
</el-col>
|
>
|
||||||
</el-row>
|
{{ row.placeholderB }}
|
||||||
|
</td>
|
||||||
|
<td>{{ row.descriptionB }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Special Settings Card -->
|
||||||
|
<div class="setting-card content-card">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="setting-section">
|
||||||
|
<!-- Special Switch Fields -->
|
||||||
|
<CustomSwitch
|
||||||
|
v-for="item in switchFieldsSpecialList"
|
||||||
|
:key="item.configName"
|
||||||
|
v-model="form[item.configName]"
|
||||||
|
:segments="item.segments"
|
||||||
|
:tooltip="item.tooltip"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Download Settings Card -->
|
||||||
|
<div class="setting-card content-card">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="setting-section">
|
||||||
|
<!-- Max Download File Count -->
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="form-label-wrapper">
|
||||||
|
<span class="form-label">
|
||||||
|
{{ t('pages.manage.setting.maxDownLoadFileLimit') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="form-control">
|
||||||
|
<input
|
||||||
|
v-model.number="form.maxDownloadFileCount"
|
||||||
|
type="number"
|
||||||
|
class="form-input number-input"
|
||||||
|
:placeholder="t('pages.manage.setting.maxDownLoadFileLimitDesc')"
|
||||||
|
min="1"
|
||||||
|
max="9999"
|
||||||
|
step="1"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- PreSigned URL Expire -->
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="form-label-wrapper">
|
||||||
|
<span class="form-label">
|
||||||
|
{{ t('pages.manage.setting.preSignedUrlExpire') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="form-control">
|
||||||
|
<input
|
||||||
|
v-model.number="form.PreSignedExpire"
|
||||||
|
type="number"
|
||||||
|
class="form-input number-input"
|
||||||
|
:placeholder="t('pages.manage.setting.preSignedUrlExpireDesc')"
|
||||||
|
min="1"
|
||||||
|
step="1"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Copy Format Card -->
|
||||||
|
<div class="setting-card content-card">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="setting-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<h4 class="section-title">
|
||||||
|
{{ t('pages.manage.setting.copyFormat.title') }}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div class="radio-group">
|
||||||
|
<label
|
||||||
|
v-for="item in pasteFormatList"
|
||||||
|
:key="item"
|
||||||
|
class="radio-option"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
v-model="form.pasteFormat"
|
||||||
|
type="radio"
|
||||||
|
:value="item"
|
||||||
|
class="radio-input"
|
||||||
|
>
|
||||||
|
<span class="radio-custom" />
|
||||||
|
<span class="radio-text">
|
||||||
|
{{ t(`pages.manage.setting.copyFormat.${item}`) }}
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Custom Copy Format -->
|
||||||
|
<div
|
||||||
|
class="form-group"
|
||||||
|
>
|
||||||
|
<div class="form-label-wrapper">
|
||||||
|
<span class="form-label">
|
||||||
|
{{ t('pages.manage.setting.copyFormat.customTitle') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
v-model="form.customPasteFormat"
|
||||||
|
type="text"
|
||||||
|
class="form-input"
|
||||||
|
:placeholder="t('pages.manage.setting.copyFormat.customTips')"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Download Folder Card -->
|
||||||
|
<div class="setting-card content-card">
|
||||||
|
<div class="card-content">
|
||||||
|
<div class="setting-section">
|
||||||
|
<div class="section-header">
|
||||||
|
<h4 class="section-title">
|
||||||
|
{{ t('pages.manage.setting.selectDownloadFolderTitle') }}
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="input-group">
|
||||||
|
<input
|
||||||
|
v-model="form.downloadDir"
|
||||||
|
type="text"
|
||||||
|
class="form-input group-input"
|
||||||
|
disabled
|
||||||
|
:placeholder="t('pages.manage.setting.defaultDownloadFolder')"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="input-append-button"
|
||||||
|
@click="handleDownloadDirClick"
|
||||||
|
>
|
||||||
|
<FolderIcon :size="16" />
|
||||||
|
{{ t('pages.manage.setting.browse') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { Folder, InfoFilled } from '@element-plus/icons-vue'
|
import { FolderIcon, Trash2Icon } from 'lucide-vue-next'
|
||||||
import { ElMessage } from 'element-plus'
|
|
||||||
import { onBeforeMount, ref, watch } from 'vue'
|
import { onBeforeMount, ref, watch } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import DynamicSwitch from '@/manage/components/DynamicSwitch.vue'
|
import useConfirm from '@/hooks/useConfirm'
|
||||||
|
import useMessage from '@/hooks/useMessage'
|
||||||
|
import CustomSwitch from '@/manage/components/CustomSwitch.vue'
|
||||||
import { fileCacheDbInstance } from '@/manage/store/bucketFileDb'
|
import { fileCacheDbInstance } from '@/manage/store/bucketFileDb'
|
||||||
import { customRenameFormatTable, formatFileSize } from '@/manage/utils/common'
|
import { customRenameFormatTable, formatFileSize } from '@/manage/utils/common'
|
||||||
import { getConfig, saveConfig } from '@/manage/utils/dataSender'
|
import { getConfig, saveConfig } from '@/manage/utils/dataSender'
|
||||||
@@ -236,13 +255,14 @@ import { IRPCActionType } from '@/utils/enum'
|
|||||||
import type { IStringKeyMap } from '#/types/types'
|
import type { IStringKeyMap } from '#/types/types'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
const message = useMessage()
|
||||||
|
const { confirm } = useConfirm()
|
||||||
const form = ref<IStringKeyMap>({
|
const form = ref<IStringKeyMap>({
|
||||||
timestampRename: false,
|
timestampRename: false,
|
||||||
randomStringRename: false,
|
randomStringRename: false,
|
||||||
customRename: false,
|
customRename: false,
|
||||||
isAutoRefresh: false,
|
isAutoRefresh: false,
|
||||||
isShowThumbnail: false,
|
isShowThumbnail: false,
|
||||||
isShowList: false,
|
|
||||||
isUsePreSignedUrl: false,
|
isUsePreSignedUrl: false,
|
||||||
isIgnoreCase: false,
|
isIgnoreCase: false,
|
||||||
isForceCustomUrlHttps: false,
|
isForceCustomUrlHttps: false,
|
||||||
@@ -275,7 +295,6 @@ settingsKeys.forEach(key => {
|
|||||||
const switchFieldsList = [
|
const switchFieldsList = [
|
||||||
'isAutoRefresh',
|
'isAutoRefresh',
|
||||||
'isShowThumbnail',
|
'isShowThumbnail',
|
||||||
'isShowList',
|
|
||||||
'isUsePreSignedUrl',
|
'isUsePreSignedUrl',
|
||||||
'isForceCustomUrlHttps',
|
'isForceCustomUrlHttps',
|
||||||
'isEncodeUrl',
|
'isEncodeUrl',
|
||||||
@@ -285,23 +304,23 @@ const switchFieldsList = [
|
|||||||
'randomStringRename',
|
'randomStringRename',
|
||||||
'customRename'
|
'customRename'
|
||||||
]
|
]
|
||||||
const switchFieldsNoTipsList = ['isShowThumbnail', 'isShowList', 'isUsePreSignedUrl']
|
const switchFieldsNoTipsList = ['isShowThumbnail', 'isUsePreSignedUrl']
|
||||||
const switchFieldsHasActiveTextList = ['isShowList']
|
const switchFieldsHasActiveTextList = [] as string[]
|
||||||
|
|
||||||
const switchFieldsConfigList = switchFieldsList.map(item => ({
|
const switchFieldsConfigList = switchFieldsList.map(item => ({
|
||||||
configName: item,
|
configName: item,
|
||||||
segments: [
|
segments: [
|
||||||
{
|
{
|
||||||
text: t(`MANAGE_SETTING_${item.toUpperCase()}_TITLE` as any),
|
text: t(`pages.manage.setting.${item}Title` as any),
|
||||||
style: 'color: black;'
|
style: 'color: var(--color-text-primary);'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
tooltip: switchFieldsNoTipsList.includes(item) ? undefined : t(`MANAGE_SETTING_${item.toUpperCase()}_TIPS` as any),
|
tooltip: switchFieldsNoTipsList.includes(item) ? undefined : t(`pages.manage.setting.${item}Tips` as any),
|
||||||
activeText: switchFieldsHasActiveTextList.includes(item)
|
activeText: switchFieldsHasActiveTextList.includes(item)
|
||||||
? t(`MANAGE_SETTING_${item.toUpperCase()}_ON` as any)
|
? t(`pages.manage.setting.${item}On` as any)
|
||||||
: undefined,
|
: undefined,
|
||||||
inactiveText: switchFieldsHasActiveTextList.includes(item)
|
inactiveText: switchFieldsHasActiveTextList.includes(item)
|
||||||
? t(`MANAGE_SETTING_${item.toUpperCase()}_OFF` as any)
|
? t(`pages.manage.setting.${item}Off` as any)
|
||||||
: undefined
|
: undefined
|
||||||
}))
|
}))
|
||||||
|
|
||||||
@@ -310,37 +329,37 @@ const switchFieldsSpecialList = [
|
|||||||
configName: 'isDownloadFileKeepDirStructure',
|
configName: 'isDownloadFileKeepDirStructure',
|
||||||
segments: [
|
segments: [
|
||||||
{
|
{
|
||||||
text: t('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_A'),
|
text: t('pages.manage.setting.download'),
|
||||||
style: 'color: black;'
|
style: 'color: var(--color-text-primary);'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: t('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_B'),
|
text: t('pages.manage.setting.file'),
|
||||||
style: 'color: orange;'
|
style: 'color: orange;'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: t('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_C'),
|
text: t('pages.manage.setting.keepDirStructure'),
|
||||||
style: 'color: black;'
|
style: 'color: var(--color-text-primary);'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
tooltip: t('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TIPS')
|
tooltip: t('pages.manage.setting.keepDirStructureDesc')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
configName: 'isDownloadFolderKeepDirStructure',
|
configName: 'isDownloadFolderKeepDirStructure',
|
||||||
segments: [
|
segments: [
|
||||||
{
|
{
|
||||||
text: t('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_A'),
|
text: t('pages.manage.setting.download'),
|
||||||
style: 'color: black;'
|
style: 'color: var(--color-text-primary);'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: t('MANAGE_SETTING_ISDOWNLOADFOLDERKEEPDIRSTRUCTURE_TITLE_D'),
|
text: t('pages.manage.setting.folder'),
|
||||||
style: 'color: coral;'
|
style: 'color: orange;'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: t('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TITLE_C'),
|
text: t('pages.manage.setting.keepDirStructure'),
|
||||||
style: 'color: black;'
|
style: 'color: var(--color-text-primary);'
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
tooltip: t('MANAGE_SETTING_ISDOWNLOADFILEKEEPDIRSTRUCTURE_TIPS')
|
tooltip: t('pages.manage.setting.keepDirStructureDesc')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -360,18 +379,33 @@ async function handleDownloadDirClick () {
|
|||||||
|
|
||||||
const handleCellClick = (row: any, column: any) => {
|
const handleCellClick = (row: any, column: any) => {
|
||||||
navigator.clipboard.writeText(row[column.property])
|
navigator.clipboard.writeText(row[column.property])
|
||||||
ElMessage.success(`${t('MANAGE_SETTING_COPY_MESSAGE')}${row[column.property]}`)
|
message.success(`${t('pages.manage.setting.copySuccess', { name: row[column.property] })}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleClearDb () {
|
function handleConfirmClearDb () {
|
||||||
|
confirm({
|
||||||
|
title: t('pages.manage.setting.notice'),
|
||||||
|
message: t('pages.manage.setting.clearCacheMsg'),
|
||||||
|
type: 'warning',
|
||||||
|
confirmButtonText: t('common.confirm'),
|
||||||
|
cancelButtonText: t('common.cancel'),
|
||||||
|
center: true
|
||||||
|
}).then(result => {
|
||||||
|
if (result) {
|
||||||
|
confirmClearDb()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirmClearDb () {
|
||||||
fileCacheDbInstance
|
fileCacheDbInstance
|
||||||
.delete()
|
.delete()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
getIndexDbSize()
|
getIndexDbSize()
|
||||||
ElMessage.success(t('MANAGE_SETTING_CLEAR_CACHE_SUCCESS'))
|
message.success(t('pages.manage.setting.clearSuccess'))
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
ElMessage.error(t('MANAGE_SETTING_CLEAR_CACHE_FAILED'))
|
message.error(t('pages.manage.setting.clearFailed'))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,8 +422,4 @@ onBeforeMount(() => {
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus">
|
<style scoped src="./css/ManageSetting.css"></style>
|
||||||
#manage-setting
|
|
||||||
height 100%
|
|
||||||
overflow-y auto
|
|
||||||
</style>
|
|
||||||
|
|||||||
1272
src/renderer/manage/pages/css/BucketPage.css
Normal file
1272
src/renderer/manage/pages/css/BucketPage.css
Normal file
File diff suppressed because it is too large
Load Diff
647
src/renderer/manage/pages/css/ManageMain.css
Normal file
647
src/renderer/manage/pages/css/ManageMain.css
Normal file
@@ -0,0 +1,647 @@
|
|||||||
|
/* ManageMain Page Styles */
|
||||||
|
|
||||||
|
.manage-container {
|
||||||
|
height: 97%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.manage-card {
|
||||||
|
background: var(--color-background-secondary);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-card {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-icon {
|
||||||
|
width: 68px;
|
||||||
|
height: 48px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-icon-img {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-text .header-title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
margin: 0 0 0.01rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-text .header-subtitle {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-card {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
min-height: 0; /* Fix for flex overflow */
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-layout {
|
||||||
|
display: flex;
|
||||||
|
height:99%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: 160px;
|
||||||
|
background: var(--color-surface-secondary);
|
||||||
|
border-right: 1px solid var(--color-border);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 0; /* Fix for flex overflow */
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-header {
|
||||||
|
padding: 1rem;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-title {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-content {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 0.5rem;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 2rem;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-spinner {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 2px solid var(--color-border);
|
||||||
|
border-top: 2px solid var(--color-accent);
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item:hover {
|
||||||
|
background: var(--color-surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item.active {
|
||||||
|
background: var(--color-accent);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item.active .menu-icon {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-icon.active {
|
||||||
|
color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-text {
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.2;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-footer {
|
||||||
|
border-top: 1px solid var(--color-border);
|
||||||
|
padding: 0.5rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-actions {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-action-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
padding: 0.75rem;
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
text-align: left;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-action-item:hover {
|
||||||
|
background: var(--color-surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-text {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-area {
|
||||||
|
flex: 1;
|
||||||
|
padding: 1.5rem;
|
||||||
|
overflow-y: auto;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border: none;
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
font-family: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button.primary {
|
||||||
|
background: var(--color-accent);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button.primary:hover {
|
||||||
|
background: var(--color-accent-hover);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button.secondary {
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button.secondary:hover {
|
||||||
|
background: var(--color-surface);
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dialog styles */
|
||||||
|
.dialog-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-container {
|
||||||
|
background: var(--color-surface);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
box-shadow: var(--shadow-xl);
|
||||||
|
max-width: 600px;
|
||||||
|
width: 90%;
|
||||||
|
max-height: 80vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-header {
|
||||||
|
padding: 1.5rem 1.5rem 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-close {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.25rem;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-close:hover {
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-content {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choice-cos {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picbed-card {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
position: relative;
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
}
|
||||||
|
|
||||||
|
.picbed-card:hover {
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
}
|
||||||
|
|
||||||
|
.picbed-card.active {
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
background-color: rgba(64, 158, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.picbed-card.main-card {
|
||||||
|
border-color: var(--color-error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.picbed-card.main-card:hover {
|
||||||
|
border-color: var(--color-error);
|
||||||
|
background-color: rgba(255, 59, 48, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-icon {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picbed-icon {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
color: var(--color-error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-title {
|
||||||
|
color: var(--color-error);
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.5rem;
|
||||||
|
right: 0.5rem;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Drawer styles */
|
||||||
|
.drawer-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 32px;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
z-index: 2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-container {
|
||||||
|
background: var(--color-surface);
|
||||||
|
height: 100vh;
|
||||||
|
width: 400px;
|
||||||
|
max-width: 90vw;
|
||||||
|
overflow-y: auto;
|
||||||
|
box-shadow: var(--shadow-xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-header {
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-bottom: 1px solid var(--color-border);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-close {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.25rem;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-close:hover {
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.drawer-content {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 2rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-icon {
|
||||||
|
width: 60px;
|
||||||
|
height: 60px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picbed-form-icon {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-divider {
|
||||||
|
height: 1px;
|
||||||
|
background: var(--color-border);
|
||||||
|
margin: 1.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.75rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-input {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-append {
|
||||||
|
padding: 0.75rem;
|
||||||
|
background: var(--color-background-secondary);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-left: none;
|
||||||
|
border-top-right-radius: var(--radius-md);
|
||||||
|
border-bottom-right-radius: var(--radius-md);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-wrapper {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.75rem 2.5rem 0.75rem 0.75rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
appearance: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-select:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-arrow {
|
||||||
|
position: absolute;
|
||||||
|
right: 0.75rem;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-slider {
|
||||||
|
position: relative;
|
||||||
|
width: 3rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
background: var(--color-border);
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-button {
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
left: 2px;
|
||||||
|
width: 1.25rem;
|
||||||
|
height: 1.25rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input:checked + .switch-slider {
|
||||||
|
background: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch-input:checked + .switch-slider .switch-button {
|
||||||
|
transform: translateX(1.5rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
515
src/renderer/manage/pages/css/ManageSetting.css
Normal file
515
src/renderer/manage/pages/css/ManageSetting.css
Normal file
@@ -0,0 +1,515 @@
|
|||||||
|
/* Container */
|
||||||
|
.manage-setting-container {
|
||||||
|
padding: 1rem;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 1rem;
|
||||||
|
min-height: 100vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card Base */
|
||||||
|
.setting-card {
|
||||||
|
background: var(--color-surface);
|
||||||
|
border: 1px solid var(--color-border-secondary);
|
||||||
|
border-radius: var(--radius-xl);
|
||||||
|
overflow: hidden;
|
||||||
|
transition: var(--transition-medium);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-card:hover {
|
||||||
|
box-shadow: var(--shadow-md);
|
||||||
|
border-color: var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header Card */
|
||||||
|
.header-card .card-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
border-bottom: 1px solid var(--color-border-secondary);
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-icon {
|
||||||
|
color: var(--color-blue-common);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content h1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
margin: 0;
|
||||||
|
letter-spacing: -0.025em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-content p {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Action Button Base */
|
||||||
|
.action-button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button:hover {
|
||||||
|
background: var(--color-background-secondary);
|
||||||
|
border-color: var(--color-border-darker);
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: var(--shadow-sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button:active {
|
||||||
|
transform: translateY(0);
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button.primary {
|
||||||
|
background: var(--color-blue-common);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--color-blue-common);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button.primary:hover {
|
||||||
|
background: var(--color-accent);
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button.secondary {
|
||||||
|
background: var(--color-background-secondary);
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button.warning {
|
||||||
|
background: var(--color-warning);
|
||||||
|
color: white;
|
||||||
|
border-color: var(--color-warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button.warning:hover {
|
||||||
|
background: var(--color-warning);
|
||||||
|
border-color: var(--color-warning);
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button .button-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Content Cards */
|
||||||
|
.content-card {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content {
|
||||||
|
padding: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setting sections with reduced spacing */
|
||||||
|
.setting-section {
|
||||||
|
display: flex;
|
||||||
|
gap: 0.5rem;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.setting-section + .setting-section {
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding-top: 1rem;
|
||||||
|
border-top: 1px solid var(--color-border-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Form Groups */
|
||||||
|
.form-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.75rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
box-shadow: 0 0 0 2px rgba(0, 122, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input:disabled {
|
||||||
|
background: var(--color-background-secondary);
|
||||||
|
color: var(--color-text-tertiary);
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.number-input {
|
||||||
|
max-width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cache Info */
|
||||||
|
.cache-info {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cache-size {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section Headers */
|
||||||
|
.section-header {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-accent);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pattern Table */
|
||||||
|
.pattern-table-container {
|
||||||
|
margin-top: 0.75rem;
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pattern-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pattern-table th {
|
||||||
|
background: var(--color-background-secondary);
|
||||||
|
padding: 0.5rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pattern-table td {
|
||||||
|
padding: 0.5rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pattern-table td.clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--color-accent);
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pattern-table td.clickable:hover {
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Radio Groups */
|
||||||
|
.radio-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-option {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.75rem;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.625rem;
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--radius-md);
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-option:hover {
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
background: var(--color-surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-input {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-custom {
|
||||||
|
position: relative;
|
||||||
|
width: 1.25rem;
|
||||||
|
height: 1.25rem;
|
||||||
|
border: 2px solid var(--color-border);
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-custom::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: var(--color-accent);
|
||||||
|
transform: translate(-50%, -50%) scale(0);
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-input:checked + .radio-custom {
|
||||||
|
border-color: var(--color-accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-input:checked + .radio-custom::after {
|
||||||
|
transform: translate(-50%, -50%) scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-text {
|
||||||
|
font-size: 0.875rem;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input Groups */
|
||||||
|
.input-group {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.group-input {
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-append-button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
background: var(--color-accent);
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-top-right-radius: var(--radius-md);
|
||||||
|
border-bottom-right-radius: var(--radius-md);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-append-button:hover {
|
||||||
|
background: var(--color-accent-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dialog Styles */
|
||||||
|
.dialog-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 2000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-container {
|
||||||
|
background: var(--color-surface);
|
||||||
|
border-radius: var(--radius-lg);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
box-shadow: var(--shadow-xl);
|
||||||
|
max-width: 400px;
|
||||||
|
width: 90%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-header {
|
||||||
|
padding: 1.5rem 1.5rem 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-close {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 0.25rem;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border-radius: var(--radius-sm);
|
||||||
|
transition: var(--transition-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-close:hover {
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
color: var(--color-text-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-content {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-message {
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
line-height: 1.5;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 0 1.5rem 1.5rem;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode adjustments */
|
||||||
|
:root.dark .manage-setting-container,
|
||||||
|
:root.auto.dark .manage-setting-container {
|
||||||
|
background: var(--color-background-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.dark .form-input,
|
||||||
|
:root.auto.dark .form-input {
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
border-color: var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.dark .radio-custom,
|
||||||
|
:root.auto.dark .radio-custom {
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
border-color: var(--color-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root.dark .pattern-table th,
|
||||||
|
:root.auto.dark .pattern-table th {
|
||||||
|
background: var(--color-surface-elevated);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive Design */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.manage-setting-container {
|
||||||
|
padding: 0.75rem;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-content {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-card .card-header {
|
||||||
|
padding: 1rem;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
|
width: 100%;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pattern-table {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pattern-table th,
|
||||||
|
.pattern-table td {
|
||||||
|
padding: 0.375rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-option {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input {
|
||||||
|
padding: 0.625rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -613,7 +613,7 @@ small {
|
|||||||
/* Dark mode adjustments */
|
/* Dark mode adjustments */
|
||||||
:root.dark .piclist-settings,
|
:root.dark .piclist-settings,
|
||||||
:root.auto.dark .piclist-settings {
|
:root.auto.dark .piclist-settings {
|
||||||
background: var(--color-background-primary);
|
background: var(--color-background-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
:root.dark .settings-header,
|
:root.dark .settings-header,
|
||||||
|
|||||||
Reference in New Issue
Block a user