Refactor code structure for improved readability and maintainability

This commit is contained in:
2026-05-13 05:47:11 +10:00
parent aaf8089ba6
commit 43bd6320b8
5 changed files with 27 additions and 49 deletions

BIN
build_output.txt Normal file

Binary file not shown.

View File

@@ -21,7 +21,6 @@ import { useEmojiGroupIcons } from './useEmojiGroupIcons';
import { preventScrollWithArrowKey, stopPropagation } from '../../utils/keyboard'; import { preventScrollWithArrowKey, stopPropagation } from '../../utils/keyboard';
import { useRelevantImagePacks } from '../../hooks/useImagePacks'; import { useRelevantImagePacks } from '../../hooks/useImagePacks';
import { useMatrixClient } from '../../hooks/useMatrixClient'; import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useRecentEmoji } from '../../hooks/useRecentEmoji';
import { useEmojiUsage } from '../../hooks/useEmojiUsage'; import { useEmojiUsage } from '../../hooks/useEmojiUsage';
import { isUserId, mxcUrlToHttp } from '../../utils/matrix'; import { isUserId, mxcUrlToHttp } from '../../utils/matrix';
import { editableActiveElement, targetFromEvent } from '../../utils/dom'; import { editableActiveElement, targetFromEvent } from '../../utils/dom';
@@ -76,7 +75,6 @@ const useGroups = (
const mx = useMatrixClient(); const mx = useMatrixClient();
const { getTopEmojis } = useEmojiUsage(); const { getTopEmojis } = useEmojiUsage();
const recentEmojis = useRecentEmoji(mx, 21);
const labels = useEmojiGroupLabels(); const labels = useEmojiGroupLabels();
const emojiGroupItems = useMemo(() => { const emojiGroupItems = useMemo(() => {
@@ -99,12 +97,6 @@ const useGroups = (
} }
} }
g.push({
id: RECENT_GROUP_ID,
name: 'Recent',
items: recentEmojis,
});
imagePacks.forEach((pack) => { imagePacks.forEach((pack) => {
let label = pack.meta.name; let label = pack.meta.name;
if (!label) label = isUserId(pack.id) ? 'Personal Pack' : mx.getRoom(pack.id)?.name; if (!label) label = isUserId(pack.id) ? 'Personal Pack' : mx.getRoom(pack.id)?.name;
@@ -127,7 +119,7 @@ const useGroups = (
}); });
return g; return g;
}, [mx, recentEmojis, labels, imagePacks, tab]); }, [mx, labels, imagePacks, tab, getTopEmojis]);
const stickerGroupItems = useMemo(() => { const stickerGroupItems = useMemo(() => {
const g: StickerGroupItem[] = []; const g: StickerGroupItem[] = [];
@@ -212,13 +204,6 @@ function EmojiSidebar({ activeGroupAtom, packs, onScrollToGroup }: EmojiSidebarP
icon={Icons.Heart} icon={Icons.Heart}
onClick={handleScrollToGroup} onClick={handleScrollToGroup}
/> />
<GroupIcon
active={activeGroupId === RECENT_GROUP_ID}
id={RECENT_GROUP_ID}
label="Recent"
icon={Icons.RecentClock}
onClick={handleScrollToGroup}
/>
</SidebarStack> </SidebarStack>
{packs.length > 0 && ( {packs.length > 0 && (
<SidebarStack> <SidebarStack>

View File

@@ -81,6 +81,9 @@ export function MText({ edited, content, renderBody, renderUrlsPreview, style }:
if (typeof body !== 'string') return <BrokenContent />; if (typeof body !== 'string') return <BrokenContent />;
const trimmedBody = trimReplyFromBody(body).trim(); const trimmedBody = trimReplyFromBody(body).trim();
const trimmedCustomBody = typeof customBody === 'string'
? customBody.trim().replace(/(<br\s*\/?>\s*)+$/gi, '')
: undefined;
const urlsMatch = renderUrlsPreview && trimmedBody.match(URL_REG); const urlsMatch = renderUrlsPreview && trimmedBody.match(URL_REG);
const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined; const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined;
@@ -93,7 +96,7 @@ export function MText({ edited, content, renderBody, renderUrlsPreview, style }:
> >
{renderBody({ {renderBody({
body: trimmedBody, body: trimmedBody,
customBody: typeof customBody === 'string' ? customBody : undefined, customBody: trimmedCustomBody,
})} })}
{edited && <MessageEditedContent />} {edited && <MessageEditedContent />}
</MessageTextBody> </MessageTextBody>
@@ -119,7 +122,10 @@ export function MEmote({
const { body, formatted_body: customBody } = content; const { body, formatted_body: customBody } = content;
if (typeof body !== 'string') return <BrokenContent />; if (typeof body !== 'string') return <BrokenContent />;
const trimmedBody = trimReplyFromBody(body); const trimmedBody = trimReplyFromBody(body).trim();
const trimmedCustomBody = typeof customBody === 'string'
? customBody.trim().replace(/(<br\s*\/?>\s*)+$/gi, '')
: undefined;
const urlsMatch = renderUrlsPreview && trimmedBody.match(URL_REG); const urlsMatch = renderUrlsPreview && trimmedBody.match(URL_REG);
const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined; const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined;
@@ -133,7 +139,7 @@ export function MEmote({
<b>{`${displayName} `}</b> <b>{`${displayName} `}</b>
{renderBody({ {renderBody({
body: trimmedBody, body: trimmedBody,
customBody: typeof customBody === 'string' ? customBody : undefined, customBody: trimmedCustomBody,
})} })}
{edited && <MessageEditedContent />} {edited && <MessageEditedContent />}
</MessageTextBody> </MessageTextBody>
@@ -152,7 +158,10 @@ export function MNotice({ edited, content, renderBody, renderUrlsPreview }: MNot
const { body, formatted_body: customBody } = content; const { body, formatted_body: customBody } = content;
if (typeof body !== 'string') return <BrokenContent />; if (typeof body !== 'string') return <BrokenContent />;
const trimmedBody = trimReplyFromBody(body); const trimmedBody = trimReplyFromBody(body).trim();
const trimmedCustomBody = typeof customBody === 'string'
? customBody.trim().replace(/(<br\s*\/?>\s*)+$/gi, '')
: undefined;
const urlsMatch = renderUrlsPreview && trimmedBody.match(URL_REG); const urlsMatch = renderUrlsPreview && trimmedBody.match(URL_REG);
const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined; const urls = urlsMatch ? [...new Set(urlsMatch)] : undefined;
@@ -165,7 +174,7 @@ export function MNotice({ edited, content, renderBody, renderUrlsPreview }: MNot
> >
{renderBody({ {renderBody({
body: trimmedBody, body: trimmedBody,
customBody: typeof customBody === 'string' ? customBody : undefined, customBody: trimmedCustomBody,
})} })}
{edited && <MessageEditedContent />} {edited && <MessageEditedContent />}
</MessageTextBody> </MessageTextBody>

View File

@@ -405,10 +405,10 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
return; return;
} }
if (plainText === '') return;
let body = plainText.trim(); let body = plainText.trim();
let formattedBody = customHtml.trim(); let formattedBody = customHtml.trim().replace(/(<br\s*\/?>\s*)+$/gi, '');
if (body === '') return;
// Apply emoticon conversion if enabled // Apply emoticon conversion if enabled
if (autoConvertEmoticons) { if (autoConvertEmoticons) {

View File

@@ -62,6 +62,8 @@ import {
import { MessageLayout, MessageSpacing } from '../../../state/settings'; import { MessageLayout, MessageSpacing } from '../../../state/settings';
import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { useRecentEmoji } from '../../../hooks/useRecentEmoji'; import { useRecentEmoji } from '../../../hooks/useRecentEmoji';
import { useEmojiUsage } from '../../../hooks/useEmojiUsage';
import { emojis } from '../../../plugins/emoji';
import * as css from './styles.css'; import * as css from './styles.css';
import { EventReaders } from '../../../components/event-readers'; import { EventReaders } from '../../../components/event-readers';
import { TextViewer } from '../../../components/text-viewer'; import { TextViewer } from '../../../components/text-viewer';
@@ -71,8 +73,6 @@ import { ReactionViewer } from '../reaction-viewer';
import { MessageEditor } from './MessageEditor'; import { MessageEditor } from './MessageEditor';
import { UserAvatar } from '../../../components/user-avatar'; import { UserAvatar } from '../../../components/user-avatar';
import { copyToClipboard } from '../../../utils/dom'; import { copyToClipboard } from '../../../utils/dom';
import { useEmojiUsage } from '../../../hooks/useEmojiUsage';
import { emojis } from '../../../plugins/emoji';
import { stopPropagation } from '../../../utils/keyboard'; import { stopPropagation } from '../../../utils/keyboard';
import { getMatrixToRoomEvent } from '../../../plugins/matrix-to'; import { getMatrixToRoomEvent } from '../../../plugins/matrix-to';
import { getViaServers } from '../../../plugins/via-servers'; import { getViaServers } from '../../../plugins/via-servers';
@@ -93,10 +93,13 @@ type MessageQuickReactionsProps = {
}; };
export const MessageQuickReactions = as<'div', MessageQuickReactionsProps>( export const MessageQuickReactions = as<'div', MessageQuickReactionsProps>(
({ onReaction, ...props }, ref) => { ({ onReaction, ...props }, ref) => {
const mx = useMatrixClient(); const { getTopEmojis } = useEmojiUsage();
const recentEmojis = useRecentEmoji(mx, 4); const topShortcodes = getTopEmojis(4);
const mostUsedEmojis = topShortcodes
.map((shortcode) => emojis.find((e) => e.shortcode === shortcode))
.filter((e): e is IEmoji => e !== undefined);
if (recentEmojis.length === 0) return <span />; if (mostUsedEmojis.length === 0) return <span />;
return ( return (
<> <>
<Box <Box
@@ -107,7 +110,7 @@ export const MessageQuickReactions = as<'div', MessageQuickReactionsProps>(
{...props} {...props}
ref={ref} ref={ref}
> >
{recentEmojis.map((emoji) => ( {mostUsedEmojis.map((emoji) => (
<IconButton <IconButton
key={emoji.unicode} key={emoji.unicode}
className={css.MessageQuickReaction} className={css.MessageQuickReaction}
@@ -776,7 +779,6 @@ export const Message = as<'div', MessageProps>(
const useAuthentication = useMediaAuthentication(); const useAuthentication = useMediaAuthentication();
const senderId = mEvent.getSender() ?? ''; const senderId = mEvent.getSender() ?? '';
const senderPresence = useUserPresence(senderId); const senderPresence = useUserPresence(senderId);
const { getMostUsedEmoji } = useEmojiUsage();
const [hover, setHover] = useState(false); const [hover, setHover] = useState(false);
const { hoverProps } = useHover({ onHoverChange: setHover }); const { hoverProps } = useHover({ onHoverChange: setHover });
@@ -978,24 +980,6 @@ export const Message = as<'div', MessageProps>(
<div className={css.MessageOptionsBase}> <div className={css.MessageOptionsBase}>
<Menu className={css.MessageOptionsBar} variant="SurfaceVariant"> <Menu className={css.MessageOptionsBar} variant="SurfaceVariant">
<Box gap="100"> <Box gap="100">
{canSendReaction && (() => {
const mostUsedShortcode = getMostUsedEmoji();
const mostUsedEmoji = mostUsedShortcode
? emojis.find((e) => e.shortcode === mostUsedShortcode)
: null;
return mostUsedEmoji ? (
<IconButton
onClick={() => onReactionToggle(mEvent.getId()!, mostUsedEmoji.unicode)}
variant="SurfaceVariant"
size="300"
radii="300"
title={`Quick react with ${mostUsedEmoji.unicode}`}
>
<Text size="T300">{mostUsedEmoji.unicode}</Text>
</IconButton>
) : null;
})()}
{canSendReaction && ( {canSendReaction && (
<PopOut <PopOut
position="Bottom" position="Bottom"