You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-23 17:02:25 +03:00
Start using Namespaced value everywhere.
This commit is contained in:
@@ -315,6 +315,28 @@ export const UNSIGNED_THREAD_ID_FIELD = new UnstableValue("thread_id", "org.matr
|
||||
*/
|
||||
export const UNSIGNED_MEMBERSHIP_FIELD = new NamespacedValue("membership", "io.element.msc4115.membership");
|
||||
|
||||
|
||||
/**
|
||||
* https://github.com/matrix-org/matrix-spec-proposals/pull/4354
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export const STICKY_EVENT_FIELD = new NamespacedValue(null, "msc4354_sticky");
|
||||
|
||||
/**
|
||||
* https://github.com/matrix-org/matrix-spec-proposals/pull/4354
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export const STICKY_EVENT_KEY_FIELD = new NamespacedValue(null, "msc4354_sticky_key");
|
||||
|
||||
/**
|
||||
* https://github.com/matrix-org/matrix-spec-proposals/pull/4354
|
||||
*
|
||||
* @experimental
|
||||
*/
|
||||
export const STICKY_EVENT_DURATION_TTL_MS = new NamespacedValue(null, "msc4354_sticky_duration_ttl_ms")
|
||||
|
||||
/**
|
||||
* Mapped type from event type to content type for all specified non-state room events.
|
||||
*/
|
||||
|
||||
@@ -143,6 +143,7 @@ import {
|
||||
RoomCreateTypeField,
|
||||
RoomType,
|
||||
type StateEvents,
|
||||
STICKY_EVENT_KEY_FIELD,
|
||||
type TimelineEvents,
|
||||
UNSTABLE_MSC3088_ENABLED,
|
||||
UNSTABLE_MSC3088_PURPOSE,
|
||||
@@ -3443,7 +3444,7 @@ export class MatrixClient extends TypedEventEmitter<EmittedEvents, ClientEventHa
|
||||
delayOpts: SendDelayedEventRequestOpts,
|
||||
threadId: string | null,
|
||||
eventType: K,
|
||||
content: TimelineEvents[K] & { msc4354_sticky_key: string },
|
||||
content: TimelineEvents[K] & { [STICKY_EVENT_KEY_FIELD.name]: string },
|
||||
txnId?: string,
|
||||
): Promise<SendDelayedEventResponse> {
|
||||
if (!(await this.doesServerSupportUnstableFeature(UNSTABLE_MSC4140_DELAYED_EVENTS))) {
|
||||
|
||||
@@ -20,7 +20,7 @@ import { type LivekitFocusSelection } from "./LivekitTransport.ts";
|
||||
import { slotDescriptionToId, slotIdToDescription, type SlotDescription } from "./MatrixRTCSession.ts";
|
||||
import type { RTCCallIntent, Transport } from "./types.ts";
|
||||
import { type IContent, type MatrixEvent } from "../models/event.ts";
|
||||
import { type RelationType } from "../@types/event.ts";
|
||||
import { STICKY_EVENT_KEY_FIELD, type RelationType } from "../@types/event.ts";
|
||||
import { logger } from "../logger.ts";
|
||||
|
||||
/**
|
||||
@@ -47,7 +47,7 @@ export interface RtcMembershipData {
|
||||
};
|
||||
"rtc_transports": Transport[];
|
||||
"versions": string[];
|
||||
"msc4354_sticky_key"?: string;
|
||||
[STICKY_EVENT_KEY_FIELD.name]?: string;
|
||||
"sticky_key"?: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ import {
|
||||
ToDeviceMessageId,
|
||||
UNSIGNED_THREAD_ID_FIELD,
|
||||
UNSIGNED_MEMBERSHIP_FIELD,
|
||||
STICKY_EVENT_DURATION_TTL_MS,
|
||||
STICKY_EVENT_FIELD,
|
||||
} from "../@types/event.ts";
|
||||
import { deepSortedObjectEntries, internaliseString } from "../utils.ts";
|
||||
import { type RoomMember } from "./room-member.ts";
|
||||
@@ -75,7 +77,7 @@ export interface IUnsigned {
|
||||
"transaction_id"?: string;
|
||||
"invite_room_state"?: StrippedState[];
|
||||
"m.relations"?: Record<RelationType | string, any>; // No common pattern for aggregated relations
|
||||
"msc4354_sticky_duration_ttl_ms"?: number;
|
||||
[STICKY_EVENT_DURATION_TTL_MS.name]?: number;
|
||||
[UNSIGNED_THREAD_ID_FIELD.name]?: string;
|
||||
}
|
||||
|
||||
@@ -97,7 +99,7 @@ export interface IEvent {
|
||||
membership?: Membership;
|
||||
unsigned: IUnsigned;
|
||||
redacts?: string;
|
||||
msc4354_sticky?: { duration_ms: number };
|
||||
[STICKY_EVENT_FIELD.name]?: { duration_ms: number };
|
||||
}
|
||||
|
||||
export interface IAggregatedRelation {
|
||||
@@ -1771,13 +1773,14 @@ export class MatrixEvent extends TypedEventEmitter<MatrixEventEmittedEvents, Mat
|
||||
* `duration_ms` is safely bounded to a hour.
|
||||
*/
|
||||
public get unstableStickyInfo(): { duration_ms: number; duration_ttl_ms?: number } | undefined {
|
||||
if (!this.event.msc4354_sticky?.duration_ms) {
|
||||
const stickyInfo = (this.event[STICKY_EVENT_FIELD.name] ?? this.event[STICKY_EVENT_FIELD.unstable!]) as { duration_ms: number }|undefined;
|
||||
if (!stickyInfo?.duration_ms) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
duration_ms: Math.min(MAX_STICKY_DURATION_MS, this.event.msc4354_sticky.duration_ms),
|
||||
duration_ms: Math.min(MAX_STICKY_DURATION_MS, stickyInfo.duration_ms),
|
||||
// This is assumed to be bounded server-side.
|
||||
duration_ttl_ms: this.event.unsigned?.msc4354_sticky_duration_ttl_ms,
|
||||
duration_ttl_ms: this.event.unsigned?.[STICKY_EVENT_DURATION_TTL_MS.name] ?? this.event.unsigned?.[STICKY_EVENT_DURATION_TTL_MS.unstable!],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { STICKY_EVENT_KEY_FIELD } from "src/matrix.ts";
|
||||
import { logger as loggerInstance } from "../logger.ts";
|
||||
import { type MatrixEvent } from "./event.ts";
|
||||
import { TypedEventEmitter } from "./typed-event-emitter.ts";
|
||||
@@ -78,14 +79,14 @@ export class RoomStickyEventsStore extends TypedEventEmitter<RoomStickyEventsEve
|
||||
* and the previous event it may have replaced.
|
||||
*/
|
||||
private addStickyEvent(event: MatrixEvent): { added: true; prevEvent?: StickyMatrixEvent } | { added: false } {
|
||||
const stickyKey = event.getContent().msc4354_sticky_key;
|
||||
const stickyKey = event.getContent()[STICKY_EVENT_KEY_FIELD.name] ?? event.getContent()[STICKY_EVENT_KEY_FIELD.unstable!];
|
||||
if (typeof stickyKey !== "string" && stickyKey !== undefined) {
|
||||
throw new Error(`${event.getId()} is missing msc4354_sticky_key`);
|
||||
throw new Error(`${event.getId()} is missing ${STICKY_EVENT_KEY_FIELD.name}`);
|
||||
}
|
||||
|
||||
// With this we have the guarantee, that all events in stickyEventsMap are correctly formatted
|
||||
if (event.unstableStickyExpiresAt === undefined) {
|
||||
throw new Error(`${event.getId()} is missing msc4354_sticky.duration_ms`);
|
||||
throw new Error(`${event.getId()} is missing ${STICKY_EVENT_KEY_FIELD.name}.duration_ms`);
|
||||
}
|
||||
const sender = event.getSender();
|
||||
const type = event.getType();
|
||||
|
||||
@@ -22,7 +22,7 @@ import { logger } from "./logger.ts";
|
||||
import { deepCopy } from "./utils.ts";
|
||||
import { MAX_STICKY_DURATION_MS, type IContent, type IUnsigned } from "./models/event.ts";
|
||||
import { type IRoomSummary } from "./models/room-summary.ts";
|
||||
import { type EventType } from "./@types/event.ts";
|
||||
import { STICKY_EVENT_FIELD, STICKY_EVENT_KEY_FIELD, type EventType } from "./@types/event.ts";
|
||||
import { UNREAD_THREAD_NOTIFICATIONS } from "./@types/sync.ts";
|
||||
import { ReceiptAccumulator } from "./receipt-accumulator.ts";
|
||||
import { type OlmEncryptionInfo } from "./crypto-api/index.ts";
|
||||
@@ -77,8 +77,8 @@ export interface ITimeline {
|
||||
}
|
||||
|
||||
type StickyEventFields = {
|
||||
msc4354_sticky: { duration_ms: number };
|
||||
content: { msc4354_sticky_key?: string };
|
||||
[STICKY_EVENT_FIELD.name]: { duration_ms: number };
|
||||
content: { [STICKY_EVENT_KEY_FIELD.name]?: string };
|
||||
};
|
||||
|
||||
export type IStickyEvent = IRoomEvent & StickyEventFields;
|
||||
@@ -94,7 +94,7 @@ export interface IJoinedRoom {
|
||||
// One of `state` or `state_after` is required.
|
||||
"state"?: IState;
|
||||
"org.matrix.msc4222.state_after"?: IState; // https://github.com/matrix-org/matrix-spec-proposals/pull/4222
|
||||
"msc4354_sticky"?: ISticky; // https://github.com/matrix-org/matrix-spec-proposals/pull/4354
|
||||
[STICKY_EVENT_FIELD.name]: ISticky; // https://github.com/matrix-org/matrix-spec-proposals/pull/4354
|
||||
"timeline": ITimeline;
|
||||
"ephemeral": IEphemeral;
|
||||
"account_data": IAccountData;
|
||||
@@ -570,18 +570,23 @@ export class SyncAccumulator {
|
||||
|
||||
// We want this to be fast, so don't worry about duplicate events here. The RoomStickyEventsStore will
|
||||
// process these events into the correct mapped order.
|
||||
if (data.msc4354_sticky?.events) {
|
||||
const stickyEventData = (data.sticky ?? data['msc4354_sticky']) as ISticky;
|
||||
if (stickyEventData?.events.length) {
|
||||
currentData._stickyEvents = currentData._stickyEvents.concat(
|
||||
data.msc4354_sticky.events.map((event) => {
|
||||
stickyEventData.events.map((event) => {
|
||||
// If `duration_ms` exceeds the spec limit of a hour, we cap it.
|
||||
const cappedDuration = Math.min(event.msc4354_sticky.duration_ms, MAX_STICKY_DURATION_MS);
|
||||
const duration = event['sticky_event']?.duration_ms ?? event['msc4354_sticky']?.duration_ms;
|
||||
if (typeof duration !== "number") {
|
||||
return null;
|
||||
}
|
||||
const cappedDuration = Math.min(duration, MAX_STICKY_DURATION_MS);
|
||||
// If `origin_server_ts` claims to have been from the future, we still bound it to now.
|
||||
const createdTs = Math.min(event.origin_server_ts, now);
|
||||
return {
|
||||
event,
|
||||
expiresTs: cappedDuration + createdTs,
|
||||
};
|
||||
}),
|
||||
}).filter(e => e !== null),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -659,7 +664,7 @@ export class SyncAccumulator {
|
||||
"msc4354_sticky": roomData._stickyEvents?.length
|
||||
? {
|
||||
events: roomData._stickyEvents.map((e) => e.event),
|
||||
}
|
||||
} satisfies ISticky
|
||||
: undefined,
|
||||
};
|
||||
// Add account data
|
||||
|
||||
@@ -40,6 +40,7 @@ import {
|
||||
type ResetTimelineCallback,
|
||||
} from "./client.ts";
|
||||
import {
|
||||
ISticky,
|
||||
type IEphemeral,
|
||||
type IInvitedRoom,
|
||||
type IInviteState,
|
||||
@@ -58,7 +59,7 @@ import {
|
||||
import { MatrixEvent } from "./models/event.ts";
|
||||
import { type MatrixError, Method } from "./http-api/index.ts";
|
||||
import { type ISavedSync } from "./store/index.ts";
|
||||
import { EventType } from "./@types/event.ts";
|
||||
import { EventType, STICKY_EVENT_FIELD } from "./@types/event.ts";
|
||||
import { type IPushRules } from "./@types/PushRules.ts";
|
||||
import { type IMarkerFoundOptions, RoomStateEvent } from "./models/room-state.ts";
|
||||
import { RoomMemberEvent } from "./models/room-member.ts";
|
||||
@@ -1221,7 +1222,7 @@ export class SyncApi {
|
||||
const timelineEvents = this.mapSyncEventsFormat(joinObj.timeline, room, false);
|
||||
const ephemeralEvents = this.mapSyncEventsFormat(joinObj.ephemeral);
|
||||
const accountDataEvents = this.mapSyncEventsFormat(joinObj.account_data);
|
||||
const stickyEvents = this.mapSyncEventsFormat(joinObj.msc4354_sticky);
|
||||
const stickyEvents = this.mapSyncEventsFormat((joinObj[STICKY_EVENT_FIELD.name] ?? joinObj[STICKY_EVENT_FIELD.unstable!]) as ISticky);
|
||||
|
||||
// If state_after is present, this is the events that form the state at the end of the timeline block and
|
||||
// regular timeline events do *not* count towards state. If it's not present, then the state is formed by
|
||||
|
||||
Reference in New Issue
Block a user