fix: media gallery encrypted rooms + Ctrl+K double-menu
- MediaGallery: switch from createMessagesRequest (returns raw encrypted events) to room.getLiveTimeline().getEvents() which gives already- decrypted MatrixEvent objects. Load More uses paginateEventTimeline(). - QuickSwitcher: change hotkey from Ctrl+K to Ctrl+P to avoid conflict with the existing SearchModalRenderer mod+k handler Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,7 @@ import {
|
||||
TooltipProvider,
|
||||
config,
|
||||
} from 'folds';
|
||||
import { Direction, EventType, MatrixEvent, MsgType, Room } from 'matrix-js-sdk';
|
||||
import { EventType, MsgType, Room } from 'matrix-js-sdk';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
|
||||
import { mxcUrlToHttp } from '../../utils/matrix';
|
||||
@@ -65,53 +65,45 @@ export function MediaGallery({ room, onClose }: MediaGalleryProps) {
|
||||
const useAuthentication = useMediaAuthentication();
|
||||
|
||||
const [tab, setTab] = useState<GalleryTab>('image');
|
||||
const [events, setEvents] = useState<MatrixEvent[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [paginationToken, setPaginationToken] = useState<string | null>(null);
|
||||
const [canLoadMore, setCanLoadMore] = useState(true);
|
||||
|
||||
const msgtype = TAB_MSGTYPES[tab];
|
||||
|
||||
const loadMedia = useCallback(
|
||||
async (fromToken: string | null, append: boolean) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await mx.createMessagesRequest(
|
||||
room.roomId,
|
||||
fromToken,
|
||||
100,
|
||||
Direction.Backward,
|
||||
undefined,
|
||||
);
|
||||
const { end, chunk } = response;
|
||||
const filtered = chunk
|
||||
.filter(
|
||||
(ev) =>
|
||||
ev.type === EventType.RoomMessage &&
|
||||
ev.content?.msgtype === msgtype &&
|
||||
!ev.unsigned?.redacted_because,
|
||||
)
|
||||
.map((ev) => new MatrixEvent(ev));
|
||||
// Read already-decrypted events from the live timeline (works for E2EE rooms)
|
||||
const getFilteredEvents = useCallback(() => {
|
||||
const timeline = room.getLiveTimeline();
|
||||
return timeline
|
||||
.getEvents()
|
||||
.filter((ev) => {
|
||||
if (ev.isRedacted()) return false;
|
||||
const content = ev.getContent();
|
||||
return ev.getType() === EventType.RoomMessage && content.msgtype === msgtype;
|
||||
})
|
||||
.slice()
|
||||
.reverse(); // newest first
|
||||
}, [room, msgtype]);
|
||||
|
||||
setEvents((prev) => (append ? [...prev, ...filtered] : filtered));
|
||||
setPaginationToken(end ?? null);
|
||||
} catch {
|
||||
// silently swallow fetch errors — gallery stays showing what it has
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
},
|
||||
[mx, room.roomId, msgtype],
|
||||
);
|
||||
const [events, setEvents] = useState(() => getFilteredEvents());
|
||||
|
||||
useEffect(() => {
|
||||
setEvents([]);
|
||||
setPaginationToken(null);
|
||||
loadMedia(null, false).catch(() => undefined);
|
||||
}, [loadMedia]);
|
||||
setEvents(getFilteredEvents());
|
||||
setCanLoadMore(true);
|
||||
}, [getFilteredEvents]);
|
||||
|
||||
const handleLoadMore = () => {
|
||||
if (paginationToken) loadMedia(paginationToken, true).catch(() => undefined);
|
||||
};
|
||||
const handleLoadMore = useCallback(async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const timeline = room.getLiveTimeline();
|
||||
const hasMore = await mx.paginateEventTimeline(timeline, { backwards: true, limit: 100 });
|
||||
setEvents(getFilteredEvents());
|
||||
setCanLoadMore(hasMore);
|
||||
} catch {
|
||||
// silently swallow
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [mx, room, getFilteredEvents]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
@@ -306,7 +298,7 @@ export function MediaGallery({ room, onClose }: MediaGalleryProps) {
|
||||
)}
|
||||
|
||||
{/* Load more */}
|
||||
{paginationToken !== null && !loading && (
|
||||
{canLoadMore && !loading && events.length > 0 && (
|
||||
<Box justifyContent="Center" style={{ padding: config.space.S200 }}>
|
||||
<Button
|
||||
size="300"
|
||||
|
||||
@@ -267,7 +267,7 @@ function QuickSwitcherFeature() {
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === 'p') {
|
||||
e.preventDefault();
|
||||
setOpen(true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user