diff --git a/src/app/components/create-room/utils.ts b/src/app/components/create-room/utils.ts index 05ad79c33..4a00e54fa 100644 --- a/src/app/components/create-room/utils.ts +++ b/src/app/components/create-room/utils.ts @@ -80,7 +80,7 @@ const createSpacePowerLevelsOverride = () => ({ }); export const createRoomEncryptionState = () => ({ - type: 'm.room.encryption', + type: EventType.RoomEncryption, state_key: '', content: { algorithm: 'm.megolm.v1.aes-sha2', diff --git a/src/app/components/event-history/EventHistory.tsx b/src/app/components/event-history/EventHistory.tsx index 7fc644262..810cbd9b0 100644 --- a/src/app/components/event-history/EventHistory.tsx +++ b/src/app/components/event-history/EventHistory.tsx @@ -48,7 +48,7 @@ import { usePowerLevelsContext } from '$hooks/usePowerLevels'; import { useSettingsLinkBaseUrl } from '$features/settings/useSettingsLinkBaseUrl'; import * as css from './EventHistory.css'; -import { EventType } from '$types/matrix-sdk'; +import { EventType, RelationType } from '$types/matrix-sdk'; type EventHistoryProps = { room: Room; @@ -104,7 +104,7 @@ export const EventHistory = as<'div', EventHistoryProps>( const formattedBody = content?.['m.new_content']?.formatted_body ?? content?.formatted_body ?? ''; const { 'm.relates_to': relation } = startThread - ? { 'm.relates_to': { rel_type: 'm.thread', event_id: replyId } } + ? { 'm.relates_to': { rel_type: RelationType.Thread, event_id: replyId } } : replyEvt.getWireContent(); const senderId = replyEvt.getSender(); if (senderId) { diff --git a/src/app/components/message/PollEvent.tsx b/src/app/components/message/PollEvent.tsx index 7060af819..dd29bf969 100644 --- a/src/app/components/message/PollEvent.tsx +++ b/src/app/components/message/PollEvent.tsx @@ -13,6 +13,7 @@ import { } from 'matrix-js-sdk'; import * as css from './PollEvent.css'; import { useCallback, useEffect, useState } from 'react'; +import { MsgType, RelationType } from '$types/matrix-sdk'; import { PollResponsesViewer } from '$features/room/poll-modals'; import { ModalOverlay } from '$components/modal-overlay/ModalOverlay'; import { useMatrixEvent } from '$hooks/useMatrixEvent'; @@ -188,7 +189,7 @@ export function PollEvent({ content, mEvent, mx, room }: PollEventProps) { let newContent: PollResponse = { 'm.relates_to': { - rel_type: 'm.reference', + rel_type: RelationType.Reference, event_id: eventId, }, [M_POLL_RESPONSE.name]: { @@ -220,13 +221,13 @@ export function PollEvent({ content, mEvent, mx, room }: PollEventProps) { const endContent = { 'm.relates_to': { - rel_type: 'm.reference', + rel_type: RelationType.Reference, event_id: eventId, }, 'org.matrix.msc3381.poll.end': {}, [M_TEXT.name]: endText, body: endText, - msgtype: 'm.text', + msgtype: MsgType.Text, }; mx.sendEvent( roomId, diff --git a/src/app/components/message/modals/MessageForward.tsx b/src/app/components/message/modals/MessageForward.tsx index 9752dec20..01a651995 100644 --- a/src/app/components/message/modals/MessageForward.tsx +++ b/src/app/components/message/modals/MessageForward.tsx @@ -6,6 +6,7 @@ import { MenuItem, Text, as } from 'folds'; import { ArrowRight, menuIcon } from '$components/icons/phosphor'; import { useSetAtom } from 'jotai'; import type { MatrixEvent, Room } from '$types/matrix-sdk'; +import { MsgType } from '$types/matrix-sdk'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { useAllJoinedRoomsSet, useGetRoom } from '$hooks/useGetRoom'; import { useMessageTargetRooms } from '$hooks/useMessageTargetRooms'; @@ -129,7 +130,7 @@ export function MessageForwardInternal({ const eventType = mEvent.getType() as SendEventType; const originalContent = mEvent.getContent(); - const isTextMessage = originalContent.msgtype === 'm.text'; + const isTextMessage = originalContent.msgtype === MsgType.Text; const originalBody = typeof originalContent.body === 'string' ? originalContent.body : ''; const originalFormattedBody = diff --git a/src/app/components/message/modals/Options.tsx b/src/app/components/message/modals/Options.tsx index 7ad25366b..0f5b27dee 100644 --- a/src/app/components/message/modals/Options.tsx +++ b/src/app/components/message/modals/Options.tsx @@ -586,7 +586,7 @@ function OptionMenu({ const store = useStore(); const mx = useMatrixClient(); const isThreadedMessage = isThreadRelationEvent(mEvent, mEvent.threadRootId); - const isStickerMessage = mEvent.getType() === 'm.stidoecker'; + const isStickerMessage = mEvent.getType() === (EventType.Sticker as string); const evtId = mEvent.getId()!; const evtTimeline = room.getTimelineForEvent(evtId); const edits = diff --git a/src/app/features/common-settings/developer-tools/DevelopTools.tsx b/src/app/features/common-settings/developer-tools/DevelopTools.tsx index cdbf5d19a..52ae323f7 100644 --- a/src/app/features/common-settings/developer-tools/DevelopTools.tsx +++ b/src/app/features/common-settings/developer-tools/DevelopTools.tsx @@ -102,7 +102,11 @@ export function DeveloperTools({ requestBack, requestClose }: DeveloperToolsProp const latestTimelineEventId = latestTimelineEvent?.getId() ?? null; const latestMessageEvent = [...liveEvents].toReversed().find((event) => { const type = event.getType(); - return type === 'm.room.message' || type === 'm.room.encrypted' || type === 'm.sticker'; + return ( + type === (EventType.RoomMessage as string) || + type === (EventType.RoomMessageEncrypted as string) || + type === (EventType.Sticker as string) + ); }); const latestMessageEventId = latestMessageEvent?.getId() ?? null; const latestNotificationEvent = [...liveEvents] diff --git a/src/app/features/room/RoomTimeline.tsx b/src/app/features/room/RoomTimeline.tsx index e8f858e25..327e51505 100644 --- a/src/app/features/room/RoomTimeline.tsx +++ b/src/app/features/room/RoomTimeline.tsx @@ -1169,7 +1169,7 @@ export function RoomTimeline({ .find( (e) => e.mEvent.getSender() === myUserId && - e.mEvent.getType() === 'm.room.message' && + e.mEvent.getType() === (EventType.RoomMessage as string) && !e.mEvent.isRedacted() ); if (found?.mEvent.getId()) actions.handleEdit(found.mEvent.getId()); diff --git a/src/app/features/room/location-modal/LocationDialog.tsx b/src/app/features/room/location-modal/LocationDialog.tsx index 6a14deac7..d35c07281 100644 --- a/src/app/features/room/location-modal/LocationDialog.tsx +++ b/src/app/features/room/location-modal/LocationDialog.tsx @@ -12,6 +12,7 @@ import type { LatLngLiteral } from 'leaflet'; import L from 'leaflet'; import { getReplyContent } from '../RoomInput'; import type { RoomMessageEventContent } from '$types/matrix-sdk'; +import { MsgType } from '$types/matrix-sdk'; import { settingsAtom } from '$state/settings'; import { useSetting } from '$state/hooks/settings'; import classNames from 'classnames'; @@ -238,7 +239,7 @@ export function LocationDialog({ const mlat = pinPosition.lat.toFixed(6); const mlon = pinPosition.lng.toFixed(6); const content: IContent = { - msgtype: 'm.location', + msgtype: MsgType.Location, geo_uri: `geo:${mlat},${mlon};u=0`, body: `https://www.openstreetmap.org/?mlat=${mlat}&mlon=${mlon}#map=16/${mlat}/${mlon}"`, }; diff --git a/src/app/features/room/message/Message.tsx b/src/app/features/room/message/Message.tsx index 01636c402..6926a8d6b 100644 --- a/src/app/features/room/message/Message.tsx +++ b/src/app/features/room/message/Message.tsx @@ -24,7 +24,7 @@ import { } from 'react'; import { useHover, useFocusWithin } from 'react-aria'; import type { MatrixEvent, Room, Relations } from '$types/matrix-sdk'; -import { EventStatus, MatrixEventEvent, RoomEvent } from '$types/matrix-sdk'; +import { EventStatus, MatrixEventEvent, MsgType, RoomEvent } from '$types/matrix-sdk'; import classNames from 'classnames'; import { useSetAtom } from 'jotai'; import { @@ -393,7 +393,7 @@ function MessageInternal( const isGif = useMemo(() => { const content = mEvent.getContent(); - if (content.msgtype !== 'm.image') return false; + if (content.msgtype !== MsgType.Image) return false; return checkIfGif(content?.info?.url ?? '', content?.info?.mimetype, content?.body); }, [mEvent]); diff --git a/src/app/features/room/poll-modals/PollDialog.tsx b/src/app/features/room/poll-modals/PollDialog.tsx index a906bfc4a..a0e15b8f6 100644 --- a/src/app/features/room/poll-modals/PollDialog.tsx +++ b/src/app/features/room/poll-modals/PollDialog.tsx @@ -25,6 +25,7 @@ import { M_POLL_START, M_TEXT, } from 'matrix-js-sdk'; +import { MsgType } from '$types/matrix-sdk'; import { isKeyHotkey } from 'is-hotkey'; import * as css from './PollDialog.css'; import type { IReplyDraft } from '$state/room/roomInputDrafts'; @@ -113,7 +114,7 @@ export function PollDialog({ onCancel, mx, room, replyDraft, clearReplyDraft }: question: { [M_TEXT.name]: title.current, body: title.current, - msgtype: 'm.text', + msgtype: MsgType.Text, }, kind: isDisclosed ? M_POLL_KIND_DISCLOSED.name : M_POLL_KIND_UNDISCLOSED.name, max_selections: maxSelections, diff --git a/src/app/features/room/schedule-send/ScheduledMessagesList.tsx b/src/app/features/room/schedule-send/ScheduledMessagesList.tsx index 5ddc1bf8e..16583b392 100644 --- a/src/app/features/room/schedule-send/ScheduledMessagesList.tsx +++ b/src/app/features/room/schedule-send/ScheduledMessagesList.tsx @@ -11,7 +11,7 @@ import { X, } from '$components/icons/phosphor'; import type { Room } from '$types/matrix-sdk'; -import { MatrixEvent } from '$types/matrix-sdk'; +import { EventType, MatrixEvent } from '$types/matrix-sdk'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; import { useMatrixClient } from '$hooks/useMatrixClient'; import { @@ -157,7 +157,8 @@ export function ScheduledMessagesList({ room, onEditMessage }: ScheduledMessages const roomEvents = data?.delayed_events.filter( (event) => event.room_id === room.roomId && - (event.type === 'm.room.message' || event.type === 'm.room.encrypted') + (event.type === (EventType.RoomMessage as string) || + event.type === (EventType.RoomMessageEncrypted as string)) ); const invalidateEvents = useCallback(() => { diff --git a/src/app/features/settings/notifications/AllMessages.tsx b/src/app/features/settings/notifications/AllMessages.tsx index 87d5a699e..66d4d4895 100644 --- a/src/app/features/settings/notifications/AllMessages.tsx +++ b/src/app/features/settings/notifications/AllMessages.tsx @@ -25,7 +25,7 @@ const getAllMessageDefaultRule = ( conditions.push({ kind: ConditionKind.EventMatch, key: 'type', - pattern: encrypted ? 'm.room.encrypted' : 'm.room.message', + pattern: encrypted ? EventType.RoomMessageEncrypted : EventType.RoomMessage, }); return { diff --git a/src/app/features/settings/notifications/UnifiedPushNotifications.ts b/src/app/features/settings/notifications/UnifiedPushNotifications.ts index 3375271e6..31ed4dda7 100644 --- a/src/app/features/settings/notifications/UnifiedPushNotifications.ts +++ b/src/app/features/settings/notifications/UnifiedPushNotifications.ts @@ -364,7 +364,7 @@ async function decryptPreviewFromPayload( const crypto = mx.getCrypto(); if (!crypto || !pushData.content) return undefined; const mEvent = new MatrixEvent({ - type: 'm.room.encrypted', + type: EventType.RoomMessageEncrypted, content: pushData.content, room_id: roomId, event_id: eventId, diff --git a/src/app/hooks/commands/fun.ts b/src/app/hooks/commands/fun.ts index d2f356d08..a4dd60b07 100644 --- a/src/app/hooks/commands/fun.ts +++ b/src/app/hooks/commands/fun.ts @@ -1,4 +1,5 @@ import type { RoomMessageEventContent } from '$types/matrix-sdk'; +import { MsgType } from '$types/matrix-sdk'; import type { CommandContext, CommandRecord } from './types'; import { Command } from './types'; @@ -102,7 +103,7 @@ export const createFunCommands = (ctx: CommandContext): Partial = exe: async (payload) => { const target = payload.trim(); await mx.sendMessage(room.roomId, { - msgtype: 'm.emote', + msgtype: MsgType.Emote, 'm.mentions': { user_ids: target ? [target] : [], }, diff --git a/src/app/hooks/commands/misc.ts b/src/app/hooks/commands/misc.ts index 83952551a..23da23bbe 100644 --- a/src/app/hooks/commands/misc.ts +++ b/src/app/hooks/commands/misc.ts @@ -1,5 +1,5 @@ import type { RoomMessageEventContent } from '$types/matrix-sdk'; -import { MatrixError } from '$types/matrix-sdk'; +import { MatrixError, MsgType } from '$types/matrix-sdk'; import { sendFeedback } from '$utils/sendFeedbackToUser'; import { CustomStateEvent } from '$types/matrix/room'; import { ErrorCode } from '../../cs-errorcode'; @@ -140,7 +140,7 @@ export const createMiscCommands = (ctx: CommandContext): Partial if (mlat && mlon) await mx.sendMessage(room.roomId, { - msgtype: 'm.location', + msgtype: MsgType.Location, geo_uri: `geo:${mlat},${mlon};u=0`, body: `https://www.openstreetmap.org/?mlat=${mlat}&mlon=${mlon}#map=16/${mlat}/${mlon}"`, } as RoomMessageEventContent); @@ -176,7 +176,7 @@ export const createMiscCommands = (ctx: CommandContext): Partial return; } mx.sendMessage(room.roomId, { - msgtype: 'm.location', + msgtype: MsgType.Location, geo_uri: `geo:${mlat},${mlon}${malt ? `,${malt}` : ''};u=0`, body: `https://www.openstreetmap.org/?mlat=${mlat}&mlon=${mlon}#map=16/${mlat}/${mlon}"`, } as unknown as RoomMessageEventContent); diff --git a/src/app/hooks/timeline/useProcessedTimeline.ts b/src/app/hooks/timeline/useProcessedTimeline.ts index fcc91e1bb..d7c6bba36 100644 --- a/src/app/hooks/timeline/useProcessedTimeline.ts +++ b/src/app/hooks/timeline/useProcessedTimeline.ts @@ -69,27 +69,32 @@ export function getProcessedRowIndexForRawTimelineIndex( return bestRowIndex >= 0 ? { rowIndex: bestRowIndex, focusRawIndex: bestRawIndex } : undefined; } +// Decrypted room-message events are re-typed to this app-internal value; there is no SDK constant for it. +const ROOM_MESSAGE_DECRYPTED = 'm.room.message.encrypted'; + const MESSAGE_EVENT_TYPES = new Set([ - 'm.room.message', - 'm.room.message.encrypted', - 'm.sticker', - 'm.room.encrypted', + EventType.RoomMessage, + ROOM_MESSAGE_DECRYPTED, + EventType.Sticker, + EventType.RoomMessageEncrypted, ]); export const STANDARD_RENDERED_EVENT_TYPES = new Set([ - 'm.room.message', - 'm.room.message.encrypted', - 'm.sticker', + EventType.RoomMessage, + ROOM_MESSAGE_DECRYPTED, + EventType.Sticker, M_POLL_START.name, - 'm.room.member', - 'm.room.name', - 'm.room.topic', - 'm.room.avatar', - 'org.matrix.msc3401.call.member', + EventType.RoomMember, + EventType.RoomName, + EventType.RoomTopic, + EventType.RoomAvatar, + EventType.GroupCallMemberPrefix, ]); const normalizeMessageType = (t: string): string => - t === 'm.room.encrypted' || t === 'm.room.message.encrypted' ? 'm.room.message' : t; + t === (EventType.RoomMessageEncrypted as string) || t === ROOM_MESSAGE_DECRYPTED + ? EventType.RoomMessage + : t; const isMessageRow = (mEvent: MatrixEvent): boolean => MESSAGE_EVENT_TYPES.has(mEvent.getType()) && !isEditEvent(mEvent); diff --git a/src/app/hooks/timeline/useTimelineActions.ts b/src/app/hooks/timeline/useTimelineActions.ts index aee5028b4..b68a71f71 100644 --- a/src/app/hooks/timeline/useTimelineActions.ts +++ b/src/app/hooks/timeline/useTimelineActions.ts @@ -2,7 +2,7 @@ import type { MouseEventHandler } from 'react'; import { useCallback } from 'react'; import type { MatrixClient, Room, MatrixEvent } from '$types/matrix-sdk'; import type { UserProfile } from '$hooks/useUserProfile'; -import { EventStatus } from '$types/matrix-sdk'; +import { EventStatus, RelationType } from '$types/matrix-sdk'; import type { Editor } from 'slate'; import { ReactEditor } from 'slate-react'; @@ -154,7 +154,7 @@ export function useTimelineActions({ userId: mx.getUserId() ?? '', eventId: threadRootId, body: '', - relation: { rel_type: 'm.thread', event_id: threadRootId }, + relation: { rel_type: RelationType.Thread, event_id: threadRootId }, } : undefined ); @@ -165,7 +165,7 @@ export function useTimelineActions({ const { body, formattedBody } = extractReplyDraftBody(replyEvt, timelineSet); const { 'm.relates_to': relation } = startThread - ? { 'm.relates_to': { rel_type: 'm.thread', event_id: draftEventId } } + ? { 'm.relates_to': { rel_type: RelationType.Thread, event_id: draftEventId } } : replyEvt.getWireContent(); const senderId = replyEvt.getSender(); diff --git a/src/app/hooks/timeline/useTimelineRendererContext.ts b/src/app/hooks/timeline/useTimelineRendererContext.ts index ce47d892d..9b87ec892 100644 --- a/src/app/hooks/timeline/useTimelineRendererContext.ts +++ b/src/app/hooks/timeline/useTimelineRendererContext.ts @@ -1,5 +1,6 @@ import { useMemo } from 'react'; import type { Room } from '$types/matrix-sdk'; +import { EventType } from '$types/matrix-sdk'; import type { HTMLReactParserOptions } from 'html-react-parser'; import type { Opts as LinkifyOpts } from 'linkifyjs'; import { @@ -109,9 +110,9 @@ export function useTimelineRendererContext(room: Room): TimelineRendererContextV const creators = useRoomCreators(room); const permissions = useRoomPermissions(creators, powerLevels); const canRedact = permissions.action('redact', mx.getSafeUserId()); - const canDeleteOwn = permissions.event('m.room.redaction', mx.getSafeUserId()); - const canSendReaction = permissions.event('m.reaction', mx.getSafeUserId()); - const canPinEvent = permissions.stateEvent('m.room.pinned_events', mx.getSafeUserId()); + const canDeleteOwn = permissions.event(EventType.RoomRedaction, mx.getSafeUserId()); + const canSendReaction = permissions.event(EventType.Reaction, mx.getSafeUserId()); + const canPinEvent = permissions.stateEvent(EventType.RoomPinnedEvents, mx.getSafeUserId()); const isReadOnly = !permissions.message(room.hasEncryptionStateEvent(), mx.getSafeUserId()); const getMemberPowerTag = useGetMemberPowerTag(room, creators, powerLevels); const parseMemberEvent = useMemberEventParser(); diff --git a/src/app/pages/client/BackgroundNotifications.tsx b/src/app/pages/client/BackgroundNotifications.tsx index 8f40a1443..3a9ba270b 100644 --- a/src/app/pages/client/BackgroundNotifications.tsx +++ b/src/app/pages/client/BackgroundNotifications.tsx @@ -346,7 +346,7 @@ export function BackgroundNotifications() { if (!eventId) return; const eventType = mEvent.getType(); - const isEncryptedType = eventType === 'm.room.encrypted'; + const isEncryptedType = eventType === (EventType.RoomMessageEncrypted as string); // For encrypted events that haven't been decrypted yet, wait for decryption // before processing the notification. The SDK's Timeline re-emission after diff --git a/src/app/pages/client/client-non-ui/notifications.tsx b/src/app/pages/client/client-non-ui/notifications.tsx index 88419c64d..80b43bc51 100644 --- a/src/app/pages/client/client-non-ui/notifications.tsx +++ b/src/app/pages/client/client-non-ui/notifications.tsx @@ -248,7 +248,7 @@ export function MessageNotifications() { // For encrypted events that haven't been decrypted yet, wait for decryption // before processing the notification. The SDK's Timeline re-emission after // decryption comes with data.liveEvent=false which would wrongly block it. - if (mEvent.getType() === 'm.room.encrypted' && mEvent.isEncrypted()) { + if (mEvent.getType() === (EventType.RoomMessageEncrypted as string) && mEvent.isEncrypted()) { if (eventId) { // Mark this event to skip focus check when decrypted, so we use the focus // state from when the encrypted event originally arrived, not when it decrypts. diff --git a/src/app/plugins/call/CallEmbed.ts b/src/app/plugins/call/CallEmbed.ts index edde57b3e..0de990d71 100644 --- a/src/app/plugins/call/CallEmbed.ts +++ b/src/app/plugins/call/CallEmbed.ts @@ -1,5 +1,11 @@ import type { MatrixClient, MatrixEvent, Room } from '$types/matrix-sdk'; -import { ClientEvent, KnownMembership, MatrixEventEvent, RoomStateEvent } from '$types/matrix-sdk'; +import { + ClientEvent, + EventType, + KnownMembership, + MatrixEventEvent, + RoomStateEvent, +} from '$types/matrix-sdk'; import { invoke } from '@tauri-apps/api/core'; import type { IRoomEvent, IWidget, WidgetDriver } from 'matrix-widget-api'; import { @@ -333,11 +339,11 @@ export class CallEmbed { }); // Sliding sync may not have delivered m.room.member yet. - if (!this.room.currentState.getStateEvents('m.room.member', myUserId)) { + if (!this.room.currentState.getStateEvents(EventType.RoomMember, myUserId)) { const membership = this.room.getMyMembership(); if (membership) { const memberRaw = { - type: 'm.room.member', + type: EventType.RoomMember, state_key: myUserId, room_id: this.roomId, sender: myUserId, diff --git a/src/app/utils/messageReaction.ts b/src/app/utils/messageReaction.ts index ae74030ad..ea71caa51 100644 --- a/src/app/utils/messageReaction.ts +++ b/src/app/utils/messageReaction.ts @@ -1,5 +1,6 @@ import type { MatrixReactionEvent } from '$types/matrix/common'; -import type { MatrixClient, Room } from 'matrix-js-sdk'; +import type { MatrixClient, Room } from '$types/matrix-sdk'; +import { RelationType } from '$types/matrix-sdk'; import { ImageUsage } from '$plugins/custom-emoji'; import { getImagePackReferencesForMxcWrappedInMap } from './msc4459helper'; import { MATRIX_UNSTABLE_IMAGE_SOURCE_PACK_PROPERTY_NAME } from '$unstable/prefixes'; @@ -14,7 +15,7 @@ export const getReactionContent = ( 'm.relates_to': { event_id: eventId, key, - rel_type: 'm.annotation', + rel_type: RelationType.Annotation, }, shortcode, 'com.beeper.reaction.shortcode': shortcode, diff --git a/src/app/utils/notificationStyle.ts b/src/app/utils/notificationStyle.ts index c06345716..dfc16091c 100644 --- a/src/app/utils/notificationStyle.ts +++ b/src/app/utils/notificationStyle.ts @@ -1,3 +1,5 @@ +import { EventType } from 'matrix-js-sdk/lib/@types/event'; + export const DEFAULT_NOTIFICATION_ICON = '/public/res/logo-maskable/logo-maskable-180x180.png'; export const DEFAULT_NOTIFICATION_BADGE = '/public/res/logo-maskable/logo-maskable-72x72.png'; const DEFAULT_MESSAGE_PREVIEW = 'new message'; @@ -63,7 +65,7 @@ export const resolveNotificationPreviewText = ({ return 'Added a reaction'; } - const encryptedContext = isEncryptedRoom || eventType === 'm.room.encrypted'; + const encryptedContext = isEncryptedRoom || eventType === EventType.RoomMessageEncrypted; if (!showMessageContent) { return encryptedContext ? ENCRYPTED_MESSAGE_PREVIEW : DEFAULT_MESSAGE_PREVIEW; diff --git a/src/app/utils/room/relations.ts b/src/app/utils/room/relations.ts index 53de30903..56474ea7a 100644 --- a/src/app/utils/room/relations.ts +++ b/src/app/utils/room/relations.ts @@ -211,7 +211,6 @@ export const collectRelationEditEvents = ( export const isRedactableMessageType = (type: string): boolean => type === (EventType.RoomMessage as string) || type === (EventType.RoomMessageEncrypted as string) || - type === 'm.room.encrypted' || type === (EventType.Sticker as string); export const getRedactionTargetId = (redactionEvent: MatrixEvent): string | undefined => { diff --git a/src/app/utils/room/unread.ts b/src/app/utils/room/unread.ts index 6d04eddaa..85ac4f1d4 100644 --- a/src/app/utils/room/unread.ts +++ b/src/app/utils/room/unread.ts @@ -1,5 +1,10 @@ import type { IPushRule, IPushRules, MatrixClient, MatrixEvent, Room } from '$types/matrix-sdk'; -import { EventType, NotificationCountType, PushRuleActionName } from '$types/matrix-sdk'; +import { + EventType, + NotificationCountType, + PushRuleActionName, + RelationType, +} from '$types/matrix-sdk'; import type { UnreadInfo } from '$types/matrix/room'; import { NotificationType } from '$types/matrix/room'; @@ -86,13 +91,13 @@ export const getNotificationType = (mx: MatrixClient, roomId: string): Notificat return NotificationType.MentionsAndKeywords; }; -const NOTIFICATION_EVENT_TYPES = new Set([ - 'm.room.create', - 'm.room.message', - 'm.room.encrypted', - 'm.room.member', - 'm.sticker', - 'm.reaction', +const NOTIFICATION_EVENT_TYPES = new Set([ + EventType.RoomCreate, + EventType.RoomMessage, + EventType.RoomMessageEncrypted, + EventType.RoomMember, + EventType.Sticker, + EventType.Reaction, ]); export const isNotificationEvent = (mEvent: MatrixEvent, room?: Room, userId?: string) => { const eType = mEvent.getType(); @@ -109,7 +114,7 @@ export const isNotificationEvent = (mEvent: MatrixEvent, room?: Room, userId?: s if (relationType === 'm.replace') return false; // For reactions: only count them if they're reactions to the current user's messages - if (relationType === 'm.annotation') { + if (relationType === RelationType.Annotation) { if (!room || !userId || !relation) { // If we don't have room/userId/relation context, filter out all reactions (safe default) return false; diff --git a/src/app/utils/sendFeedbackToUser.ts b/src/app/utils/sendFeedbackToUser.ts index 03fd3a6fa..f8b935e48 100644 --- a/src/app/utils/sendFeedbackToUser.ts +++ b/src/app/utils/sendFeedbackToUser.ts @@ -1,10 +1,10 @@ import type { Room } from '$types/matrix-sdk'; -import { DuplicateStrategy, MatrixEvent } from '$types/matrix-sdk'; +import { DuplicateStrategy, EventType, MatrixEvent, MsgType } from '$types/matrix-sdk'; export function sendFeedback(msg: string, room: Room, userId: string) { const localNotice = new MatrixEvent({ - type: 'm.room.message', - content: { msgtype: 'm.notice', body: msg }, + type: EventType.RoomMessage, + content: { msgtype: MsgType.Notice, body: msg }, event_id: `~sable-feedback-${Date.now()}`, room_id: room.roomId, sender: userId, diff --git a/src/client/presenceSync.ts b/src/client/presenceSync.ts index 3111be8a7..4d2b9a6d8 100644 --- a/src/client/presenceSync.ts +++ b/src/client/presenceSync.ts @@ -1,6 +1,7 @@ import type { CryptoBackend, IDeviceLists, IToDeviceEvent, MatrixClient } from '$types/matrix-sdk'; import { ClientEvent, + EventType, Filter, Method, processToDeviceMessages, @@ -106,7 +107,7 @@ export class PresenceSyncManager { if ( typeof rawEvent !== 'object' || !rawEvent || - (rawEvent as Record).type !== 'm.presence' + (rawEvent as Record).type !== (EventType.Presence as string) ) return; @@ -137,7 +138,7 @@ export class PresenceSyncManager { filter.setDefinition({ room: { rooms: [] }, account_data: { types: [] }, - presence: { types: ['m.presence'] }, + presence: { types: [EventType.Presence] }, }); const filterId = await this.mx.getOrCreateFilter('presence_only', filter); diff --git a/src/client/slidingSync.ts b/src/client/slidingSync.ts index 7214083a5..3eec08431 100644 --- a/src/client/slidingSync.ts +++ b/src/client/slidingSync.ts @@ -170,8 +170,8 @@ const SPACE_REQUIRED_STATE: MSC3575RoomSubscription['required_state'] = [ [EventType.RoomEncryption, ''], [EventType.RoomTombstone, ''], [CustomStateEvent.RoomBanner, ''], - ['m.space.child', MSC3575_WILDCARD], - ['m.space.parent', MSC3575_WILDCARD], + [EventType.SpaceChild, MSC3575_WILDCARD], + [EventType.SpaceParent, MSC3575_WILDCARD], ]; const ACTIVE_ROOM_REQUIRED_STATE: MSC3575RoomSubscription['required_state'] = [ @@ -192,8 +192,8 @@ const ACTIVE_ROOM_REQUIRED_STATE: MSC3575RoomSubscription['required_state'] = [ [EventType.RoomThirdPartyInvite, MSC3575_WILDCARD], [EventType.RoomMember, MSC3575_STATE_KEY_ME], [EventType.RoomMember, MSC3575_STATE_KEY_LAZY], - ['m.space.child', MSC3575_WILDCARD], - ['m.space.parent', MSC3575_WILDCARD], + [EventType.SpaceChild, MSC3575_WILDCARD], + [EventType.SpaceParent, MSC3575_WILDCARD], [EventType.GroupCallPrefix, ''], [EventType.GroupCallMemberPrefix, MSC3575_WILDCARD], ...Object.values(CustomStateEvent).map((type) => [type, MSC3575_WILDCARD] as [string, string]), diff --git a/src/client/slidingSyncSidebarCache.ts b/src/client/slidingSyncSidebarCache.ts index 098a8ff59..9ee118a35 100644 --- a/src/client/slidingSyncSidebarCache.ts +++ b/src/client/slidingSyncSidebarCache.ts @@ -66,7 +66,8 @@ const mergeStateEvents = ( const merged = new Map(); previous?.forEach((event) => merged.set(stateEventKey(event), event)); incoming?.forEach((event) => { - const cacheMember = event.type === 'm.room.member' && event.state_key === userId; + const cacheMember = + event.type === (EventType.RoomMember as string) && event.state_key === userId; if (cacheMember || CACHED_STATE_TYPES.has(event.type)) { merged.set(stateEventKey(event), event); } @@ -75,7 +76,9 @@ const mergeStateEvents = ( }; const selfMembership = (events: StateEvent[] | undefined, userId: string): string | undefined => { - const event = events?.find((e) => e.type === 'm.room.member' && e.state_key === userId); + const event = events?.find( + (e) => e.type === (EventType.RoomMember as string) && e.state_key === userId + ); const content = event?.content; return content && typeof content === 'object' ? (content as { membership?: string }).membership diff --git a/src/sw.ts b/src/sw.ts index 96093fcc4..8b20daea5 100644 --- a/src/sw.ts +++ b/src/sw.ts @@ -2,6 +2,7 @@ /* oxlint-disable no-console, unicorn/require-post-message-target-origin */ import { precacheAndRoute, cleanupOutdatedCaches } from 'workbox-precaching'; +import { EventType } from 'matrix-js-sdk/lib/@types/event'; import { createPushNotifications } from './sw/pushNotification'; import { withMediaFetchSlot } from './app/utils/mediaConcurrency'; @@ -497,7 +498,7 @@ async function handleMinimalPushPayload( sender_id: sender, }; - if (eventType === 'm.room.encrypted') { + if (eventType === EventType.RoomMessageEncrypted) { // Try to relay decryption to an open app tab. const result = windowClients.length > 0 diff --git a/src/types/matrix/common.ts b/src/types/matrix/common.ts index acef5ed08..c900deea0 100644 --- a/src/types/matrix/common.ts +++ b/src/types/matrix/common.ts @@ -2,6 +2,7 @@ import type { SerializableMap } from '$types/wrapper/SerializableMap'; import type { SerializableSet } from '$types/wrapper/SerializableSet'; import type { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; import type { MsgType } from '$types/matrix-sdk'; +import type { RelationType } from '$types/matrix-sdk'; import type * as prefix from '$unstable/prefixes'; export type IImageInfo = { @@ -13,7 +14,7 @@ export type IImageInfo = { }; export type MatrixRelatesTo = { - rel_type: 'm.annotation'; + rel_type: RelationType.Annotation; event_id: string; key?: string; };