Skip to content

Commit

Permalink
feat: new theme switching function
Browse files Browse the repository at this point in the history
  • Loading branch information
ayangweb committed Mar 9, 2023
1 parent c7a785a commit 72e663b
Show file tree
Hide file tree
Showing 22 changed files with 256 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_APP_NAME=ChatGPT-Desktop
VITE_OPEN_AI_URL=https://api.openai.com/v1/chat/completions
4 changes: 3 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@ module.exports = {
parser: '@typescript-eslint/parser'
},
plugins: ['vue', '@typescript-eslint', 'prettier'],
rules: {}
rules: {
'vue/multi-word-component-names': 'off'
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@
"vite": "^4.0.0",
"vue-tsc": "^1.0.11"
}
}
}
13 changes: 13 additions & 0 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ tauri = { version = "1.2", features = ["api-all", "macos-private-api", "system-t
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tauri-plugin-store = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" }
window-vibrancy = "0.3.2"

[dependencies.tauri-plugin-sql]
git = "https://github.com/tauri-apps/plugins-workspace"
Expand Down
3 changes: 3 additions & 0 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use tauri::Manager;

use window_vibrancy::{apply_blur, apply_vibrancy, NSVisualEffectMaterial};

mod folder;
mod tray;
Expand Down
5 changes: 3 additions & 2 deletions src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"icons/icon.icns",
"icons/icon.ico"
],
"identifier": "com.tauri.dev",
"identifier": "com.ChatGPT-Desktop",
"targets": "all"
},
"security": {
Expand All @@ -41,7 +41,8 @@
{
"label": "main",
"fullscreen": false,
"resizable": true,
"resizable": false,
"maximized": false,
"title": "ChatGPT-Desktop",
"alwaysOnTop": true,
"decorations": false,
Expand Down
25 changes: 21 additions & 4 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import Theme from './components/Theme/index.vue'
import { useMutationObserver } from './hooks'
const { themeMode } = useMutationObserver()
const background = computed(() =>
themeMode.value === 'light' ? 'bg-white/50' : 'bg-black/50'
)
</script>

<template>
<div class="main h-screen rounded-xl bg-white/80" data-tauri-drag-region>
<button class="btn btn-link">Button</button>
</div>
<Suspense>
<div
class="main h-screen rounded-xl backdrop-blur"
:class="background"
data-tauri-drag-region
>
<button class="btn btn-active btn-ghost">Button</button>

<Theme />
</div>
</Suspense>
</template>

<style scoped lang="scss"></style>
49 changes: 49 additions & 0 deletions src/components/Theme/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script setup lang="ts">
import { getStore, setStore } from '@/stores'
import { ThemeMode } from '@/types'
const themeMode = ref<ThemeMode>(await getStore('theme-mode'))
console.log('themeMode.value', themeMode.value)
watch(
themeMode,
(newTheme) => {
console.log('newTheme', newTheme)
document.documentElement.setAttribute('data-theme', newTheme)
setStore('theme-mode', newTheme)
},
{ immediate: true }
)
</script>

<template>
<label class="swap swap-rotate">
<input
type="checkbox"
@click="themeMode = themeMode === 'light' ? 'dark' : 'light'"
/>

<svg
class="swap-off h-10 w-10 fill-current"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z"
/>
</svg>

<svg
class="swap-on h-10 w-10 fill-current"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path
d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z"
/>
</svg>
</label>
</template>
1 change: 1 addition & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './store'
12 changes: 12 additions & 0 deletions src/constants/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { configDir } from '@tauri-apps/api/path'
import { version } from '../../package.json'

// 默认配置文件路径
export const FILE_STORAGE_PATH =
(await configDir()) + import.meta.env.VITE_APP_NAME

// store 初始默认值
export const STORE_DEFAULT_VALUES: Record<string, any> = {
version,
'theme-mode': 'light'
}
1 change: 1 addition & 0 deletions src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './useMutationObserver'
27 changes: 27 additions & 0 deletions src/hooks/useMutationObserver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { ThemeMode } from '@/types'

export const useMutationObserver = () => {
// 主题模式
const themeMode = ref<ThemeMode>('light')

// 监听body元素的属性变化,如果是主题变化就更改主题模式
const observer = new MutationObserver((mutationsList) => {
for (const { type, attributeName } of mutationsList) {
if (type === 'attributes' && attributeName === 'data-theme') {
themeMode.value = document.documentElement.getAttribute(
'data-theme'
) as ThemeMode
}
}
})

onMounted(() => {
observer.observe(document.documentElement, {
attributes: true
})
})

return {
themeMode
}
}
10 changes: 10 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import { createApp } from 'vue'
import { message } from '@tauri-apps/api/dialog'
import App from './App.vue'
import 'uno.css'
import '@kidonng/daisyui/index.css'
import './assets/css/global.scss'

window.onerror = (errorMessage) => {
message((errorMessage as string).replace('Error: ', ''), {
title: import.meta.env.VITE_APP_NAME,
type: 'error'
})

return true
}

createApp(App).mount('#app')
85 changes: 85 additions & 0 deletions src/stores/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Store } from 'tauri-plugin-store-api'
import { STORE_DEFAULT_VALUES, FILE_STORAGE_PATH } from '@/constants'
import { isNil } from '@/utils'

// 创建配置文件
const storeFile = import.meta.env.DEV ? '.config.dev.dat' : '.config.dat'
const store = new Store(`${FILE_STORAGE_PATH}/${storeFile}`)

/**
* 初始化 store 配置
*/
export const initStore = async () => {
try {
await store.load()
// 合并初始配置和用户自定义配置,防止缺少配置项
for (const key of Object.keys(STORE_DEFAULT_VALUES)) {
const value = (await getStore(key)) || STORE_DEFAULT_VALUES[key]
await setStore(key, value)
}
await saveStore()
} catch (error) {
for (const key of Object.keys(STORE_DEFAULT_VALUES)) {
const defaultValue = STORE_DEFAULT_VALUES[key]
await setStore(key, defaultValue)
}
}
}

/**
* 从 store 获取属性值
* @param key 获取值的属性名
* @returns 属性值
*/
export const getStore = async (key: string, defaultValue?: any) => {
const value = await store.get(key)

return !isNil(value) ? JSON.parse(value as string) : defaultValue
}

/**
* 在 store 写入属性
* @param key 需要设置的值的属性名
* @param value 需要设置的值的属性名
*/
export const setStore = async (key: string, value: string | boolean) => {
if (isNil(value)) {
deleteStore(key)

return
}

await store.set(key, JSON.stringify(value))

await saveStore()
}

/**
* 写入配置文件
*/
export const saveStore = async () => {
try {
await store.save()
} catch (error) {
throw new Error('数据写入配置文件时遇到了问题,请重试!')
}
}

/**
* 删除配置参数
* @param key 要删除的参数的属性名
*/
export const deleteStore = async (key: string) => {
await store.delete(key)

await saveStore()
}

/**
* 清空所有配置
*/
export const clearStore = async () => {
await store.clear()

await saveStore()
}
1 change: 1 addition & 0 deletions src/types/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './shared'
1 change: 1 addition & 0 deletions src/types/shared.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type ThemeMode = 'light' | 'dark'
1 change: 1 addition & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './shared'
6 changes: 6 additions & 0 deletions src/utils/shared.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* 判断数据是否为 null 或者 undefined
* @param value 数据
* @returns 判断结果
*/
export const isNil = (value: any) => value == null
12 changes: 12 additions & 0 deletions src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/// <reference types="vite/client" />

// 只有前缀为 VITE_ 的变量才会被 Vite 客户端暴露在浏览器中
interface ImportMetaEnv {
readonly VITE_APP_NAME: string
readonly VITE_OPEN_AI_URL: string
}

// eslint-disable-next-line no-unused-vars
interface ImportMeta {
readonly env: ImportMetaEnv
}
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"types": ["vite/client"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
Expand Down
2 changes: 1 addition & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default defineConfig(async () => ({
},
envPrefix: ['VITE_', 'TAURI_'],
build: {
target: process.env.TAURI_PLATFORM == 'windows' ? 'chrome105' : 'safari13',
target: 'esnext',
minify: !process.env.TAURI_DEBUG ? 'esbuild' : false,
sourcemap: !!process.env.TAURI_DEBUG
}
Expand Down

0 comments on commit 72e663b

Please sign in to comment.