Add authenticated media support (#1930)

* chore: Bump matrix-js-sdk to 34.4.0

* feat: Authenticated media support

* chore: Use Vite PWA for service worker support

* fix: Fix Vite PWA SW entry point

Forget this. :P

* fix: Also add Nginx rewrite for sw.js

* fix: Correct Nginx rewrite

* fix: Add Netlify redirect for sw.js

Otherwise the generic SPA rewrite to index.html would take effect, breaking Service Worker.

* fix: Account for subpath when regisering service worker

* chore: Correct types
This commit is contained in:
夜坂雅 2024-09-07 21:45:55 +08:00 committed by GitHub
parent 043012e809
commit c6a8fb1117
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
46 changed files with 3562 additions and 487 deletions

View file

@ -42,13 +42,14 @@ import { useRelevantImagePacks } from '../../hooks/useImagePacks';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useRecentEmoji } from '../../hooks/useRecentEmoji';
import { ExtendedPackImage, ImagePack, PackUsage } from '../../plugins/custom-emoji';
import { isUserId } from '../../utils/matrix';
import { isUserId, mxcUrlToHttp } from '../../utils/matrix';
import { editableActiveElement, isIntersectingScrollView, targetFromEvent } from '../../utils/dom';
import { useAsyncSearch, UseAsyncSearchOptions } from '../../hooks/useAsyncSearch';
import { useDebounce } from '../../hooks/useDebounce';
import { useThrottle } from '../../hooks/useThrottle';
import { addRecentEmoji } from '../../plugins/recent-emoji';
import { mobileOrTablet } from '../../utils/user-agent';
import { useSpecVersions } from '../../hooks/useSpecVersions';
const RECENT_GROUP_ID = 'recent_group';
const SEARCH_GROUP_ID = 'search_group';
@ -354,11 +355,13 @@ function ImagePackSidebarStack({
packs,
usage,
onItemClick,
useAuthentication,
}: {
mx: MatrixClient;
packs: ImagePack[];
usage: PackUsage;
onItemClick: (id: string) => void;
useAuthentication?: boolean;
}) {
const activeGroupId = useAtomValue(activeGroupIdAtom);
return (
@ -381,7 +384,7 @@ function ImagePackSidebarStack({
height: toRem(24),
objectFit: 'contain',
}}
src={mx.mxcUrlToHttp(pack.getPackAvatarUrl(usage) ?? '') || pack.avatarUrl}
src={mxcUrlToHttp(mx, pack.getPackAvatarUrl(usage) ?? '', useAuthentication) || pack.avatarUrl}
alt={label || 'Unknown Pack'}
/>
</SidebarBtn>
@ -453,68 +456,70 @@ export function SearchEmojiGroup({
label,
id,
emojis: searchResult,
useAuthentication,
}: {
mx: MatrixClient;
tab: EmojiBoardTab;
label: string;
id: string;
emojis: Array<ExtendedPackImage | IEmoji>;
useAuthentication?: boolean;
}) {
return (
<EmojiGroup key={id} id={id} label={label}>
{tab === EmojiBoardTab.Emoji
? searchResult.map((emoji) =>
'unicode' in emoji ? (
<EmojiItem
key={emoji.unicode}
label={emoji.label}
type={EmojiType.Emoji}
data={emoji.unicode}
shortcode={emoji.shortcode}
>
{emoji.unicode}
</EmojiItem>
) : (
<EmojiItem
key={emoji.shortcode}
label={emoji.body || emoji.shortcode}
type={EmojiType.CustomEmoji}
data={emoji.url}
shortcode={emoji.shortcode}
>
<img
loading="lazy"
className={css.CustomEmojiImg}
alt={emoji.body || emoji.shortcode}
src={mx.mxcUrlToHttp(emoji.url) ?? emoji.url}
/>
</EmojiItem>
)
'unicode' in emoji ? (
<EmojiItem
key={emoji.unicode}
label={emoji.label}
type={EmojiType.Emoji}
data={emoji.unicode}
shortcode={emoji.shortcode}
>
{emoji.unicode}
</EmojiItem>
) : (
<EmojiItem
key={emoji.shortcode}
label={emoji.body || emoji.shortcode}
type={EmojiType.CustomEmoji}
data={emoji.url}
shortcode={emoji.shortcode}
>
<img
loading="lazy"
className={css.CustomEmojiImg}
alt={emoji.body || emoji.shortcode}
src={mxcUrlToHttp(mx, emoji.url, useAuthentication) ?? emoji.url}
/>
</EmojiItem>
)
)
: searchResult.map((emoji) =>
'unicode' in emoji ? null : (
<StickerItem
key={emoji.shortcode}
label={emoji.body || emoji.shortcode}
type={EmojiType.Sticker}
data={emoji.url}
shortcode={emoji.shortcode}
>
<img
loading="lazy"
className={css.StickerImg}
alt={emoji.body || emoji.shortcode}
src={mx.mxcUrlToHttp(emoji.url) ?? emoji.url}
/>
</StickerItem>
)
)}
'unicode' in emoji ? null : (
<StickerItem
key={emoji.shortcode}
label={emoji.body || emoji.shortcode}
type={EmojiType.Sticker}
data={emoji.url}
shortcode={emoji.shortcode}
>
<img
loading="lazy"
className={css.StickerImg}
alt={emoji.body || emoji.shortcode}
src={mxcUrlToHttp(mx, emoji.url, useAuthentication) ?? emoji.url}
/>
</StickerItem>
)
)}
</EmojiGroup>
);
}
export const CustomEmojiGroups = memo(
({ mx, groups }: { mx: MatrixClient; groups: ImagePack[] }) => (
({ mx, groups, useAuthentication }: { mx: MatrixClient; groups: ImagePack[]; useAuthentication?: boolean }) => (
<>
{groups.map((pack) => (
<EmojiGroup key={pack.id} id={pack.id} label={pack.displayName || 'Unknown'}>
@ -530,7 +535,7 @@ export const CustomEmojiGroups = memo(
loading="lazy"
className={css.CustomEmojiImg}
alt={image.body || image.shortcode}
src={mx.mxcUrlToHttp(image.url) ?? image.url}
src={mxcUrlToHttp(mx, image.url, useAuthentication) ?? image.url}
/>
</EmojiItem>
))}
@ -540,7 +545,7 @@ export const CustomEmojiGroups = memo(
)
);
export const StickerGroups = memo(({ mx, groups }: { mx: MatrixClient; groups: ImagePack[] }) => (
export const StickerGroups = memo(({ mx, groups, useAuthentication }: { mx: MatrixClient; groups: ImagePack[]; useAuthentication?: boolean }) => (
<>
{groups.length === 0 && (
<Box
@ -573,7 +578,7 @@ export const StickerGroups = memo(({ mx, groups }: { mx: MatrixClient; groups: I
loading="lazy"
className={css.StickerImg}
alt={image.body || image.shortcode}
src={mx.mxcUrlToHttp(image.url) ?? image.url}
src={mxcUrlToHttp(mx, image.url, useAuthentication) ?? image.url}
/>
</StickerItem>
))}
@ -645,6 +650,8 @@ export function EmojiBoard({
const setActiveGroupId = useSetAtom(activeGroupIdAtom);
const mx = useMatrixClient();
const { versions } = useSpecVersions();
const useAuthentication = versions.includes('v1.11');
const emojiGroupLabels = useEmojiGroupLabels();
const emojiGroupIcons = useEmojiGroupIcons();
const imagePacks = useRelevantImagePacks(mx, usage, imagePackRooms);
@ -729,14 +736,14 @@ export function EmojiBoard({
} else if (emojiInfo.type === EmojiType.CustomEmoji && emojiPreviewRef.current) {
const img = document.createElement('img');
img.className = css.CustomEmojiImg;
img.setAttribute('src', mx.mxcUrlToHttp(emojiInfo.data) || emojiInfo.data);
img.setAttribute('src', mxcUrlToHttp(mx, emojiInfo.data, useAuthentication) || emojiInfo.data);
img.setAttribute('alt', emojiInfo.shortcode);
emojiPreviewRef.current.textContent = '';
emojiPreviewRef.current.appendChild(img);
}
emojiPreviewTextRef.current.textContent = `:${emojiInfo.shortcode}:`;
},
[mx]
[mx, useAuthentication]
);
const throttleEmojiHover = useThrottle(handleEmojiPreview, {
@ -829,6 +836,7 @@ export function EmojiBoard({
usage={usage}
packs={imagePacks}
onItemClick={handleScrollToGroup}
useAuthentication={useAuthentication}
/>
)}
{emojiTab && (
@ -890,13 +898,14 @@ export function EmojiBoard({
id={SEARCH_GROUP_ID}
label={result.items.length ? 'Search Results' : 'No Results found'}
emojis={result.items}
useAuthentication={useAuthentication}
/>
)}
{emojiTab && recentEmojis.length > 0 && (
<RecentEmojiGroup id={RECENT_GROUP_ID} label="Recent" emojis={recentEmojis} />
)}
{emojiTab && <CustomEmojiGroups mx={mx} groups={imagePacks} />}
{stickerTab && <StickerGroups mx={mx} groups={imagePacks} />}
{emojiTab && <CustomEmojiGroups mx={mx} groups={imagePacks} useAuthentication={useAuthentication} />}
{stickerTab && <StickerGroups mx={mx} groups={imagePacks} useAuthentication={useAuthentication} />}
{emojiTab && <NativeEmojiGroups groups={emojiGroups} labels={emojiGroupLabels} />}
</Box>
</Scroll>