mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-05 23:10:28 +03:00
Add incomplete dateFormatString setting
This commit is contained in:
parent
4588168a66
commit
1295c1c9b7
14 changed files with 203 additions and 15 deletions
|
|
@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
|
||||||
import dateFormat from 'dateformat';
|
import dateFormat from 'dateformat';
|
||||||
import { isInSameDay } from '../../../util/common';
|
import { isInSameDay } from '../../../util/common';
|
||||||
|
|
||||||
function Time({ timestamp, fullTime, hour24Clock }) {
|
function Time({ timestamp, fullTime, hour24Clock, dateFormatString }) {
|
||||||
const date = new Date(timestamp);
|
const date = new Date(timestamp);
|
||||||
|
|
||||||
const formattedFullTime = dateFormat(
|
const formattedFullTime = dateFormat(
|
||||||
|
|
@ -21,7 +21,7 @@ function Time({ timestamp, fullTime, hour24Clock }) {
|
||||||
|
|
||||||
const timeFormat = hour24Clock ? 'HH:MM' : 'hh:MM TT';
|
const timeFormat = hour24Clock ? 'HH:MM' : 'hh:MM TT';
|
||||||
|
|
||||||
formattedDate = dateFormat(date, isToday || isYesterday ? timeFormat : 'dd/mm/yyyy');
|
formattedDate = dateFormat(date, isToday || isYesterday ? timeFormat : dateFormatString);
|
||||||
if (isYesterday) {
|
if (isYesterday) {
|
||||||
formattedDate = `Yesterday, ${formattedDate}`;
|
formattedDate = `Yesterday, ${formattedDate}`;
|
||||||
}
|
}
|
||||||
|
|
@ -42,6 +42,7 @@ Time.propTypes = {
|
||||||
timestamp: PropTypes.number.isRequired,
|
timestamp: PropTypes.number.isRequired,
|
||||||
fullTime: PropTypes.bool,
|
fullTime: PropTypes.bool,
|
||||||
hour24Clock: PropTypes.bool.isRequired,
|
hour24Clock: PropTypes.bool.isRequired,
|
||||||
|
dateFormatString: PropTypes.string.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Time;
|
export default Time;
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,11 @@ export type TimeProps = {
|
||||||
compact?: boolean;
|
compact?: boolean;
|
||||||
ts: number;
|
ts: number;
|
||||||
hour24Clock: boolean;
|
hour24Clock: boolean;
|
||||||
|
dateFormatString: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Time = as<'span', TimeProps & ComponentProps<typeof Text>>(
|
export const Time = as<'span', TimeProps & ComponentProps<typeof Text>>(
|
||||||
({ compact, hour24Clock, ts, ...props }, ref) => {
|
({ compact, hour24Clock, dateFormatString, ts, ...props }, ref) => {
|
||||||
const formattedTime = timeHourMinute(ts, hour24Clock);
|
const formattedTime = timeHourMinute(ts, hour24Clock);
|
||||||
|
|
||||||
let time = '';
|
let time = '';
|
||||||
|
|
@ -20,7 +21,7 @@ export const Time = as<'span', TimeProps & ComponentProps<typeof Text>>(
|
||||||
} else if (yesterday(ts)) {
|
} else if (yesterday(ts)) {
|
||||||
time = `Yesterday ${formattedTime}`;
|
time = `Yesterday ${formattedTime}`;
|
||||||
} else {
|
} else {
|
||||||
time = `${timeDayMonYear(ts)} ${formattedTime}`;
|
time = `${timeDayMonYear(ts, dateFormatString)} ${formattedTime}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ export function MessageSearch({
|
||||||
const [legacyUsernameColor] = useSetting(settingsAtom, 'legacyUsernameColor');
|
const [legacyUsernameColor] = useSetting(settingsAtom, 'legacyUsernameColor');
|
||||||
|
|
||||||
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
||||||
|
const [dateFormatString] = useSetting(settingsAtom, 'dateFormatString');
|
||||||
|
|
||||||
const searchInputRef = useRef<HTMLInputElement>(null);
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
||||||
const scrollTopAnchorRef = useRef<HTMLDivElement>(null);
|
const scrollTopAnchorRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
@ -292,6 +293,7 @@ export function MessageSearch({
|
||||||
onOpen={navigateRoom}
|
onOpen={navigateRoom}
|
||||||
legacyUsernameColor={legacyUsernameColor || mDirects.has(groupRoom.roomId)}
|
legacyUsernameColor={legacyUsernameColor || mDirects.has(groupRoom.roomId)}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
/>
|
/>
|
||||||
</VirtualTile>
|
</VirtualTile>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ type SearchResultGroupProps = {
|
||||||
onOpen: (roomId: string, eventId: string) => void;
|
onOpen: (roomId: string, eventId: string) => void;
|
||||||
legacyUsernameColor?: boolean;
|
legacyUsernameColor?: boolean;
|
||||||
hour24Clock: boolean;
|
hour24Clock: boolean;
|
||||||
|
dateFormatString: string;
|
||||||
};
|
};
|
||||||
export function SearchResultGroup({
|
export function SearchResultGroup({
|
||||||
room,
|
room,
|
||||||
|
|
@ -68,6 +69,7 @@ export function SearchResultGroup({
|
||||||
onOpen,
|
onOpen,
|
||||||
legacyUsernameColor,
|
legacyUsernameColor,
|
||||||
hour24Clock,
|
hour24Clock,
|
||||||
|
dateFormatString,
|
||||||
}: SearchResultGroupProps) {
|
}: SearchResultGroupProps) {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const useAuthentication = useMediaAuthentication();
|
const useAuthentication = useMediaAuthentication();
|
||||||
|
|
@ -277,7 +279,11 @@ export function SearchResultGroup({
|
||||||
</Username>
|
</Username>
|
||||||
{tagIconSrc && <PowerIcon size="100" iconSrc={tagIconSrc} />}
|
{tagIconSrc && <PowerIcon size="100" iconSrc={tagIconSrc} />}
|
||||||
</Box>
|
</Box>
|
||||||
<Time ts={event.origin_server_ts} hour24Clock={hour24Clock} />
|
<Time
|
||||||
|
ts={event.origin_server_ts}
|
||||||
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Box shrink="No" gap="200" alignItems="Center">
|
<Box shrink="No" gap="200" alignItems="Center">
|
||||||
<Chip
|
<Chip
|
||||||
|
|
|
||||||
|
|
@ -449,6 +449,7 @@ export function RoomTimeline({
|
||||||
const showUrlPreview = room.hasEncryptionStateEvent() ? encUrlPreview : urlPreview;
|
const showUrlPreview = room.hasEncryptionStateEvent() ? encUrlPreview : urlPreview;
|
||||||
const [showHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents');
|
const [showHiddenEvents] = useSetting(settingsAtom, 'showHiddenEvents');
|
||||||
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
||||||
|
const [dateFormatString] = useSetting(settingsAtom, 'dateFormatString');
|
||||||
|
|
||||||
const ignoredUsersList = useIgnoredUsers();
|
const ignoredUsersList = useIgnoredUsers();
|
||||||
const ignoredUsersSet = useMemo(() => new Set(ignoredUsersList), [ignoredUsersList]);
|
const ignoredUsersSet = useMemo(() => new Set(ignoredUsersList), [ignoredUsersList]);
|
||||||
|
|
@ -1070,6 +1071,7 @@ export function RoomTimeline({
|
||||||
accessibleTagColors={accessibleTagColors}
|
accessibleTagColors={accessibleTagColors}
|
||||||
legacyUsernameColor={legacyUsernameColor || direct}
|
legacyUsernameColor={legacyUsernameColor || direct}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
>
|
>
|
||||||
{mEvent.isRedacted() ? (
|
{mEvent.isRedacted() ? (
|
||||||
<RedactedContent reason={mEvent.getUnsigned().redacted_because?.content.reason} />
|
<RedactedContent reason={mEvent.getUnsigned().redacted_because?.content.reason} />
|
||||||
|
|
@ -1152,6 +1154,7 @@ export function RoomTimeline({
|
||||||
accessibleTagColors={accessibleTagColors}
|
accessibleTagColors={accessibleTagColors}
|
||||||
legacyUsernameColor={legacyUsernameColor || direct}
|
legacyUsernameColor={legacyUsernameColor || direct}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
>
|
>
|
||||||
<EncryptedContent mEvent={mEvent}>
|
<EncryptedContent mEvent={mEvent}>
|
||||||
{() => {
|
{() => {
|
||||||
|
|
@ -1254,6 +1257,7 @@ export function RoomTimeline({
|
||||||
accessibleTagColors={accessibleTagColors}
|
accessibleTagColors={accessibleTagColors}
|
||||||
legacyUsernameColor={legacyUsernameColor || direct}
|
legacyUsernameColor={legacyUsernameColor || direct}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
>
|
>
|
||||||
{mEvent.isRedacted() ? (
|
{mEvent.isRedacted() ? (
|
||||||
<RedactedContent reason={mEvent.getUnsigned().redacted_because?.content.reason} />
|
<RedactedContent reason={mEvent.getUnsigned().redacted_because?.content.reason} />
|
||||||
|
|
@ -1286,6 +1290,7 @@ export function RoomTimeline({
|
||||||
ts={mEvent.getTs()}
|
ts={mEvent.getTs()}
|
||||||
compact={messageLayout === MessageLayout.Compact}
|
compact={messageLayout === MessageLayout.Compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1326,6 +1331,7 @@ export function RoomTimeline({
|
||||||
ts={mEvent.getTs()}
|
ts={mEvent.getTs()}
|
||||||
compact={messageLayout === MessageLayout.Compact}
|
compact={messageLayout === MessageLayout.Compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1367,6 +1373,7 @@ export function RoomTimeline({
|
||||||
ts={mEvent.getTs()}
|
ts={mEvent.getTs()}
|
||||||
compact={messageLayout === MessageLayout.Compact}
|
compact={messageLayout === MessageLayout.Compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1408,6 +1415,7 @@ export function RoomTimeline({
|
||||||
ts={mEvent.getTs()}
|
ts={mEvent.getTs()}
|
||||||
compact={messageLayout === MessageLayout.Compact}
|
compact={messageLayout === MessageLayout.Compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1451,6 +1459,7 @@ export function RoomTimeline({
|
||||||
ts={mEvent.getTs()}
|
ts={mEvent.getTs()}
|
||||||
compact={messageLayout === MessageLayout.Compact}
|
compact={messageLayout === MessageLayout.Compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1499,6 +1508,7 @@ export function RoomTimeline({
|
||||||
ts={mEvent.getTs()}
|
ts={mEvent.getTs()}
|
||||||
compact={messageLayout === MessageLayout.Compact}
|
compact={messageLayout === MessageLayout.Compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -679,6 +679,7 @@ export type MessageProps = {
|
||||||
accessibleTagColors?: Map<string, string>;
|
accessibleTagColors?: Map<string, string>;
|
||||||
legacyUsernameColor?: boolean;
|
legacyUsernameColor?: boolean;
|
||||||
hour24Clock: boolean;
|
hour24Clock: boolean;
|
||||||
|
dateFormatString: string;
|
||||||
};
|
};
|
||||||
export const Message = as<'div', MessageProps>(
|
export const Message = as<'div', MessageProps>(
|
||||||
(
|
(
|
||||||
|
|
@ -708,6 +709,7 @@ export const Message = as<'div', MessageProps>(
|
||||||
accessibleTagColors,
|
accessibleTagColors,
|
||||||
legacyUsernameColor,
|
legacyUsernameColor,
|
||||||
hour24Clock,
|
hour24Clock,
|
||||||
|
dateFormatString,
|
||||||
children,
|
children,
|
||||||
...props
|
...props
|
||||||
},
|
},
|
||||||
|
|
@ -776,6 +778,7 @@ export const Message = as<'div', MessageProps>(
|
||||||
ts={mEvent.getTs()}
|
ts={mEvent.getTs()}
|
||||||
compact={messageLayout === MessageLayout.Compact}
|
compact={messageLayout === MessageLayout.Compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,7 @@ function PinnedMessage({ room, eventId, renderContent, onOpen, canPinEvent }: Pi
|
||||||
const accessibleTagColors = useAccessibleTagColors(theme.kind, powerLevelTags);
|
const accessibleTagColors = useAccessibleTagColors(theme.kind, powerLevelTags);
|
||||||
|
|
||||||
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
||||||
|
const [dateFormatString] = useSetting(settingsAtom, 'dateFormatString');
|
||||||
|
|
||||||
const [unpinState, unpin] = useAsyncCallback(
|
const [unpinState, unpin] = useAsyncCallback(
|
||||||
useCallback(() => {
|
useCallback(() => {
|
||||||
|
|
@ -207,7 +208,11 @@ function PinnedMessage({ room, eventId, renderContent, onOpen, canPinEvent }: Pi
|
||||||
</Username>
|
</Username>
|
||||||
{tagIconSrc && <PowerIcon size="100" iconSrc={tagIconSrc} />}
|
{tagIconSrc && <PowerIcon size="100" iconSrc={tagIconSrc} />}
|
||||||
</Box>
|
</Box>
|
||||||
<Time ts={pinnedEvent.getTs()} hour24Clock={hour24Clock} />
|
<Time
|
||||||
|
ts={pinnedEvent.getTs()}
|
||||||
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
{renderOptions()}
|
{renderOptions()}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ export function DeviceTilePlaceholder() {
|
||||||
|
|
||||||
function DeviceActiveTime({ ts }: { ts: number }) {
|
function DeviceActiveTime({ ts }: { ts: number }) {
|
||||||
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
||||||
|
const [dateFormatString] = useSetting(settingsAtom, 'dateFormatString');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Text className={BreakWord} size="T200">
|
<Text className={BreakWord} size="T200">
|
||||||
|
|
@ -53,7 +54,8 @@ function DeviceActiveTime({ ts }: { ts: number }) {
|
||||||
<>
|
<>
|
||||||
{today(ts) && 'Today'}
|
{today(ts) && 'Today'}
|
||||||
{yesterday(ts) && 'Yesterday'}
|
{yesterday(ts) && 'Yesterday'}
|
||||||
{!today(ts) && !yesterday(ts) && timeDayMonYear(ts)} {timeHourMinute(ts, hour24Clock)}
|
{!today(ts) && !yesterday(ts) && timeDayMonYear(ts, dateFormatString)}{' '}
|
||||||
|
{timeHourMinute(ts, hour24Clock)}
|
||||||
</>
|
</>
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ import FocusTrap from 'focus-trap-react';
|
||||||
import { Page, PageContent, PageHeader } from '../../../components/page';
|
import { Page, PageContent, PageHeader } from '../../../components/page';
|
||||||
import { SequenceCard } from '../../../components/sequence-card';
|
import { SequenceCard } from '../../../components/sequence-card';
|
||||||
import { useSetting } from '../../../state/hooks/settings';
|
import { useSetting } from '../../../state/hooks/settings';
|
||||||
import { MessageLayout, MessageSpacing, settingsAtom } from '../../../state/settings';
|
import { DateFormat, MessageLayout, MessageSpacing, settingsAtom } from '../../../state/settings';
|
||||||
import { SettingTile } from '../../../components/setting-tile';
|
import { SettingTile } from '../../../components/setting-tile';
|
||||||
import { KeySymbol } from '../../../utils/key-symbol';
|
import { KeySymbol } from '../../../utils/key-symbol';
|
||||||
import { isMacOS } from '../../../utils/user-agent';
|
import { isMacOS } from '../../../utils/user-agent';
|
||||||
|
|
@ -44,6 +44,7 @@ import {
|
||||||
import { stopPropagation } from '../../../utils/keyboard';
|
import { stopPropagation } from '../../../utils/keyboard';
|
||||||
import { useMessageLayoutItems } from '../../../hooks/useMessageLayout';
|
import { useMessageLayoutItems } from '../../../hooks/useMessageLayout';
|
||||||
import { useMessageSpacingItems } from '../../../hooks/useMessageSpacing';
|
import { useMessageSpacingItems } from '../../../hooks/useMessageSpacing';
|
||||||
|
import { useDateFormatItems } from '../../../hooks/useDateFormat';
|
||||||
import { SequenceCardStyle } from '../styles.css';
|
import { SequenceCardStyle } from '../styles.css';
|
||||||
|
|
||||||
type ThemeSelectorProps = {
|
type ThemeSelectorProps = {
|
||||||
|
|
@ -513,6 +514,76 @@ function SelectMessageSpacing() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function SelectDateFormat() {
|
||||||
|
// ADD TEXT INPUT AND RELATED LOGIC-- ADD LIVE PREVIEW
|
||||||
|
const [menuCords, setMenuCords] = useState<RectCords>();
|
||||||
|
const [dateFormatString, setDateFormatString] = useSetting(settingsAtom, 'dateFormatString');
|
||||||
|
const dateFormatItems = useDateFormatItems();
|
||||||
|
|
||||||
|
const handleMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
|
||||||
|
setMenuCords(evt.currentTarget.getBoundingClientRect());
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelect = (format: DateFormat) => {
|
||||||
|
setDateFormatString(format);
|
||||||
|
setMenuCords(undefined);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
size="300"
|
||||||
|
variant="Secondary"
|
||||||
|
outlined
|
||||||
|
fill="Soft"
|
||||||
|
radii="300"
|
||||||
|
after={<Icon size="300" src={Icons.ChevronBottom} />}
|
||||||
|
onClick={handleMenu}
|
||||||
|
>
|
||||||
|
<Text size="T300">
|
||||||
|
{dateFormatItems.find((i) => i.format === dateFormatString)?.name ?? dateFormatString}
|
||||||
|
</Text>
|
||||||
|
</Button>
|
||||||
|
<PopOut
|
||||||
|
anchor={menuCords}
|
||||||
|
offset={5}
|
||||||
|
position="Bottom"
|
||||||
|
align="End"
|
||||||
|
content={
|
||||||
|
<FocusTrap
|
||||||
|
focusTrapOptions={{
|
||||||
|
initialFocus: false,
|
||||||
|
onDeactivate: () => setMenuCords(undefined),
|
||||||
|
clickOutsideDeactivates: true,
|
||||||
|
isKeyForward: (evt: KeyboardEvent) =>
|
||||||
|
evt.key === 'ArrowDown' || evt.key === 'ArrowRight',
|
||||||
|
isKeyBackward: (evt: KeyboardEvent) =>
|
||||||
|
evt.key === 'ArrowUp' || evt.key === 'ArrowLeft',
|
||||||
|
escapeDeactivates: stopPropagation,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Menu>
|
||||||
|
<Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
|
||||||
|
{dateFormatItems.map((item) => (
|
||||||
|
<MenuItem
|
||||||
|
key={item.format}
|
||||||
|
size="300"
|
||||||
|
variant={dateFormatString === item.format ? 'Primary' : 'Surface'}
|
||||||
|
radii="300"
|
||||||
|
onClick={() => handleSelect(item.format)}
|
||||||
|
>
|
||||||
|
<Text size="T300">{item.name}</Text>
|
||||||
|
</MenuItem>
|
||||||
|
))}
|
||||||
|
</Box>
|
||||||
|
</Menu>
|
||||||
|
</FocusTrap>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function Messages() {
|
function Messages() {
|
||||||
const [legacyUsernameColor, setLegacyUsernameColor] = useSetting(
|
const [legacyUsernameColor, setLegacyUsernameColor] = useSetting(
|
||||||
settingsAtom,
|
settingsAtom,
|
||||||
|
|
@ -615,6 +686,9 @@ function Messages() {
|
||||||
after={<Switch variant="Primary" value={hour24Clock} onChange={setHour24Clock} />}
|
after={<Switch variant="Primary" value={hour24Clock} onChange={setHour24Clock} />}
|
||||||
/>
|
/>
|
||||||
</SequenceCard>
|
</SequenceCard>
|
||||||
|
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
|
||||||
|
<SettingTile title="Date Format" after={<SelectDateFormat />} />
|
||||||
|
</SequenceCard>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
30
src/app/hooks/useDateFormat.ts
Normal file
30
src/app/hooks/useDateFormat.ts
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
import { useMemo } from 'react';
|
||||||
|
import { DateFormat } from '../state/settings';
|
||||||
|
|
||||||
|
export type DateFormatItem = {
|
||||||
|
name: string;
|
||||||
|
format: DateFormat;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useDateFormatItems = (): DateFormatItem[] =>
|
||||||
|
useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
format: 'D MMM YYYY',
|
||||||
|
name: 'D MMM YYYY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: 'DD/MM/YYYY',
|
||||||
|
name: 'DD/MM/YYYY',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: 'YYYY/MM/DD',
|
||||||
|
name: 'YYYY/MM/DD',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
format: '',
|
||||||
|
name: 'Custom',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
@ -138,10 +138,18 @@ type InviteCardProps = {
|
||||||
invite: InviteData;
|
invite: InviteData;
|
||||||
compact?: boolean;
|
compact?: boolean;
|
||||||
hour24Clock: boolean;
|
hour24Clock: boolean;
|
||||||
|
dateFormatString: string;
|
||||||
onNavigate: NavigateHandler;
|
onNavigate: NavigateHandler;
|
||||||
hideAvatar: boolean;
|
hideAvatar: boolean;
|
||||||
};
|
};
|
||||||
function InviteCard({ invite, compact, hour24Clock, onNavigate, hideAvatar }: InviteCardProps) {
|
function InviteCard({
|
||||||
|
invite,
|
||||||
|
compact,
|
||||||
|
hour24Clock,
|
||||||
|
dateFormatString,
|
||||||
|
onNavigate,
|
||||||
|
hideAvatar,
|
||||||
|
}: InviteCardProps) {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const userId = mx.getSafeUserId();
|
const userId = mx.getSafeUserId();
|
||||||
|
|
||||||
|
|
@ -298,7 +306,13 @@ function InviteCard({ invite, compact, hour24Clock, onNavigate, hideAvatar }: In
|
||||||
</Box>
|
</Box>
|
||||||
{invite.inviteTs && (
|
{invite.inviteTs && (
|
||||||
<Box shrink="No">
|
<Box shrink="No">
|
||||||
<Time size="T200" ts={invite.inviteTs} hour24Clock={hour24Clock} priority="300" />
|
<Time
|
||||||
|
size="T200"
|
||||||
|
ts={invite.inviteTs}
|
||||||
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
|
priority="300"
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|
@ -388,8 +402,15 @@ type KnownInvitesProps = {
|
||||||
handleNavigate: NavigateHandler;
|
handleNavigate: NavigateHandler;
|
||||||
compact: boolean;
|
compact: boolean;
|
||||||
hour24Clock: boolean;
|
hour24Clock: boolean;
|
||||||
|
dateFormatString: string;
|
||||||
};
|
};
|
||||||
function KnownInvites({ invites, handleNavigate, compact, hour24Clock }: KnownInvitesProps) {
|
function KnownInvites({
|
||||||
|
invites,
|
||||||
|
handleNavigate,
|
||||||
|
compact,
|
||||||
|
hour24Clock,
|
||||||
|
dateFormatString,
|
||||||
|
}: KnownInvitesProps) {
|
||||||
return (
|
return (
|
||||||
<Box direction="Column" gap="200">
|
<Box direction="Column" gap="200">
|
||||||
<Text size="H4">Primary</Text>
|
<Text size="H4">Primary</Text>
|
||||||
|
|
@ -401,6 +422,7 @@ function KnownInvites({ invites, handleNavigate, compact, hour24Clock }: KnownIn
|
||||||
invite={invite}
|
invite={invite}
|
||||||
compact={compact}
|
compact={compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
onNavigate={handleNavigate}
|
onNavigate={handleNavigate}
|
||||||
hideAvatar={false}
|
hideAvatar={false}
|
||||||
/>
|
/>
|
||||||
|
|
@ -426,8 +448,15 @@ type UnknownInvitesProps = {
|
||||||
handleNavigate: NavigateHandler;
|
handleNavigate: NavigateHandler;
|
||||||
compact: boolean;
|
compact: boolean;
|
||||||
hour24Clock: boolean;
|
hour24Clock: boolean;
|
||||||
|
dateFormatString: string;
|
||||||
};
|
};
|
||||||
function UnknownInvites({ invites, handleNavigate, compact, hour24Clock }: UnknownInvitesProps) {
|
function UnknownInvites({
|
||||||
|
invites,
|
||||||
|
handleNavigate,
|
||||||
|
compact,
|
||||||
|
hour24Clock,
|
||||||
|
dateFormatString,
|
||||||
|
}: UnknownInvitesProps) {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
|
|
||||||
const [declineAllStatus, declineAll] = useAsyncCallback(
|
const [declineAllStatus, declineAll] = useAsyncCallback(
|
||||||
|
|
@ -466,6 +495,7 @@ function UnknownInvites({ invites, handleNavigate, compact, hour24Clock }: Unkno
|
||||||
invite={invite}
|
invite={invite}
|
||||||
compact={compact}
|
compact={compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
onNavigate={handleNavigate}
|
onNavigate={handleNavigate}
|
||||||
hideAvatar
|
hideAvatar
|
||||||
/>
|
/>
|
||||||
|
|
@ -491,8 +521,15 @@ type SpamInvitesProps = {
|
||||||
handleNavigate: NavigateHandler;
|
handleNavigate: NavigateHandler;
|
||||||
compact: boolean;
|
compact: boolean;
|
||||||
hour24Clock: boolean;
|
hour24Clock: boolean;
|
||||||
|
dateFormatString: string;
|
||||||
};
|
};
|
||||||
function SpamInvites({ invites, handleNavigate, compact, hour24Clock }: SpamInvitesProps) {
|
function SpamInvites({
|
||||||
|
invites,
|
||||||
|
handleNavigate,
|
||||||
|
compact,
|
||||||
|
hour24Clock,
|
||||||
|
dateFormatString,
|
||||||
|
}: SpamInvitesProps) {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const [showInvites, setShowInvites] = useState(false);
|
const [showInvites, setShowInvites] = useState(false);
|
||||||
|
|
||||||
|
|
@ -617,6 +654,7 @@ function SpamInvites({ invites, handleNavigate, compact, hour24Clock }: SpamInvi
|
||||||
invite={invite}
|
invite={invite}
|
||||||
compact={compact}
|
compact={compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
onNavigate={handleNavigate}
|
onNavigate={handleNavigate}
|
||||||
hideAvatar
|
hideAvatar
|
||||||
/>
|
/>
|
||||||
|
|
@ -681,6 +719,7 @@ export function Invites() {
|
||||||
const screenSize = useScreenSizeContext();
|
const screenSize = useScreenSizeContext();
|
||||||
|
|
||||||
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
||||||
|
const [dateFormatString] = useSetting(settingsAtom, 'dateFormatString');
|
||||||
|
|
||||||
const handleNavigate = (roomId: string, space: boolean) => {
|
const handleNavigate = (roomId: string, space: boolean) => {
|
||||||
if (space) {
|
if (space) {
|
||||||
|
|
@ -735,6 +774,7 @@ export function Invites() {
|
||||||
invites={knownInvites}
|
invites={knownInvites}
|
||||||
compact={compact}
|
compact={compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
handleNavigate={handleNavigate}
|
handleNavigate={handleNavigate}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
@ -744,6 +784,7 @@ export function Invites() {
|
||||||
invites={unknownInvites}
|
invites={unknownInvites}
|
||||||
compact={compact}
|
compact={compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
handleNavigate={handleNavigate}
|
handleNavigate={handleNavigate}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
@ -753,6 +794,7 @@ export function Invites() {
|
||||||
invites={spamInvites}
|
invites={spamInvites}
|
||||||
compact={compact}
|
compact={compact}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
handleNavigate={handleNavigate}
|
handleNavigate={handleNavigate}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,7 @@ type RoomNotificationsGroupProps = {
|
||||||
onOpen: (roomId: string, eventId: string) => void;
|
onOpen: (roomId: string, eventId: string) => void;
|
||||||
legacyUsernameColor?: boolean;
|
legacyUsernameColor?: boolean;
|
||||||
hour24Clock: boolean;
|
hour24Clock: boolean;
|
||||||
|
dateFormatString: string;
|
||||||
};
|
};
|
||||||
function RoomNotificationsGroupComp({
|
function RoomNotificationsGroupComp({
|
||||||
room,
|
room,
|
||||||
|
|
@ -216,6 +217,7 @@ function RoomNotificationsGroupComp({
|
||||||
onOpen,
|
onOpen,
|
||||||
legacyUsernameColor,
|
legacyUsernameColor,
|
||||||
hour24Clock,
|
hour24Clock,
|
||||||
|
dateFormatString,
|
||||||
}: RoomNotificationsGroupProps) {
|
}: RoomNotificationsGroupProps) {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const useAuthentication = useMediaAuthentication();
|
const useAuthentication = useMediaAuthentication();
|
||||||
|
|
@ -498,7 +500,11 @@ function RoomNotificationsGroupComp({
|
||||||
</Username>
|
</Username>
|
||||||
{tagIconSrc && <PowerIcon size="100" iconSrc={tagIconSrc} />}
|
{tagIconSrc && <PowerIcon size="100" iconSrc={tagIconSrc} />}
|
||||||
</Box>
|
</Box>
|
||||||
<Time ts={event.origin_server_ts} hour24Clock={hour24Clock} />
|
<Time
|
||||||
|
ts={event.origin_server_ts}
|
||||||
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
<Box shrink="No" gap="200" alignItems="Center">
|
<Box shrink="No" gap="200" alignItems="Center">
|
||||||
<Chip
|
<Chip
|
||||||
|
|
@ -552,6 +558,7 @@ export function Notifications() {
|
||||||
const [urlPreview] = useSetting(settingsAtom, 'urlPreview');
|
const [urlPreview] = useSetting(settingsAtom, 'urlPreview');
|
||||||
const [legacyUsernameColor] = useSetting(settingsAtom, 'legacyUsernameColor');
|
const [legacyUsernameColor] = useSetting(settingsAtom, 'legacyUsernameColor');
|
||||||
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
const [hour24Clock] = useSetting(settingsAtom, 'hour24Clock');
|
||||||
|
const [dateFormatString] = useSetting(settingsAtom, 'dateFormatString');
|
||||||
const screenSize = useScreenSizeContext();
|
const screenSize = useScreenSizeContext();
|
||||||
const mDirects = useAtomValue(mDirectAtom);
|
const mDirects = useAtomValue(mDirectAtom);
|
||||||
|
|
||||||
|
|
@ -717,6 +724,7 @@ export function Notifications() {
|
||||||
legacyUsernameColor || mDirects.has(groupRoom.roomId)
|
legacyUsernameColor || mDirects.has(groupRoom.roomId)
|
||||||
}
|
}
|
||||||
hour24Clock={hour24Clock}
|
hour24Clock={hour24Clock}
|
||||||
|
dateFormatString={dateFormatString}
|
||||||
/>
|
/>
|
||||||
</VirtualTile>
|
</VirtualTile>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import { atom } from 'jotai';
|
import { atom } from 'jotai';
|
||||||
|
|
||||||
const STORAGE_KEY = 'settings';
|
const STORAGE_KEY = 'settings';
|
||||||
|
export type DateFormat = 'D MMM YYYY' | 'DD/MM/YYYY' | 'YYYY/MM/DD' | '';
|
||||||
export type MessageSpacing = '0' | '100' | '200' | '300' | '400' | '500';
|
export type MessageSpacing = '0' | '100' | '200' | '300' | '400' | '500';
|
||||||
export enum MessageLayout {
|
export enum MessageLayout {
|
||||||
Modern = 0,
|
Modern = 0,
|
||||||
|
|
@ -36,6 +37,7 @@ export interface Settings {
|
||||||
isNotificationSounds: boolean;
|
isNotificationSounds: boolean;
|
||||||
|
|
||||||
hour24Clock: boolean;
|
hour24Clock: boolean;
|
||||||
|
dateFormatString: string;
|
||||||
|
|
||||||
developerTools: boolean;
|
developerTools: boolean;
|
||||||
}
|
}
|
||||||
|
|
@ -68,6 +70,7 @@ const defaultSettings: Settings = {
|
||||||
isNotificationSounds: true,
|
isNotificationSounds: true,
|
||||||
|
|
||||||
hour24Clock: false,
|
hour24Clock: false,
|
||||||
|
dateFormatString: 'D MMM YYYY',
|
||||||
|
|
||||||
developerTools: false,
|
developerTools: false,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,8 @@ export const yesterday = (ts: number): boolean => dayjs(ts).isYesterday();
|
||||||
export const timeHourMinute = (ts: number, hour24Clock: boolean): string =>
|
export const timeHourMinute = (ts: number, hour24Clock: boolean): string =>
|
||||||
dayjs(ts).format(hour24Clock ? 'HH:mm' : 'hh:mm A');
|
dayjs(ts).format(hour24Clock ? 'HH:mm' : 'hh:mm A');
|
||||||
|
|
||||||
export const timeDayMonYear = (ts: number): string => dayjs(ts).format('D MMM YYYY');
|
export const timeDayMonYear = (ts: number, dateFormatString: string): string =>
|
||||||
|
dayjs(ts).format(dateFormatString);
|
||||||
|
|
||||||
export const timeDayMonthYear = (ts: number): string => dayjs(ts).format('D MMMM YYYY');
|
export const timeDayMonthYear = (ts: number): string => dayjs(ts).format('D MMMM YYYY');
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue