Lint and fixes
This commit is contained in:
4
src/@types/matrix-js-sdk.d.ts
vendored
4
src/@types/matrix-js-sdk.d.ts
vendored
@@ -18,8 +18,6 @@ import { MediaPreviewConfig } from "./media_preview.ts";
|
|||||||
|
|
||||||
// Extend Matrix JS SDK types via Typescript declaration merging to support unspecced event fields and types
|
// Extend Matrix JS SDK types via Typescript declaration merging to support unspecced event fields and types
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
declare module "matrix-js-sdk/src/types" {
|
declare module "matrix-js-sdk/src/types" {
|
||||||
export interface FileInfo {
|
export interface FileInfo {
|
||||||
/**
|
/**
|
||||||
@@ -91,7 +89,7 @@ declare module "matrix-js-sdk/src/types" {
|
|||||||
accepted: string[];
|
accepted: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
"io.element.msc4278.media_preview_config": MediaPreviewConfig,
|
"io.element.msc4278.media_preview_config": MediaPreviewConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AudioContent {
|
export interface AudioContent {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
export enum MediaPreviewValue {
|
export enum MediaPreviewValue {
|
||||||
On = "on",
|
On = "on",
|
||||||
Private = "private",
|
Private = "private",
|
||||||
Off = "off"
|
Off = "off",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const MEDIA_PREVIEW_ACCOUNT_DATA_TYPE = "io.element.msc4278.media_preview_config";
|
||||||
export interface MediaPreviewConfig extends Record<string, unknown> {
|
export interface MediaPreviewConfig extends Record<string, unknown> {
|
||||||
media_previews: MediaPreviewValue,
|
media_previews: MediaPreviewValue;
|
||||||
invite_avatars: MediaPreviewValue,
|
invite_avatars: MediaPreviewValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,8 +97,9 @@ export default class RoomAvatar extends React.Component<IProps, IState> {
|
|||||||
private static getImageUrls(props: IProps): string[] {
|
private static getImageUrls(props: IProps): string[] {
|
||||||
const myMembership = props.room?.getMyMembership();
|
const myMembership = props.room?.getMyMembership();
|
||||||
if (myMembership === KnownMembership.Invite || !myMembership) {
|
if (myMembership === KnownMembership.Invite || !myMembership) {
|
||||||
|
if (
|
||||||
if (SettingsStore.getValue("mediaPreviewConfig", props.room?.roomId).invite_avatars !== MediaPreviewValue.On) {
|
SettingsStore.getValue("mediaPreviewConfig", props.room?.roomId).invite_avatars !== MediaPreviewValue.On
|
||||||
|
) {
|
||||||
// The user has opted out of showing avatars, so return no urls here.
|
// The user has opted out of showing avatars, so return no urls here.
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import AccessibleButton from "../elements/AccessibleButton";
|
|||||||
import { _t } from "../../../languageHandler";
|
import { _t } from "../../../languageHandler";
|
||||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||||
import { useAsyncMemo } from "../../../hooks/useAsyncMemo";
|
import { useAsyncMemo } from "../../../hooks/useAsyncMemo";
|
||||||
|
import { useMediaVisible } from "../../../hooks/useMediaVisible";
|
||||||
|
|
||||||
const INITIAL_NUM_PREVIEWS = 2;
|
const INITIAL_NUM_PREVIEWS = 2;
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ interface IProps {
|
|||||||
const LinkPreviewGroup: React.FC<IProps> = ({ links, mxEvent, onCancelClick }) => {
|
const LinkPreviewGroup: React.FC<IProps> = ({ links, mxEvent, onCancelClick }) => {
|
||||||
const cli = useContext(MatrixClientContext);
|
const cli = useContext(MatrixClientContext);
|
||||||
const [expanded, toggleExpanded] = useStateToggle();
|
const [expanded, toggleExpanded] = useStateToggle();
|
||||||
|
const [mediaVisible] = useMediaVisible(mxEvent.getId()!, mxEvent.getRoomId()!);
|
||||||
|
|
||||||
const ts = mxEvent.getTs();
|
const ts = mxEvent.getTs();
|
||||||
const previews = useAsyncMemo<[string, IPreviewUrlResponse][]>(
|
const previews = useAsyncMemo<[string, IPreviewUrlResponse][]>(
|
||||||
@@ -55,7 +57,13 @@ const LinkPreviewGroup: React.FC<IProps> = ({ links, mxEvent, onCancelClick }) =
|
|||||||
return (
|
return (
|
||||||
<div className="mx_LinkPreviewGroup">
|
<div className="mx_LinkPreviewGroup">
|
||||||
{showPreviews.map(([link, preview], i) => (
|
{showPreviews.map(([link, preview], i) => (
|
||||||
<LinkPreviewWidget key={link} link={link} preview={preview} mxEvent={mxEvent}>
|
<LinkPreviewWidget
|
||||||
|
mediaVisible={mediaVisible}
|
||||||
|
key={link}
|
||||||
|
link={link}
|
||||||
|
preview={preview}
|
||||||
|
mxEvent={mxEvent}
|
||||||
|
>
|
||||||
{i === 0 ? (
|
{i === 0 ? (
|
||||||
<AccessibleButton
|
<AccessibleButton
|
||||||
className="mx_LinkPreviewGroup_hide"
|
className="mx_LinkPreviewGroup_hide"
|
||||||
|
|||||||
@@ -11,20 +11,19 @@ import { decode } from "html-entities";
|
|||||||
import { type MatrixEvent, type IPreviewUrlResponse } from "matrix-js-sdk/src/matrix";
|
import { type MatrixEvent, type IPreviewUrlResponse } from "matrix-js-sdk/src/matrix";
|
||||||
|
|
||||||
import { Linkify } from "../../../HtmlUtils";
|
import { Linkify } from "../../../HtmlUtils";
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
|
||||||
import Modal from "../../../Modal";
|
import Modal from "../../../Modal";
|
||||||
import * as ImageUtils from "../../../ImageUtils";
|
import * as ImageUtils from "../../../ImageUtils";
|
||||||
import { mediaFromMxc } from "../../../customisations/Media";
|
import { mediaFromMxc } from "../../../customisations/Media";
|
||||||
import ImageView from "../elements/ImageView";
|
import ImageView from "../elements/ImageView";
|
||||||
import LinkWithTooltip from "../elements/LinkWithTooltip";
|
import LinkWithTooltip from "../elements/LinkWithTooltip";
|
||||||
import PlatformPeg from "../../../PlatformPeg";
|
import PlatformPeg from "../../../PlatformPeg";
|
||||||
import { MediaPreviewValue } from "../../../@types/media_preview";
|
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
link: string;
|
link: string;
|
||||||
preview: IPreviewUrlResponse;
|
preview: IPreviewUrlResponse;
|
||||||
mxEvent: MatrixEvent; // the Event associated with the preview
|
mxEvent: MatrixEvent; // the Event associated with the preview
|
||||||
children?: ReactNode;
|
children?: ReactNode;
|
||||||
|
mediaVisible: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class LinkPreviewWidget extends React.Component<IProps> {
|
export default class LinkPreviewWidget extends React.Component<IProps> {
|
||||||
@@ -70,8 +69,7 @@ export default class LinkPreviewWidget extends React.Component<IProps> {
|
|||||||
|
|
||||||
// FIXME: do we want to factor out all image displaying between this and MImageBody - especially for lightboxing?
|
// FIXME: do we want to factor out all image displaying between this and MImageBody - especially for lightboxing?
|
||||||
let image: string | null = p["og:image"] ?? null;
|
let image: string | null = p["og:image"] ?? null;
|
||||||
// HSTODO: Private rooms?
|
if (!this.props.mediaVisible) {
|
||||||
if (!SettingsStore.getValue("mediaPreviewConfig", this.props.mxEvent.getRoomId()).media_previews !== MediaPreviewValue.On) {
|
|
||||||
image = null; // Don't render a button to show the image, just hide it outright
|
image = null; // Don't render a button to show the image, just hide it outright
|
||||||
}
|
}
|
||||||
const imageMaxWidth = 100;
|
const imageMaxWidth = 100;
|
||||||
|
|||||||
111
src/components/views/settings/tabs/user/MediaPreviewSetting.tsx
Normal file
111
src/components/views/settings/tabs/user/MediaPreviewSetting.tsx
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
import React, { ChangeEventHandler } from "react";
|
||||||
|
import { Field, HelpMessage, InlineField, Label, RadioInput, Root } from "@vector-im/compound-web";
|
||||||
|
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
|
||||||
|
import { useCallback } from "react";
|
||||||
|
import { MediaPreviewConfig, MediaPreviewValue } from "../../../../../@types/media_preview";
|
||||||
|
import { _t } from "../../../../../languageHandler";
|
||||||
|
import { useSettingValue } from "../../../../../hooks/useSettings";
|
||||||
|
import SettingsStore from "../../../../../settings/SettingsStore";
|
||||||
|
import { SettingLevel } from "../../../../../settings/SettingLevel";
|
||||||
|
|
||||||
|
export function MediaPreviewAccountSettings() {
|
||||||
|
const currentMediaPreview = useSettingValue("mediaPreviewConfig");
|
||||||
|
|
||||||
|
const avatarOnChange = useCallback(
|
||||||
|
(c: boolean) => {
|
||||||
|
const newValue = {
|
||||||
|
...currentMediaPreview,
|
||||||
|
// N.B. Switch is inverted. "Hide avatars..."
|
||||||
|
invite_avatars: c ? MediaPreviewValue.Off : MediaPreviewValue.On,
|
||||||
|
} satisfies MediaPreviewConfig;
|
||||||
|
SettingsStore.setValue("mediaPreviewConfig", null, SettingLevel.ACCOUNT, newValue);
|
||||||
|
},
|
||||||
|
[currentMediaPreview],
|
||||||
|
);
|
||||||
|
|
||||||
|
const mediaPreviewOnChangeOff = useCallback<ChangeEventHandler<HTMLInputElement>>(
|
||||||
|
(event) => {
|
||||||
|
if (!event.target.checked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SettingsStore.setValue("mediaPreviewConfig", null, SettingLevel.ACCOUNT, {
|
||||||
|
...currentMediaPreview,
|
||||||
|
media_previews: MediaPreviewValue.Off,
|
||||||
|
} satisfies MediaPreviewConfig);
|
||||||
|
},
|
||||||
|
[currentMediaPreview],
|
||||||
|
);
|
||||||
|
|
||||||
|
const mediaPreviewOnChangePrivate = useCallback<ChangeEventHandler<HTMLInputElement>>(
|
||||||
|
(event) => {
|
||||||
|
if (!event.target.checked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SettingsStore.setValue("mediaPreviewConfig", null, SettingLevel.ACCOUNT, {
|
||||||
|
...currentMediaPreview,
|
||||||
|
media_previews: MediaPreviewValue.Private,
|
||||||
|
} satisfies MediaPreviewConfig);
|
||||||
|
},
|
||||||
|
[currentMediaPreview],
|
||||||
|
);
|
||||||
|
|
||||||
|
const mediaPreviewOnChangeOn = useCallback<ChangeEventHandler<HTMLInputElement>>(
|
||||||
|
(event) => {
|
||||||
|
if (!event.target.checked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SettingsStore.setValue("mediaPreviewConfig", null, SettingLevel.ACCOUNT, {
|
||||||
|
...currentMediaPreview,
|
||||||
|
media_previews: MediaPreviewValue.On,
|
||||||
|
} satisfies MediaPreviewConfig);
|
||||||
|
},
|
||||||
|
[currentMediaPreview],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Root>
|
||||||
|
<LabelledToggleSwitch
|
||||||
|
label={_t("settings|media_preview|hide_avatars")}
|
||||||
|
value={currentMediaPreview.invite_avatars === MediaPreviewValue.Off}
|
||||||
|
onChange={avatarOnChange}
|
||||||
|
/>
|
||||||
|
<Field role="radiogroup" name="media_previews">
|
||||||
|
<Label>{_t("settings|media_preview|media_preview_label")}</Label>
|
||||||
|
<HelpMessage>{_t("settings|media_preview|media_preview_description")}</HelpMessage>
|
||||||
|
<InlineField
|
||||||
|
name="media_preview_off"
|
||||||
|
control={
|
||||||
|
<RadioInput
|
||||||
|
checked={currentMediaPreview.media_previews === MediaPreviewValue.Off}
|
||||||
|
onChange={mediaPreviewOnChangeOff}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Label>{_t("settings|media_preview|hide_media")}</Label>
|
||||||
|
</InlineField>
|
||||||
|
<InlineField
|
||||||
|
name="media_preview_private"
|
||||||
|
control={
|
||||||
|
<RadioInput
|
||||||
|
checked={currentMediaPreview.media_previews === MediaPreviewValue.Private}
|
||||||
|
onChange={mediaPreviewOnChangePrivate}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Label>{_t("settings|media_preview|show_in_private")}</Label>
|
||||||
|
</InlineField>
|
||||||
|
<InlineField
|
||||||
|
name="media_preview_on"
|
||||||
|
control={
|
||||||
|
<RadioInput
|
||||||
|
checked={currentMediaPreview.media_previews === MediaPreviewValue.On}
|
||||||
|
onChange={mediaPreviewOnChangeOn}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Label>{_t("settings|media_preview|show_media")}</Label>
|
||||||
|
</InlineField>
|
||||||
|
</Field>
|
||||||
|
</Root>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -32,6 +32,7 @@ import SpellCheckSettings from "../../SpellCheckSettings";
|
|||||||
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
|
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
|
||||||
import * as TimezoneHandler from "../../../../../TimezoneHandler";
|
import * as TimezoneHandler from "../../../../../TimezoneHandler";
|
||||||
import { type BooleanSettingKey } from "../../../../../settings/Settings.tsx";
|
import { type BooleanSettingKey } from "../../../../../settings/Settings.tsx";
|
||||||
|
import { MediaPreviewAccountSettings } from "./MediaPreviewSetting.tsx";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
closeSettingsFn(success: boolean): void;
|
closeSettingsFn(success: boolean): void;
|
||||||
@@ -162,11 +163,6 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
|
|||||||
"useOnlyCurrentProfiles",
|
"useOnlyCurrentProfiles",
|
||||||
];
|
];
|
||||||
|
|
||||||
private static SAFETY_SETTINGS: BooleanSettingKey[] = [
|
|
||||||
"showAvatarsOnInvites",
|
|
||||||
"showImages", // "Show media in timeline"
|
|
||||||
];
|
|
||||||
|
|
||||||
private static ROOM_DIRECTORY_SETTINGS: BooleanSettingKey[] = ["SpotlightSearch.showNsfwPublicRooms"];
|
private static ROOM_DIRECTORY_SETTINGS: BooleanSettingKey[] = ["SpotlightSearch.showNsfwPublicRooms"];
|
||||||
|
|
||||||
private static GENERAL_SETTINGS: BooleanSettingKey[] = [
|
private static GENERAL_SETTINGS: BooleanSettingKey[] = [
|
||||||
@@ -340,7 +336,7 @@ export default class PreferencesUserSettingsTab extends React.Component<IProps,
|
|||||||
</SettingsSubsection>
|
</SettingsSubsection>
|
||||||
|
|
||||||
<SettingsSubsection heading={_t("common|moderation_and_safety")}>
|
<SettingsSubsection heading={_t("common|moderation_and_safety")}>
|
||||||
{this.renderGroup(PreferencesUserSettingsTab.SAFETY_SETTINGS)}
|
<MediaPreviewAccountSettings />
|
||||||
</SettingsSubsection>
|
</SettingsSubsection>
|
||||||
|
|
||||||
<SettingsSubsection heading={_t("settings|preferences|room_directory_heading")}>
|
<SettingsSubsection heading={_t("settings|preferences|room_directory_heading")}>
|
||||||
|
|||||||
@@ -35,6 +35,16 @@ export function useMediaVisible(eventId: string, roomId: string): [boolean, (vis
|
|||||||
[eventId, eventVisibility],
|
[eventId, eventVisibility],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const roomIsPrivate = useMemo(() => {
|
||||||
|
const joinRule = client.getRoom(roomId)?.getJoinRule();
|
||||||
|
if (PRIVATE_JOIN_RULES.includes(joinRule as JoinRule)) {
|
||||||
|
return true;
|
||||||
|
} else { // All other join rules, and unknown will default to hiding.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}, [client, roomId])
|
||||||
|
|
||||||
|
|
||||||
// Always prefer the explicit per-event user preference here.
|
// Always prefer the explicit per-event user preference here.
|
||||||
if (eventVisibility[eventId]) {
|
if (eventVisibility[eventId]) {
|
||||||
return [true, setMediaVisible];
|
return [true, setMediaVisible];
|
||||||
@@ -42,13 +52,12 @@ export function useMediaVisible(eventId: string, roomId: string): [boolean, (vis
|
|||||||
return [false, setMediaVisible];
|
return [false, setMediaVisible];
|
||||||
} else if (mediaPreviewSetting.media_previews === MediaPreviewValue.On) {
|
} else if (mediaPreviewSetting.media_previews === MediaPreviewValue.On) {
|
||||||
return [true, setMediaVisible];
|
return [true, setMediaVisible];
|
||||||
}
|
} else if (mediaPreviewSetting.media_previews === MediaPreviewValue.Private) {
|
||||||
const joinRule = client.getRoom(roomId)?.getJoinRule();
|
return [roomIsPrivate, setMediaVisible];
|
||||||
if (PRIVATE_JOIN_RULES.includes(joinRule as JoinRule)) {
|
} else {
|
||||||
console.log("Room is private");
|
// Invalid setting.
|
||||||
return [true, setMediaVisible];
|
console.warn("Invalid media visibility setting", mediaPreviewSetting.media_previews);
|
||||||
} else { // All other join rules, and unknown will default to hiding.
|
|
||||||
console.log("Room is probably public");
|
|
||||||
return [false, setMediaVisible];
|
return [false, setMediaVisible];
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -525,6 +525,7 @@
|
|||||||
"message_timestamp_invalid": "Invalid timestamp",
|
"message_timestamp_invalid": "Invalid timestamp",
|
||||||
"microphone": "Microphone",
|
"microphone": "Microphone",
|
||||||
"model": "Model",
|
"model": "Model",
|
||||||
|
"moderation_and_safety": "Moderation and safety",
|
||||||
"modern": "Modern",
|
"modern": "Modern",
|
||||||
"mute": "Mute",
|
"mute": "Mute",
|
||||||
"n_members": {
|
"n_members": {
|
||||||
@@ -2681,13 +2682,10 @@
|
|||||||
"unable_to_load_msisdns": "Unable to load phone numbers",
|
"unable_to_load_msisdns": "Unable to load phone numbers",
|
||||||
"username": "Username"
|
"username": "Username"
|
||||||
},
|
},
|
||||||
"show_media": "Show media in timeline",
|
|
||||||
"show_media_description": "A hidden media can always be shown by tapping on it",
|
|
||||||
"inline_url_previews_default": "Enable inline URL previews by default",
|
"inline_url_previews_default": "Enable inline URL previews by default",
|
||||||
"inline_url_previews_room": "Enable URL previews by default for participants in this room",
|
"inline_url_previews_room": "Enable URL previews by default for participants in this room",
|
||||||
"inline_url_previews_room_account": "Enable URL previews for this room (only affects you)",
|
"inline_url_previews_room_account": "Enable URL previews for this room (only affects you)",
|
||||||
"insert_trailing_colon_mentions": "Insert a trailing colon after user mentions at the start of a message",
|
"insert_trailing_colon_mentions": "Insert a trailing colon after user mentions at the start of a message",
|
||||||
"invite_avatars": "Show avatars of rooms you have been invited to",
|
|
||||||
"jump_to_bottom_on_send": "Jump to the bottom of the timeline when you send a message",
|
"jump_to_bottom_on_send": "Jump to the bottom of the timeline when you send a message",
|
||||||
"key_backup": {
|
"key_backup": {
|
||||||
"backup_in_progress": "Your keys are being backed up (the first backup could take a few minutes).",
|
"backup_in_progress": "Your keys are being backed up (the first backup could take a few minutes).",
|
||||||
@@ -2746,6 +2744,14 @@
|
|||||||
"labs_mjolnir": {
|
"labs_mjolnir": {
|
||||||
"dialog_title": "<strong>Settings:</strong> Ignored Users"
|
"dialog_title": "<strong>Settings:</strong> Ignored Users"
|
||||||
},
|
},
|
||||||
|
"media_preview": {
|
||||||
|
"hide_avatars": "Hide avatars of room and inviter",
|
||||||
|
"media_preview_label": "Show media in timeline",
|
||||||
|
"media_preview_description": "A hidden media can always be shown by tapping on it",
|
||||||
|
"hide_media": "Always hide",
|
||||||
|
"show_in_private": "In private rooms",
|
||||||
|
"show_media": "Always show"
|
||||||
|
},
|
||||||
"notifications": {
|
"notifications": {
|
||||||
"default_setting_description": "This setting will be applied by default to all your rooms.",
|
"default_setting_description": "This setting will be applied by default to all your rooms.",
|
||||||
"default_setting_section": "I want to be notified for (Default Setting)",
|
"default_setting_section": "I want to be notified for (Default Setting)",
|
||||||
|
|||||||
@@ -716,7 +716,7 @@ export default class SettingsStore {
|
|||||||
localStorage.setItem(MIGRATION_DONE_FLAG, "true");
|
localStorage.setItem(MIGRATION_DONE_FLAG, "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrate the setting for visible images to a setting.
|
* Migrate the setting for visible images to a setting.
|
||||||
*/
|
*/
|
||||||
private static migrateMediaControlsToSetting(): void {
|
private static migrateMediaControlsToSetting(): void {
|
||||||
@@ -735,7 +735,6 @@ export default class SettingsStore {
|
|||||||
});
|
});
|
||||||
} // else, we don't set anything and use the server value
|
} // else, we don't set anything and use the server value
|
||||||
|
|
||||||
|
|
||||||
localStorage.setItem(MIGRATION_DONE_FLAG, "true");
|
localStorage.setItem(MIGRATION_DONE_FLAG, "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,23 +7,19 @@ Please see LICENSE files in the repository root for full details.
|
|||||||
|
|
||||||
import { ClientEvent, MatrixEvent, type MatrixClient } from "matrix-js-sdk/src/matrix";
|
import { ClientEvent, MatrixEvent, type MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||||
import { AccountDataEvents } from "matrix-js-sdk/src/types";
|
import { AccountDataEvents } from "matrix-js-sdk/src/types";
|
||||||
import { MediaPreviewConfig, MediaPreviewValue } from "../../@types/media_preview.ts";
|
import { MEDIA_PREVIEW_ACCOUNT_DATA_TYPE, MediaPreviewConfig, MediaPreviewValue } from "../../@types/media_preview.ts";
|
||||||
|
|
||||||
import { SettingLevel } from "../SettingLevel.ts";
|
import { SettingLevel } from "../SettingLevel.ts";
|
||||||
import MatrixClientBackedController from "./MatrixClientBackedController.ts";
|
import MatrixClientBackedController from "./MatrixClientBackedController.ts";
|
||||||
|
|
||||||
|
|
||||||
const CLIENT_KEY = "io.element.msc4278.media_preview_config";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* TODO
|
||||||
*/
|
*/
|
||||||
export default class MediaPreviewConfigController extends MatrixClientBackedController {
|
export default class MediaPreviewConfigController extends MatrixClientBackedController {
|
||||||
|
|
||||||
public static readonly default: AccountDataEvents["io.element.msc4278.media_preview_config"] = {
|
public static readonly default: AccountDataEvents["io.element.msc4278.media_preview_config"] = {
|
||||||
media_previews: MediaPreviewValue.On,
|
media_previews: MediaPreviewValue.On,
|
||||||
invite_avatars: MediaPreviewValue.On
|
invite_avatars: MediaPreviewValue.On,
|
||||||
}
|
};
|
||||||
|
|
||||||
private globalSetting: MediaPreviewConfig = MediaPreviewConfigController.default;
|
private globalSetting: MediaPreviewConfig = MediaPreviewConfigController.default;
|
||||||
|
|
||||||
@@ -31,29 +27,52 @@ export default class MediaPreviewConfigController extends MatrixClientBackedCont
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
private getRoomValue = (roomId: string): MediaPreviewConfig|null => {
|
private getRoomValue = (roomId: string): MediaPreviewConfig | null => {
|
||||||
return this.client?.getRoom(roomId)?.getAccountData(CLIENT_KEY)?.getContent<MediaPreviewConfig>() ?? null;
|
return (
|
||||||
}
|
this.client
|
||||||
|
?.getRoom(roomId)
|
||||||
|
?.getAccountData(MEDIA_PREVIEW_ACCOUNT_DATA_TYPE)
|
||||||
|
?.getContent<MediaPreviewConfig>() ?? null
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
private onAccountData = (event: MatrixEvent): void => {
|
private onAccountData = (event: MatrixEvent): void => {
|
||||||
|
if (event.getType() !== MEDIA_PREVIEW_ACCOUNT_DATA_TYPE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("OnAccountData", event);
|
||||||
// TODO: Validate.
|
// TODO: Validate.
|
||||||
const roomId = event.getRoomId();
|
const roomId = event.getRoomId();
|
||||||
if (!roomId) {
|
if (!roomId) {
|
||||||
this.globalSetting = event.getContent();
|
this.globalSetting = {
|
||||||
|
...MediaPreviewConfigController.default,
|
||||||
|
...event.getContent(),
|
||||||
|
};
|
||||||
|
console.log("CONFIG Updating global settings", this.globalSetting);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
protected async initMatrixClient(newClient: MatrixClient, oldClient?: MatrixClient): Promise<void> {
|
protected async initMatrixClient(newClient: MatrixClient, oldClient?: MatrixClient): Promise<void> {
|
||||||
oldClient?.off(ClientEvent.AccountData, this.onAccountData);
|
oldClient?.off(ClientEvent.AccountData, this.onAccountData);
|
||||||
newClient.on(ClientEvent.AccountData, this.onAccountData);
|
newClient.on(ClientEvent.AccountData, this.onAccountData);
|
||||||
const accountData = newClient.getAccountData(CLIENT_KEY);
|
const accountData = newClient.getAccountData(MEDIA_PREVIEW_ACCOUNT_DATA_TYPE);
|
||||||
if (accountData) this.onAccountData(accountData);
|
if (accountData) this.onAccountData(accountData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public getValueOverride(level: SettingLevel, roomId: string | null,): MediaPreviewConfig {
|
public getValueOverride(level: SettingLevel, roomId: string | null): MediaPreviewConfig {
|
||||||
// TODO: Use SettingLevel?
|
// TODO: Use SettingLevel?
|
||||||
if (roomId) {
|
if (roomId) {
|
||||||
return this.getRoomValue(roomId) ?? this.globalSetting;
|
console.log(
|
||||||
|
"MediaPreviewConfigController",
|
||||||
|
"getValueOverride",
|
||||||
|
this.getRoomValue(roomId),
|
||||||
|
this.globalSetting,
|
||||||
|
);
|
||||||
|
// Use globals for any undefined setting
|
||||||
|
return {
|
||||||
|
...this.getRoomValue(roomId),
|
||||||
|
...this.globalSetting,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
return this.globalSetting;
|
return this.globalSetting;
|
||||||
}
|
}
|
||||||
@@ -62,13 +81,26 @@ export default class MediaPreviewConfigController extends MatrixClientBackedCont
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public onChange(_level: SettingLevel, roomId: string | null, newValue: MediaPreviewConfig): void {
|
public async beforeChange(
|
||||||
if (roomId) {
|
level: SettingLevel,
|
||||||
this.client?.setRoomAccountData(roomId, CLIENT_KEY, {
|
roomId: string | null,
|
||||||
value: newValue
|
newValue: MediaPreviewConfig,
|
||||||
});
|
): Promise<boolean> {
|
||||||
return;
|
if (!this.client) {
|
||||||
|
// No client!
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
this.client?.setAccountDataRaw(CLIENT_KEY, newValue);
|
if (roomId) {
|
||||||
|
await this.client.setRoomAccountData(roomId, MEDIA_PREVIEW_ACCOUNT_DATA_TYPE, {
|
||||||
|
value: newValue,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
await this.client.setAccountDataRaw(MEDIA_PREVIEW_ACCOUNT_DATA_TYPE, newValue);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public onChange(_level: SettingLevel, roomId: string | null, newValue: MediaPreviewConfig): void {
|
||||||
|
console.log("onChange", roomId, newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import MatrixClientBackedSettingsHandler from "./MatrixClientBackedSettingsHandl
|
|||||||
import { objectClone, objectKeyChanges } from "../../utils/objects";
|
import { objectClone, objectKeyChanges } from "../../utils/objects";
|
||||||
import { SettingLevel } from "../SettingLevel";
|
import { SettingLevel } from "../SettingLevel";
|
||||||
import { type WatchManager } from "../WatchManager";
|
import { type WatchManager } from "../WatchManager";
|
||||||
|
import { MEDIA_PREVIEW_ACCOUNT_DATA_TYPE } from "../../@types/media_preview";
|
||||||
|
|
||||||
const BREADCRUMBS_LEGACY_EVENT_TYPE = "im.vector.riot.breadcrumb_rooms";
|
const BREADCRUMBS_LEGACY_EVENT_TYPE = "im.vector.riot.breadcrumb_rooms";
|
||||||
const BREADCRUMBS_EVENT_TYPE = "im.vector.setting.breadcrumbs";
|
const BREADCRUMBS_EVENT_TYPE = "im.vector.setting.breadcrumbs";
|
||||||
@@ -68,6 +69,9 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa
|
|||||||
} else if (event.getType() === RECENT_EMOJI_EVENT_TYPE) {
|
} else if (event.getType() === RECENT_EMOJI_EVENT_TYPE) {
|
||||||
const val = event.getContent()["enabled"];
|
const val = event.getContent()["enabled"];
|
||||||
this.watchers.notifyUpdate("recent_emoji", null, SettingLevel.ACCOUNT, val);
|
this.watchers.notifyUpdate("recent_emoji", null, SettingLevel.ACCOUNT, val);
|
||||||
|
} else if (event.getType() === MEDIA_PREVIEW_ACCOUNT_DATA_TYPE) {
|
||||||
|
console.log("notifyupdate");
|
||||||
|
this.watchers.notifyUpdate("mediaPreviewConfig", null, SettingLevel.ROOM_ACCOUNT, event.getContent());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import MatrixClientBackedSettingsHandler from "./MatrixClientBackedSettingsHandl
|
|||||||
import { objectClone, objectKeyChanges } from "../../utils/objects";
|
import { objectClone, objectKeyChanges } from "../../utils/objects";
|
||||||
import { SettingLevel } from "../SettingLevel";
|
import { SettingLevel } from "../SettingLevel";
|
||||||
import { type WatchManager } from "../WatchManager";
|
import { type WatchManager } from "../WatchManager";
|
||||||
|
import { MEDIA_PREVIEW_ACCOUNT_DATA_TYPE } from "../../@types/media_preview";
|
||||||
|
|
||||||
const ALLOWED_WIDGETS_EVENT_TYPE = "im.vector.setting.allowed_widgets";
|
const ALLOWED_WIDGETS_EVENT_TYPE = "im.vector.setting.allowed_widgets";
|
||||||
const DEFAULT_SETTINGS_EVENT_TYPE = "im.vector.web.settings";
|
const DEFAULT_SETTINGS_EVENT_TYPE = "im.vector.web.settings";
|
||||||
@@ -56,6 +57,9 @@ export default class RoomAccountSettingsHandler extends MatrixClientBackedSettin
|
|||||||
}
|
}
|
||||||
} else if (event.getType() === ALLOWED_WIDGETS_EVENT_TYPE) {
|
} else if (event.getType() === ALLOWED_WIDGETS_EVENT_TYPE) {
|
||||||
this.watchers.notifyUpdate("allowedWidgets", roomId, SettingLevel.ROOM_ACCOUNT, event.getContent());
|
this.watchers.notifyUpdate("allowedWidgets", roomId, SettingLevel.ROOM_ACCOUNT, event.getContent());
|
||||||
|
} else if (event.getType() === MEDIA_PREVIEW_ACCOUNT_DATA_TYPE) {
|
||||||
|
console.log("notifyupdate");
|
||||||
|
this.watchers.notifyUpdate("mediaPreviewConfig", roomId, SettingLevel.ROOM_ACCOUNT, event.getContent());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user