From 81c1263bfd8325c112455a4f9af0b2ef7dd47e4d Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Mon, 12 Feb 2024 15:05:58 +1100 Subject: [PATCH] chore: address PR reviews --- preload.js | 13 +++--- .../message-content/MessageReactBar.tsx | 43 ++++++++++--------- .../message-info/components/MessageInfo.tsx | 5 +-- ts/mains/main_node.ts | 16 +++---- ts/models/messageFactory.ts | 2 +- ts/session/disappearing_messages/index.ts | 2 +- .../disappearing_messages/timerOptions.ts | 9 +--- ts/shared/env_vars.ts | 16 +++++++ ts/util/privacy.ts | 3 +- ts/window.d.ts | 13 ++---- 10 files changed, 64 insertions(+), 58 deletions(-) create mode 100644 ts/shared/env_vars.ts diff --git a/preload.js b/preload.js index 643e7938f..13712388d 100644 --- a/preload.js +++ b/preload.js @@ -2,6 +2,8 @@ const { clipboard, ipcRenderer, webFrame } = require('electron/main'); const { Storage } = require('./ts/util/storage'); +const { isTestNet, isTestIntegration } = require('./ts/shared/env_vars'); + const url = require('url'); const _ = require('lodash'); @@ -22,19 +24,14 @@ window.getTitle = () => title; window.getEnvironment = () => configAny.environment; window.getAppInstance = () => configAny.appInstance; window.getVersion = () => configAny.version; -window.isDev = () => config.environment === 'development'; window.getCommitHash = () => configAny.commitHash; window.getNodeVersion = () => configAny.node_version; window.sessionFeatureFlags = { useOnionRequests: true, - useTestNet: Boolean( - process.env.NODE_APP_INSTANCE && process.env.NODE_APP_INSTANCE.includes('testnet') - ), - integrationTestEnv: Boolean( - process.env.NODE_APP_INSTANCE && process.env.NODE_APP_INSTANCE.includes('test-integration') - ), - useClosedGroupV3: false || process.env.USE_CLOSED_GROUP_V3, + useTestNet: isTestNet(), + integrationTestEnv: isTestIntegration(), + useClosedGroupV3: false, debug: { debugLogging: !_.isEmpty(process.env.SESSION_DEBUG), debugLibsessionDumps: !_.isEmpty(process.env.SESSION_DEBUG_LIBSESSION_DUMPS), diff --git a/ts/components/conversation/message/message-content/MessageReactBar.tsx b/ts/components/conversation/message/message-content/MessageReactBar.tsx index e6ab3a87c..dbd5a2bd6 100644 --- a/ts/components/conversation/message/message-content/MessageReactBar.tsx +++ b/ts/components/conversation/message/message-content/MessageReactBar.tsx @@ -94,36 +94,36 @@ function useIsRenderedExpiresInItem(messageId: string) { return expiryDetails.expirationTimestamp; } -function formatExpiry({ diffMs }: { diffMs: number }) { - const diff = moment(diffMs).utc(); +function formatTimeLeft({ timeLeftMs }: { timeLeftMs: number }) { + const timeLeft = moment(timeLeftMs).utc(); - if (diffMs <= 0) { + if (timeLeftMs <= 0) { return `0s`; } const prefix = 'Message will expire in'; - if (diff.isBefore(moment.utc(0).add(1, 'minute'))) { - return `${prefix} ${diff.seconds()}s`; + if (timeLeft.isBefore(moment.utc(0).add(1, 'minute'))) { + return `${prefix} ${timeLeft.seconds()}s`; } - if (diff.isBefore(moment.utc(0).add(1, 'hour'))) { - const extraUnit = diff.seconds() ? ` ${diff.seconds()}s` : ''; - return `${prefix} ${diff.minutes()}m${extraUnit}`; + if (timeLeft.isBefore(moment.utc(0).add(1, 'hour'))) { + const extraUnit = timeLeft.seconds() ? ` ${timeLeft.seconds()}s` : ''; + return `${prefix} ${timeLeft.minutes()}m${extraUnit}`; } - if (diff.isBefore(moment.utc(0).add(1, 'day'))) { - const extraUnit = diff.minutes() ? ` ${diff.minutes()}m` : ''; - return `${prefix} ${diff.hours()}h${extraUnit}`; + if (timeLeft.isBefore(moment.utc(0).add(1, 'day'))) { + const extraUnit = timeLeft.minutes() ? ` ${timeLeft.minutes()}m` : ''; + return `${prefix} ${timeLeft.hours()}h${extraUnit}`; } - if (diff.isBefore(moment.utc(0).add(7, 'day'))) { - const extraUnit = diff.hours() ? ` ${diff.hours()}h` : ''; - return `${prefix} ${diff.dayOfYear() - 1}d${extraUnit}`; + if (timeLeft.isBefore(moment.utc(0).add(7, 'day'))) { + const extraUnit = timeLeft.hours() ? ` ${timeLeft.hours()}h` : ''; + return `${prefix} ${timeLeft.dayOfYear() - 1}d${extraUnit}`; } - if (diff.isBefore(moment.utc(0).add(31, 'day'))) { - const days = diff.dayOfYear() - 1; + if (timeLeft.isBefore(moment.utc(0).add(31, 'day'))) { + const days = timeLeft.dayOfYear() - 1; const weeks = Math.floor(days / 7); const daysLeft = days % 7; const extraUnit = daysLeft ? ` ${daysLeft}d` : ''; @@ -136,15 +136,18 @@ function formatExpiry({ diffMs }: { diffMs: number }) { const ExpiresInItem = ({ expirationTimestamp }: { expirationTimestamp?: number | null }) => { // this boolean is just used to forceRefresh the state when we get to display seconds in the contextmenu const [refresh, setRefresh] = useBoolean(false); - const diffMs = (expirationTimestamp || 0) - Date.now(); + const timeLeftMs = (expirationTimestamp || 0) - Date.now(); useInterval( () => { setRefresh(!refresh); }, - diffMs > 0 && diffMs <= 2 * DURATION.MINUTES ? 500 : null + // We want to force refresh this component a lot more if the message has more than 2 minutes before disappearing, + // because when that's the case we also display the seconds left (i.e. 1min 23s) and we want that 23s to be dynamic. + // Also, we use a refresh interval of 500 rather than 1s so that the counter is a bit smoother + timeLeftMs > 0 && timeLeftMs <= 2 * DURATION.MINUTES ? 500 : null ); - if (!expirationTimestamp || diffMs < 0) { + if (!expirationTimestamp || timeLeftMs < 0) { return null; } @@ -152,7 +155,7 @@ const ExpiresInItem = ({ expirationTimestamp }: { expirationTimestamp?: number | - {formatExpiry({ diffMs })} + {formatTimeLeft({ timeLeftMs })} ); }; diff --git a/ts/components/conversation/right-panel/overlay/message-info/components/MessageInfo.tsx b/ts/components/conversation/right-panel/overlay/message-info/components/MessageInfo.tsx index 6b80bc9e2..1875298f0 100644 --- a/ts/components/conversation/right-panel/overlay/message-info/components/MessageInfo.tsx +++ b/ts/components/conversation/right-panel/overlay/message-info/components/MessageInfo.tsx @@ -19,6 +19,7 @@ import { useMessageTimestamp, } from '../../../../../../state/selectors'; +import { isDevProd } from '../../../../../../shared/env_vars'; import { Flex } from '../../../../../basic/Flex'; import { SpacerSM } from '../../../../../basic/Text'; @@ -64,8 +65,6 @@ const showDebugLog = () => { ipcRenderer.send('show-debug-log'); }; -const showDebugMessageInfo = false; - const DebugMessageInfo = ({ messageId }: { messageId: string }) => { const messageHash = useMessageHash(messageId); const serverId = useMessageServerId(messageId); @@ -73,7 +72,7 @@ const DebugMessageInfo = ({ messageId }: { messageId: string }) => { const expirationDurationMs = useMessageExpirationDurationMs(messageId); const expirationTimestamp = useMessageExpirationTimestamp(messageId); - if (!showDebugMessageInfo) { + if (!isDevProd()) { return null; } diff --git a/ts/mains/main_node.ts b/ts/mains/main_node.ts index cf4f34122..807046738 100644 --- a/ts/mains/main_node.ts +++ b/ts/mains/main_node.ts @@ -87,10 +87,9 @@ import { windowMarkShouldQuit, windowShouldQuit } from '../node/window_state'; / let appStartInitialSpellcheckSetting = true; -const isTestIntegration = Boolean( - process.env.NODE_APP_INSTANCE && process.env.NODE_APP_INSTANCE.includes('test-integration') -); -const openDevToolsTestIntegration = isTestIntegration && !isEmpty(process.env.TEST_OPEN_DEV_TOOLS); +function openDevToolsTestIntegration() { + return isTestIntegration() && !isEmpty(process.env.TEST_OPEN_DEV_TOOLS); +} async function getSpellCheckSetting() { const json = sqlNode.getItemById('spell-check'); @@ -159,6 +158,7 @@ if (windowFromUserConfig) { import { getAppRootPath } from '../node/getRootPath'; import { setLastestRelease } from '../node/latest_desktop_release'; import { load as loadLocale, LocaleMessagesWithNameType } from '../node/locale'; +import { isDevProd, isTestIntegration } from '../shared/env_vars'; import { classicDark } from '../themes'; // Both of these will be set after app fires the 'ready' event @@ -215,7 +215,7 @@ function captureClicks(window: BrowserWindow) { function getDefaultWindowSize() { return { defaultWidth: 880, - defaultHeight: openDevToolsTestIntegration ? 1000 : 820, // the dev tools open at the bottom hide some stuff which should be visible + defaultHeight: openDevToolsTestIntegration() ? 1000 : 820, // the dev tools open at the bottom hide some stuff which should be visible minWidth: 880, minHeight: 600, }; @@ -274,7 +274,7 @@ async function createWindow() { y: (windowConfig as any).y, }; - if (isTestIntegration) { + if (isTestIntegration()) { const screenWidth = screen.getPrimaryDisplay().workAreaSize.width - getDefaultWindowSize().defaultWidth; const screenHeight = @@ -416,7 +416,7 @@ async function createWindow() { const urlToLoad = prepareURL([getAppRootPath(), 'background.html']); await mainWindow.loadURL(urlToLoad); - if (openDevToolsTestIntegration) { + if (openDevToolsTestIntegration()) { setTimeout(() => { if (mainWindow && mainWindow.webContents) { mainWindow.webContents.openDevTools({ @@ -427,7 +427,7 @@ async function createWindow() { }, 5000); } - if ((process.env.NODE_APP_INSTANCE || '').startsWith('devprod')) { + if (isDevProd()) { // Open the DevTools. mainWindow.webContents.openDevTools({ mode: 'bottom', diff --git a/ts/models/messageFactory.ts b/ts/models/messageFactory.ts index 769cd3eae..c56a3d63e 100644 --- a/ts/models/messageFactory.ts +++ b/ts/models/messageFactory.ts @@ -117,7 +117,7 @@ export function markAttributesAsReadIfNeeded(messageAttributes: MessageAttribute latestUnreadForThisConvo?.lastRead && sentAt <= latestUnreadForThisConvo.lastRead ) { - // That message was sent before our last read timestamp for that conversation. + // The message was sent before our last read timestamp for that conversation. // eslint-disable-next-line no-param-reassign messageAttributes.unread = READ_MESSAGE_STATE.read; } diff --git a/ts/session/disappearing_messages/index.ts b/ts/session/disappearing_messages/index.ts index 8ca9f432d..ad6454a02 100644 --- a/ts/session/disappearing_messages/index.ts +++ b/ts/session/disappearing_messages/index.ts @@ -547,7 +547,7 @@ function getMessageReadyToDisappear( /** * Edge case: when we send a message before we poll for a message sent earlier, our convo volatile update will * mark that incoming message as read right away (because it was sent earlier than our latest convolatile lastRead). - * To take care of this case, we need to check if the expiration of an incoming DaR, alreadt marked as read message looks to not have been updated yet. + * To take care of this case, we need to check if an incoming DaR message is in a read state but its expiration has not been updated yet. * The way we do it, is by checking that the swarm expiration is before (now + expireTimer). * If it looks like this expiration was not updated yet, we need to trigger a UpdateExpiryJob for that message. */ diff --git a/ts/session/disappearing_messages/timerOptions.ts b/ts/session/disappearing_messages/timerOptions.ts index ef1ea5281..1dc1267f3 100644 --- a/ts/session/disappearing_messages/timerOptions.ts +++ b/ts/session/disappearing_messages/timerOptions.ts @@ -1,5 +1,5 @@ -import { isEmpty } from 'lodash'; import moment from 'moment'; +import { isDevProd } from '../../shared/env_vars'; import { LocalizerKeys } from '../../types/LocalizerKeys'; type TimerOptionsEntry = { name: string; value: number }; @@ -67,12 +67,7 @@ const VALUES: Array = timerOptionsDurations.map(t => { }); const filterOutDebugValues = (option: number) => { - // process.env.NODE_APP_INSTANCE is empty when the app is packaged, and not empty when starting from start-prod or start-dev - const isPackaged = isEmpty(process.env.NODE_APP_INSTANCE); - if (isPackaged) { - return option > 60; // when packaged, filter out options with less than 60s - } - return true; + return isDevProd() || option > 60; // when not a dev build, filter out options with less than 60s }; const DELETE_AFTER_READ = VALUES.filter(option => { diff --git a/ts/shared/env_vars.ts b/ts/shared/env_vars.ts new file mode 100644 index 000000000..349277c42 --- /dev/null +++ b/ts/shared/env_vars.ts @@ -0,0 +1,16 @@ +function envAppInstanceIncludes(prefix: string) { + if (!process.env.NODE_APP_INSTANCE) { + return false; + } + return !!process.env.NODE_APP_INSTANCE.includes(prefix); +} + +export function isDevProd() { + return envAppInstanceIncludes('devprod'); +} +export function isTestNet() { + return envAppInstanceIncludes('testnet'); +} +export function isTestIntegration() { + return envAppInstanceIncludes('test-integration'); +} diff --git a/ts/util/privacy.ts b/ts/util/privacy.ts index 387876f0b..148aef54b 100644 --- a/ts/util/privacy.ts +++ b/ts/util/privacy.ts @@ -3,6 +3,7 @@ import { escapeRegExp, isEmpty, isRegExp, isString } from 'lodash'; import { compose } from 'lodash/fp'; import { getAppRootPath } from '../node/getRootPath'; +import { isDevProd } from '../shared/env_vars'; const APP_ROOT_PATH = getAppRootPath(); const SESSION_ID_PATTERN = /\b((05)?[0-9a-f]{64})\b/gi; @@ -103,7 +104,7 @@ function shouldNotRedactLogs() { return true; } // otherwise we don't want to redact logs when running on the devprod env - return (process.env.NODE_APP_INSTANCE || '').startsWith('devprod'); + return isDevProd(); } // redactAll :: String -> String diff --git a/ts/window.d.ts b/ts/window.d.ts index 2e5da8494..b90a6b03b 100644 --- a/ts/window.d.ts +++ b/ts/window.d.ts @@ -17,14 +17,11 @@ If you import anything in global.d.ts, the type system won't work correctly. declare global { interface Window { - CONSTANTS: any; Events: any; - Lodash: any; Session: any; Whisper: any; - clearLocalData: any; + clearLocalData: () => Promise; clipboard: any; - dcodeIO: any; getSettingValue: (id: string, comparisonValue?: any) => any; setSettingValue: (id: string, value: any) => Promise; @@ -43,22 +40,20 @@ declare global { debugOnionRequests: boolean; }; }; - SessionSnodeAPI: SessionSnodeAPI; onLogin: (pw: string) => Promise; persistStore?: Persistor; - restart: any; + restart: () => void; getSeedNodeList: () => Array | undefined; - setPassword: any; + setPassword: (newPassword: string | null, oldPassword: string | null) => Promise; isOnline: boolean; toggleMediaPermissions: () => Promise; toggleCallMediaPermissionsTo: (enabled: boolean) => Promise; getCallMediaPermissions: () => boolean; toggleMenuBar: () => void; - toggleSpellCheck: any; + toggleSpellCheck: () => void; primaryColor: PrimaryColorStateType; theme: ThemeStateType; setTheme: (newTheme: string) => Promise; - isDev?: () => boolean; userConfig: any; versionInfo: any; getConversations: () => ConversationCollection;