feat: add WinFSP installation tips for Windows users close #37

This commit is contained in:
Kuingsmile
2025-07-04 13:46:35 +08:00
parent 4d2229c628
commit 9b85453ed0
5 changed files with 176 additions and 22 deletions

2
src-tauri/Cargo.lock generated
View File

@@ -2887,7 +2887,7 @@ dependencies = [
[[package]]
name = "openlist-desktop"
version = "0.1.0"
version = "0.2.0"
dependencies = [
"anyhow",
"base64 0.22.1",

View File

@@ -358,6 +358,8 @@
"tip": {
"webdavTitle": "Enable WebDAV Management Required",
"webdavMessage": "Before mounting remotes, please ensure WebDAV management for specific user is enabled in OpenList Core.",
"winfspTitle": "WinFSP Installation Required",
"winfspMessage": "On Windows, you need to install WinFSP first to use mount functionality. Please download and install it from GitHub: https://github.com/winfsp/winfsp/releases",
"dismissForever": "Dismiss forever"
}
},

View File

@@ -358,6 +358,8 @@
"tip": {
"webdavTitle": "需要启用 WebDAV 管理功能",
"webdavMessage": "在挂载远程存储之前,请确保在 OpenList 核心中为用户启用了 WebDAV 管理功能",
"winfspTitle": "需要安装 WinFSP",
"winfspMessage": "在 Windows 系统上,您需要先安装 WinFSP 才能使用挂载功能。请从 GitHub 下载并安装https://github.com/winfsp/winfsp/releases",
"dismissForever": "永久关闭"
}
},

View File

@@ -330,6 +330,21 @@ const dismissWebdavTip = () => {
localStorage.setItem('webdav_tip_dismissed', 'true')
}
const isWindows = /win/i.test(navigator.platform) || /win/i.test(navigator.userAgent)
const showWinfspTip = ref(isWindows && !localStorage.getItem('winfsp_tip_dismissed'))
const dismissWinfspTip = () => {
showWinfspTip.value = false
localStorage.setItem('winfsp_tip_dismissed', 'true')
}
const shouldShowWebdavTip = computed(() => {
if (isWindows) {
return !showWinfspTip.value && showWebdavTip.value
}
return showWebdavTip.value
})
onMounted(async () => {
document.addEventListener('keydown', handleKeydown)
await rcloneStore.checkRcloneBackendStatus()
@@ -408,7 +423,7 @@ onUnmounted(() => {
</div>
</div>
<div v-if="showWebdavTip" class="webdav-tip">
<div v-if="shouldShowWebdavTip" class="webdav-tip">
<div class="tip-content">
<div class="tip-icon">
<Settings class="icon" />
@@ -423,6 +438,21 @@ onUnmounted(() => {
</div>
</div>
<div v-if="showWinfspTip" class="winfsp-tip">
<div class="tip-content">
<div class="tip-icon">
<HardDrive class="icon" />
</div>
<div class="tip-message">
<h4 class="tip-title">{{ t('mount.tip.winfspTitle') }}</h4>
<p class="tip-description">{{ t('mount.tip.winfspMessage') }}</p>
</div>
<button @click="dismissWinfspTip" class="tip-close" :title="t('mount.tip.dismissForever')">
<X class="close-icon" />
</button>
</div>
</div>
<!-- Controls Section -->
<div class="controls-section">
<div class="search-container">

View File

@@ -1030,65 +1030,92 @@
.webdav-tip {
position: relative;
z-index: 1;
margin: 0 28px 20px;
margin: 0 28px 12px;
background: linear-gradient(135deg, #fef3cd 0%, #fff3cd 100%);
border: 1px solid #f9cc33;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(249, 204, 51, 0.1);
border-radius: 8px;
box-shadow: 0 1px 4px rgba(249, 204, 51, 0.1);
overflow: hidden;
}
.winfsp-tip {
position: relative;
z-index: 1;
margin: 0 28px 12px;
background: linear-gradient(135deg, #dbeafe 0%, #e0f2fe 100%);
border: 1px solid #3b82f6;
border-radius: 8px;
box-shadow: 0 1px 4px rgba(59, 130, 246, 0.1);
overflow: hidden;
}
.tip-content {
display: flex;
align-items: flex-start;
gap: 16px;
padding: 16px 20px;
gap: 12px;
padding: 12px 16px;
}
.tip-icon {
flex-shrink: 0;
width: 40px;
height: 40px;
width: 32px;
height: 32px;
background: rgba(249, 204, 51, 0.1);
border-radius: 10px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
}
.winfsp-tip .tip-icon {
background: rgba(59, 130, 246, 0.1);
}
.tip-icon .icon {
width: 20px;
height: 20px;
width: 16px;
height: 16px;
color: #b45309;
}
.winfsp-tip .tip-icon .icon {
color: #1d4ed8;
}
.tip-message {
flex: 1;
min-width: 0;
}
.tip-title {
margin: 0 0 8px 0;
font-size: 15px;
margin: 0 0 4px 0;
font-size: 13px;
font-weight: 600;
color: #92400e;
line-height: 1.3;
}
.winfsp-tip .tip-title {
color: #1e40af;
}
.tip-description {
margin: 0;
font-size: 14px;
font-size: 12px;
color: #a16207;
line-height: 1.5;
line-height: 1.4;
}
.winfsp-tip .tip-description {
color: #1d4ed8;
}
.tip-close {
flex-shrink: 0;
width: 32px;
height: 32px;
width: 28px;
height: 28px;
background: rgba(249, 204, 51, 0.1);
border: none;
border-radius: 8px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
@@ -1096,22 +1123,41 @@
transition: all 0.2s ease;
}
.winfsp-tip .tip-close {
background: rgba(59, 130, 246, 0.1);
}
.tip-close:hover {
background: rgba(249, 204, 51, 0.2);
transform: scale(1.05);
}
.winfsp-tip .tip-close:hover {
background: rgba(59, 130, 246, 0.2);
}
.tip-close .close-icon {
width: 16px;
height: 16px;
width: 14px;
height: 14px;
color: #a16207;
}
.winfsp-tip .tip-close .close-icon {
color: #1d4ed8;
}
:root.dark .webdav-tip,
:root.auto.dark .webdav-tip {
background: linear-gradient(135deg, #451a03 0%, #541c15 100%);
border-color: #a16207;
box-shadow: 0 2px 8px rgba(161, 98, 7, 0.1);
box-shadow: 0 1px 4px rgba(161, 98, 7, 0.1);
}
:root.dark .winfsp-tip,
:root.auto.dark .winfsp-tip {
background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
border-color: #3b82f6;
box-shadow: 0 1px 4px rgba(59, 130, 246, 0.1);
}
:root.dark .tip-icon,
@@ -1119,36 +1165,71 @@
background: rgba(161, 98, 7, 0.1);
}
:root.dark .winfsp-tip .tip-icon,
:root.auto.dark .winfsp-tip .tip-icon {
background: rgba(59, 130, 246, 0.1);
}
:root.dark .tip-icon .icon,
:root.auto.dark .tip-icon .icon {
color: #f59e0b;
}
:root.dark .winfsp-tip .tip-icon .icon,
:root.auto.dark .winfsp-tip .tip-icon .icon {
color: #60a5fa;
}
:root.dark .tip-title,
:root.auto.dark .tip-title {
color: #fbbf24;
}
:root.dark .winfsp-tip .tip-title,
:root.auto.dark .winfsp-tip .tip-title {
color: #93c5fd;
}
:root.dark .tip-description,
:root.auto.dark .tip-description {
color: #d97706;
}
:root.dark .winfsp-tip .tip-description,
:root.auto.dark .winfsp-tip .tip-description {
color: #60a5fa;
}
:root.dark .tip-close,
:root.auto.dark .tip-close {
background: rgba(161, 98, 7, 0.1);
}
:root.dark .winfsp-tip .tip-close,
:root.auto.dark .winfsp-tip .tip-close {
background: rgba(59, 130, 246, 0.1);
}
:root.dark .tip-close:hover,
:root.auto.dark .tip-close:hover {
background: rgba(161, 98, 7, 0.2);
}
:root.dark .winfsp-tip .tip-close:hover,
:root.auto.dark .winfsp-tip .tip-close:hover {
background: rgba(59, 130, 246, 0.2);
}
:root.dark .tip-close .close-icon,
:root.auto.dark .tip-close .close-icon {
color: #d97706;
}
:root.dark .winfsp-tip .tip-close .close-icon,
:root.auto.dark .winfsp-tip .tip-close .close-icon {
color: #60a5fa;
}
@media (max-width: 1024px) {
.header-content {
grid-template-columns: 1fr;
@@ -1197,6 +1278,45 @@
gap: 12px;
}
.webdav-tip,
.winfsp-tip {
margin: 0 16px 8px;
}
.tip-content {
padding: 10px 12px;
gap: 10px;
}
.tip-icon {
width: 28px;
height: 28px;
}
.tip-icon .icon {
width: 14px;
height: 14px;
}
.tip-title {
font-size: 12px;
margin-bottom: 2px;
}
.tip-description {
font-size: 11px;
}
.tip-close {
width: 24px;
height: 24px;
}
.tip-close .close-icon {
width: 12px;
height: 12px;
}
.config-grid {
grid-template-columns: 1fr;
}