Files
desktop/app/views/Theme/Theme.tsx
rosetta 83f38dc63f 'init'
2026-01-30 05:01:05 +02:00

295 lines
15 KiB
TypeScript

import { Breadcrumbs } from "@/app/components/Breadcrumbs/Breadcrumbs";
import { InternalScreen } from "@/app/components/InternalScreen/InternalScreen";
import { SettingsInput } from "@/app/components/SettingsInput/SettingsInput";
import { useRosettaColors } from "@/app/hooks/useRosettaColors";
import { Box, darken, Divider, Flex, Image, lighten, Paper, Text, useComputedColorScheme, useMantineColorScheme, useMantineTheme } from "@mantine/core";
import lightThemeImage from './comments-light.svg'
import darkThemeImage from './comments-dark.svg'
import { useSetting } from "@/app/providers/SettingsProvider/useSetting";
import { SettingsPaper } from "@/app/components/SettingsPaper/SettingsPaper";
import { Message, MessageStyle, MessageSystem } from "@/app/components/Messages/Message";
import { DeliveredMessageState, DialogProvider } from "@/app/providers/DialogProvider/DialogProvider";
import { AttachmentType } from "@/app/providers/ProtocolProvider/protocol/packets/packet.message";
import { usePublicKey } from "@/app/providers/AccountProvider/usePublicKey";
import { WALLPAPERS } from "@/app/wallpapers/wallpapers";
import { useEffect, useRef } from "react";
export function Theme() {
const {setColorScheme} = useMantineColorScheme({
keepTransitions: true
});
const currentColorSchemeValue = useMantineColorScheme().colorScheme;
const colorScheme = useComputedColorScheme();
const colors = useRosettaColors();
const theme = useMantineTheme();
const publicKey = usePublicKey();
const scrollContainerRef = useRef<HTMLDivElement>(null);
const [showAlertInReplyMessages, setShowAlertInReplyMessages] = useSetting<boolean>
('showAlertInReplyMessages', true);
const [showTimeInReplyMessages, setShowTimeInReplyMessages] = useSetting<boolean>
('showTimeInReplyMessages', false);
const [bgInReplyMessages, setBgInReplyMessages] = useSetting<string>
('bgInReplyMessages', '');
const [messageStyle, setMessageStyle] = useSetting<MessageStyle>
('messageStyle', MessageStyle.ROWS);
const [wallpaper, setWallpaper] = useSetting<string>
('wallpaper', '');
const themeSwitcherColor = colorScheme == 'light' ? darken(colors.chevrons.active, 0.6) :
lighten(colors.chevrons.active, 0.6);
const colorSchemeSwitch = (scheme : any) => {
setColorScheme(scheme);
}
useEffect(() => {
const handleWheel = (event: WheelEvent) => {
event.preventDefault();
if (scrollContainerRef.current) {
scrollContainerRef.current.scrollLeft += event.deltaY;
}
};
const element = scrollContainerRef.current;
if (element) {
element.addEventListener('wheel', handleWheel, { passive: false });
}
return () => {
if (element) {
element.removeEventListener('wheel', handleWheel);
}
};
}, []);
return (<>
<Breadcrumbs text="Theme"></Breadcrumbs>
<InternalScreen>
<SettingsPaper>
<Box style={{
width: '100%',
pointerEvents: 'none',
backgroundImage: wallpaper != '' ? `url(${wallpaper})` : undefined,
backgroundSize: 'cover',
backgroundPosition: 'center',
padding: '10px',
borderTopLeftRadius: '8px',
borderTopRightRadius: '8px',
border: '1px solid ' + colors.borderColor
}}>
<DialogProvider dialog="demo">
<MessageSystem message="today" ></MessageSystem>
<Message
message="Hello! :emoji_1f600:"
timestamp={Math.floor(Date.now())}
delivered={DeliveredMessageState.DELIVERED}
chacha_key_plain=""
from_me={true}
readed={true}
from={""}
attachments={[]}
message_id="example-message-id"
is_last_message_in_stack={true}
/>
<Message
message="How are you? :emoji_1f481:"
timestamp={Math.floor(Date.now() + 60000)}
delivered={DeliveredMessageState.DELIVERED}
chacha_key_plain=""
from_me={false}
from="0x000000000000000000000000000000000000000001"
attachments={[{
id: "",
preview: "",
type: AttachmentType.MESSAGES,
blob: JSON.stringify([
{
publicKey: publicKey,
timestamp: Math.floor(Date.now()),
message: "Hello! :emoji_1f600:",
attachments: []
}
])
}]}
is_last_message_in_stack={true}
message_id="example-message-id"
/>
<Message
message="Good :emoji_1f639:!"
timestamp={Math.floor(Date.now() - 60000)}
delivered={DeliveredMessageState.DELIVERED}
chacha_key_plain=""
from_me={true}
from="0x000000000000000000000000000000000000000001"
attachments={[]}
message_id="example-message-id"
is_last_message_in_stack={true}
/>
</DialogProvider>
</Box>
<Divider w={'100%'}></Divider>
<Flex ref={scrollContainerRef} p={'xs'} style={{
overflowX: 'scroll',
scrollbarWidth: 'none',
}} direction={'row'} align={'center'}>
<Flex direction={'column'} onClick={() => colorSchemeSwitch('light')} align={'center'} justify={'center'}>
<Paper style={{
border: colorScheme == 'light' ? '2px solid var(--mantine-primary-color-6)' : undefined
}} bg={'white'} withBorder w={130} h={80}>
<Image src={lightThemeImage}></Image>
</Paper>
<Text mt={'xs'} size={'xs'} fw={colorScheme == 'light' ? 600 : undefined} c={themeSwitcherColor}>Light</Text>
</Flex>
<Flex direction={'column'} onClick={() => colorSchemeSwitch('dark')} align={'center'} justify={'center'}>
<Paper style={{
border: colorScheme == 'light' ? undefined : '2px solid var(--mantine-primary-color-6)'
}} ml={'sm'} bg={theme.colors.dark[7]} withBorder w={130} h={80}>
<Image src={darkThemeImage}></Image>
</Paper>
<Text mt={'xs'} size={'xs'} fw={colorScheme == 'light' ? undefined : 600} c={themeSwitcherColor}>Dark</Text>
</Flex>
<Divider orientation={'vertical'} ml={'sm'}></Divider>
<Flex direction={'column'} onClick={() => setWallpaper('')} align={'center'} justify={'center'}>
<Paper style={{
border: wallpaper == '' ? '2px solid var(--mantine-primary-color-6)' : undefined
}} ml={'sm'} bg={colorScheme == 'dark' ? 'white' : 'dark'} withBorder w={130} h={80}></Paper>
<Text mt={'xs'} size={'xs'} fw={colorScheme == 'light' ? undefined : 600} c={themeSwitcherColor}>No wallpaper</Text>
</Flex>
{WALLPAPERS.map((wp, index) => (
<Flex style={{
cursor: 'pointer'
}} key={index} direction={'column'} onClick={() => {
setWallpaper(wp.src);
setMessageStyle(MessageStyle.BUBBLES);
}} align={'center'} justify={'center'}>
<Paper style={{
border: wallpaper == wp.src ? '2px solid var(--mantine-primary-color-6)' : undefined
}} ml={'sm'} bg={theme.colors.dark[7]} withBorder w={130} h={80}>
<Image src={wp.src} w={'100%'} h={'100%'} radius={'sm'}></Image>
</Paper>
<Text mt={'xs'} size={'xs'} fw={colorScheme == 'light' ? undefined : 600} c={themeSwitcherColor}>{wp.name}</Text>
</Flex>
))}
</Flex>
</SettingsPaper>
{/* <Paper withBorder styles={{
root: {
borderTop: '1px solid ' + colors.borderColor,
borderBottom: '1px solid ' + colors.borderColor,
borderLeft: '1px solid ' + colors.borderColor,
borderRight: '1px solid ' + colors.borderColor,
cursor: 'pointer'
}
}}
>
<Flex direction={'row'} p={'sm'} justify={'space-between'}>
<Text size={'sm'} fw={400}>Theme</Text>
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end'
}}>
<Flex direction={'column'} onClick={() => colorSchemeSwitch('light')} align={'center'} justify={'center'}>
<Paper style={{
border: colorScheme == 'light' ? '2px solid var(--mantine-primary-color-6)' : undefined
}} bg={'white'} withBorder w={130} h={80}>
<Image src={lightThemeImage}></Image>
</Paper>
<Text mt={'xs'} size={'xs'} fw={colorScheme == 'light' ? 600 : undefined} c={themeSwitcherColor}>Light</Text>
</Flex>
<Flex direction={'column'} onClick={() => colorSchemeSwitch('dark')} align={'center'} justify={'center'}>
<Paper style={{
border: colorScheme == 'light' ? undefined : '2px solid var(--mantine-primary-color-6)'
}} ml={'sm'} bg={theme.colors.dark[7]} withBorder w={130} h={80}>
<Image src={darkThemeImage}></Image>
</Paper>
<Text mt={'xs'} size={'xs'} fw={colorScheme == 'light' ? undefined : 600} c={themeSwitcherColor}>Dark</Text>
</Flex>
</div>
</Flex>
</Paper> */}
{/* <Paper mt={'md'} withBorder styles={{
root: {
borderTop: '1px solid ' + colors.borderColor,
borderBottom: '1px solid ' + colors.borderColor,
borderLeft: '1px solid ' + colors.borderColor,
borderRight: '1px solid ' + colors.borderColor,
}
}}
>
<Message
message="This is an example of reply messages attachment. Reply messages may be forged by sender."
timestamp={Math.floor(Date.now())}
delivered={DeliveredMessageState.DELIVERED}
chacha_key_plain=""
from_me={false}
from="0x000000000000000000000000000000000000000001"
attachments={[{
type: AttachmentType.MESSAGES,
blob: JSON.stringify(exampleMessages),
id: 'attachment-example-id',
preview: ""
}]}
message_id="example-message-id"
/>
</Paper> */}
<SettingsInput.Switch
hit="Dark theme"
defaultValue={currentColorSchemeValue == 'dark'}
mt={'sm'}
onChange={(v) => colorSchemeSwitch(v ? 'dark' : 'light')}
>
</SettingsInput.Switch>
<SettingsInput.Switch
hit="Messages as bubbles"
defaultValue={messageStyle == MessageStyle.BUBBLES || wallpaper != ''}
mt={'sm'}
onChange={(v) => {
if(!v) {
setWallpaper('');
}
setMessageStyle(v ? MessageStyle.BUBBLES : MessageStyle.ROWS)
}}
>
</SettingsInput.Switch>
<Text fz={10} mt={3} c={'gray'} pl={'xs'} pr={'xs'}>
Enable this option to display messages in bubble style, similar to many modern messaging apps.
</Text>
<SettingsInput.Switch
hit="Show alerts in reply messages"
defaultValue={showAlertInReplyMessages}
mt={'sm'}
onChange={(v) => setShowAlertInReplyMessages(v)}
>
</SettingsInput.Switch>
<Text fz={10} mt={3} c={'gray'} pl={'xs'} pr={'xs'}>
Reply messages may be forged by sender, if its option enabled you will see alert in such messages.
</Text>
<SettingsInput.Switch
hit="Show time in reply messages"
defaultValue={showTimeInReplyMessages}
mt={'sm'}
onChange={(v) => setShowTimeInReplyMessages(v)}
>
</SettingsInput.Switch>
<Text fz={10} mt={3} c={'gray'} pl={'xs'} pr={'xs'}>
If this option is enabled, the time will be displayed for each reply message.
</Text>
<SettingsInput.Select
hit={'Background color'}
mt={'sm'}
width={200}
defaultValue={bgInReplyMessages == '' ? 'none' : bgInReplyMessages}
onChange={(v) => {
setBgInReplyMessages(v == 'none' ? '' : v!);
}}
variants={['none', 'red', 'pink', 'grape', 'violet', 'indigo', 'blue', 'cyan', 'teal', 'green', 'lime', 'yellow', 'orange', 'brown', 'gray']}
></SettingsInput.Select>
<Text fz={10} mt={3} c={'gray'} pl={'xs'} pr={'xs'}>
This setting allows you to choose a background color for reply messages to make them stand out more clearly.
</Text>
</InternalScreen>
</>)
}