mirror of
https://github.com/Grasscutters/Cultivation.git
synced 2025-12-12 15:14:35 +01:00
Push custom-options
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
"semi": [
|
"semi": [
|
||||||
"error",
|
"error",
|
||||||
"never"
|
"never"
|
||||||
]
|
],
|
||||||
|
"no-explicit-any": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
<title>Cultivation</title>
|
<title>Cultivation</title>
|
||||||
|
<script src="%PUBLIC_URL%/theme-engine.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
14
public/theme-engine.js
Normal file
14
public/theme-engine.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/**
|
||||||
|
* Passes a message through to the React backend.
|
||||||
|
* @param type The message type.
|
||||||
|
* @param data The message data.
|
||||||
|
*/
|
||||||
|
function passthrough(type, data) {
|
||||||
|
document.dispatchEvent(new CustomEvent('domMessage', {
|
||||||
|
type, msg: data
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
function setConfigValue(key, value) {
|
||||||
|
passthrough('updateConfig', {setting: key, value})
|
||||||
|
}
|
||||||
11
src-tauri/Cargo.lock
generated
11
src-tauri/Cargo.lock
generated
@@ -740,7 +740,7 @@ checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cultivation"
|
name = "cultivation"
|
||||||
version = "0.1.0"
|
version = "1.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"duct",
|
"duct",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@@ -2103,6 +2103,12 @@ version = "0.2.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minisign-verify"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "933dca44d65cdd53b355d0b73d380a2ff5da71f87f036053188bf1eab6a19881"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@@ -3886,6 +3892,7 @@ checksum = "a34cef4a0ebee0230baaa319b1709c4336f4add550149d2b005a9a5dc5d33617"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"attohttpc",
|
"attohttpc",
|
||||||
|
"base64",
|
||||||
"bincode",
|
"bincode",
|
||||||
"cocoa",
|
"cocoa",
|
||||||
"dirs-next",
|
"dirs-next",
|
||||||
@@ -3899,6 +3906,7 @@ dependencies = [
|
|||||||
"heck 0.4.0",
|
"heck 0.4.0",
|
||||||
"http",
|
"http",
|
||||||
"ignore",
|
"ignore",
|
||||||
|
"minisign-verify",
|
||||||
"notify-rust",
|
"notify-rust",
|
||||||
"objc",
|
"objc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
@@ -3930,6 +3938,7 @@ dependencies = [
|
|||||||
"webkit2gtk",
|
"webkit2gtk",
|
||||||
"webview2-com",
|
"webview2-com",
|
||||||
"windows 0.30.0",
|
"windows 0.30.0",
|
||||||
|
"zip 0.6.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "cultivation"
|
name = "cultivation"
|
||||||
version = "0.1.0"
|
version = "1.0.1"
|
||||||
description = "A custom launcher for anime game."
|
description = "A custom launcher for anime game."
|
||||||
authors = ["KingRainbow44", "SpikeHD"]
|
authors = ["KingRainbow44", "SpikeHD"]
|
||||||
license = ""
|
license = "Apache-2.0"
|
||||||
repository = "https://github.com/Grasscutters/Cultivation.git"
|
repository = "https://github.com/Grasscutters/Cultivation.git"
|
||||||
default-run = "cultivation"
|
default-run = "cultivation"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
@@ -16,7 +16,7 @@ tauri-build = { version = "1.0.0-rc.8", features = [] }
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
tauri = { version = "1.0.0-rc.9", features = ["api-all"] }
|
tauri = { version = "1.0.0-rc.9", features = ["api-all", "updater"] }
|
||||||
|
|
||||||
# Access system process info.
|
# Access system process info.
|
||||||
sysinfo = "0.23.12"
|
sysinfo = "0.23.12"
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
"csp": "default-src 'self' https://asset.localhost; img-src 'self'; img-src https://* asset: https://asset.localhost"
|
"csp": "default-src 'self' https://asset.localhost; img-src 'self'; img-src https://* asset: https://asset.localhost"
|
||||||
},
|
},
|
||||||
"updater": {
|
"updater": {
|
||||||
"active": false,
|
"active": true,
|
||||||
"dialog": true,
|
"dialog": true,
|
||||||
"endpoints": [
|
"endpoints": [
|
||||||
"https://api.grasscutter.io/cultivation/updater?version={{current_version}}",
|
"https://api.grasscutter.io/cultivation/updater?version={{current_version}}",
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ let isDebug = false;
|
|||||||
isDebug = await getConfigOption('debug_enabled')
|
isDebug = await getConfigOption('debug_enabled')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Render the app.
|
||||||
root.render(
|
root.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
{
|
{
|
||||||
@@ -25,5 +26,10 @@ root.render(
|
|||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Enable web vitals if needed.
|
||||||
import reportWebVitals from './utils/reportWebVitals'
|
import reportWebVitals from './utils/reportWebVitals'
|
||||||
isDebug && reportWebVitals(console.log)
|
isDebug && reportWebVitals(console.log)
|
||||||
|
|
||||||
|
// Setup DOM message passing.
|
||||||
|
import { parseMessageFromDOM } from './utils/dom'
|
||||||
|
document.addEventListener<string>('domMessage', parseMessageFromDOM)
|
||||||
34
src/resources/example-theme/index.json
Normal file
34
src/resources/example-theme/index.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"name": "Example Theme",
|
||||||
|
"version": "420.69",
|
||||||
|
"description": "Show off some of the abilities of the Cultivation theme system",
|
||||||
|
|
||||||
|
"includes": {
|
||||||
|
"_README": "You can include any amount of CSS and JS files here. Paths are relative to the theme directory.",
|
||||||
|
|
||||||
|
"css": ["/index.css"],
|
||||||
|
"js": ["/index.js"]
|
||||||
|
},
|
||||||
|
|
||||||
|
"settings": [
|
||||||
|
{
|
||||||
|
"label": "Example Setting",
|
||||||
|
"type": "input",
|
||||||
|
"className": "Input",
|
||||||
|
|
||||||
|
"data": {
|
||||||
|
"placeholder": "Enter a value",
|
||||||
|
"initialValue": "Change this value"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Example Setting",
|
||||||
|
"type": "checkbox",
|
||||||
|
"className": "Checkbox"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
"_README": "These are optional. Including neither will result in the launcher simply using the default background choice.",
|
||||||
|
"customBackgroundPath": "/background/bg.png",
|
||||||
|
"customBackgroundURL": ""
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.BottomSection .CheckboxDisplay {
|
.BottomSection .CheckboxDisplay {
|
||||||
margin-right: 6px;
|
margin-right: 6px;
|
||||||
box-shadow: 0 0 5px 4px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 0 5px 4px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|||||||
105
src/ui/components/common/ThemeOptionValue.tsx
Normal file
105
src/ui/components/common/ThemeOptionValue.tsx
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import TextInput from './TextInput'
|
||||||
|
import Checkbox from './Checkbox'
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Valid types for the theme option value.
|
||||||
|
* - input: A text input.
|
||||||
|
* - dropdown: A select/dropdown input.
|
||||||
|
* - checkbox: A toggle.
|
||||||
|
* - button: A button.
|
||||||
|
*/
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
type: string;
|
||||||
|
className?: string;
|
||||||
|
jsCallback?: string;
|
||||||
|
data: InputSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
toggled: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InputSettings {
|
||||||
|
/* Input. */
|
||||||
|
placeholder?: string;
|
||||||
|
initialValue?: string;
|
||||||
|
|
||||||
|
/* Dropdown. */
|
||||||
|
options?: string[];
|
||||||
|
|
||||||
|
/* Checkbox. */
|
||||||
|
toggled?: boolean
|
||||||
|
id?: string;
|
||||||
|
|
||||||
|
/* Button. */
|
||||||
|
text?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class ThemeOptionValue extends React.Component<IProps, IState> {
|
||||||
|
constructor(props: IProps) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
toggled: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDerivedStateFromProps(props: IProps, state: IState) {
|
||||||
|
return { toggled: props.data.toggled || state.toggled }
|
||||||
|
}
|
||||||
|
|
||||||
|
async componentDidMount() {
|
||||||
|
const data = this.props.data
|
||||||
|
|
||||||
|
if(this.props.type == 'checkbox')
|
||||||
|
this.setState({ toggled: data.toggled || false })
|
||||||
|
}
|
||||||
|
|
||||||
|
async onChange() {
|
||||||
|
// Change toggled state if needed.
|
||||||
|
if(this.props.type == 'checkbox')
|
||||||
|
this.setState({
|
||||||
|
toggled: !this.state.toggled
|
||||||
|
})
|
||||||
|
|
||||||
|
if(!this.props.jsCallback)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const data = this.props.data
|
||||||
|
|
||||||
|
switch(this.props.type) {
|
||||||
|
case 'input':
|
||||||
|
return (
|
||||||
|
<div className={this.props.className}>
|
||||||
|
<TextInput placeholder={data.placeholder} initalValue={data.initialValue} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
case 'dropdown':
|
||||||
|
return (
|
||||||
|
<div className={this.props.className}>
|
||||||
|
<select>
|
||||||
|
{data.options ? data.options.map((option, index) => {
|
||||||
|
return <option key={index}>{option}</option>
|
||||||
|
}) : null}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
case 'button':
|
||||||
|
return (
|
||||||
|
<div className={this.props.className}>
|
||||||
|
<button>{data.text}</button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
<div className={this.props.className}>
|
||||||
|
<Checkbox checked={this.state?.toggled} onChange={this.onChange} id={this.props.className || 'a'} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,11 +7,12 @@ import Tr, { getLanguages, translate } from '../../../utils/language'
|
|||||||
import { setConfigOption, getConfig, getConfigOption } from '../../../utils/configuration'
|
import { setConfigOption, getConfig, getConfigOption } from '../../../utils/configuration'
|
||||||
import Checkbox from '../common/Checkbox'
|
import Checkbox from '../common/Checkbox'
|
||||||
import Divider from './Divider'
|
import Divider from './Divider'
|
||||||
import { getThemeList } from '../../../utils/themes'
|
import { getTheme, getThemeList, ThemeList } from '../../../utils/themes'
|
||||||
import * as server from '../../../utils/server'
|
import * as server from '../../../utils/server'
|
||||||
|
|
||||||
import './Options.css'
|
import './Options.css'
|
||||||
import BigButton from '../common/BigButton'
|
import BigButton from '../common/BigButton'
|
||||||
|
import ThemeOptionValue from '../common/ThemeOptionValue'
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
closeFn: () => void;
|
closeFn: () => void;
|
||||||
@@ -28,6 +29,8 @@ interface IState {
|
|||||||
themes: string[]
|
themes: string[]
|
||||||
theme: string
|
theme: string
|
||||||
encryption: boolean
|
encryption: boolean
|
||||||
|
|
||||||
|
theme_object: ThemeList|null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class Options extends React.Component<IProps, IState> {
|
export default class Options extends React.Component<IProps, IState> {
|
||||||
@@ -44,7 +47,9 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
bg_url_or_path: '',
|
bg_url_or_path: '',
|
||||||
themes: ['default'],
|
themes: ['default'],
|
||||||
theme: '',
|
theme: '',
|
||||||
encryption: false
|
encryption: false,
|
||||||
|
|
||||||
|
theme_object: null
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setGameExec = this.setGameExec.bind(this)
|
this.setGameExec = this.setGameExec.bind(this)
|
||||||
@@ -74,7 +79,9 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
bg_url_or_path: config.customBackground || '',
|
bg_url_or_path: config.customBackground || '',
|
||||||
themes: (await getThemeList()).map(t => t.name),
|
themes: (await getThemeList()).map(t => t.name),
|
||||||
theme: config.theme || 'default',
|
theme: config.theme || 'default',
|
||||||
encryption: await translate(encEnabled ? 'options.enabled' : 'options.disabled')
|
encryption: await translate(encEnabled ? 'options.enabled' : 'options.disabled'),
|
||||||
|
|
||||||
|
theme_object: (await getTheme(config.theme))
|
||||||
})
|
})
|
||||||
|
|
||||||
this.forceUpdate()
|
this.forceUpdate()
|
||||||
@@ -124,7 +131,7 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async setCustomBackground(value: string) {
|
async setCustomBackground(value: string) {
|
||||||
const isUrl = /^(?:http(s)?:\/\/)/gm.test(value)
|
const isUrl = /^http(s)?:\/\//gm.test(value)
|
||||||
|
|
||||||
if (!value) return await setConfigOption('customBackground', '')
|
if (!value) return await setConfigOption('customBackground', '')
|
||||||
|
|
||||||
@@ -168,6 +175,8 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const themeSettings = this.state.theme_object?.settings
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu closeFn={this.props.closeFn} className="Options" heading="Options">
|
<Menu closeFn={this.props.closeFn} className="Options" heading="Options">
|
||||||
<div className='OptionSection' id="menuOptionsContainerGameExec">
|
<div className='OptionSection' id="menuOptionsContainerGameExec">
|
||||||
@@ -178,6 +187,7 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
<DirInput onChange={this.setGameExec} value={this.state?.game_install_path} extensions={['exe']} />
|
<DirInput onChange={this.setGameExec} value={this.state?.game_install_path} extensions={['exe']} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='OptionSection' id="menuOptionsContainerGCJar">
|
<div className='OptionSection' id="menuOptionsContainerGCJar">
|
||||||
<div className='OptionLabel' id="menuOptionsLabelGCJar">
|
<div className='OptionLabel' id="menuOptionsLabelGCJar">
|
||||||
<Tr text="options.grasscutter_jar" />
|
<Tr text="options.grasscutter_jar" />
|
||||||
@@ -186,6 +196,7 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
<DirInput onChange={this.setGrasscutterJar} value={this.state?.grasscutter_path} extensions={['jar']} />
|
<DirInput onChange={this.setGrasscutterJar} value={this.state?.grasscutter_path} extensions={['jar']} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='OptionSection' id="menuOptionsContainerToggleEnc">
|
<div className='OptionSection' id="menuOptionsContainerToggleEnc">
|
||||||
<div className='OptionLabel' id="menuOptionsLabelToggleEnc">
|
<div className='OptionLabel' id="menuOptionsLabelToggleEnc">
|
||||||
<Tr text="options.toggle_encryption" />
|
<Tr text="options.toggle_encryption" />
|
||||||
@@ -281,6 +292,23 @@ export default class Options extends React.Component<IProps, IState> {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
|
||||||
|
{
|
||||||
|
themeSettings ? themeSettings.map((settings, index) => {
|
||||||
|
return (
|
||||||
|
<div className='OptionSection' key={index}>
|
||||||
|
<div className='OptionLabel'>
|
||||||
|
{settings.label}
|
||||||
|
</div>
|
||||||
|
<div className='OptionValue'>
|
||||||
|
<ThemeOptionValue type={settings.type} className={settings.className} data={settings.data} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}) : null
|
||||||
|
}
|
||||||
</Menu>
|
</Menu>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/utils/dom.ts
Normal file
31
src/utils/dom.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { setConfigOption } from './configuration'
|
||||||
|
|
||||||
|
interface DOMMessage {
|
||||||
|
type: string
|
||||||
|
data: ConfigUpdate
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ConfigUpdate {
|
||||||
|
setting: string
|
||||||
|
value: any
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a message received from the DOM.
|
||||||
|
* @param document The document.
|
||||||
|
* @param msg The message received from the DOM.
|
||||||
|
*/
|
||||||
|
export function parseMessageFromDOM(document: Document, msg: any): void {
|
||||||
|
msg = msg.detail
|
||||||
|
|
||||||
|
if(!msg || !msg.type || !msg.data)
|
||||||
|
return
|
||||||
|
|
||||||
|
switch(msg.type) {
|
||||||
|
case 'updateConfig':
|
||||||
|
if(!msg.data.setting || !msg.data.value)
|
||||||
|
return
|
||||||
|
setConfigOption(msg.data.setting, msg.data.value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
import { invoke } from '@tauri-apps/api'
|
import {invoke} from '@tauri-apps/api'
|
||||||
import { dataDir } from '@tauri-apps/api/path'
|
import {dataDir} from '@tauri-apps/api/path'
|
||||||
import { convertFileSrc } from '@tauri-apps/api/tauri'
|
import {convertFileSrc} from '@tauri-apps/api/tauri'
|
||||||
import { getConfig, setConfigOption } from './configuration'
|
import {getConfig, setConfigOption} from './configuration'
|
||||||
|
|
||||||
|
import {InputSettings} from '../ui/components/common/ThemeOptionValue'
|
||||||
|
|
||||||
interface Theme {
|
interface Theme {
|
||||||
name: string
|
name: string
|
||||||
@@ -13,6 +15,16 @@ interface Theme {
|
|||||||
css: string[]
|
css: string[]
|
||||||
js: string[]
|
js: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom settings.
|
||||||
|
settings?: {
|
||||||
|
label: string // The setting's label.
|
||||||
|
type: string // The setting's type.
|
||||||
|
data: InputSettings // The data for the setting.
|
||||||
|
|
||||||
|
className?: string // The name of the class this setting should take.
|
||||||
|
jsCallback?: string // The name of the callback method that should be invoked.
|
||||||
|
}[]
|
||||||
|
|
||||||
customBackgroundURL?: string
|
customBackgroundURL?: string
|
||||||
customBackgroundPath?: string
|
customBackgroundPath?: string
|
||||||
@@ -23,7 +35,7 @@ interface BackendThemeList {
|
|||||||
path: string
|
path: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ThemeList extends Theme {
|
export interface ThemeList extends Theme {
|
||||||
path: string
|
path: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +49,7 @@ const defaultTheme = {
|
|||||||
},
|
},
|
||||||
path: 'default'
|
path: 'default'
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getThemeList() {
|
export async function getThemeList() {
|
||||||
// Do some invoke to backend to get the theme list
|
// Do some invoke to backend to get the theme list
|
||||||
const themes = await invoke('get_theme_list', {
|
const themes = await invoke('get_theme_list', {
|
||||||
@@ -77,6 +90,11 @@ export async function getTheme(name: string) {
|
|||||||
return themes.find(t => t.name === name) || defaultTheme
|
return themes.find(t => t.name === name) || defaultTheme
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getSelectedTheme() {
|
||||||
|
const config = await getConfig()
|
||||||
|
return await getTheme(config.theme)
|
||||||
|
}
|
||||||
|
|
||||||
export async function loadTheme(theme: ThemeList, document: Document) {
|
export async function loadTheme(theme: ThemeList, document: Document) {
|
||||||
// Get config, since we will set the custom background in there
|
// Get config, since we will set the custom background in there
|
||||||
const config = await getConfig()
|
const config = await getConfig()
|
||||||
|
|||||||
Reference in New Issue
Block a user