Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit e7ae41d

Browse files
committed
Merge branch 'develop' into voice-rooms
2 parents baeeb1e + d8a939d commit e7ae41d

File tree

72 files changed

+1009
-592
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+1009
-592
lines changed

docs/settings.md

Lines changed: 64 additions & 64 deletions
Large diffs are not rendered by default.

res/css/views/messages/_MLocationBody.scss

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,17 @@ limitations under the License.
2727
width: 31px;
2828
height: 31px;
2929
border-radius: 50%;
30-
background-color: $accent;
3130
filter: drop-shadow(0px 3px 5px rgba(0, 0, 0, 0.2));
31+
background-color: $accent;
32+
33+
// See _LocationPicker.scss
34+
display: flex;
35+
justify-content: center;
36+
align-items: center;
3237

3338
.mx_BaseAvatar {
34-
margin-top: 2px;
35-
margin-left: 2px;
39+
margin: 0;
40+
line-height: 1;
3641
}
3742
}
3843

src/@types/common.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,11 @@ export type RecursivePartial<T> = {
4141
T[P] extends object ? RecursivePartial<T[P]> :
4242
T[P];
4343
};
44+
45+
// Inspired by https://stackoverflow.com/a/60206860
46+
export type KeysWithObjectShape<Input> = {
47+
[P in keyof Input]: Input[P] extends object
48+
// Arrays are counted as objects - exclude them
49+
? (Input[P] extends Array<unknown> ? never : P)
50+
: never;
51+
}[keyof Input];

src/@types/global.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import { ConsoleLogger, IndexedDBLogStore } from "../rageshake/rageshake";
5252
import ActiveWidgetStore from "../stores/ActiveWidgetStore";
5353
import { Skinner } from "../Skinner";
5454
import AutoRageshakeStore from "../stores/AutoRageshakeStore";
55-
import { ConfigOptions } from "../SdkConfig";
55+
import { IConfigOptions } from "../IConfigOptions";
5656

5757
/* eslint-disable @typescript-eslint/naming-convention */
5858

@@ -63,7 +63,7 @@ declare global {
6363
Olm: {
6464
init: () => Promise<void>;
6565
};
66-
mxReactSdkConfig: ConfigOptions;
66+
mxReactSdkConfig: IConfigOptions;
6767

6868
// Needed for Safari, unknown to TypeScript
6969
webkitAudioContext: typeof AudioContext;

src/Analytics.tsx

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ limitations under the License.
1717

1818
import React from 'react';
1919
import { logger } from "matrix-js-sdk/src/logger";
20+
import { Optional } from "matrix-events-sdk";
2021

2122
import { getCurrentLanguage, _t, _td, IVariables } from './languageHandler';
2223
import PlatformPeg from './PlatformPeg';
2324
import SdkConfig from './SdkConfig';
2425
import Modal from './Modal';
2526
import * as sdk from './index';
27+
import { SnakedObject } from "./utils/SnakedObject";
28+
import { IConfigOptions } from "./IConfigOptions";
2629

2730
const hashRegex = /#\/(groups?|room|user|settings|register|login|forgot_password|home|directory)/;
2831
const hashVarRegex = /#\/(group|room|user)\/.*$/;
@@ -193,8 +196,12 @@ export class Analytics {
193196
}
194197

195198
public canEnable() {
196-
const config = SdkConfig.get();
197-
return navigator.doNotTrack !== "1" && config && config.piwik && config.piwik.url && config.piwik.siteId;
199+
const piwikConfig = SdkConfig.get("piwik");
200+
let piwik: Optional<SnakedObject<Extract<IConfigOptions["piwik"], object>>>;
201+
if (typeof piwikConfig === 'object') {
202+
piwik = new SnakedObject(piwikConfig);
203+
}
204+
return navigator.doNotTrack !== "1" && piwik?.get("site_id");
198205
}
199206

200207
/**
@@ -204,12 +211,16 @@ export class Analytics {
204211
public async enable() {
205212
if (!this.disabled) return;
206213
if (!this.canEnable()) return;
207-
const config = SdkConfig.get();
214+
const piwikConfig = SdkConfig.get("piwik");
215+
let piwik: Optional<SnakedObject<Extract<IConfigOptions["piwik"], object>>>;
216+
if (typeof piwikConfig === 'object') {
217+
piwik = new SnakedObject(piwikConfig);
218+
}
208219

209-
this.baseUrl = new URL("piwik.php", config.piwik.url);
220+
this.baseUrl = new URL("piwik.php", piwik.get("url"));
210221
// set constants
211222
this.baseUrl.searchParams.set("rec", "1"); // rec is required for tracking
212-
this.baseUrl.searchParams.set("idsite", config.piwik.siteId); // rec is required for tracking
223+
this.baseUrl.searchParams.set("idsite", piwik.get("site_id")); // idsite is required for tracking
213224
this.baseUrl.searchParams.set("apiv", "1"); // API version to use
214225
this.baseUrl.searchParams.set("send_image", "0"); // we want a 204, not a tiny GIF
215226
// set user parameters
@@ -347,10 +358,14 @@ export class Analytics {
347358
public setLoggedIn(isGuest: boolean, homeserverUrl: string) {
348359
if (this.disabled) return;
349360

350-
const config = SdkConfig.get();
351-
if (!config.piwik) return;
361+
const piwikConfig = SdkConfig.get("piwik");
362+
let piwik: Optional<SnakedObject<Extract<IConfigOptions["piwik"], object>>>;
363+
if (typeof piwikConfig === 'object') {
364+
piwik = new SnakedObject(piwikConfig);
365+
}
366+
if (!piwik) return;
352367

353-
const whitelistedHSUrls = config.piwik.whitelistedHSUrls || [];
368+
const whitelistedHSUrls = piwik.get("whitelisted_hs_urls", "whitelistedHSUrls") || [];
354369

355370
this.setVisitVariable('User Type', isGuest ? 'Guest' : 'Logged In');
356371
this.setVisitVariable('Homeserver URL', whitelistRedact(whitelistedHSUrls, homeserverUrl));
@@ -391,7 +406,12 @@ export class Analytics {
391406
];
392407

393408
// FIXME: Using an import will result in test failures
394-
const cookiePolicyUrl = SdkConfig.get().piwik?.policyUrl;
409+
const piwikConfig = SdkConfig.get("piwik");
410+
let piwik: Optional<SnakedObject<Extract<IConfigOptions["piwik"], object>>>;
411+
if (typeof piwikConfig === 'object') {
412+
piwik = new SnakedObject(piwikConfig);
413+
}
414+
const cookiePolicyUrl = piwik?.get("policy_url");
395415
const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog');
396416
const cookiePolicyLink = _t(
397417
"Our complete cookie policy can be found <CookiePolicyLink>here</CookiePolicyLink>.",

src/BasePlatform.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { hideToast as hideUpdateToast } from "./toasts/UpdateToast";
3232
import { MatrixClientPeg } from "./MatrixClientPeg";
3333
import { idbLoad, idbSave, idbDelete } from "./utils/StorageManager";
3434
import { ViewRoomPayload } from "./dispatcher/payloads/ViewRoomPayload";
35+
import { IConfigOptions } from "./IConfigOptions";
3536

3637
export const SSO_HOMESERVER_URL_KEY = "mx_sso_hs_url";
3738
export const SSO_ID_SERVER_URL_KEY = "mx_sso_is_url";
@@ -62,7 +63,7 @@ export default abstract class BasePlatform {
6263
this.startUpdateCheck = this.startUpdateCheck.bind(this);
6364
}
6465

65-
abstract getConfig(): Promise<{}>;
66+
abstract getConfig(): Promise<IConfigOptions>;
6667

6768
abstract getDefaultDeviceDisplayName(): string;
6869

src/CallHandler.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ export default class CallHandler extends EventEmitter {
256256
}
257257

258258
private shouldObeyAssertedfIdentity(): boolean {
259-
return SdkConfig.get()['voip']?.obeyAssertedIdentity;
259+
return SdkConfig.getObject("voip")?.get("obey_asserted_identity");
260260
}
261261

262262
public getSupportsPstnProtocol(): boolean {

src/IConfigOptions.ts

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*
2+
Copyright 2016 OpenMarket Ltd
3+
Copyright 2019 - 2022 The Matrix.org Foundation C.I.C.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
*/
17+
18+
import { IClientWellKnown } from "matrix-js-sdk/src/matrix";
19+
20+
import { ValidatedServerConfig } from "./utils/AutoDiscoveryUtils";
21+
22+
// Convention decision: All config options are lower_snake_case
23+
// We use an isolated file for the interface so we can mess around with the eslint options.
24+
25+
/* eslint-disable camelcase */
26+
/* eslint @typescript-eslint/naming-convention: ["error", { "selector": "property", "format": ["snake_case"] } ] */
27+
28+
// see element-web config.md for non-developer docs
29+
export interface IConfigOptions {
30+
// dev note: while true that this is arbitrary JSON, it's valuable to enforce that all
31+
// config options are documented for "find all usages" sort of searching.
32+
// [key: string]: any;
33+
34+
// Properties of this interface are roughly grouped by their subject matter, such as
35+
// "instance customisation", "login stuff", "branding", etc. Use blank lines to denote
36+
// a logical separation of properties, but keep similar ones near each other.
37+
38+
// Exactly one of the following must be supplied
39+
default_server_config?: IClientWellKnown; // copy/paste of client well-known
40+
default_server_name?: string; // domain to do well-known lookup on
41+
default_hs_url?: string; // http url
42+
43+
default_is_url?: string; // used in combination with default_hs_url, but for the identity server
44+
45+
// This is intended to be overridden by app startup and not specified by the user
46+
// This is also why it's allowed to have an interface that isn't snake_case
47+
validated_server_config?: ValidatedServerConfig;
48+
49+
fallback_hs_url?: string;
50+
51+
disable_custom_urls?: boolean;
52+
disable_guests?: boolean;
53+
disable_login_language_selector?: boolean;
54+
disable_3pid_login?: boolean;
55+
56+
brand: string;
57+
branding?: {
58+
welcome_background_url?: string | string[]; // chosen at random if array
59+
auth_header_logo_url?: string;
60+
auth_footer_links?: {text: string, url: string}[];
61+
};
62+
63+
map_style_url?: string; // for location-shared maps
64+
65+
embedded_pages?: {
66+
welcome_url?: string;
67+
home_url?: string;
68+
login_for_welcome?: boolean;
69+
};
70+
71+
permalink_prefix?: string;
72+
73+
update_base_url?: string;
74+
desktop_builds?: {
75+
available: boolean;
76+
logo: string; // url
77+
url: string; // download url
78+
};
79+
mobile_builds?: {
80+
ios?: string; // download url
81+
android?: string; // download url
82+
fdroid?: string; // download url
83+
};
84+
85+
mobile_guide_toast?: boolean;
86+
87+
default_theme?: "light" | "dark" | string; // custom themes are strings
88+
default_country_code?: string; // ISO 3166 alpha2 country code
89+
default_federate?: boolean;
90+
default_device_display_name?: string; // for device naming on login+registration
91+
92+
setting_defaults?: Record<string, any>; // <SettingName, Value>
93+
94+
integrations_ui_url?: string;
95+
integrations_rest_url?: string;
96+
integrations_widgets_urls?: string[];
97+
98+
show_labs_settings?: boolean;
99+
features?: Record<string, boolean>; // <FeatureName, EnabledBool>
100+
101+
bug_report_endpoint_url?: string; // omission disables bug reporting
102+
uisi_autorageshake_app?: string;
103+
sentry?: {
104+
dsn: string;
105+
environment?: string; // "production", etc
106+
};
107+
108+
widget_build_url?: string; // url called to replace jitsi/call widget creation
109+
audio_stream_url?: string;
110+
jitsi?: {
111+
preferred_domain: string;
112+
};
113+
jitsi_widget?: {
114+
skip_built_in_welcome_screen?: boolean;
115+
};
116+
voip?: {
117+
obey_asserted_identity?: boolean; // MSC3086
118+
};
119+
120+
logout_redirect_url?: string;
121+
122+
// sso_immediate_redirect is deprecated in favour of sso_redirect_options.immediate
123+
sso_immediate_redirect?: boolean;
124+
sso_redirect_options?: ISsoRedirectOptions;
125+
126+
custom_translations_url?: string;
127+
128+
report_event?: {
129+
admin_message_md: string; // message for how to contact the server owner when reporting an event
130+
};
131+
132+
welcome_user_id?: string;
133+
134+
room_directory?: {
135+
servers: string[];
136+
};
137+
138+
// piwik (matomo) is deprecated in favour of posthog
139+
piwik?: false | {
140+
url: string; // piwik instance
141+
site_id: string;
142+
policy_url: string; // cookie policy
143+
whitelisted_hs_urls: string[];
144+
};
145+
posthog?: {
146+
project_api_key: string;
147+
api_host: string; // hostname
148+
};
149+
analytics_owner?: string; // defaults to `brand`
150+
151+
// Server hosting upsell options
152+
hosting_signup_link?: string; // slightly different from `host_signup`
153+
host_signup?: {
154+
brand?: string; // acts as the enabled flag too (truthy == show)
155+
156+
// Required-ness denotes when `brand` is truthy
157+
cookie_policy_url: string;
158+
privacy_policy_url: string;
159+
terms_of_service_url: string;
160+
url: string;
161+
domains?: string[];
162+
};
163+
164+
enable_presence_by_hs_url?: Record<string, boolean>; // <HomeserverName, Enabled>
165+
166+
terms_and_conditions_links?: { url: string, text: string }[];
167+
168+
latex_maths_delims?: {
169+
inline?: {
170+
left?: string;
171+
right?: string;
172+
};
173+
display?: {
174+
left?: string;
175+
right?: string;
176+
};
177+
};
178+
179+
sync_timeline_limit?: number;
180+
dangerously_allow_unsafe_and_insecure_passwords?: boolean; // developer option
181+
}
182+
183+
export interface ISsoRedirectOptions {
184+
immediate?: boolean;
185+
on_welcome_page?: boolean;
186+
}

src/KeyBindingsDefaults.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ const callBindings = (): KeyBinding[] => {
161161
};
162162

163163
const labsBindings = (): KeyBinding[] => {
164-
if (!SdkConfig.get()['showLabsSettings']) return [];
164+
if (!SdkConfig.get("show_labs_settings")) return [];
165165

166166
return getBindingsByCategory(CategoryName.LABS);
167167
};

src/Livestream.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import SdkConfig from "./SdkConfig";
2121
import { ElementWidgetActions } from "./stores/widgets/ElementWidgetActions";
2222

2323
export function getConfigLivestreamUrl() {
24-
return SdkConfig.get()["audioStreamUrl"];
24+
return SdkConfig.get("audio_stream_url");
2525
}
2626

2727
// Dummy rtmp URL used to signal that we want a special audio-only stream

0 commit comments

Comments
 (0)