add interactive tutorials

This commit is contained in:
pompurin404 2024-09-08 21:52:26 +08:00
parent a2a63f473d
commit 5e19ee301b
No known key found for this signature in database
7 changed files with 131 additions and 2 deletions

View File

@ -52,6 +52,7 @@
"@vitejs/plugin-react": "^4.3.1", "@vitejs/plugin-react": "^4.3.1",
"apexcharts": "^3.53.0", "apexcharts": "^3.53.0",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"driver.js": "^1.3.1",
"electron": "^32.0.2", "electron": "^32.0.2",
"electron-builder": "^25.0.5", "electron-builder": "^25.0.5",
"electron-vite": "^2.3.0", "electron-vite": "^2.3.0",

View File

@ -93,6 +93,9 @@ importers:
autoprefixer: autoprefixer:
specifier: ^10.4.20 specifier: ^10.4.20
version: 10.4.20(postcss@8.4.45) version: 10.4.20(postcss@8.4.45)
driver.js:
specifier: ^1.3.1
version: 1.3.1
electron: electron:
specifier: ^32.0.2 specifier: ^32.0.2
version: 32.0.2 version: 32.0.2
@ -2784,6 +2787,9 @@ packages:
resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
engines: {node: '>=12'} engines: {node: '>=12'}
driver.js@1.3.1:
resolution: {integrity: sha512-MvUdXbqSgEsgS/H9KyWb5Rxy0aE6BhOVT4cssi2x2XjmXea6qQfgdx32XKVLLSqTaIw7q/uxU5Xl3NV7+cN6FQ==}
eastasianwidth@0.2.0: eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
@ -8753,6 +8759,8 @@ snapshots:
dotenv@16.4.5: {} dotenv@16.4.5: {}
driver.js@1.3.1: {}
eastasianwidth@0.2.0: {} eastasianwidth@0.2.0: {}
ee-first@1.1.1: {} ee-first@1.1.1: {}

View File

@ -33,6 +33,8 @@ import { platform } from '@renderer/utils/init'
import { TitleBarOverlayOptions } from 'electron' import { TitleBarOverlayOptions } from 'electron'
import SubStoreCard from '@renderer/components/sider/substore-card' import SubStoreCard from '@renderer/components/sider/substore-card'
import MihomoIcon from './components/base/mihomo-icon' import MihomoIcon from './components/base/mihomo-icon'
import { driver } from 'driver.js'
import 'driver.js/dist/driver.css'
const App: React.FC = () => { const App: React.FC = () => {
const { appConfig, patchAppConfig } = useAppConfig() const { appConfig, patchAppConfig } = useAppConfig()
@ -66,6 +68,14 @@ const App: React.FC = () => {
setOrder(siderOrder) setOrder(siderOrder)
}, [siderOrder]) }, [siderOrder])
useEffect(() => {
const tourShown = window.localStorage.getItem('tourShown')
if (!tourShown) {
window.localStorage.setItem('tourShown', 'true')
firstDriver.drive()
}
}, [])
useEffect(() => { useEffect(() => {
if (appTheme.includes('light')) { if (appTheme.includes('light')) {
setNativeTheme('light') setNativeTheme('light')
@ -195,3 +205,52 @@ const App: React.FC = () => {
} }
export default App export default App
export const firstDriver = driver({
showProgress: true,
nextBtnText: '下一步',
prevBtnText: '上一步',
doneBtnText: '完成',
progressText: '{{current}} / {{total}}',
overlayOpacity: 0.9,
steps: [
{
element: '.side',
popover: {
title: '导航栏',
description:
'左侧是应用的导航栏,兼顾仪表盘功能,在这里可以切换不同页面,也可以概览常用的状态信息',
side: 'left',
align: 'start'
}
},
{
element: '.sysproxy-card',
popover: {
title: '卡片',
description: '点击导航栏卡片可以跳转到对应页面,拖动导航栏卡片可以自由排列卡片顺序',
side: 'bottom',
align: 'start'
}
},
{
element: '.main',
popover: {
title: '主要区域',
description: '右侧是应用的主要区域,展示了导航栏所选页面的内容',
side: 'right',
align: 'start'
}
},
{
element: '.profile-card',
popover: {
title: '订阅管理',
description:
'订阅管理卡片展示当前运行的订阅配置信息,点击进入订阅管理页面可以在这里管理订阅配置\n更多功能请查阅 <a href="https://mihomo.party" target="_blank">官方文档</a>',
side: 'bottom',
align: 'start'
}
}
]
})

View File

@ -7,6 +7,61 @@
src: url('./NotoColorEmoji.ttf'); src: url('./NotoColorEmoji.ttf');
} }
.driver-popover {
background-color: hsl(var(--nextui-content2)) !important;
border-radius: 8px !important;
color: hsl(var(--nextui-foreground)) !important;
}
.driver-popover a {
color: hsl(var(--nextui-primary)) !important;
text-decoration: underline !important;
}
.driver-popover-close-btn {
color: hsl(var(--nextui-foreground)) !important;
}
.driver-popover-progress-text {
color: hsl(var(--nextui-default-500)) !important;
}
.driver-popover-prev-btn {
color: white !important;
text-shadow: none !important;
border: none !important;
padding: 8px !important;
border-radius: 5px !important;
font-size: 12px !important;
background-color: hsl(var(--nextui-primary)) !important;
}
.driver-popover-next-btn {
color: white !important;
text-shadow: none !important;
border: none !important;
padding: 8px !important;
border-radius: 5px !important;
font-size: 12px !important;
background-color: hsl(var(--nextui-primary)) !important;
}
.driver-popover-arrow-side-bottom {
border-bottom-color: hsl(var(--nextui-content2)) !important;
}
.driver-popover-arrow-side-top {
border-top-color: hsl(var(--nextui-content2)) !important;
}
.driver-popover-arrow-side-left {
border-left-color: hsl(var(--nextui-content2)) !important;
}
.driver-popover-arrow-side-right {
border-right-color: hsl(var(--nextui-content2)) !important;
}
.app-nodrag { .app-nodrag {
-webkit-app-region: none; -webkit-app-region: none;
} }

View File

@ -6,6 +6,7 @@ import { useState } from 'react'
import UpdaterModal from '../updater/updater-modal' import UpdaterModal from '../updater/updater-modal'
import { version } from '@renderer/utils/init' import { version } from '@renderer/utils/init'
import { IoIosHelpCircle } from 'react-icons/io' import { IoIosHelpCircle } from 'react-icons/io'
import { firstDriver } from '@renderer/App'
const Actions: React.FC = () => { const Actions: React.FC = () => {
const [newVersion, setNewVersion] = useState('') const [newVersion, setNewVersion] = useState('')
@ -23,6 +24,11 @@ const Actions: React.FC = () => {
/> />
)} )}
<SettingCard> <SettingCard>
<SettingItem title="打开引导页面" divider>
<Button size="sm" onPress={() => firstDriver.drive()}>
</Button>
</SettingItem>
<SettingItem title="检查更新" divider> <SettingItem title="检查更新" divider>
<Button <Button
size="sm" size="sm"

View File

@ -55,7 +55,7 @@ const ProfileCard: React.FC = () => {
transition, transition,
zIndex: isDragging ? 'calc(infinity)' : undefined zIndex: isDragging ? 'calc(infinity)' : undefined
}} }}
className={profileCardStatus} className={`${profileCardStatus} profile-card`}
> >
{showRuntimeConfig && <ConfigViewer onClose={() => setShowRuntimeConfig(false)} />} {showRuntimeConfig && <ConfigViewer onClose={() => setShowRuntimeConfig(false)} />}
{profileCardStatus === 'col-span-2' ? ( {profileCardStatus === 'col-span-2' ? (

View File

@ -43,7 +43,7 @@ const SysproxySwitcher: React.FC = () => {
transition, transition,
zIndex: isDragging ? 'calc(infinity)' : undefined zIndex: isDragging ? 'calc(infinity)' : undefined
}} }}
className={sysproxyCardStatus} className={`${sysproxyCardStatus} sysproxy-card`}
> >
<Card <Card
fullWidth fullWidth