Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a9787ef041 | |||
| fcf16fd654 |
@@ -933,6 +933,17 @@ function Editor() {
|
||||
setComposerToolbarButtons({ ...composerToolbarButtons, [key]: !composerToolbarButtons[key] });
|
||||
};
|
||||
|
||||
const TOOLBAR_CHIPS: Array<{ key: keyof ComposerToolbarSettings; label: string }> = [
|
||||
{ key: 'showFormat', label: 'Format' },
|
||||
{ key: 'showEmoji', label: 'Emoji' },
|
||||
{ key: 'showSticker', label: 'Sticker' },
|
||||
{ key: 'showGif', label: 'GIF' },
|
||||
{ key: 'showLocation', label: 'Location' },
|
||||
{ key: 'showPoll', label: 'Poll' },
|
||||
{ key: 'showVoice', label: 'Voice' },
|
||||
{ key: 'showSchedule', label: 'Schedule' },
|
||||
];
|
||||
|
||||
return (
|
||||
<Box direction="Column" gap="100">
|
||||
<Text size="L400">Editor</Text>
|
||||
@@ -958,89 +969,32 @@ function Editor() {
|
||||
after={<Switch variant="Primary" value={editorToolbar} onChange={setEditorToolbar} />}
|
||||
/>
|
||||
</SequenceCard>
|
||||
<Text size="L400" style={{ marginTop: '8px' }}>Composer Toolbar Buttons</Text>
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column" gap="300">
|
||||
<SettingTile
|
||||
title="Format Toggle"
|
||||
description="Button to show/hide the text formatting toolbar."
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showFormat ?? true}
|
||||
onChange={() => toggleToolbarButton('showFormat')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="Emoji"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showEmoji ?? true}
|
||||
onChange={() => toggleToolbarButton('showEmoji')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="Sticker"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showSticker ?? true}
|
||||
onChange={() => toggleToolbarButton('showSticker')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="GIF"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showGif ?? true}
|
||||
onChange={() => toggleToolbarButton('showGif')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="Location"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showLocation ?? true}
|
||||
onChange={() => toggleToolbarButton('showLocation')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="Poll"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showPoll ?? true}
|
||||
onChange={() => toggleToolbarButton('showPoll')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="Voice Message"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showVoice ?? true}
|
||||
onChange={() => toggleToolbarButton('showVoice')}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<SettingTile
|
||||
title="Schedule Message"
|
||||
after={
|
||||
<Switch
|
||||
variant="Primary"
|
||||
value={composerToolbarButtons?.showSchedule ?? true}
|
||||
onChange={() => toggleToolbarButton('showSchedule')}
|
||||
/>
|
||||
}
|
||||
title="Composer Toolbar"
|
||||
description="Tap a button to show or hide it in the message composer."
|
||||
/>
|
||||
<Box
|
||||
wrap="Wrap"
|
||||
gap="200"
|
||||
style={{ padding: `0 ${config.space.S400} ${config.space.S300}` }}
|
||||
>
|
||||
{TOOLBAR_CHIPS.map(({ key, label }) => {
|
||||
const active = composerToolbarButtons?.[key] ?? true;
|
||||
return (
|
||||
<Chip
|
||||
key={key}
|
||||
variant={active ? 'Primary' : 'Secondary'}
|
||||
outlined={active}
|
||||
radii="Pill"
|
||||
onClick={() => toggleToolbarButton(key)}
|
||||
aria-pressed={active}
|
||||
>
|
||||
<Text size="T300">{label}</Text>
|
||||
</Chip>
|
||||
);
|
||||
})}
|
||||
</Box>
|
||||
</SequenceCard>
|
||||
</Box>
|
||||
);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { roomToUnreadAtom } from '../state/room/roomToUnread';
|
||||
|
||||
// Tauri v2 injects __TAURI_INTERNALS__ into the webview at runtime.
|
||||
// We use it directly so cinny doesn't need @tauri-apps/api as a dependency.
|
||||
type TauriInternals = { invoke: (cmd: string, args?: Record<string, unknown>) => Promise<unknown> };
|
||||
const tauriInvoke = (): TauriInternals['invoke'] | undefined =>
|
||||
(window as unknown as { __TAURI_INTERNALS__?: TauriInternals }).__TAURI_INTERNALS__?.invoke;
|
||||
|
||||
export function useTauriNotificationBadge() {
|
||||
const roomToUnread = useAtomValue(roomToUnreadAtom);
|
||||
|
||||
useEffect(() => {
|
||||
const invoke = tauriInvoke();
|
||||
if (!invoke) return;
|
||||
|
||||
let totalHighlights = 0;
|
||||
roomToUnread.forEach((unread) => {
|
||||
totalHighlights += unread.highlight;
|
||||
});
|
||||
|
||||
invoke('set_badge_count', { count: totalHighlights }).catch(() => {});
|
||||
}, [roomToUnread]);
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import { ScreenSizeProvider, useScreenSize } from '../hooks/useScreenSize';
|
||||
import { useCompositionEndTracking } from '../hooks/useComposingCheck';
|
||||
import { settingsAtom } from '../state/settings';
|
||||
import { LotusToastContainer } from '../features/toast/LotusToastContainer';
|
||||
import { useTauriNotificationBadge } from '../hooks/useTauriNotificationBadge';
|
||||
|
||||
const FONT_MAP: Record<string, string> = {
|
||||
system: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
||||
@@ -52,6 +53,11 @@ function AppearanceEffects() {
|
||||
return null;
|
||||
}
|
||||
|
||||
function TauriEffects() {
|
||||
useTauriNotificationBadge();
|
||||
return null;
|
||||
}
|
||||
|
||||
function NightLightOverlay() {
|
||||
const settings = useAtomValue(settingsAtom);
|
||||
if (!settings.nightLightEnabled) return null;
|
||||
@@ -131,6 +137,7 @@ function App() {
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<JotaiProvider>
|
||||
<AppearanceEffects />
|
||||
<TauriEffects />
|
||||
<RouterProvider router={createRouter(clientConfig, screenSize)} />
|
||||
<NightLightOverlay />
|
||||
<LotusToastContainer />
|
||||
|
||||
Reference in New Issue
Block a user