Skip to content
This repository has been archived by the owner on Feb 5, 2025. It is now read-only.

Commit

Permalink
support edit theme
Browse files Browse the repository at this point in the history
  • Loading branch information
pompurin404 committed Sep 21, 2024
1 parent bce9d24 commit 67a4a3a
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 5 deletions.
14 changes: 11 additions & 3 deletions src/main/resolve/theme.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { copyFile, readdir, readFile } from 'fs/promises'
import { copyFile, readdir, readFile, writeFile } from 'fs/promises'
import { themesDir } from '../utils/dirs'
import path from 'path'
import axios from 'axios'
Expand Down Expand Up @@ -56,9 +56,17 @@ export async function importThemes(files: string[]): Promise<void> {
}
}

export async function readTheme(theme: string): Promise<string> {
if (!existsSync(path.join(themesDir(), theme))) return ''
return await readFile(path.join(themesDir(), theme), 'utf-8')
}

export async function writeTheme(theme: string, css: string): Promise<void> {
await writeFile(path.join(themesDir(), theme), css)
}

export async function applyTheme(theme: string): Promise<void> {
if (!existsSync(path.join(themesDir(), theme))) return
const css = await readFile(path.join(themesDir(), theme), 'utf-8')
const css = await readTheme(theme)
await mainWindow?.webContents.removeInsertedCSS(insertedCSSKey || '')
insertedCSSKey = await mainWindow?.webContents.insertCSS(css)
}
11 changes: 10 additions & 1 deletion src/main/utils/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ import { getInterfaces } from '../sys/interface'
import { copyEnv } from '../resolve/tray'
import { registerShortcut } from '../resolve/shortcut'
import { mainWindow } from '..'
import { applyTheme, fetchThemes, importThemes, resolveThemes } from '../resolve/theme'
import {
applyTheme,
fetchThemes,
importThemes,
readTheme,
resolveThemes,
writeTheme
} from '../resolve/theme'
import { subStoreCollections, subStoreSubs } from '../core/subStoreApi'
import { logDir } from './dirs'
import path from 'path'
Expand Down Expand Up @@ -205,6 +212,8 @@ export function registerIpcMainHandlers(): void {
ipcMain.handle('resolveThemes', () => ipcErrorWrapper(resolveThemes)())
ipcMain.handle('fetchThemes', () => ipcErrorWrapper(fetchThemes)())
ipcMain.handle('importThemes', (_e, file) => ipcErrorWrapper(importThemes)(file))
ipcMain.handle('readTheme', (_e, theme) => ipcErrorWrapper(readTheme)(theme))
ipcMain.handle('writeTheme', (_e, theme, css) => ipcErrorWrapper(writeTheme)(theme, css))
ipcMain.handle('applyTheme', (_e, theme) => ipcErrorWrapper(applyTheme)(theme))
ipcMain.handle('copyEnv', (_e, type) => ipcErrorWrapper(copyEnv)(type))
ipcMain.handle('alert', (_e, msg) => {
Expand Down
54 changes: 54 additions & 0 deletions src/renderer/src/components/settings/css-editor-modal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Button } from '@nextui-org/react'
import { BaseEditor } from '@renderer/components/base/base-editor'
import { readTheme } from '@renderer/utils/ipc'
import React, { useEffect, useState } from 'react'
interface Props {
theme: string
onCancel: () => void
onConfirm: (script: string) => void
}
const CSSEditorModal: React.FC<Props> = (props) => {
const { theme, onCancel, onConfirm } = props
const [currData, setCurrData] = useState('')

useEffect(() => {
if (theme) {
readTheme(theme).then((css) => {
setCurrData(css)
})
}
}, [theme])

return (
<Modal
backdrop="blur"
classNames={{ backdrop: 'top-[48px]' }}
size="5xl"
hideCloseButton
isOpen={true}
onOpenChange={onCancel}
scrollBehavior="inside"
>
<ModalContent className="h-full w-[calc(100%-100px)]">
<ModalHeader className="flex pb-0">编辑主题</ModalHeader>
<ModalBody className="h-full">
<BaseEditor
language="css"
value={currData}
onChange={(value) => setCurrData(value || '')}
/>
</ModalBody>
<ModalFooter className="pt-0">
<Button size="sm" variant="light" onPress={onCancel}>
取消
</Button>
<Button size="sm" color="primary" onPress={() => onConfirm(currData)}>
确认
</Button>
</ModalFooter>
</ModalContent>
</Modal>
)
}

export default CSSEditorModal
29 changes: 28 additions & 1 deletion src/renderer/src/components/settings/general-config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Button, Input, Select, SelectItem, Switch, Tab, Tabs, Tooltip } from '@
import { BiCopy, BiSolidFileImport } from 'react-icons/bi'
import useSWR from 'swr'
import {
applyTheme,
checkAutoRun,
copyEnv,
disableAutoRun,
Expand All @@ -14,17 +15,21 @@ import {
importThemes,
relaunchApp,
resolveThemes,
restartCore
restartCore,
writeTheme
} from '@renderer/utils/ipc'
import { useAppConfig } from '@renderer/hooks/use-app-config'
import { platform } from '@renderer/utils/init'
import { useTheme } from 'next-themes'
import { IoIosHelpCircle, IoMdCloudDownload } from 'react-icons/io'
import { MdEditDocument } from 'react-icons/md'
import CSSEditorModal from './css-editor-modal'

const GeneralConfig: React.FC = () => {
const { data: enable, mutate: mutateEnable } = useSWR('checkAutoRun', checkAutoRun)
const { appConfig, patchAppConfig } = useAppConfig()
const [customThemes, setCustomThemes] = useState<{ key: string; label: string }[]>()
const [openCSSEditor, setOpenCSSEditor] = useState(false)
const [fetching, setFetching] = useState(false)
const { setTheme } = useTheme()
const {
Expand All @@ -49,6 +54,17 @@ const GeneralConfig: React.FC = () => {

return (
<>
{openCSSEditor && (
<CSSEditorModal
theme={customTheme}
onCancel={() => setOpenCSSEditor(false)}
onConfirm={async (css: string) => {
await writeTheme(customTheme, css)
await applyTheme(customTheme)
setOpenCSSEditor(false)
}}
/>
)}
<SettingCard>
<SettingItem title="开机自启" divider>
<Switch
Expand Down Expand Up @@ -261,6 +277,17 @@ const GeneralConfig: React.FC = () => {
>
<BiSolidFileImport className="text-lg" />
</Button>
<Button
size="sm"
isIconOnly
title="编辑主题"
variant="light"
onPress={async () => {
setOpenCSSEditor(true)
}}
>
<MdEditDocument className="text-lg" />
</Button>
</>
}
>
Expand Down
8 changes: 8 additions & 0 deletions src/renderer/src/utils/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,14 @@ export async function importThemes(files: string[]): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('importThemes', files))
}

export async function readTheme(theme: string): Promise<string> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('readTheme', theme))
}

export async function writeTheme(theme: string, css: string): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('writeTheme', theme, css))
}

let applyThemeRunning = false
const waitList: string[] = []
export async function applyTheme(theme: string): Promise<void> {
Expand Down

0 comments on commit 67a4a3a

Please sign in to comment.