diff --git a/components.d.ts b/components.d.ts
index bee6347..bd09d52 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -8,12 +8,14 @@ export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
+ FloatLabelInput: typeof import('./src/components/FloatLabelInput.vue')['default']
NA: typeof import('naive-ui')['NA']
NButton: typeof import('naive-ui')['NButton']
NCheckbox: typeof import('naive-ui')['NCheckbox']
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDialog: typeof import('naive-ui')['NDialog']
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
+ NEl: typeof import('naive-ui')['NEl']
NIcon: typeof import('naive-ui')['NIcon']
NInput: typeof import('naive-ui')['NInput']
NInputGroup: typeof import('naive-ui')['NInputGroup']
@@ -21,7 +23,10 @@ declare module 'vue' {
NModal: typeof import('naive-ui')['NModal']
NModalProvider: typeof import('naive-ui')['NModalProvider']
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
+ NQrCode: typeof import('naive-ui')['NQrCode']
NSelect: typeof import('naive-ui')['NSelect']
+ NTabPane: typeof import('naive-ui')['NTabPane']
+ NTabs: typeof import('naive-ui')['NTabs']
NTooltip: typeof import('naive-ui')['NTooltip']
NVirtualList: typeof import('naive-ui')['NVirtualList']
TitleBar: typeof import('./src/components/TitleBar.vue')['default']
diff --git a/index.html b/index.html
index 99f203f..85c3a16 100644
--- a/index.html
+++ b/index.html
@@ -4,6 +4,7 @@
+
Tauri + Vue + Typescript App
diff --git a/src/components/FloatLabelInput.vue b/src/components/FloatLabelInput.vue
new file mode 100644
index 0000000..62547db
--- /dev/null
+++ b/src/components/FloatLabelInput.vue
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+ {{ label }}
+
+
+
+
+
+
diff --git a/src/components/TitleBar.vue b/src/components/TitleBar.vue
index 8907395..3881aff 100644
--- a/src/components/TitleBar.vue
+++ b/src/components/TitleBar.vue
@@ -3,7 +3,12 @@ import icon from '../../src-tauri/icons/128x128.png'
import { PhCopySimple, PhMinus, PhSquare, PhX } from '@phosphor-icons/vue'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { onMounted, ref } from 'vue'
+import { useStore } from '../store.ts'
import { platform } from '@tauri-apps/plugin-os'
+import { ensureHttps } from '../utils.tsx'
+import LoginDialog from '../dialogs/LoginDialog.vue'
+
+const store = useStore()
const appWindow = getCurrentWindow()
const windowMaximised = ref(false)
@@ -15,7 +20,6 @@ const loginDialogShowing = ref(false)
onMounted(async () => {
windowMaximised.value = await appWindow.isMaximized()
- windowFullscreen.value = await appWindow.isFullscreen()
await appWindow.onResized(async () => {
windowMaximised.value = await appWindow.isMaximized()
@@ -32,7 +36,24 @@ onMounted(async () => {
哔哩哔哩视频下载器
-
+
+
+
![]()
+
{{ store.userInfo.uname }}
+
+
+

+
未登录
+
+
+import { commands, QrcodeData, QrcodeStatus } from '../bindings.ts'
+import { ref, watch } from 'vue'
+import { useMessage } from 'naive-ui'
+import { useStore } from '../store.ts'
+import icon from '../../src-tauri/icons/128x128.png'
+import FloatLabelInput from '../components/FloatLabelInput.vue'
+
+const store = useStore()
+
+const message = useMessage()
+
+const showing = defineModel
('showing', { required: true })
+
+const currentTabName = ref<'cookie' | 'qrcode'>('cookie')
+
+// 只要showing有任何变动,currentTabName就改为cookie
+watch(showing, () => {
+ currentTabName.value = 'cookie'
+})
+
+watch(
+ () => store.config?.sessdata,
+ async (value, oldValue) => {
+ if (store.config === undefined) {
+ return
+ }
+ if (oldValue !== undefined && oldValue !== '' && value === '') {
+ // 如果旧的 sessdata 不为空,新的 sessdata 为空,相当于退出登录
+ store.userInfo = undefined
+ message.success('已退出登录')
+ return
+ } else if (value === undefined || value === '') {
+ // 如果 sessdata 为空,说明用户没有登录
+ return
+ }
+ const result = await commands.getUserInfo(value)
+ if (result.status === 'error') {
+ console.error(result.error)
+ store.userInfo = undefined
+ return
+ }
+ store.userInfo = result.data
+ message.success('获取用户信息成功')
+ showing.value = false
+ },
+)
+
+watch([showing, currentTabName], async () => {
+ if (currentTabName.value !== 'qrcode' || !showing.value) {
+ return
+ }
+ // 如果当前选项卡是二维码,并且dialog正在显示,则生成二维码
+ await generateQrcode()
+})
+
+const qrcodeData = ref()
+const qrcodeStatus = ref()
+
+async function generateQrcode() {
+ const result = await commands.generateQrcode()
+ if (result.status === 'error') {
+ console.error(result.error)
+ return
+ }
+ qrcodeData.value = result.data
+ // 每隔一秒获取一次二维码状态,直到showing为false
+ const interval = setInterval(async () => {
+ if (!showing.value) {
+ clearInterval(interval)
+ return
+ }
+ await getQrcodeStatus()
+ handleQrcodeStatus()
+ }, 1000)
+}
+
+async function getQrcodeStatus() {
+ if (qrcodeData.value === undefined) {
+ return
+ }
+ const result = await commands.getQrcodeStatus(qrcodeData.value?.qrcode_key)
+ if (result.status === 'error') {
+ console.error(result.error)
+ return
+ }
+ qrcodeStatus.value = result.data
+}
+
+function handleQrcodeStatus() {
+ if (qrcodeStatus.value === undefined || store.config === undefined) {
+ return
+ }
+
+ if (qrcodeStatus.value.code === 0) {
+ const sessdata = qrcodeStatus.value.url.split('SESSDATA=')[1].split('&')[0]
+ store.config.sessdata = encodeURIComponent(sessdata)
+ showing.value = false
+ message.success('登录成功')
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+ 二维码状态:{{ qrcodeStatus?.message }}
+
+
+
+
+
+
+
+
+
diff --git a/src/store.ts b/src/store.ts
index 986b160..be68477 100644
--- a/src/store.ts
+++ b/src/store.ts
@@ -1,9 +1,10 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
-import { Config } from './bindings.ts'
+import { Config, UserInfo } from './bindings.ts'
export const useStore = defineStore('store', () => {
const config = ref()
+ const userInfo = ref()
- return { config }
+ return { config, userInfo }
})
diff --git a/src/utils.tsx b/src/utils.tsx
new file mode 100644
index 0000000..f5c3425
--- /dev/null
+++ b/src/utils.tsx
@@ -0,0 +1,6 @@
+export function ensureHttps(url: string): string {
+ if (url.startsWith('http://')) {
+ return url.replace('http://', 'https://')
+ }
+ return url
+}