chore: prettier format all files, brotli, Sentry release tagging, CI gates

Prettier: auto-formatted 103 files to fix baseline. Prettier check in CI
  is now a hard gate (removed continue-on-error).

Brotli: installed libnginx-mod-http-brotli-filter/static. Enabled in nginx
  with brotli_static on for pre-compressed assets and comp_level 6.

Sentry releases: deploy script now exports VITE_APP_VERSION=<git-short-sha>
  before building so each Sentry release maps to an exact commit.
  CI also passes github.sha as VITE_APP_VERSION.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lotus Bot
2026-05-21 20:49:33 -04:00
parent 408fc1b846
commit 42b9cc2b64
105 changed files with 2749 additions and 1850 deletions
+68 -31
View File
@@ -30,7 +30,9 @@ import {
} from 'folds';
import { useMatrixClient } from '../../hooks/useMatrixClient';
const GifPicker = React.lazy(() => import('../../components/GifPicker').then((m) => ({ default: m.GifPicker })));
const GifPicker = React.lazy(() =>
import('../../components/GifPicker').then((m) => ({ default: m.GifPicker }))
);
import { useClientConfig } from '../../hooks/useClientConfig';
import {
CustomEditor,
@@ -57,7 +59,9 @@ import {
getMentions,
} from '../../components/editor';
import { EmojiBoardTab } from '../../components/emoji-board/types';
const EmojiBoard = React.lazy(() => import('../../components/emoji-board').then((m) => ({ default: m.EmojiBoard })));
const EmojiBoard = React.lazy(() =>
import('../../components/emoji-board').then((m) => ({ default: m.EmojiBoard }))
);
import { UseStateProvider } from '../../components/UseStateProvider';
import {
TUploadContent,
@@ -143,7 +147,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
const powerLevels = usePowerLevelsContext();
const creators = useRoomCreators(room);
const alive = useAlive();
const alive = useAlive();
const [msgDraft, setMsgDraft] = useAtom(roomIdToMsgDraftAtomFamily(roomId));
const [replyDraft, setReplyDraft] = useAtom(roomIdToReplyDraftAtomFamily(roomId));
const replyUserID = replyDraft?.userId;
@@ -467,8 +471,15 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
async (gifUrl: string, w: number, h: number) => {
try {
// Only fetch from trusted Giphy CDN domains
const allowed = ['media.giphy.com', 'i.giphy.com', 'media0.giphy.com',
'media1.giphy.com', 'media2.giphy.com', 'media3.giphy.com', 'media4.giphy.com'];
const allowed = [
'media.giphy.com',
'i.giphy.com',
'media0.giphy.com',
'media1.giphy.com',
'media2.giphy.com',
'media3.giphy.com',
'media4.giphy.com',
];
const { hostname } = new URL(gifUrl);
if (!allowed.includes(hostname)) return;
@@ -695,24 +706,26 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
: emojiBtnRef.current?.getBoundingClientRect() ?? undefined
}
content={
<React.Suspense fallback={null}><EmojiBoard
tab={emojiBoardTab}
onTabChange={setEmojiBoardTab}
imagePackRooms={imagePackRooms}
returnFocusOnDeactivate={false}
onEmojiSelect={handleEmoticonSelect}
onCustomEmojiSelect={handleEmoticonSelect}
onStickerSelect={handleStickerSelect}
requestClose={() => {
setEmojiBoardTab((t) => {
if (t) {
if (!mobileOrTablet()) ReactEditor.focus(editor);
return undefined;
}
return t;
});
}}
/></React.Suspense>
<React.Suspense fallback={null}>
<EmojiBoard
tab={emojiBoardTab}
onTabChange={setEmojiBoardTab}
imagePackRooms={imagePackRooms}
returnFocusOnDeactivate={false}
onEmojiSelect={handleEmoticonSelect}
onCustomEmojiSelect={handleEmoticonSelect}
onStickerSelect={handleStickerSelect}
requestClose={() => {
setEmojiBoardTab((t) => {
if (t) {
if (!mobileOrTablet()) ReactEditor.focus(editor);
return undefined;
}
return t;
});
}}
/>
</React.Suspense>
}
>
{!hideStickerBtn && (
@@ -765,11 +778,13 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
: undefined
}
content={
<React.Suspense fallback={null}><GifPicker
apiKey={gifApiKey}
onSelect={handleGifSelect}
requestClose={() => setGifOpen(false)}
/></React.Suspense>
<React.Suspense fallback={null}>
<GifPicker
apiKey={gifApiKey}
onSelect={handleGifSelect}
requestClose={() => setGifOpen(false)}
/>
</React.Suspense>
}
>
<IconButton
@@ -798,7 +813,15 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
</UseStateProvider>
)}
{gifError && (
<Text size="T100" style={{ color: 'var(--tc-danger-normal)', padding: '2px 6px', alignSelf: 'center', whiteSpace: 'nowrap' }}>
<Text
size="T100"
style={{
color: 'var(--tc-danger-normal)',
padding: '2px 6px',
alignSelf: 'center',
whiteSpace: 'nowrap',
}}
>
{gifError}
</Text>
)}
@@ -811,14 +834,28 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
title="Share location"
>
{locating ? (
<Text size="T200" style={{ fontWeight: 800, fontSize: '10px', letterSpacing: '0.04em', lineHeight: 1 }}>
<Text
size="T200"
style={{
fontWeight: 800,
fontSize: '10px',
letterSpacing: '0.04em',
lineHeight: 1,
}}
>
...
</Text>
) : (
<Icon src={Icons.Pin} size="100" />
)}
</IconButton>
<IconButton onClick={submit} variant="SurfaceVariant" size="300" radii="300" aria-label="Send message">
<IconButton
onClick={submit}
variant="SurfaceVariant"
size="300"
radii="300"
aria-label="Send message"
>
<Icon src={Icons.Send} />
</IconButton>
</>