diff --git a/build/menubar-icon-dakr@2x.png b/build/menubar-icon-dakr@2x.png new file mode 100644 index 0000000..0c5d855 Binary files /dev/null and b/build/menubar-icon-dakr@2x.png differ diff --git a/build/menubar-icon-dark.png b/build/menubar-icon-dark.png new file mode 100644 index 0000000..76abe91 Binary files /dev/null and b/build/menubar-icon-dark.png differ diff --git a/build/menubar-icon.png b/build/menubar-icon.png index 76abe91..8252aaa 100644 Binary files a/build/menubar-icon.png and b/build/menubar-icon.png differ diff --git a/build/menubar-icon@2x.png b/build/menubar-icon@2x.png index 0c5d855..b05ba81 100644 Binary files a/build/menubar-icon@2x.png and b/build/menubar-icon@2x.png differ diff --git a/electron-builder.yml b/electron-builder.yml index ea2b518..455371c 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -12,6 +12,8 @@ files: extraResources: - build/menubar-icon.png - build/menubar-icon@2x.png + - build/menubar-icon-dark.png + - build/menubar-icon-dark@2x.png asarUnpack: - resources/** win: diff --git a/src/main/constants/index.ts b/src/main/constants/index.ts index 08a2b0b..faf2a90 100644 --- a/src/main/constants/index.ts +++ b/src/main/constants/index.ts @@ -1,8 +1,10 @@ import path from 'path' -export const ICON_PATH_DEV = path.join(__dirname, '..', '..', 'build', 'menubar-icon.png') +export const ICON_PATH_DEV = path.join(__dirname, '..', '..', 'build', 'menubar-icon-dark.png') +export const DARK_ICON_PATH_DEV = path.join(__dirname, '..', '..', 'build', 'menubar-icon.png') -export const ICON_PATH_PROD = path.join(process.resourcesPath, 'build', 'menubar-icon.png') +export const ICON_PATH_PROD = path.join(process.resourcesPath, 'build', 'menubar-icon-dark.png') +export const DARK_ICON_PATH_PROD = path.join(process.resourcesPath, 'build', 'menubar-icon.png') export const INDEX_HTML_PATH = require('url').format({ protocol: 'file', diff --git a/src/main/index.ts b/src/main/index.ts index ce7f1b2..a2e9611 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -1,14 +1,13 @@ import { electronApp, is, optimizer } from '@electron-toolkit/utils' -import { app, BrowserWindow, ipcMain, nativeImage, shell, Tray } from 'electron' +import { app, BrowserWindow, ipcMain, nativeTheme, shell, Tray } from 'electron' import { Menubar, menubar } from 'menubar' import { join } from 'path' -import { ICON_PATH_DEV, ICON_PATH_PROD, INDEX_HTML_PATH } from './constants' +import { INDEX_HTML_PATH } from './constants' import { addContextmenu } from './menu' - -const iconPath = app.isPackaged ? ICON_PATH_PROD : ICON_PATH_DEV -const icon = nativeImage.createFromPath(iconPath) +import { getTrayIcon, onThemeChange } from './menu/theme' let mb: Menubar | null = null +const icon = getTrayIcon() function createWindow(): void { mb = menubar({ @@ -35,11 +34,13 @@ function createWindow(): void { }) mb?.on('ready', () => { - if (mb) { - addContextmenu(mb) - } + addContextmenu(mb!) + nativeTheme.on('updated', () => { + onThemeChange(mb!) + }) }) + // set tray & dock images here app.on('open-url', (event, url) => { event.preventDefault() const authCode = new URL(url).searchParams.get('accessToken') diff --git a/src/main/menu/theme.ts b/src/main/menu/theme.ts new file mode 100644 index 0000000..146f5f9 --- /dev/null +++ b/src/main/menu/theme.ts @@ -0,0 +1,21 @@ +import { app, nativeImage, nativeTheme } from 'electron' +import { Menubar } from 'menubar' +import { + DARK_ICON_PATH_DEV, + DARK_ICON_PATH_PROD, + ICON_PATH_DEV, + ICON_PATH_PROD +} from '../constants' + +export const getTrayIcon = () => { + const isDark = nativeTheme.shouldUseDarkColors + return app.isPackaged + ? nativeImage.createFromPath(isDark ? DARK_ICON_PATH_PROD : ICON_PATH_PROD) + : nativeImage.createFromPath(isDark ? DARK_ICON_PATH_DEV : ICON_PATH_DEV) +} + +export const onThemeChange = (mb: Menubar) => { + const icon = getTrayIcon() + + mb?.tray?.setImage(icon) +} diff --git a/src/renderer/src/components/task-managment/tasks/todo-item.tsx b/src/renderer/src/components/task-managment/tasks/todo-item.tsx index 9ff41a2..36e161c 100644 --- a/src/renderer/src/components/task-managment/tasks/todo-item.tsx +++ b/src/renderer/src/components/task-managment/tasks/todo-item.tsx @@ -63,8 +63,6 @@ export const TodoItem = ({ blockId, text, completed }: NodeItemType) => { deleteMutate() } - console.log(isCompleted) - return ( { /> )} handleUpdateTodo(blockId, undefined, value)} placeholder="To-do" editable={true} diff --git a/src/renderer/src/components/ui/inline-input.tsx b/src/renderer/src/components/ui/inline-input.tsx index 6583be4..ffd2c88 100644 --- a/src/renderer/src/components/ui/inline-input.tsx +++ b/src/renderer/src/components/ui/inline-input.tsx @@ -2,7 +2,7 @@ import { cn } from '@nextui-org/react' import { useEffect, useRef, useState } from 'react' export interface InlineInputProps { - value: string | undefined + defaultValue: string | undefined onChange: (value: string) => void editable?: boolean placeholder?: string @@ -11,44 +11,8 @@ export interface InlineInputProps { customEditing?: boolean } -const useCalculateRows = (width: number) => { - const dummyDivRef = useRef(null) - - useEffect(() => { - dummyDivRef.current = document.createElement('div') - dummyDivRef.current.style.width = `${width}px` - dummyDivRef.current.style.visibility = 'hidden' - dummyDivRef.current.style.whiteSpace = 'pre-wrap' - dummyDivRef.current.style.wordWrap = 'break-word' - dummyDivRef.current.style.position = 'absolute' - dummyDivRef.current.style.pointerEvents = 'none' - dummyDivRef.current.style.zIndex = '-9999' - dummyDivRef.current.style.fontFamily = 'inherit' - dummyDivRef.current.style.fontSize = 'inherit' - dummyDivRef.current.style.lineHeight = 'inherit' - document.body.appendChild(dummyDivRef.current) - - return () => { - if (dummyDivRef.current) { - document.body.removeChild(dummyDivRef.current) - } - } - }, [width]) - - const calculateRows = (text: string) => { - if (dummyDivRef.current) { - dummyDivRef.current.innerText = text - const rows = dummyDivRef.current.clientHeight / 25 // 20 is an approximate line height - return Math.ceil(rows) - } - return 1 - } - - return calculateRows -} - export const InlineInput = ({ - value, + defaultValue, onChange, placeholder, endContent, @@ -56,56 +20,43 @@ export const InlineInput = ({ customEditing = false }: InlineInputProps) => { const [isEditing, setIsEditing] = useState(customEditing) - const [inputValue, setInputValue] = useState(value || '') - const [rows, setRows] = useState(1) - const inputRef = useRef(null) + const [value, setValue] = useState(defaultValue || '') + const [displayValue, setDisplayValue] = useState(defaultValue || '') + const divRef = useRef(null) const containerRef = useRef(null) - const TEXTAREA_WIDTH = 450 - const calculateRows = useCalculateRows(TEXTAREA_WIDTH) - useEffect(() => { if (customEditing) { setIsEditing(true) setTimeout(() => { - inputRef.current?.focus() - resizeTextarea() + divRef.current?.focus() }, 100) } else { setIsEditing(false) } }, [customEditing]) - useEffect(() => { - setInputValue(value || '') - updateRows(value || '') - }, [value]) - - const handleEdit = (e: React.MouseEvent) => { - e.stopPropagation() + const handleEdit = () => { setIsEditing(true) setTimeout(() => { - inputRef.current?.focus() - resizeTextarea() + if (divRef.current) { + divRef.current.focus() + } }, 100) } const handleSave = () => { setIsEditing(false) - onChange(inputValue) + onChange(value) } - const handleKeyDown = (e: React.KeyboardEvent) => { + const handleKeyDown = (e: React.KeyboardEvent) => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault() handleSave() } else if (e.key === 'Escape') { setIsEditing(false) - setInputValue(value || '') - updateRows(value || '') - } else if (e.key === 'a' && e.metaKey) { - e.preventDefault() - inputRef.current?.select() + setDisplayValue(value || '') } } @@ -124,59 +75,40 @@ export const InlineInput = ({ } }, [isEditing]) - const handleInput = (e: React.ChangeEvent) => { - setInputValue(e.target.value) - updateRows(e.target.value) - resizeTextarea() - } - - const resizeTextarea = () => { - if (inputRef.current) { - inputRef.current.style.height = 'auto' - inputRef.current.style.height = `${inputRef.current.scrollHeight}px` - } - } - - const updateRows = (text: string) => { - const calculatedRows = calculateRows(text) - setRows(calculatedRows > 1 ? calculatedRows : 1) + const handleInput = (e: React.FormEvent) => { + setValue(e.currentTarget.textContent || '') } - useEffect(() => { - resizeTextarea() - }, [inputValue]) - return ( -
- {isEditing ? ( -