Remove ts/services/timers.ts
This commit is contained in:
parent
26eabf16a8
commit
a537204fc0
10 changed files with 38 additions and 144 deletions
|
@ -147,7 +147,6 @@ const {
|
|||
initializeUpdateListener,
|
||||
} = require('../../ts/services/updateListener');
|
||||
const { calling } = require('../../ts/services/calling');
|
||||
const { onTimeout, removeTimeout } = require('../../ts/services/timers');
|
||||
const {
|
||||
enableStorageService,
|
||||
eraseAllStorageServiceState,
|
||||
|
@ -388,8 +387,6 @@ exports.setup = (options = {}) => {
|
|||
initializeGroupCredentialFetcher,
|
||||
initializeNetworkObserver,
|
||||
initializeUpdateListener,
|
||||
onTimeout,
|
||||
removeTimeout,
|
||||
runStorageServiceSyncJob,
|
||||
storageServiceUploadJob,
|
||||
};
|
||||
|
|
|
@ -383,11 +383,6 @@ try {
|
|||
version: config.version,
|
||||
});
|
||||
|
||||
// Linux seems to periodically let the event loop stop, so this is a global workaround
|
||||
setInterval(() => {
|
||||
window.nodeSetImmediate(() => {});
|
||||
}, 1000);
|
||||
|
||||
const { imageToBlurHash } = require('./ts/util/imageToBlurHash');
|
||||
const { isValidGuid } = require('./ts/util/isValidGuid');
|
||||
const { ActiveWindowService } = require('./ts/services/ActiveWindowService');
|
||||
|
|
|
@ -54,7 +54,10 @@ export function start(): void {
|
|||
this.on('add remove change:unreadCount', debouncedUpdateUnreadCount);
|
||||
window.Whisper.events.on('updateUnreadCount', debouncedUpdateUnreadCount);
|
||||
this.on('add', (model: ConversationModel): void => {
|
||||
this.initMuteExpirationTimer(model);
|
||||
// If the conversation is muted we set a timeout so when the mute expires
|
||||
// we can reset the mute state on the model. If the mute has already expired
|
||||
// then we reset the state right away.
|
||||
model.startMuteTimer();
|
||||
});
|
||||
},
|
||||
addActive(model: ConversationModel) {
|
||||
|
@ -64,25 +67,6 @@ export function start(): void {
|
|||
this.remove(model);
|
||||
}
|
||||
},
|
||||
// If the conversation is muted we set a timeout so when the mute expires
|
||||
// we can reset the mute state on the model. If the mute has already expired
|
||||
// then we reset the state right away.
|
||||
initMuteExpirationTimer(model: ConversationModel): void {
|
||||
const muteExpiresAt = model.get('muteExpiresAt');
|
||||
// This check for `muteExpiresAt` is likely redundant, but is needed to appease
|
||||
// TypeScript.
|
||||
if (model.isMuted() && muteExpiresAt) {
|
||||
window.Signal.Services.onTimeout(
|
||||
muteExpiresAt,
|
||||
() => {
|
||||
model.set({ muteExpiresAt: undefined });
|
||||
},
|
||||
model.getMuteTimeoutId()
|
||||
);
|
||||
} else if (muteExpiresAt) {
|
||||
model.set({ muteExpiresAt: undefined });
|
||||
}
|
||||
},
|
||||
updateUnreadCount() {
|
||||
const canCountMutedConversations = window.storage.get(
|
||||
'badge-count-muted-conversations'
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
import React, { KeyboardEvent, MouseEvent, ReactNode, useEffect } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { onTimeout, removeTimeout } from '../services/timers';
|
||||
import { useRestoreFocus } from '../hooks/useRestoreFocus';
|
||||
|
||||
export type PropsType = {
|
||||
|
@ -48,11 +47,11 @@ export const Toast = ({
|
|||
return;
|
||||
}
|
||||
|
||||
const timeoutId = onTimeout(Date.now() + timeout, onClose);
|
||||
const timeoutId = setTimeout(onClose, timeout);
|
||||
|
||||
return () => {
|
||||
if (timeoutId) {
|
||||
removeTimeout(timeoutId);
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
};
|
||||
}, [autoDismissDisabled, onClose, root, timeout]);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
/* eslint-disable class-methods-use-this */
|
||||
/* eslint-disable camelcase */
|
||||
import { compact } from 'lodash';
|
||||
import { compact, isNumber } from 'lodash';
|
||||
import {
|
||||
ConversationAttributesType,
|
||||
ConversationModelCollectionType,
|
||||
|
@ -190,6 +190,8 @@ export class ConversationModel extends window.Backbone
|
|||
|
||||
private lastIsTyping?: boolean;
|
||||
|
||||
private muteTimer?: NodeJS.Timer;
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
defaults(): Partial<ConversationAttributesType> {
|
||||
return {
|
||||
|
@ -1593,7 +1595,7 @@ export class ConversationModel extends window.Backbone
|
|||
}
|
||||
|
||||
const temporaryMemberCount = this.get('temporaryMemberCount');
|
||||
if (window._.isNumber(temporaryMemberCount)) {
|
||||
if (isNumber(temporaryMemberCount)) {
|
||||
return temporaryMemberCount;
|
||||
}
|
||||
|
||||
|
@ -4826,6 +4828,24 @@ export class ConversationModel extends window.Backbone
|
|||
});
|
||||
}
|
||||
|
||||
startMuteTimer(): void {
|
||||
if (this.muteTimer !== undefined) {
|
||||
clearTimeout(this.muteTimer);
|
||||
this.muteTimer = undefined;
|
||||
}
|
||||
|
||||
const muteExpiresAt = this.get('muteExpiresAt');
|
||||
if (isNumber(muteExpiresAt) && muteExpiresAt < Number.MAX_SAFE_INTEGER) {
|
||||
const delay = muteExpiresAt - Date.now();
|
||||
if (delay <= 0) {
|
||||
this.setMuteExpiration(0);
|
||||
return;
|
||||
}
|
||||
|
||||
this.muteTimer = setTimeout(() => this.setMuteExpiration(0), delay);
|
||||
}
|
||||
}
|
||||
|
||||
setMuteExpiration(
|
||||
muteExpiresAt = 0,
|
||||
{ viaStorageServiceSync = false } = {}
|
||||
|
@ -4836,26 +4856,8 @@ export class ConversationModel extends window.Backbone
|
|||
return;
|
||||
}
|
||||
|
||||
// we use a timeoutId here so that we can reference the mute that was
|
||||
// potentially set in the ConversationController. Specifically for a
|
||||
// scenario where a conversation is already muted and we boot up the app,
|
||||
// a timeout will be already set. But if we change the mute to a later
|
||||
// date a new timeout would need to be set and the old one cleared. With
|
||||
// this ID we can reference the existing timeout.
|
||||
const timeoutId = this.getMuteTimeoutId();
|
||||
window.Signal.Services.removeTimeout(timeoutId);
|
||||
|
||||
if (muteExpiresAt && muteExpiresAt < Number.MAX_SAFE_INTEGER) {
|
||||
window.Signal.Services.onTimeout(
|
||||
muteExpiresAt,
|
||||
() => {
|
||||
this.setMuteExpiration(0);
|
||||
},
|
||||
timeoutId
|
||||
);
|
||||
}
|
||||
|
||||
this.set({ muteExpiresAt });
|
||||
this.startMuteTimer();
|
||||
if (!viaStorageServiceSync) {
|
||||
this.captureChange('mutedUntilTimestamp');
|
||||
}
|
||||
|
@ -4866,10 +4868,6 @@ export class ConversationModel extends window.Backbone
|
|||
return isMuted(this.get('muteExpiresAt'));
|
||||
}
|
||||
|
||||
getMuteTimeoutId(): string {
|
||||
return `mute(${this.get('id')})`;
|
||||
}
|
||||
|
||||
async notify(
|
||||
message: Readonly<MessageModel>,
|
||||
reaction?: WhatIsThis
|
||||
|
|
|
@ -7,18 +7,17 @@ import {
|
|||
} from '../state/ducks/network';
|
||||
import { getSocketStatus } from '../shims/socketStatus';
|
||||
import * as log from '../logging/log';
|
||||
import { SECOND } from '../util/durations';
|
||||
|
||||
type NetworkActions = {
|
||||
checkNetworkStatus: (x: CheckNetworkStatusPayloadType) => NetworkActionType;
|
||||
closeConnectingGracePeriod: () => NetworkActionType;
|
||||
};
|
||||
|
||||
const REFRESH_INTERVAL = 5000;
|
||||
|
||||
export function initializeNetworkObserver(
|
||||
networkActions: NetworkActions
|
||||
): void {
|
||||
log.info(`Initializing network observer every ${REFRESH_INTERVAL}ms`);
|
||||
log.info('Initializing network observer');
|
||||
|
||||
const refresh = () => {
|
||||
networkActions.checkNetworkStatus({
|
||||
|
@ -31,8 +30,7 @@ export function initializeNetworkObserver(
|
|||
|
||||
window.addEventListener('online', refresh);
|
||||
window.addEventListener('offline', refresh);
|
||||
window.setInterval(refresh, REFRESH_INTERVAL);
|
||||
window.setTimeout(() => {
|
||||
networkActions.closeConnectingGracePeriod();
|
||||
}, REFRESH_INTERVAL);
|
||||
}, 5 * SECOND);
|
||||
}
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
// Copyright 2020 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { v4 as getGuid } from 'uuid';
|
||||
|
||||
type TimeoutType = {
|
||||
timestamp: number;
|
||||
uuid: string;
|
||||
};
|
||||
|
||||
const timeoutStore: Map<string, () => void> = new Map();
|
||||
const allTimeouts: Set<TimeoutType> = new Set();
|
||||
|
||||
setInterval(() => {
|
||||
if (!allTimeouts.size) {
|
||||
return;
|
||||
}
|
||||
|
||||
const now = Date.now();
|
||||
|
||||
allTimeouts.forEach((timeout: TimeoutType) => {
|
||||
const { timestamp, uuid } = timeout;
|
||||
|
||||
if (now >= timestamp) {
|
||||
if (timeoutStore.has(uuid)) {
|
||||
const callback = timeoutStore.get(uuid);
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
timeoutStore.delete(uuid);
|
||||
}
|
||||
|
||||
allTimeouts.delete(timeout);
|
||||
}
|
||||
});
|
||||
}, 100);
|
||||
|
||||
export function onTimeout(
|
||||
timestamp: number,
|
||||
callback: () => void,
|
||||
id?: string
|
||||
): string {
|
||||
if (id && timeoutStore.has(id)) {
|
||||
throw new ReferenceError(`onTimeout: ${id} already exists`);
|
||||
}
|
||||
|
||||
let uuid = id || getGuid();
|
||||
while (timeoutStore.has(uuid)) {
|
||||
uuid = getGuid();
|
||||
}
|
||||
|
||||
timeoutStore.set(uuid, callback);
|
||||
allTimeouts.add({
|
||||
timestamp,
|
||||
uuid,
|
||||
});
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
export function removeTimeout(uuid: string): void {
|
||||
if (!timeoutStore.has(uuid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
timeoutStore.delete(uuid);
|
||||
|
||||
allTimeouts.forEach((timeout: TimeoutType) => {
|
||||
if (uuid === timeout.uuid) {
|
||||
allTimeouts.delete(timeout);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -4,8 +4,8 @@
|
|||
import { ThunkAction } from 'redux-thunk';
|
||||
import * as updateIpc from '../../shims/updateIpc';
|
||||
import { DialogType } from '../../types/Dialogs';
|
||||
import { DAY } from '../../util/durations';
|
||||
import { StateType as RootStateType } from '../reducer';
|
||||
import { onTimeout } from '../../services/timers';
|
||||
|
||||
// State
|
||||
|
||||
|
@ -85,8 +85,6 @@ function showUpdateDialog(
|
|||
};
|
||||
}
|
||||
|
||||
const ONE_DAY = 24 * 60 * 60 * 1000;
|
||||
|
||||
function snoozeUpdate(): ThunkAction<
|
||||
void,
|
||||
RootStateType,
|
||||
|
@ -95,12 +93,12 @@ function snoozeUpdate(): ThunkAction<
|
|||
> {
|
||||
return (dispatch, getState) => {
|
||||
const { dialogType } = getState().updates;
|
||||
onTimeout(Date.now() + ONE_DAY, () => {
|
||||
setTimeout(() => {
|
||||
dispatch({
|
||||
type: UNSNOOZE_UPDATE,
|
||||
payload: dialogType,
|
||||
});
|
||||
});
|
||||
}, DAY);
|
||||
|
||||
dispatch({
|
||||
type: SNOOZE_UPDATE,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { onTimeout } from '../services/timers';
|
||||
import { MINUTE } from './durations';
|
||||
|
||||
class PostLinkExperience {
|
||||
private hasNotFinishedSync: boolean;
|
||||
|
@ -15,9 +15,9 @@ class PostLinkExperience {
|
|||
|
||||
// timeout "post link" after 10 minutes in case the syncs don't complete
|
||||
// in time or are never called.
|
||||
onTimeout(Date.now() + 60 * 60 * 10 * 1000, () => {
|
||||
setTimeout(() => {
|
||||
this.stop();
|
||||
});
|
||||
}, 10 * MINUTE);
|
||||
}
|
||||
|
||||
stop() {
|
||||
|
|
2
ts/window.d.ts
vendored
2
ts/window.d.ts
vendored
|
@ -291,8 +291,6 @@ declare global {
|
|||
initializeGroupCredentialFetcher: () => void;
|
||||
initializeNetworkObserver: (network: ReduxActions['network']) => void;
|
||||
initializeUpdateListener: (updates: ReduxActions['updates']) => void;
|
||||
onTimeout: (timestamp: number, cb: () => void, id?: string) => string;
|
||||
removeTimeout: (uuid: string) => void;
|
||||
retryPlaceholders?: Util.RetryPlaceholders;
|
||||
lightSessionResetQueue?: PQueue;
|
||||
runStorageServiceSyncJob: () => Promise<void>;
|
||||
|
|
Loading…
Reference in a new issue