Files
ThreadNet-Web/apps/web/src/settings/controllers/MediaPreviewConfigController.ts
T
Michael TelatynskiandGitHub bbec915fb0 Enable more oxlint rules (#34189)
* Fix type imports

* Fix jsdoc

* Fixup types

* Fix stray awaits on non-thenables

* Fixup imports

* Fix splats

* Fix this-context on callbacks

* Memoise react contexts

* Prefer find/flatMap

* Make oxlint happier about our React keys

* Avoid unsafe default function params

* Fixup jsdoc

* Fixup contexts

* Switch from eslint to oxlint

* Some oxlint-related tweaks

* Iterate

* Partial revert to defer some changes and shrink diff

* Iterate

* Add eslint-plugin-element-call and enable the copyright rule

* Set strictStorePkgContentCheck

* Iterate

* Enable forwardRef oxlint rule

* Enable no-unused-vars oxlint rule

* Enable no-implied-eval oxlint rule

* Enable no-duplicate-type-constituents oxlint rule

* Enable explicit-length-check oxlint rule

* Enable prefer-number-properties oxlint rule

* Enable no-callback-in-promise oxlint rule

* Enable no-require-imports oxlint rule

* Remove disablement of most unicorn oxlint rules

* Enable no-conditional-tests oxlint rule

* Enable promise-valid-params oxlint rule

* Enable require-unicode-regexp oxlint rule

* Remove max-len comments as we use oxfmt for formatting

* Enable majority of oxlint `suspicious` rules

* Iterate

* Fix oxlint type-aware lint running without dependencies built
2026-07-29 08:26:07 +00:00

107 lines
4.0 KiB
TypeScript

/*
Copyright 2025 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
import { type IContent } from "matrix-js-sdk/src/matrix";
import { type AccountDataEvents } from "matrix-js-sdk/src/types";
import {
MEDIA_PREVIEW_ACCOUNT_DATA_TYPE,
type MediaPreviewConfig,
MediaPreviewValue,
} from "../../@types/media_preview.ts";
import { type SettingLevel } from "../SettingLevel.ts";
import MatrixClientBackedController from "./MatrixClientBackedController.ts";
declare module "matrix-js-sdk/src/types" {
interface RoomAccountDataEvents {
[MEDIA_PREVIEW_ACCOUNT_DATA_TYPE]: MediaPreviewConfig;
}
}
/**
* Handles media preview settings provided by MSC4278.
* This uses both account-level and room-level account data.
*/
export default class MediaPreviewConfigController extends MatrixClientBackedController {
public static readonly default: AccountDataEvents[typeof MEDIA_PREVIEW_ACCOUNT_DATA_TYPE] = {
media_previews: MediaPreviewValue.On,
invite_avatars: MediaPreviewValue.On,
};
private static getValidSettingData(content: IContent): Partial<MediaPreviewConfig> {
const mediaPreviews: MediaPreviewConfig["media_previews"] = content.media_previews;
const inviteAvatars: MediaPreviewConfig["invite_avatars"] = content.invite_avatars;
const validMediaPreviews = Object.values(MediaPreviewValue);
const validInviteAvatars = [MediaPreviewValue.Off, MediaPreviewValue.On];
return {
invite_avatars: validInviteAvatars.includes(inviteAvatars!) ? inviteAvatars : undefined,
media_previews: validMediaPreviews.includes(mediaPreviews!) ? mediaPreviews : undefined,
};
}
public constructor() {
super();
}
private getValue = (roomId?: string): MediaPreviewConfig => {
const source = roomId ? this.client?.getRoom(roomId) : this.client;
const accountData =
source?.getAccountData(MEDIA_PREVIEW_ACCOUNT_DATA_TYPE)?.getContent<MediaPreviewConfig>() ?? {};
const calculatedConfig = MediaPreviewConfigController.getValidSettingData(accountData);
// Save an account data fetch if we have all the values.
if (calculatedConfig.invite_avatars && calculatedConfig.media_previews) {
return calculatedConfig;
}
// We're missing some keys.
if (roomId) {
const globalConfig = this.getValue();
return {
invite_avatars:
calculatedConfig.invite_avatars ??
globalConfig.invite_avatars ??
MediaPreviewConfigController.default.invite_avatars,
media_previews:
calculatedConfig.media_previews ??
globalConfig.media_previews ??
MediaPreviewConfigController.default.media_previews,
};
}
return {
invite_avatars: calculatedConfig.invite_avatars ?? MediaPreviewConfigController.default.invite_avatars,
media_previews: calculatedConfig.media_previews ?? MediaPreviewConfigController.default.media_previews,
};
};
public getValueOverride(_level: SettingLevel, roomId: string | null): MediaPreviewConfig {
return this.getValue(roomId ?? undefined);
}
public get settingDisabled(): false {
// No homeserver support is required for this MSC.
return false;
}
public async beforeChange(
_level: SettingLevel,
roomId: string | null,
newValue: MediaPreviewConfig,
): Promise<boolean> {
if (!this.client) {
return false;
}
if (roomId) {
await this.client.setRoomAccountData(roomId, MEDIA_PREVIEW_ACCOUNT_DATA_TYPE, newValue);
return true;
}
await this.client.setAccountData(MEDIA_PREVIEW_ACCOUNT_DATA_TYPE, newValue);
return true;
}
}