2023-07-11 18:06:44 +08:00
|
|
|
import { defineStore } from 'pinia'
|
2023-08-02 17:57:39 +08:00
|
|
|
import { lang } from '@/langs/index.js'
|
2023-10-27 13:01:18 +08:00
|
|
|
import { cloneDeep, find, get, isEmpty, map, pick, set, split } from 'lodash'
|
2023-07-12 11:48:08 +08:00
|
|
|
import {
|
2023-08-26 02:40:30 +08:00
|
|
|
CheckForUpdate,
|
2023-07-12 11:48:08 +08:00
|
|
|
GetFontList,
|
|
|
|
GetPreferences,
|
|
|
|
RestorePreferences,
|
|
|
|
SetPreferences,
|
2023-08-02 17:57:39 +08:00
|
|
|
} from 'wailsjs/go/services/preferencesService.js'
|
2023-08-20 15:33:51 +08:00
|
|
|
import { BrowserOpenURL } from 'wailsjs/runtime/runtime.js'
|
|
|
|
import { i18nGlobal } from '@/utils/i18n.js'
|
2023-09-21 18:42:45 +08:00
|
|
|
import { enUS, NButton, NSpace, useOsTheme, zhCN } from 'naive-ui'
|
|
|
|
import { h, nextTick } from 'vue'
|
2023-10-07 23:37:12 +08:00
|
|
|
import { compareVersion } from '@/utils/version.js'
|
2023-07-11 18:06:44 +08:00
|
|
|
|
2023-08-24 00:44:19 +08:00
|
|
|
const osTheme = useOsTheme()
|
2023-07-11 18:06:44 +08:00
|
|
|
const usePreferencesStore = defineStore('preferences', {
|
2023-07-12 11:48:08 +08:00
|
|
|
/**
|
|
|
|
* @typedef {Object} FontItem
|
|
|
|
* @property {string} name
|
|
|
|
* @property {string} path
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
* @typedef {Object} Preferences
|
|
|
|
* @property {Object} general
|
|
|
|
* @property {Object} editor
|
|
|
|
* @property {FontItem[]} fontList
|
|
|
|
*/
|
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @returns {Preferences}
|
|
|
|
*/
|
2023-07-11 18:06:44 +08:00
|
|
|
state: () => ({
|
2023-09-28 21:45:44 +08:00
|
|
|
behavior: {
|
|
|
|
asideWidth: 300,
|
|
|
|
windowWidth: 0,
|
|
|
|
windowHeight: 0,
|
2023-12-03 22:51:14 +08:00
|
|
|
windowMaximised: false,
|
2023-09-28 21:45:44 +08:00
|
|
|
},
|
2023-07-11 18:06:44 +08:00
|
|
|
general: {
|
2023-08-25 00:07:29 +08:00
|
|
|
theme: 'auto',
|
2023-09-29 23:02:24 +08:00
|
|
|
language: 'auto',
|
2023-07-11 18:06:44 +08:00
|
|
|
font: '',
|
|
|
|
fontSize: 14,
|
2023-10-20 18:22:53 +08:00
|
|
|
scanSize: 3000,
|
2023-07-11 18:06:44 +08:00
|
|
|
useSysProxy: false,
|
|
|
|
useSysProxyHttp: false,
|
2023-12-03 22:51:14 +08:00
|
|
|
checkUpdate: true,
|
2023-09-21 18:42:45 +08:00
|
|
|
skipVersion: '',
|
2023-07-11 18:06:44 +08:00
|
|
|
},
|
|
|
|
editor: {
|
|
|
|
font: '',
|
|
|
|
fontSize: 14,
|
2023-12-03 22:51:14 +08:00
|
|
|
showLineNum: false,
|
2023-07-11 18:06:44 +08:00
|
|
|
},
|
2023-07-12 11:48:08 +08:00
|
|
|
lastPref: {},
|
|
|
|
fontList: [],
|
2023-07-11 18:06:44 +08:00
|
|
|
}),
|
|
|
|
getters: {
|
|
|
|
getSeparator() {
|
|
|
|
return ':'
|
|
|
|
},
|
|
|
|
|
2023-07-13 15:46:12 +08:00
|
|
|
themeOption() {
|
|
|
|
return [
|
|
|
|
{
|
|
|
|
value: 'light',
|
2023-09-07 18:38:34 +08:00
|
|
|
label: i18nGlobal.t('preferences.general.theme_light'),
|
2023-07-13 15:46:12 +08:00
|
|
|
},
|
|
|
|
{
|
|
|
|
value: 'dark',
|
2023-09-07 18:38:34 +08:00
|
|
|
label: i18nGlobal.t('preferences.general.theme_dark'),
|
2023-07-13 15:46:12 +08:00
|
|
|
},
|
|
|
|
{
|
|
|
|
value: 'auto',
|
2023-09-07 18:38:34 +08:00
|
|
|
label: i18nGlobal.t('preferences.general.theme_auto'),
|
2023-07-13 15:46:12 +08:00
|
|
|
},
|
|
|
|
]
|
|
|
|
},
|
|
|
|
|
2023-07-11 18:06:44 +08:00
|
|
|
/**
|
|
|
|
* all available language
|
|
|
|
* @returns {{label: string, value: string}[]}
|
|
|
|
*/
|
|
|
|
langOption() {
|
2023-07-21 14:37:39 +08:00
|
|
|
const options = Object.entries(lang).map(([key, value]) => ({
|
2023-07-11 18:06:44 +08:00
|
|
|
value: key,
|
2023-08-26 00:49:44 +08:00
|
|
|
label: value['name'],
|
2023-07-11 18:06:44 +08:00
|
|
|
}))
|
2023-07-21 14:37:39 +08:00
|
|
|
options.splice(0, 0, {
|
|
|
|
value: 'auto',
|
2023-09-07 18:38:34 +08:00
|
|
|
label: i18nGlobal.t('preferences.general.system_lang'),
|
2023-07-21 14:37:39 +08:00
|
|
|
})
|
|
|
|
return options
|
2023-07-11 18:06:44 +08:00
|
|
|
},
|
2023-07-12 11:48:08 +08:00
|
|
|
|
2023-07-13 15:46:12 +08:00
|
|
|
/**
|
|
|
|
* all system font list
|
|
|
|
* @returns {{path: string, label: string, value: string}[]}
|
|
|
|
*/
|
2023-07-12 11:48:08 +08:00
|
|
|
fontOption() {
|
|
|
|
const option = map(this.fontList, (font) => ({
|
|
|
|
value: font.name,
|
|
|
|
label: font.name,
|
|
|
|
path: font.path,
|
|
|
|
}))
|
|
|
|
option.splice(0, 0, {
|
|
|
|
value: '',
|
2023-09-07 18:38:34 +08:00
|
|
|
label: i18nGlobal.t('preferences.general.default'),
|
2023-07-12 11:48:08 +08:00
|
|
|
path: '',
|
|
|
|
})
|
|
|
|
return option
|
|
|
|
},
|
|
|
|
|
2023-07-13 15:46:12 +08:00
|
|
|
/**
|
|
|
|
* current font selection
|
2023-11-28 01:11:45 +08:00
|
|
|
* @returns {{fontSize: string, fontFamily?: string}}
|
2023-07-13 15:46:12 +08:00
|
|
|
*/
|
2023-07-12 11:48:08 +08:00
|
|
|
generalFont() {
|
|
|
|
const fontStyle = {
|
|
|
|
fontSize: this.general.fontSize + 'px',
|
|
|
|
}
|
|
|
|
if (!isEmpty(this.general.font) && this.general.font !== 'none') {
|
|
|
|
const font = find(this.fontList, { name: this.general.font })
|
|
|
|
if (font != null) {
|
|
|
|
fontStyle['fontFamily'] = `${font.name}`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return fontStyle
|
|
|
|
},
|
2023-07-21 14:37:39 +08:00
|
|
|
|
2023-11-28 01:11:45 +08:00
|
|
|
/**
|
|
|
|
* current editor font
|
|
|
|
* @return {{fontSize: string, fontFamily?: string}}
|
|
|
|
*/
|
|
|
|
editorFont() {
|
|
|
|
const fontStyle = {
|
|
|
|
fontSize: (this.editor.fontSize || 14) + 'px',
|
|
|
|
}
|
|
|
|
if (!isEmpty(this.editor.font) && this.editor.font !== 'none') {
|
|
|
|
const font = find(this.fontList, { name: this.editor.font })
|
|
|
|
if (font != null) {
|
|
|
|
fontStyle['fontFamily'] = `${font.name}`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fontStyle['fontFamily'] = fontStyle['fontFamily'] || 'monaco'
|
|
|
|
return fontStyle
|
|
|
|
},
|
|
|
|
|
2023-07-21 14:37:39 +08:00
|
|
|
/**
|
|
|
|
* get current language setting
|
|
|
|
* @return {string}
|
|
|
|
*/
|
|
|
|
currentLanguage() {
|
|
|
|
let lang = get(this.general, 'language', 'auto')
|
|
|
|
if (lang === 'auto') {
|
|
|
|
const systemLang = navigator.language || navigator.userLanguage
|
|
|
|
lang = split(systemLang, '-')[0]
|
|
|
|
}
|
|
|
|
return lang || 'en'
|
|
|
|
},
|
2023-08-20 15:46:06 +08:00
|
|
|
|
2023-08-24 00:44:19 +08:00
|
|
|
isDark() {
|
|
|
|
const th = get(this.general, 'theme', 'auto')
|
2023-08-25 00:07:29 +08:00
|
|
|
if (th !== 'auto') {
|
|
|
|
return th === 'dark'
|
|
|
|
} else {
|
|
|
|
return osTheme.value === 'dark'
|
2023-08-24 00:44:19 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2023-08-28 11:56:51 +08:00
|
|
|
themeLocale() {
|
|
|
|
const lang = this.currentLanguage
|
|
|
|
switch (lang) {
|
|
|
|
case 'zh':
|
|
|
|
return zhCN
|
|
|
|
default:
|
|
|
|
return enUS
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2023-08-20 15:46:06 +08:00
|
|
|
autoCheckUpdate() {
|
|
|
|
return get(this.general, 'checkUpdate', false)
|
|
|
|
},
|
2023-12-03 22:51:14 +08:00
|
|
|
|
|
|
|
showLineNum() {
|
|
|
|
return get(this.editor, 'showLineNum', true)
|
|
|
|
},
|
2023-07-11 18:06:44 +08:00
|
|
|
},
|
|
|
|
actions: {
|
|
|
|
_applyPreferences(data) {
|
|
|
|
for (const key in data) {
|
2023-10-04 22:21:35 +08:00
|
|
|
set(this, key, data[key])
|
2023-07-11 18:06:44 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* load preferences from local
|
|
|
|
* @returns {Promise<void>}
|
|
|
|
*/
|
|
|
|
async loadPreferences() {
|
|
|
|
const { success, data } = await GetPreferences()
|
|
|
|
if (success) {
|
2023-10-27 13:01:18 +08:00
|
|
|
this.lastPref = cloneDeep(data)
|
2023-07-11 18:06:44 +08:00
|
|
|
this._applyPreferences(data)
|
2023-12-03 22:51:14 +08:00
|
|
|
// default value
|
|
|
|
const showLineNum = get(data, 'editor.showLineNum')
|
|
|
|
if (showLineNum === undefined) {
|
|
|
|
set(data, 'editor.showLineNum', true)
|
|
|
|
}
|
2023-08-26 00:49:44 +08:00
|
|
|
i18nGlobal.locale.value = this.currentLanguage
|
2023-07-11 18:06:44 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2023-07-12 11:48:08 +08:00
|
|
|
/**
|
|
|
|
* load system font list
|
|
|
|
* @returns {Promise<string[]>}
|
|
|
|
*/
|
|
|
|
async loadFontList() {
|
|
|
|
const { success, data } = await GetFontList()
|
|
|
|
if (success) {
|
|
|
|
const { fonts = [] } = data
|
|
|
|
this.fontList = fonts
|
|
|
|
} else {
|
|
|
|
this.fontList = []
|
|
|
|
}
|
|
|
|
return this.fontList
|
|
|
|
},
|
|
|
|
|
2023-07-11 18:06:44 +08:00
|
|
|
/**
|
|
|
|
* save preferences to local
|
|
|
|
* @returns {Promise<boolean>}
|
|
|
|
*/
|
|
|
|
async savePreferences() {
|
2023-10-04 22:21:35 +08:00
|
|
|
const pf = pick(this, ['behavior', 'general', 'editor'])
|
2023-07-11 18:06:44 +08:00
|
|
|
const { success, msg } = await SetPreferences(pf)
|
|
|
|
return success === true
|
|
|
|
},
|
|
|
|
|
2023-07-12 11:48:08 +08:00
|
|
|
/**
|
2023-10-04 22:21:35 +08:00
|
|
|
* reset to last-loaded preferences
|
2023-07-12 11:48:08 +08:00
|
|
|
* @returns {Promise<void>}
|
|
|
|
*/
|
|
|
|
async resetToLastPreferences() {
|
|
|
|
if (!isEmpty(this.lastPref)) {
|
|
|
|
this._applyPreferences(this.lastPref)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2023-07-11 18:06:44 +08:00
|
|
|
/**
|
|
|
|
* restore preferences to default
|
|
|
|
* @returns {Promise<boolean>}
|
|
|
|
*/
|
|
|
|
async restorePreferences() {
|
|
|
|
const { success, data } = await RestorePreferences()
|
|
|
|
if (success === true) {
|
|
|
|
const { pref } = data
|
|
|
|
this._applyPreferences(pref)
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
},
|
2023-07-12 15:48:49 +08:00
|
|
|
|
2023-07-13 15:46:12 +08:00
|
|
|
setAsideWidth(width) {
|
2023-10-05 23:09:35 +08:00
|
|
|
this.behavior.asideWidth = Math.max(width, 300)
|
2023-07-12 15:48:49 +08:00
|
|
|
},
|
2023-08-20 15:46:06 +08:00
|
|
|
|
|
|
|
async checkForUpdate(manual = false) {
|
|
|
|
let msgRef = null
|
|
|
|
if (manual) {
|
2023-08-24 00:44:19 +08:00
|
|
|
msgRef = $message.loading('Retrieving for new version', { duration: 0 })
|
2023-08-20 15:46:06 +08:00
|
|
|
}
|
|
|
|
try {
|
2023-08-26 02:40:30 +08:00
|
|
|
const { success, data = {} } = await CheckForUpdate()
|
|
|
|
if (success) {
|
2023-09-17 01:15:55 +08:00
|
|
|
const { version = 'v1.0.0', latest, page_url: pageUrl } = data
|
2023-10-07 23:37:12 +08:00
|
|
|
if (
|
|
|
|
(manual || latest > this.general.skipVersion) &&
|
|
|
|
compareVersion(latest, version) > 0 &&
|
|
|
|
!isEmpty(pageUrl)
|
|
|
|
) {
|
2023-09-21 18:42:45 +08:00
|
|
|
const notiRef = $notification.show({
|
|
|
|
title: i18nGlobal.t('dialogue.upgrade.title'),
|
|
|
|
content: i18nGlobal.t('dialogue.upgrade.new_version_tip', { ver: latest }),
|
|
|
|
action: () =>
|
|
|
|
h('div', { class: 'flex-box-h flex-item-expand' }, [
|
|
|
|
h(NSpace, { wrapItem: false }, () => [
|
|
|
|
h(
|
|
|
|
NButton,
|
|
|
|
{
|
|
|
|
size: 'small',
|
|
|
|
secondary: true,
|
|
|
|
onClick: () => {
|
|
|
|
// skip this update
|
|
|
|
this.general.skipVersion = latest
|
|
|
|
this.savePreferences()
|
|
|
|
notiRef.destroy()
|
|
|
|
},
|
|
|
|
},
|
|
|
|
() => i18nGlobal.t('dialogue.upgrade.skip'),
|
|
|
|
),
|
|
|
|
h(
|
|
|
|
NButton,
|
|
|
|
{
|
|
|
|
size: 'small',
|
|
|
|
secondary: true,
|
|
|
|
onClick: notiRef.destroy,
|
|
|
|
},
|
|
|
|
() => i18nGlobal.t('dialogue.upgrade.later'),
|
|
|
|
),
|
|
|
|
h(
|
|
|
|
NButton,
|
|
|
|
{
|
|
|
|
type: 'primary',
|
|
|
|
size: 'small',
|
|
|
|
secondary: true,
|
|
|
|
onClick: () => BrowserOpenURL(pageUrl),
|
|
|
|
},
|
|
|
|
() => i18nGlobal.t('dialogue.upgrade.download_now'),
|
|
|
|
),
|
|
|
|
]),
|
|
|
|
]),
|
|
|
|
onPositiveClick: () => BrowserOpenURL(pageUrl),
|
2023-08-26 02:40:30 +08:00
|
|
|
})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (manual) {
|
2023-09-07 18:38:34 +08:00
|
|
|
$message.info(i18nGlobal.t('dialogue.upgrade.no_update'))
|
2023-08-20 15:46:06 +08:00
|
|
|
}
|
|
|
|
} finally {
|
2023-09-21 18:42:45 +08:00
|
|
|
nextTick().then(() => {
|
|
|
|
if (msgRef != null) {
|
|
|
|
msgRef.destroy()
|
|
|
|
msgRef = null
|
|
|
|
}
|
|
|
|
})
|
2023-08-20 15:46:06 +08:00
|
|
|
}
|
|
|
|
},
|
2023-07-11 18:06:44 +08:00
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
export default usePreferencesStore
|