Enables sandbox on about window
This commit is contained in:
parent
58691b2f5e
commit
4591b56f7f
27 changed files with 262 additions and 93 deletions
|
@ -28,3 +28,5 @@ sticker-creator/**/*.js
|
|||
.eslintrc.js
|
||||
webpack.config.ts
|
||||
preload.bundle.*
|
||||
about.browser.bundle.*
|
||||
about.preload.bundle.*
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -26,6 +26,8 @@ libtextsecure/components.js
|
|||
stylesheets/*.css
|
||||
/storybook-static/
|
||||
preload.bundle.*
|
||||
about.browser.bundle.*
|
||||
about.preload.bundle.*
|
||||
ts/sql/mainWorker.bundle.js.LICENSE.txt
|
||||
|
||||
# React / TypeScript
|
||||
|
|
|
@ -43,3 +43,5 @@ js/WebAudioRecorderMp3.js
|
|||
stylesheets/_intlTelInput.scss
|
||||
|
||||
preload.bundle.*
|
||||
about.browser.bundle.*
|
||||
about.preload.bundle.*
|
||||
|
|
|
@ -30,5 +30,9 @@
|
|||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="application/javascript" src="ts/windows/init.js"></script>
|
||||
<script
|
||||
type="application/javascript"
|
||||
src="about.browser.bundle.js"
|
||||
></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1253,7 +1253,7 @@ async function showAbout() {
|
|||
nodeIntegrationInWorker: false,
|
||||
sandbox: false,
|
||||
contextIsolation: true,
|
||||
preload: join(__dirname, '../ts/windows/about/preload.js'),
|
||||
preload: join(__dirname, '../about.preload.bundle.js'),
|
||||
nativeWindowOpen: true,
|
||||
},
|
||||
};
|
||||
|
@ -2357,6 +2357,11 @@ ipc.on('locale-data', event => {
|
|||
event.returnValue = getResolvedMessagesLocale().messages;
|
||||
});
|
||||
|
||||
ipc.on('getHasCustomTitleBar', event => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
event.returnValue = OS.hasCustomTitleBar();
|
||||
});
|
||||
|
||||
ipc.on('user-config-key', event => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
event.returnValue = userConfig.get('key');
|
||||
|
|
|
@ -462,6 +462,8 @@
|
|||
"app/*",
|
||||
"preload.bundle.js",
|
||||
"preload_utils.js",
|
||||
"about.preload.bundle.js",
|
||||
"about.browser.bundle.js",
|
||||
"main.js",
|
||||
"images/**",
|
||||
"fonts/**",
|
||||
|
|
|
@ -98,3 +98,18 @@ main().catch(error => {
|
|||
console.error(error.stack);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
// About bundle
|
||||
esbuild.build({
|
||||
...bundleDefaults,
|
||||
mainFields: ['browser', 'main'],
|
||||
entryPoints: [path.join(ROOT_DIR, 'ts', 'windows', 'about', 'app.tsx')],
|
||||
outfile: path.join(ROOT_DIR, 'about.browser.bundle.js'),
|
||||
});
|
||||
|
||||
esbuild.build({
|
||||
...bundleDefaults,
|
||||
mainFields: ['browser', 'main'],
|
||||
entryPoints: [path.join(ROOT_DIR, 'ts', 'windows', 'about', 'preload.ts')],
|
||||
outfile: path.join(ROOT_DIR, 'about.preload.bundle.js'),
|
||||
});
|
||||
|
|
|
@ -148,7 +148,7 @@ import { deleteAllLogs } from './util/deleteAllLogs';
|
|||
import { ToastCaptchaFailed } from './components/ToastCaptchaFailed';
|
||||
import { ToastCaptchaSolved } from './components/ToastCaptchaSolved';
|
||||
import { showToast } from './util/showToast';
|
||||
import { startInteractionMode } from './windows/startInteractionMode';
|
||||
import { startInteractionMode } from './services/InteractionMode';
|
||||
import type { MainWindowStatsType } from './windows/context';
|
||||
import { ReactionSource } from './reactions/ReactionSource';
|
||||
import { singleProtoJobQueue } from './jobs/singleProtoJobQueue';
|
||||
|
|
|
@ -3,28 +3,28 @@
|
|||
|
||||
import React from 'react';
|
||||
|
||||
import type { ExecuteMenuRoleType } from './TitleBarContainer';
|
||||
import type { LocalizerType } from '../types/Util';
|
||||
import { TitleBarContainer } from './TitleBarContainer';
|
||||
import { useEscapeHandling } from '../hooks/useEscapeHandling';
|
||||
import { useTheme } from '../hooks/useTheme';
|
||||
import { TitleBarContainer } from './TitleBarContainer';
|
||||
import type { ExecuteMenuRoleType } from './TitleBarContainer';
|
||||
|
||||
export type PropsType = {
|
||||
closeAbout: () => unknown;
|
||||
environment: string;
|
||||
executeMenuRole: ExecuteMenuRoleType;
|
||||
hasCustomTitleBar: boolean;
|
||||
i18n: LocalizerType;
|
||||
version: string;
|
||||
hasCustomTitleBar: boolean;
|
||||
executeMenuRole: ExecuteMenuRoleType;
|
||||
};
|
||||
|
||||
export function About({
|
||||
closeAbout,
|
||||
i18n,
|
||||
environment,
|
||||
version,
|
||||
hasCustomTitleBar,
|
||||
executeMenuRole,
|
||||
hasCustomTitleBar,
|
||||
i18n,
|
||||
version,
|
||||
}: PropsType): JSX.Element {
|
||||
useEscapeHandling(closeAbout);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import type { Theme } from '../util/theme';
|
|||
import { themeClassName } from '../util/theme';
|
||||
import { refMerger } from '../util/refMerger';
|
||||
import { offsetDistanceModifier } from '../util/popperUtil';
|
||||
import { getInteractionMode } from '../services/InteractionMode';
|
||||
|
||||
type EventWrapperPropsType = {
|
||||
children: React.ReactNode;
|
||||
|
@ -35,7 +36,7 @@ const TooltipEventWrapper = React.forwardRef<
|
|||
}, [onHoverChanged]);
|
||||
|
||||
const onFocus = React.useCallback(() => {
|
||||
if (window.getInteractionMode() === 'keyboard') {
|
||||
if (getInteractionMode() === 'keyboard') {
|
||||
on();
|
||||
}
|
||||
}, [on]);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { getInteractionMode } from '../../services/InteractionMode';
|
||||
|
||||
export type PropsType = {
|
||||
id: string;
|
||||
|
@ -22,7 +23,7 @@ export class InlineNotificationWrapper extends React.Component<PropsType> {
|
|||
};
|
||||
|
||||
public handleFocus = (): void => {
|
||||
if (window.getInteractionMode() === 'keyboard') {
|
||||
if (getInteractionMode() === 'keyboard') {
|
||||
this.setSelected();
|
||||
}
|
||||
};
|
||||
|
|
12
ts/context/activeWindowService.ts
Normal file
12
ts/context/activeWindowService.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Copyright 2023 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { getActiveWindowService } from '../services/ActiveWindowService';
|
||||
|
||||
const activeWindowService = getActiveWindowService(
|
||||
window.document,
|
||||
ipcRenderer
|
||||
);
|
||||
|
||||
export { activeWindowService };
|
12
ts/context/config.ts
Normal file
12
ts/context/config.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
// Copyright 2023 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { RendererConfigType } from '../types/RendererConfig';
|
||||
import { strictAssert } from '../util/assert';
|
||||
|
||||
const params = new URLSearchParams(document.location.search);
|
||||
const configParam = params.get('config');
|
||||
strictAssert(typeof configParam === 'string', 'config is not a string');
|
||||
const config: RendererConfigType = JSON.parse(configParam);
|
||||
|
||||
export { config };
|
15
ts/context/environment.ts
Normal file
15
ts/context/environment.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
// Copyright 2023 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { config } from './config';
|
||||
import {
|
||||
getEnvironment,
|
||||
parseEnvironment,
|
||||
setEnvironment,
|
||||
} from '../environment';
|
||||
|
||||
setEnvironment(parseEnvironment(config.environment));
|
||||
|
||||
const environment = getEnvironment();
|
||||
|
||||
export { environment };
|
22
ts/context/i18n.ts
Normal file
22
ts/context/i18n.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
// Copyright 2023 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { config } from './config';
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import { strictAssert } from '../util/assert';
|
||||
|
||||
const { resolvedTranslationsLocale } = config;
|
||||
strictAssert(
|
||||
resolvedTranslationsLocale,
|
||||
'locale could not be parsed from config'
|
||||
);
|
||||
strictAssert(
|
||||
typeof resolvedTranslationsLocale === 'string',
|
||||
'locale is not a string'
|
||||
);
|
||||
|
||||
const localeMessages = ipcRenderer.sendSync('locale-data');
|
||||
const i18n = setupI18n(resolvedTranslationsLocale, localeMessages);
|
||||
|
||||
export { i18n };
|
|
@ -16,7 +16,7 @@ const ACTIVE_EVENTS = [
|
|||
'wheel',
|
||||
];
|
||||
|
||||
export class ActiveWindowService {
|
||||
class ActiveWindowService {
|
||||
// This starting value might be wrong but we should get an update from the main process
|
||||
// soon. We'd rather report that the window is inactive so we can show notifications.
|
||||
private isInitialized = false;
|
||||
|
@ -113,3 +113,37 @@ export class ActiveWindowService {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type ActiveWindowServiceType = {
|
||||
isActive(): boolean;
|
||||
registerForActive(callback: () => void): void;
|
||||
unregisterForActive(callback: () => void): void;
|
||||
registerForChange(callback: (isActive: boolean) => void): void;
|
||||
unregisterForChange(callback: (isActive: boolean) => void): void;
|
||||
};
|
||||
|
||||
export function getActiveWindowService(
|
||||
document: EventTarget,
|
||||
ipc: NodeJS.EventEmitter
|
||||
): ActiveWindowServiceType {
|
||||
const activeWindowService = new ActiveWindowService();
|
||||
activeWindowService.initialize(document, ipc);
|
||||
|
||||
return {
|
||||
isActive(): boolean {
|
||||
return activeWindowService.isActive();
|
||||
},
|
||||
registerForActive(callback: () => void): void {
|
||||
return activeWindowService.registerForActive(callback);
|
||||
},
|
||||
unregisterForActive(callback: () => void): void {
|
||||
return activeWindowService.unregisterForActive(callback);
|
||||
},
|
||||
registerForChange(callback: (isActive: boolean) => void): void {
|
||||
return activeWindowService.registerForChange(callback);
|
||||
},
|
||||
unregisterForChange(callback: (isActive: boolean) => void): void {
|
||||
return activeWindowService.unregisterForChange(callback);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
type InteractionModeType = 'mouse' | 'keyboard';
|
||||
|
||||
let initialized = false;
|
||||
let interactionMode: 'mouse' | 'keyboard' = 'mouse';
|
||||
let interactionMode: InteractionModeType = 'mouse';
|
||||
|
||||
export function startInteractionMode(): void {
|
||||
if (initialized) {
|
||||
|
@ -66,6 +68,8 @@ export function startInteractionMode(): void {
|
|||
);
|
||||
document.addEventListener('wheel', window.enterMouseMode, true);
|
||||
document.addEventListener('mousedown', window.enterMouseMode, true);
|
||||
|
||||
window.getInteractionMode = () => interactionMode;
|
||||
}
|
||||
|
||||
export function getInteractionMode(): InteractionModeType {
|
||||
return interactionMode;
|
||||
}
|
|
@ -36,6 +36,7 @@ import { UUIDKind } from '../types/UUID';
|
|||
import { getEmojiReducerState as emojis } from '../util/loadRecentEmojis';
|
||||
import { getInitialState as stickers } from '../types/Stickers';
|
||||
import { getThemeType } from '../util/getThemeType';
|
||||
import { getInteractionMode } from '../services/InteractionMode';
|
||||
|
||||
export function getInitialState({
|
||||
badges,
|
||||
|
@ -137,7 +138,7 @@ export function getInitialState({
|
|||
...user(),
|
||||
attachmentsPath: window.BasePaths.attachments,
|
||||
i18n: window.i18n,
|
||||
interactionMode: window.getInteractionMode(),
|
||||
interactionMode: getInteractionMode(),
|
||||
isMainWindowFullScreen: mainWindowStats.isFullScreen,
|
||||
isMainWindowMaximized: mainWindowStats.isMaximized,
|
||||
localeMessages: window.SignalContext.localeMessages,
|
||||
|
|
|
@ -5,7 +5,7 @@ import { assert } from 'chai';
|
|||
import * as sinon from 'sinon';
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
import { ActiveWindowService } from '../../services/ActiveWindowService';
|
||||
import { getActiveWindowService } from '../../services/ActiveWindowService';
|
||||
|
||||
describe('ActiveWindowService', () => {
|
||||
const fakeIpcEvent = {};
|
||||
|
@ -23,16 +23,17 @@ describe('ActiveWindowService', () => {
|
|||
}
|
||||
|
||||
it('is inactive at the start', () => {
|
||||
const service = new ActiveWindowService();
|
||||
service.initialize(createFakeDocument(), new EventEmitter());
|
||||
const service = getActiveWindowService(
|
||||
createFakeDocument(),
|
||||
new EventEmitter()
|
||||
);
|
||||
|
||||
assert.isFalse(service.isActive());
|
||||
});
|
||||
|
||||
it('becomes active after focusing', () => {
|
||||
const fakeIpc = new EventEmitter();
|
||||
const service = new ActiveWindowService();
|
||||
service.initialize(createFakeDocument(), fakeIpc);
|
||||
const service = getActiveWindowService(createFakeDocument(), fakeIpc);
|
||||
|
||||
fakeIpc.emit('set-window-focus', fakeIpcEvent, true);
|
||||
|
||||
|
@ -41,8 +42,7 @@ describe('ActiveWindowService', () => {
|
|||
|
||||
it('becomes inactive after 15 seconds without interaction', function test() {
|
||||
const fakeIpc = new EventEmitter();
|
||||
const service = new ActiveWindowService();
|
||||
service.initialize(createFakeDocument(), fakeIpc);
|
||||
const service = getActiveWindowService(createFakeDocument(), fakeIpc);
|
||||
|
||||
fakeIpc.emit('set-window-focus', fakeIpcEvent, true);
|
||||
|
||||
|
@ -61,8 +61,7 @@ describe('ActiveWindowService', () => {
|
|||
it(`is inactive even in the face of ${eventName} events if unfocused`, function test() {
|
||||
const fakeDocument = createFakeDocument();
|
||||
const fakeIpc = new EventEmitter();
|
||||
const service = new ActiveWindowService();
|
||||
service.initialize(fakeDocument, fakeIpc);
|
||||
const service = getActiveWindowService(fakeDocument, fakeIpc);
|
||||
|
||||
fakeIpc.emit('set-window-focus', fakeIpcEvent, false);
|
||||
|
||||
|
@ -73,8 +72,7 @@ describe('ActiveWindowService', () => {
|
|||
it(`stays active if focused and receiving ${eventName} events`, function test() {
|
||||
const fakeDocument = createFakeDocument();
|
||||
const fakeIpc = new EventEmitter();
|
||||
const service = new ActiveWindowService();
|
||||
service.initialize(fakeDocument, fakeIpc);
|
||||
const service = getActiveWindowService(fakeDocument, fakeIpc);
|
||||
|
||||
fakeIpc.emit('set-window-focus', fakeIpcEvent, true);
|
||||
|
||||
|
@ -94,8 +92,7 @@ describe('ActiveWindowService', () => {
|
|||
|
||||
it('calls callbacks when going from unfocused to focused', () => {
|
||||
const fakeIpc = new EventEmitter();
|
||||
const service = new ActiveWindowService();
|
||||
service.initialize(createFakeDocument(), fakeIpc);
|
||||
const service = getActiveWindowService(createFakeDocument(), fakeIpc);
|
||||
|
||||
const callback = sinon.stub();
|
||||
service.registerForActive(callback);
|
||||
|
@ -108,8 +105,7 @@ describe('ActiveWindowService', () => {
|
|||
it('calls callbacks when receiving a click event after being focused', function test() {
|
||||
const fakeDocument = createFakeDocument();
|
||||
const fakeIpc = new EventEmitter();
|
||||
const service = new ActiveWindowService();
|
||||
service.initialize(fakeDocument, fakeIpc);
|
||||
const service = getActiveWindowService(fakeDocument, fakeIpc);
|
||||
|
||||
fakeIpc.emit('set-window-focus', fakeIpcEvent, true);
|
||||
|
||||
|
@ -125,8 +121,7 @@ describe('ActiveWindowService', () => {
|
|||
|
||||
it('only calls callbacks every 5 seconds; it is throttled', function test() {
|
||||
const fakeIpc = new EventEmitter();
|
||||
const service = new ActiveWindowService();
|
||||
service.initialize(createFakeDocument(), fakeIpc);
|
||||
const service = getActiveWindowService(createFakeDocument(), fakeIpc);
|
||||
|
||||
const callback = sinon.stub();
|
||||
service.registerForActive(callback);
|
||||
|
@ -150,8 +145,7 @@ describe('ActiveWindowService', () => {
|
|||
it('can remove callbacks', () => {
|
||||
const fakeDocument = createFakeDocument();
|
||||
const fakeIpc = new EventEmitter();
|
||||
const service = new ActiveWindowService();
|
||||
service.initialize(fakeDocument, fakeIpc);
|
||||
const service = getActiveWindowService(fakeDocument, fakeIpc);
|
||||
|
||||
const callback = sinon.stub();
|
||||
service.registerForActive(callback);
|
||||
|
|
|
@ -24,6 +24,8 @@ const excludedFilesRegexp = RegExp(
|
|||
[
|
||||
'^release/',
|
||||
'^preload.bundle.js(LICENSE.txt|map)?',
|
||||
'^about.browser.bundle.js(LICENSE.txt|map)?',
|
||||
'^about.preload.bundle.js(LICENSE.txt|map)?',
|
||||
'^storybook-static/',
|
||||
|
||||
// Non-distributed files
|
||||
|
|
10
ts/window.d.ts
vendored
10
ts/window.d.ts
vendored
|
@ -3,6 +3,7 @@
|
|||
|
||||
// Captures the globals put in place by preload.js, background.js and others
|
||||
|
||||
import type { MenuItemConstructorOptions } from 'electron';
|
||||
import type { Store } from 'redux';
|
||||
import type * as Backbone from 'backbone';
|
||||
import type PQueue from 'p-queue/dist';
|
||||
|
@ -101,7 +102,16 @@ export type FeatureFlagType = {
|
|||
GV2_MIGRATION_DISABLE_INVITE: boolean;
|
||||
};
|
||||
|
||||
type AboutWindowType = {
|
||||
environmentText: string;
|
||||
executeMenuRole: (role: MenuItemConstructorOptions['role']) => Promise<void>;
|
||||
hasCustomTitleBar: boolean;
|
||||
i18n: LocalizerType;
|
||||
version: string;
|
||||
};
|
||||
|
||||
export type SignalCoreType = {
|
||||
AboutWindow?: AboutWindowType;
|
||||
Crypto: typeof Crypto;
|
||||
Curve: typeof Curve;
|
||||
Data: typeof Data;
|
||||
|
|
24
ts/windows/about/app.tsx
Normal file
24
ts/windows/about/app.tsx
Normal file
|
@ -0,0 +1,24 @@
|
|||
// Copyright 2023 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import { About } from '../../components/About';
|
||||
import { strictAssert } from '../../util/assert';
|
||||
|
||||
const { AboutWindow } = window.Signal;
|
||||
|
||||
strictAssert(AboutWindow, 'window values not provided');
|
||||
|
||||
ReactDOM.render(
|
||||
<About
|
||||
closeAbout={() => AboutWindow.executeMenuRole('close')}
|
||||
environment={AboutWindow.environmentText}
|
||||
executeMenuRole={AboutWindow.executeMenuRole}
|
||||
hasCustomTitleBar={AboutWindow.hasCustomTitleBar}
|
||||
i18n={AboutWindow.i18n}
|
||||
version={AboutWindow.version}
|
||||
/>,
|
||||
document.getElementById('app')
|
||||
);
|
|
@ -1,42 +1,63 @@
|
|||
// Copyright 2018 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { contextBridge } from 'electron';
|
||||
import type { MenuItemConstructorOptions } from 'electron';
|
||||
import { contextBridge, ipcRenderer } from 'electron';
|
||||
import { activeWindowService } from '../../context/activeWindowService';
|
||||
import { config } from '../../context/config';
|
||||
import { createNativeThemeListener } from '../../context/createNativeThemeListener';
|
||||
import { createSetting } from '../../util/preload';
|
||||
import { environment } from '../../context/environment';
|
||||
import { getClassName } from '../../OS';
|
||||
import { i18n } from '../../context/i18n';
|
||||
import { waitForSettingsChange } from '../../context/waitForSettingsChange';
|
||||
|
||||
import { SignalContext } from '../context';
|
||||
import { About } from '../../components/About';
|
||||
async function executeMenuRole(
|
||||
role: MenuItemConstructorOptions['role']
|
||||
): Promise<void> {
|
||||
await ipcRenderer.invoke('executeMenuRole', role);
|
||||
}
|
||||
|
||||
contextBridge.exposeInMainWorld('SignalContext', {
|
||||
...SignalContext,
|
||||
renderWindow: () => {
|
||||
const environmentText: Array<string> = [SignalContext.getEnvironment()];
|
||||
const environments: Array<string> = [environment];
|
||||
|
||||
const appInstance = SignalContext.getAppInstance();
|
||||
if (appInstance) {
|
||||
environmentText.push(appInstance);
|
||||
}
|
||||
if (config.appInstance) {
|
||||
environments.push(String(config.appInstance));
|
||||
}
|
||||
|
||||
let platform = '';
|
||||
if (process.platform === 'darwin') {
|
||||
if (process.arch === 'arm64') {
|
||||
platform = ` (${SignalContext.i18n('appleSilicon')})`;
|
||||
} else {
|
||||
platform = ' (Intel)';
|
||||
}
|
||||
}
|
||||
let platform = '';
|
||||
if (process.platform === 'darwin') {
|
||||
if (process.arch === 'arm64') {
|
||||
platform = ` (${i18n('appleSilicon')})`;
|
||||
} else {
|
||||
platform = ' (Intel)';
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
React.createElement(About, {
|
||||
closeAbout: () => SignalContext.executeMenuRole('close'),
|
||||
environment: `${environmentText.join(' - ')}${platform}`,
|
||||
i18n: SignalContext.i18n,
|
||||
version: SignalContext.getVersion(),
|
||||
hasCustomTitleBar: SignalContext.OS.hasCustomTitleBar(),
|
||||
executeMenuRole: SignalContext.executeMenuRole,
|
||||
}),
|
||||
document.getElementById('app')
|
||||
);
|
||||
const environmentText = `${environments.join(' - ')}${platform}`;
|
||||
const hasCustomTitleBar = ipcRenderer.sendSync('getHasCustomTitleBar');
|
||||
|
||||
const Signal = {
|
||||
AboutWindow: {
|
||||
environmentText,
|
||||
executeMenuRole,
|
||||
hasCustomTitleBar,
|
||||
i18n,
|
||||
version: String(config.version),
|
||||
},
|
||||
});
|
||||
};
|
||||
contextBridge.exposeInMainWorld('Signal', Signal);
|
||||
|
||||
// TODO DESKTOP-5054
|
||||
const SignalContext = {
|
||||
activeWindowService,
|
||||
OS: {
|
||||
getClassName,
|
||||
hasCustomTitleBar: () => hasCustomTitleBar,
|
||||
},
|
||||
Settings: {
|
||||
themeSetting: createSetting('themeSetting', { setter: false }),
|
||||
waitForChange: waitForSettingsChange,
|
||||
},
|
||||
nativeThemeListener: createNativeThemeListener(ipcRenderer, window),
|
||||
};
|
||||
contextBridge.exposeInMainWorld('SignalContext', SignalContext);
|
||||
|
|
|
@ -12,13 +12,15 @@ import type { LocaleMessagesType } from '../types/I18N';
|
|||
import type { NativeThemeType } from '../context/createNativeThemeListener';
|
||||
import type { SettingType } from '../util/preload';
|
||||
import type { RendererConfigType } from '../types/RendererConfig';
|
||||
import { ActiveWindowService } from '../services/ActiveWindowService';
|
||||
|
||||
import { Bytes } from '../context/Bytes';
|
||||
import { Crypto } from '../context/Crypto';
|
||||
import { Timers } from '../context/Timers';
|
||||
|
||||
import { setupI18n } from '../util/setupI18n';
|
||||
import type { ActiveWindowServiceType } from '../services/ActiveWindowService';
|
||||
import { config } from '../context/config';
|
||||
import { i18n } from '../context/i18n';
|
||||
import { activeWindowService } from '../context/activeWindowService';
|
||||
import {
|
||||
getEnvironment,
|
||||
parseEnvironment,
|
||||
|
@ -27,7 +29,7 @@ import {
|
|||
import { strictAssert } from '../util/assert';
|
||||
import { createSetting } from '../util/preload';
|
||||
import { initialize as initializeLogging } from '../logging/set_up_renderer_logging';
|
||||
import { waitForSettingsChange } from './waitForSettingsChange';
|
||||
import { waitForSettingsChange } from '../context/waitForSettingsChange';
|
||||
import { createNativeThemeListener } from '../context/createNativeThemeListener';
|
||||
import {
|
||||
isWindows,
|
||||
|
@ -37,24 +39,6 @@ import {
|
|||
getClassName,
|
||||
} from '../OS';
|
||||
|
||||
const activeWindowService = new ActiveWindowService();
|
||||
activeWindowService.initialize(window.document, ipcRenderer);
|
||||
|
||||
const params = new URLSearchParams(document.location.search);
|
||||
const configParam = params.get('config');
|
||||
strictAssert(typeof configParam === 'string', 'config is not a string');
|
||||
const config: RendererConfigType = JSON.parse(configParam);
|
||||
|
||||
const { resolvedTranslationsLocale } = config;
|
||||
strictAssert(
|
||||
resolvedTranslationsLocale,
|
||||
'locale could not be parsed from config'
|
||||
);
|
||||
strictAssert(
|
||||
typeof resolvedTranslationsLocale === 'string',
|
||||
'locale is not a string'
|
||||
);
|
||||
|
||||
const localeMessages = ipcRenderer.sendSync('locale-data');
|
||||
setEnvironment(parseEnvironment(config.environment));
|
||||
|
||||
|
@ -74,7 +58,7 @@ export type SignalContextType = {
|
|||
nativeThemeListener: NativeThemeType;
|
||||
setIsCallActive: (isCallActive: boolean) => unknown;
|
||||
|
||||
activeWindowService: typeof activeWindowService;
|
||||
activeWindowService: ActiveWindowServiceType;
|
||||
Settings: {
|
||||
themeSetting: SettingType<IPCEventsValuesType['themeSetting']>;
|
||||
waitForChange: () => Promise<void>;
|
||||
|
@ -128,7 +112,7 @@ export const SignalContext: SignalContextType = {
|
|||
getPath: (name: 'userData' | 'home'): string => {
|
||||
return String(config[`${name}Path`]);
|
||||
},
|
||||
i18n: setupI18n(resolvedTranslationsLocale, localeMessages),
|
||||
i18n,
|
||||
localeMessages,
|
||||
log: window.SignalContext.log,
|
||||
nativeThemeListener: createNativeThemeListener(ipcRenderer, window),
|
||||
|
|
|
@ -8,6 +8,6 @@ if (window.SignalContext.OS.hasCustomTitleBar()) {
|
|||
|
||||
if (window.SignalContext.renderWindow) {
|
||||
window.SignalContext.renderWindow();
|
||||
} else {
|
||||
} else if (window.SignalContext.log) {
|
||||
window.SignalContext.log.error('renderWindow is undefined!');
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
import { awaitObject } from '../../util/awaitObject';
|
||||
import { DurationInSeconds } from '../../util/durations';
|
||||
import { createSetting, createCallback } from '../../util/preload';
|
||||
import { startInteractionMode } from '../startInteractionMode';
|
||||
import { startInteractionMode } from '../../services/InteractionMode';
|
||||
|
||||
function doneRendering() {
|
||||
ipcRenderer.send('settings-done-rendering');
|
||||
|
|
Loading…
Reference in a new issue