mirror of
https://github.com/vector-im/element-web.git
synced 2024-09-10 07:05:14 +00:00
Merge pull request #13756 from vector-im/t3chguy/toasts2
Convert platforms to Typescript
This commit is contained in:
commit
b4284b4c68
4 changed files with 110 additions and 118 deletions
7
src/@types/global.d.ts
vendored
7
src/@types/global.d.ts
vendored
|
@ -32,3 +32,10 @@ declare global {
|
|||
InstallTrigger: any;
|
||||
}
|
||||
}
|
||||
|
||||
// add method which is missing from the node typing
|
||||
declare module "url" {
|
||||
interface Url {
|
||||
format(): string;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
// @flow
|
||||
|
||||
/*
|
||||
Copyright 2016 Aviral Dasgupta
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
|
@ -21,11 +19,20 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import VectorBasePlatform, {updateCheckStatusEnum} from './VectorBasePlatform';
|
||||
import BaseEventIndexManager from 'matrix-react-sdk/src/indexing/BaseEventIndexManager';
|
||||
import BaseEventIndexManager, {
|
||||
MatrixEvent,
|
||||
MatrixProfile,
|
||||
SearchResult,
|
||||
CrawlerCheckpoint,
|
||||
EventAndProfile,
|
||||
SearchArgs,
|
||||
IndexStats
|
||||
} from 'matrix-react-sdk/src/indexing/BaseEventIndexManager';
|
||||
import dis from 'matrix-react-sdk/src/dispatcher/dispatcher';
|
||||
import { _t, _td } from 'matrix-react-sdk/src/languageHandler';
|
||||
import * as rageshake from 'matrix-react-sdk/src/rageshake/rageshake';
|
||||
import {MatrixClient} from "matrix-js-sdk";
|
||||
import {MatrixClient} from "matrix-js-sdk/src/client";
|
||||
import {Room} from "matrix-js-sdk/src/models/room";
|
||||
import Modal from "matrix-react-sdk/src/Modal";
|
||||
import InfoDialog from "matrix-react-sdk/src/components/views/dialogs/InfoDialog";
|
||||
import Spinner from "matrix-react-sdk/src/components/views/elements/Spinner";
|
||||
|
@ -34,6 +41,7 @@ import {Key} from "matrix-react-sdk/src/Keyboard";
|
|||
import React from "react";
|
||||
import {randomString} from "matrix-js-sdk/src/randomstring";
|
||||
import {Action} from "matrix-react-sdk/src/dispatcher/actions";
|
||||
import { ActionPayload } from "matrix-react-sdk/src/dispatcher/payloads";
|
||||
|
||||
const ipcRenderer = window.ipcRenderer;
|
||||
const isMac = navigator.platform.toUpperCase().includes('MAC');
|
||||
|
@ -57,7 +65,7 @@ function platformFriendlyName(): string {
|
|||
}
|
||||
}
|
||||
|
||||
function _onAction(payload: Object) {
|
||||
function _onAction(payload: ActionPayload) {
|
||||
// Whitelist payload actions, no point sending most across
|
||||
if (['call_state'].includes(payload.action)) {
|
||||
ipcRenderer.send('app_onAction', payload);
|
||||
|
@ -77,53 +85,60 @@ function getUpdateCheckStatus(status) {
|
|||
}
|
||||
}
|
||||
|
||||
interface IPCPayload {
|
||||
id?: number;
|
||||
error?: string;
|
||||
reply?: any;
|
||||
}
|
||||
|
||||
class SeshatIndexManager extends BaseEventIndexManager {
|
||||
private pendingIpcCalls: Record<number, { resolve, reject }> = {};
|
||||
private nextIpcCallId: number = 0;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._pendingIpcCalls = {};
|
||||
this._nextIpcCallId = 0;
|
||||
ipcRenderer.on('seshatReply', this._onIpcReply.bind(this));
|
||||
ipcRenderer.on('seshatReply', this._onIpcReply);
|
||||
}
|
||||
|
||||
async _ipcCall(name: string, ...args: []): Promise<{}> {
|
||||
async _ipcCall(name: string, ...args: any[]): Promise<any> {
|
||||
// TODO this should be moved into the preload.js file.
|
||||
const ipcCallId = ++this._nextIpcCallId;
|
||||
const ipcCallId = ++this.nextIpcCallId;
|
||||
return new Promise((resolve, reject) => {
|
||||
this._pendingIpcCalls[ipcCallId] = {resolve, reject};
|
||||
this.pendingIpcCalls[ipcCallId] = {resolve, reject};
|
||||
window.ipcRenderer.send('seshat', {id: ipcCallId, name, args});
|
||||
});
|
||||
}
|
||||
|
||||
_onIpcReply(ev: {}, payload: {}) {
|
||||
_onIpcReply = (ev: {}, payload: IPCPayload) => {
|
||||
if (payload.id === undefined) {
|
||||
console.warn("Ignoring IPC reply with no ID");
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._pendingIpcCalls[payload.id] === undefined) {
|
||||
if (this.pendingIpcCalls[payload.id] === undefined) {
|
||||
console.warn("Unknown IPC payload ID: " + payload.id);
|
||||
return;
|
||||
}
|
||||
|
||||
const callbacks = this._pendingIpcCalls[payload.id];
|
||||
delete this._pendingIpcCalls[payload.id];
|
||||
const callbacks = this.pendingIpcCalls[payload.id];
|
||||
delete this.pendingIpcCalls[payload.id];
|
||||
if (payload.error) {
|
||||
callbacks.reject(payload.error);
|
||||
} else {
|
||||
callbacks.resolve(payload.reply);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
async supportsEventIndexing(): Promise<boolean> {
|
||||
return this._ipcCall('supportsEventIndexing');
|
||||
}
|
||||
|
||||
async initEventIndex(): Promise<> {
|
||||
async initEventIndex(): Promise<void> {
|
||||
return this._ipcCall('initEventIndex');
|
||||
}
|
||||
|
||||
async addEventToIndex(ev: MatrixEvent, profile: MatrixProfile): Promise<> {
|
||||
async addEventToIndex(ev: MatrixEvent, profile: MatrixProfile): Promise<void> {
|
||||
return this._ipcCall('addEventToIndex', ev, profile);
|
||||
}
|
||||
|
||||
|
@ -135,27 +150,27 @@ class SeshatIndexManager extends BaseEventIndexManager {
|
|||
return this._ipcCall('isEventIndexEmpty');
|
||||
}
|
||||
|
||||
async commitLiveEvents(): Promise<> {
|
||||
async commitLiveEvents(): Promise<void> {
|
||||
return this._ipcCall('commitLiveEvents');
|
||||
}
|
||||
|
||||
async searchEventIndex(searchConfig: SearchConfig): Promise<SearchResult> {
|
||||
async searchEventIndex(searchConfig: SearchArgs): Promise<SearchResult> {
|
||||
return this._ipcCall('searchEventIndex', searchConfig);
|
||||
}
|
||||
|
||||
async addHistoricEvents(
|
||||
events: [HistoricEvent],
|
||||
events: [EventAndProfile],
|
||||
checkpoint: CrawlerCheckpoint | null,
|
||||
oldCheckpoint: CrawlerCheckpoint | null,
|
||||
): Promise<> {
|
||||
): Promise<boolean> {
|
||||
return this._ipcCall('addHistoricEvents', events, checkpoint, oldCheckpoint);
|
||||
}
|
||||
|
||||
async addCrawlerCheckpoint(checkpoint: CrawlerCheckpoint): Promise<> {
|
||||
async addCrawlerCheckpoint(checkpoint: CrawlerCheckpoint): Promise<void> {
|
||||
return this._ipcCall('addCrawlerCheckpoint', checkpoint);
|
||||
}
|
||||
|
||||
async removeCrawlerCheckpoint(checkpoint: CrawlerCheckpoint): Promise<> {
|
||||
async removeCrawlerCheckpoint(checkpoint: CrawlerCheckpoint): Promise<void> {
|
||||
return this._ipcCall('removeCrawlerCheckpoint', checkpoint);
|
||||
}
|
||||
|
||||
|
@ -167,27 +182,29 @@ class SeshatIndexManager extends BaseEventIndexManager {
|
|||
return this._ipcCall('loadCheckpoints');
|
||||
}
|
||||
|
||||
async closeEventIndex(): Promise<> {
|
||||
async closeEventIndex(): Promise<void> {
|
||||
return this._ipcCall('closeEventIndex');
|
||||
}
|
||||
|
||||
async getStats(): Promise<> {
|
||||
async getStats(): Promise<IndexStats> {
|
||||
return this._ipcCall('getStats');
|
||||
}
|
||||
|
||||
async deleteEventIndex(): Promise<> {
|
||||
async deleteEventIndex(): Promise<void> {
|
||||
return this._ipcCall('deleteEventIndex');
|
||||
}
|
||||
}
|
||||
|
||||
export default class ElectronPlatform extends VectorBasePlatform {
|
||||
private eventIndexManager: BaseEventIndexManager = new SeshatIndexManager();
|
||||
private pendingIpcCalls: Record<number, { resolve, reject }> = {};
|
||||
private nextIpcCallId: number = 0;
|
||||
// this is the opaque token we pass to the HS which when we get it in our callback we can resolve to a profile
|
||||
private ssoID: string = randomString(32);
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._pendingIpcCalls = {};
|
||||
this._nextIpcCallId = 0;
|
||||
this.eventIndexManager = new SeshatIndexManager();
|
||||
|
||||
dis.register(_onAction);
|
||||
/*
|
||||
IPC Call `check_updates` returns:
|
||||
|
@ -217,9 +234,6 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
|||
dis.fire(Action.ViewUserSettings);
|
||||
});
|
||||
|
||||
this.startUpdateCheck = this.startUpdateCheck.bind(this);
|
||||
this.stopUpdateCheck = this.stopUpdateCheck.bind(this);
|
||||
|
||||
// register OS-specific shortcuts
|
||||
if (isMac) {
|
||||
registerShortcut(Categories.NAVIGATION, {
|
||||
|
@ -253,8 +267,6 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
|||
});
|
||||
}
|
||||
|
||||
// this is the opaque token we pass to the HS which when we get it in our callback we can resolve to a profile
|
||||
this.ssoID = randomString(32);
|
||||
this._ipcCall("startSSOFlow", this.ssoID);
|
||||
}
|
||||
|
||||
|
@ -290,7 +302,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
|||
return true;
|
||||
}
|
||||
|
||||
displayNotification(title: string, msg: string, avatarUrl: string, room: Object): Notification {
|
||||
displayNotification(title: string, msg: string, avatarUrl: string, room: Room): Notification {
|
||||
// GNOME notification spec parses HTML tags for styling...
|
||||
// Electron Docs state all supported linux notification systems follow this markup spec
|
||||
// https://github.com/electron/electron/blob/master/docs/tutorial/desktop-environment-integration.md#linux
|
||||
|
@ -307,14 +319,14 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
|||
silent: true, // we play our own sounds
|
||||
};
|
||||
if (avatarUrl) notifBody['icon'] = avatarUrl;
|
||||
const notification = new global.Notification(title, notifBody);
|
||||
const notification = new window.Notification(title, notifBody);
|
||||
|
||||
notification.onclick = () => {
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: room.roomId,
|
||||
});
|
||||
global.focus();
|
||||
window.focus();
|
||||
this._ipcCall('focusWindow');
|
||||
};
|
||||
|
||||
|
@ -337,11 +349,11 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
|||
return true;
|
||||
}
|
||||
|
||||
async getAutoLaunchEnabled(): boolean {
|
||||
async getAutoLaunchEnabled(): Promise<boolean> {
|
||||
return this._ipcCall('getAutoLaunchEnabled');
|
||||
}
|
||||
|
||||
async setAutoLaunchEnabled(enabled: boolean): void {
|
||||
async setAutoLaunchEnabled(enabled: boolean): Promise<void> {
|
||||
return this._ipcCall('setAutoLaunchEnabled', enabled);
|
||||
}
|
||||
|
||||
|
@ -350,11 +362,11 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
|||
return !isMac;
|
||||
}
|
||||
|
||||
async getAutoHideMenuBarEnabled(): boolean {
|
||||
async getAutoHideMenuBarEnabled(): Promise<boolean> {
|
||||
return this._ipcCall('getAutoHideMenuBarEnabled');
|
||||
}
|
||||
|
||||
async setAutoHideMenuBarEnabled(enabled: boolean): void {
|
||||
async setAutoHideMenuBarEnabled(enabled: boolean): Promise<void> {
|
||||
return this._ipcCall('setAutoHideMenuBarEnabled', enabled);
|
||||
}
|
||||
|
||||
|
@ -363,25 +375,25 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
|||
return !isMac;
|
||||
}
|
||||
|
||||
async getMinimizeToTrayEnabled(): boolean {
|
||||
async getMinimizeToTrayEnabled(): Promise<boolean> {
|
||||
return this._ipcCall('getMinimizeToTrayEnabled');
|
||||
}
|
||||
|
||||
async setMinimizeToTrayEnabled(enabled: boolean): void {
|
||||
async setMinimizeToTrayEnabled(enabled: boolean): Promise<void> {
|
||||
return this._ipcCall('setMinimizeToTrayEnabled', enabled);
|
||||
}
|
||||
|
||||
async canSelfUpdate(): boolean {
|
||||
async canSelfUpdate(): Promise<boolean> {
|
||||
const feedUrl = await this._ipcCall('getUpdateFeedUrl');
|
||||
return Boolean(feedUrl);
|
||||
}
|
||||
|
||||
startUpdateCheck() {
|
||||
startUpdateCheck = () => {
|
||||
if (this.showUpdateCheck) return;
|
||||
super.startUpdateCheck();
|
||||
|
||||
ipcRenderer.send('check_updates');
|
||||
}
|
||||
};
|
||||
|
||||
installUpdate() {
|
||||
// IPC to the main process to install the update, since quitAndInstall
|
||||
|
@ -394,7 +406,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
|||
return _t('Riot Desktop (%(platformName)s)', { platformName: platformFriendlyName() });
|
||||
}
|
||||
|
||||
screenCaptureErrorString(): ?string {
|
||||
screenCaptureErrorString(): string | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -409,10 +421,10 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
|||
window.location.reload(false);
|
||||
}
|
||||
|
||||
async _ipcCall(name, ...args) {
|
||||
const ipcCallId = ++this._nextIpcCallId;
|
||||
async _ipcCall(name: string, ...args: any[]): Promise<any> {
|
||||
const ipcCallId = ++this.nextIpcCallId;
|
||||
return new Promise((resolve, reject) => {
|
||||
this._pendingIpcCalls[ipcCallId] = {resolve, reject};
|
||||
this.pendingIpcCalls[ipcCallId] = {resolve, reject};
|
||||
window.ipcRenderer.send('ipcCall', {id: ipcCallId, name, args});
|
||||
// Maybe add a timeout to these? Probably not necessary.
|
||||
});
|
||||
|
@ -424,13 +436,13 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this._pendingIpcCalls[payload.id] === undefined) {
|
||||
if (this.pendingIpcCalls[payload.id] === undefined) {
|
||||
console.warn("Unknown IPC payload ID: " + payload.id);
|
||||
return;
|
||||
}
|
||||
|
||||
const callbacks = this._pendingIpcCalls[payload.id];
|
||||
delete this._pendingIpcCalls[payload.id];
|
||||
const callbacks = this.pendingIpcCalls[payload.id];
|
||||
delete this.pendingIpcCalls[payload.id];
|
||||
if (payload.error) {
|
||||
callbacks.reject(payload.error);
|
||||
} else {
|
|
@ -1,9 +1,7 @@
|
|||
// @flow
|
||||
|
||||
/*
|
||||
Copyright 2016 Aviral Dasgupta
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
Copyright 2018 New Vector Ltd
|
||||
Copyright 2018, 2020 New Vector Ltd
|
||||
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
@ -24,7 +22,7 @@ import { _t } from 'matrix-react-sdk/src/languageHandler';
|
|||
import dis from 'matrix-react-sdk/src/dispatcher/dispatcher';
|
||||
import {getVectorConfig} from "../getconfig";
|
||||
|
||||
import Favico from '../../favicon';
|
||||
import Favicon from "../../favicon";
|
||||
|
||||
export const updateCheckStatusEnum = {
|
||||
CHECKING: 'CHECKING',
|
||||
|
@ -37,14 +35,9 @@ export const updateCheckStatusEnum = {
|
|||
/**
|
||||
* Vector-specific extensions to the BasePlatform template
|
||||
*/
|
||||
export default class VectorBasePlatform extends BasePlatform {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.showUpdateCheck = false;
|
||||
this.startUpdateCheck = this.startUpdateCheck.bind(this);
|
||||
this.stopUpdateCheck = this.stopUpdateCheck.bind(this);
|
||||
}
|
||||
export default abstract class VectorBasePlatform extends BasePlatform {
|
||||
protected showUpdateCheck: boolean = false;
|
||||
protected _favicon: Favicon;
|
||||
|
||||
async getConfig(): Promise<{}> {
|
||||
return getVectorConfig();
|
||||
|
@ -55,40 +48,27 @@ export default class VectorBasePlatform extends BasePlatform {
|
|||
}
|
||||
|
||||
/**
|
||||
* Delay creating the `Favico` instance until first use (on the first notification) as
|
||||
* it uses canvas, which can trigger a permission prompt in Firefox's resist
|
||||
* fingerprinting mode.
|
||||
* Delay creating the `Favicon` instance until first use (on the first notification) as
|
||||
* it uses canvas, which can trigger a permission prompt in Firefox's resist fingerprinting mode.
|
||||
* See https://github.com/vector-im/riot-web/issues/9605.
|
||||
*/
|
||||
get favicon() {
|
||||
if (this._favicon) {
|
||||
return this._favicon;
|
||||
}
|
||||
// The 'animations' are really low framerate and look terrible.
|
||||
// Also it re-starts the animation every time you set the badge,
|
||||
// and we set the state each time, even if the value hasn't changed,
|
||||
// so we'd need to fix that if enabling the animation.
|
||||
this._favicon = new Favico({ animation: 'none' });
|
||||
return this._favicon;
|
||||
return this._favicon = new Favicon();
|
||||
}
|
||||
|
||||
_updateFavicon() {
|
||||
try {
|
||||
// This needs to be in in a try block as it will throw
|
||||
// if there are more than 100 badge count changes in
|
||||
// its internal queue
|
||||
let bgColor = "#d00";
|
||||
let notif = this.notificationCount;
|
||||
let bgColor = "#d00";
|
||||
let notif: string | number = this.notificationCount;
|
||||
|
||||
if (this.errorDidOccur) {
|
||||
notif = notif || "×";
|
||||
bgColor = "#f00";
|
||||
}
|
||||
|
||||
this.favicon.badge(notif, { bgColor });
|
||||
} catch (e) {
|
||||
console.warn(`Failed to set badge count: ${e.message}`);
|
||||
if (this.errorDidOccur) {
|
||||
notif = notif || "×";
|
||||
bgColor = "#f00";
|
||||
}
|
||||
|
||||
this.favicon.badge(notif, { bgColor });
|
||||
}
|
||||
|
||||
setNotificationCount(count: number) {
|
||||
|
@ -112,25 +92,25 @@ export default class VectorBasePlatform extends BasePlatform {
|
|||
/**
|
||||
* Whether we can call checkForUpdate on this platform build
|
||||
*/
|
||||
async canSelfUpdate(): boolean {
|
||||
async canSelfUpdate(): Promise<boolean> {
|
||||
return false;
|
||||
}
|
||||
|
||||
startUpdateCheck() {
|
||||
startUpdateCheck = () => {
|
||||
this.showUpdateCheck = true;
|
||||
dis.dispatch({
|
||||
action: 'check_updates',
|
||||
value: { status: updateCheckStatusEnum.CHECKING },
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
stopUpdateCheck() {
|
||||
stopUpdateCheck = () => {
|
||||
this.showUpdateCheck = false;
|
||||
dis.dispatch({
|
||||
action: 'check_updates',
|
||||
value: false,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
getUpdateCheckStatusEnum() {
|
||||
return updateCheckStatusEnum;
|
|
@ -1,5 +1,3 @@
|
|||
// @flow
|
||||
|
||||
/*
|
||||
Copyright 2016 Aviral Dasgupta
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
|
@ -22,6 +20,7 @@ import VectorBasePlatform, {updateCheckStatusEnum} from './VectorBasePlatform';
|
|||
import request from 'browser-request';
|
||||
import dis from 'matrix-react-sdk/src/dispatcher/dispatcher';
|
||||
import { _t } from 'matrix-react-sdk/src/languageHandler';
|
||||
import {Room} from "matrix-js-sdk/src/models/room";
|
||||
|
||||
import url from 'url';
|
||||
import UAParser from 'ua-parser-js';
|
||||
|
@ -29,13 +28,7 @@ import UAParser from 'ua-parser-js';
|
|||
const POKE_RATE_MS = 10 * 60 * 1000; // 10 min
|
||||
|
||||
export default class WebPlatform extends VectorBasePlatform {
|
||||
constructor() {
|
||||
super();
|
||||
this.runningVersion = null;
|
||||
|
||||
this.startUpdateCheck = this.startUpdateCheck.bind(this);
|
||||
this.stopUpdateCheck = this.stopUpdateCheck.bind(this);
|
||||
}
|
||||
private runningVersion: string = null;
|
||||
|
||||
getHumanReadableName(): string {
|
||||
return 'Web Platform'; // no translation required: only used for analytics
|
||||
|
@ -46,7 +39,7 @@ export default class WebPlatform extends VectorBasePlatform {
|
|||
* notifications, otherwise false.
|
||||
*/
|
||||
supportsNotifications(): boolean {
|
||||
return Boolean(global.Notification);
|
||||
return Boolean(window.Notification);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,7 +47,7 @@ export default class WebPlatform extends VectorBasePlatform {
|
|||
* to display notifications. Otherwise false.
|
||||
*/
|
||||
maySendNotifications(): boolean {
|
||||
return global.Notification.permission === 'granted';
|
||||
return window.Notification.permission === 'granted';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,27 +62,27 @@ export default class WebPlatform extends VectorBasePlatform {
|
|||
// promise, but this is only supported in Chrome 46
|
||||
// and Firefox 47, so adapt the callback API.
|
||||
return new Promise(function(resolve, reject) {
|
||||
global.Notification.requestPermission((result) => {
|
||||
window.Notification.requestPermission((result) => {
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
displayNotification(title: string, msg: string, avatarUrl: string, room: Object) {
|
||||
displayNotification(title: string, msg: string, avatarUrl: string, room: Room) {
|
||||
const notifBody = {
|
||||
body: msg,
|
||||
tag: "vector",
|
||||
silent: true, // we play our own sounds
|
||||
};
|
||||
if (avatarUrl) notifBody['icon'] = avatarUrl;
|
||||
const notification = new global.Notification(title, notifBody);
|
||||
const notification = new window.Notification(title, notifBody);
|
||||
|
||||
notification.onclick = function() {
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_id: room.roomId,
|
||||
});
|
||||
global.focus();
|
||||
window.focus();
|
||||
notification.close();
|
||||
};
|
||||
}
|
||||
|
@ -131,14 +124,14 @@ export default class WebPlatform extends VectorBasePlatform {
|
|||
|
||||
startUpdater() {
|
||||
this.pollForUpdate();
|
||||
setInterval(this.pollForUpdate.bind(this), POKE_RATE_MS);
|
||||
setInterval(this.pollForUpdate, POKE_RATE_MS);
|
||||
}
|
||||
|
||||
async canSelfUpdate(): boolean {
|
||||
async canSelfUpdate(): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
pollForUpdate() {
|
||||
pollForUpdate = () => {
|
||||
return this._getVersion().then((ver) => {
|
||||
if (this.runningVersion === null) {
|
||||
this.runningVersion = ver;
|
||||
|
@ -159,9 +152,9 @@ export default class WebPlatform extends VectorBasePlatform {
|
|||
detail: err.message || err.status ? err.status.toString() : 'Unknown Error',
|
||||
};
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
startUpdateCheck() {
|
||||
startUpdateCheck = () => {
|
||||
if (this.showUpdateCheck) return;
|
||||
super.startUpdateCheck();
|
||||
this.pollForUpdate().then((updateState) => {
|
||||
|
@ -172,7 +165,7 @@ export default class WebPlatform extends VectorBasePlatform {
|
|||
value: updateState,
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
installUpdate() {
|
||||
window.location.reload(true);
|
||||
|
@ -204,9 +197,9 @@ export default class WebPlatform extends VectorBasePlatform {
|
|||
});
|
||||
}
|
||||
|
||||
screenCaptureErrorString(): ?string {
|
||||
screenCaptureErrorString(): string | null {
|
||||
// it won't work at all if you're not on HTTPS so whine whine whine
|
||||
if (!global.window || global.window.location.protocol !== "https:") {
|
||||
if (window.location.protocol !== "https:") {
|
||||
return _t("You need to be using HTTPS to place a screen-sharing call.");
|
||||
}
|
||||
return null;
|
Loading…
Reference in a new issue