From 5fe6a8212f9e648e408ecc3dd65a98ffb44e4e7e Mon Sep 17 00:00:00 2001 From: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com> Date: Thu, 16 Apr 2026 11:37:43 -0700 Subject: [PATCH] Remove loading screen --- images/logo-parts/base.svg | 1 - images/logo-parts/p1.svg | 1 - images/logo-parts/p10.svg | 1 - images/logo-parts/p11.svg | 1 - images/logo-parts/p12.svg | 1 - images/logo-parts/p13.svg | 1 - images/logo-parts/p14.svg | 1 - images/logo-parts/p15.svg | 1 - images/logo-parts/p16.svg | 1 - images/logo-parts/p2.svg | 1 - images/logo-parts/p3.svg | 1 - images/logo-parts/p4.svg | 1 - images/logo-parts/p5.svg | 1 - images/logo-parts/p6.svg | 1 - images/logo-parts/p7.svg | 1 - images/logo-parts/p8.svg | 1 - images/logo-parts/p9.svg | 1 - stylesheets/components/Inbox.scss | 61 ----------- ts/components/Inbox.dom.stories.tsx | 74 ------------- ts/components/Inbox.dom.tsx | 163 +--------------------------- ts/state/selectors/inbox.std.ts | 17 --- ts/state/smart/Inbox.preload.tsx | 16 --- 22 files changed, 1 insertion(+), 347 deletions(-) delete mode 100644 images/logo-parts/base.svg delete mode 100644 images/logo-parts/p1.svg delete mode 100644 images/logo-parts/p10.svg delete mode 100644 images/logo-parts/p11.svg delete mode 100644 images/logo-parts/p12.svg delete mode 100644 images/logo-parts/p13.svg delete mode 100644 images/logo-parts/p14.svg delete mode 100644 images/logo-parts/p15.svg delete mode 100644 images/logo-parts/p16.svg delete mode 100644 images/logo-parts/p2.svg delete mode 100644 images/logo-parts/p3.svg delete mode 100644 images/logo-parts/p4.svg delete mode 100644 images/logo-parts/p5.svg delete mode 100644 images/logo-parts/p6.svg delete mode 100644 images/logo-parts/p7.svg delete mode 100644 images/logo-parts/p8.svg delete mode 100644 images/logo-parts/p9.svg delete mode 100644 ts/components/Inbox.dom.stories.tsx delete mode 100644 ts/state/selectors/inbox.std.ts diff --git a/images/logo-parts/base.svg b/images/logo-parts/base.svg deleted file mode 100644 index ce119e2876..0000000000 --- a/images/logo-parts/base.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p1.svg b/images/logo-parts/p1.svg deleted file mode 100644 index 3304f4ff64..0000000000 --- a/images/logo-parts/p1.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p10.svg b/images/logo-parts/p10.svg deleted file mode 100644 index f7d73be79a..0000000000 --- a/images/logo-parts/p10.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p11.svg b/images/logo-parts/p11.svg deleted file mode 100644 index 6cf133025a..0000000000 --- a/images/logo-parts/p11.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p12.svg b/images/logo-parts/p12.svg deleted file mode 100644 index 28792f9bb1..0000000000 --- a/images/logo-parts/p12.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p13.svg b/images/logo-parts/p13.svg deleted file mode 100644 index 3be4b4314c..0000000000 --- a/images/logo-parts/p13.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p14.svg b/images/logo-parts/p14.svg deleted file mode 100644 index 8c67e8e94d..0000000000 --- a/images/logo-parts/p14.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p15.svg b/images/logo-parts/p15.svg deleted file mode 100644 index 058174d24a..0000000000 --- a/images/logo-parts/p15.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p16.svg b/images/logo-parts/p16.svg deleted file mode 100644 index 7e11086a1e..0000000000 --- a/images/logo-parts/p16.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p2.svg b/images/logo-parts/p2.svg deleted file mode 100644 index 58b761d21a..0000000000 --- a/images/logo-parts/p2.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p3.svg b/images/logo-parts/p3.svg deleted file mode 100644 index 1742c9e821..0000000000 --- a/images/logo-parts/p3.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p4.svg b/images/logo-parts/p4.svg deleted file mode 100644 index 5fd78883d4..0000000000 --- a/images/logo-parts/p4.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p5.svg b/images/logo-parts/p5.svg deleted file mode 100644 index 466144f44e..0000000000 --- a/images/logo-parts/p5.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p6.svg b/images/logo-parts/p6.svg deleted file mode 100644 index e21833447e..0000000000 --- a/images/logo-parts/p6.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p7.svg b/images/logo-parts/p7.svg deleted file mode 100644 index 19029f7d4d..0000000000 --- a/images/logo-parts/p7.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p8.svg b/images/logo-parts/p8.svg deleted file mode 100644 index 562ab1fdfd..0000000000 --- a/images/logo-parts/p8.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/logo-parts/p9.svg b/images/logo-parts/p9.svg deleted file mode 100644 index 9987b8a5ae..0000000000 --- a/images/logo-parts/p9.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/stylesheets/components/Inbox.scss b/stylesheets/components/Inbox.scss index b4a5808a54..c01f54e71c 100644 --- a/stylesheets/components/Inbox.scss +++ b/stylesheets/components/Inbox.scss @@ -42,67 +42,6 @@ margin: 0; } -.Inbox__logo { - flex-shrink: 0; - - display: block; - width: 128px; - height: 128px; - margin-block: 24px; - position: relative; - - @include mixins.light-theme() { - --Inbox__logo__bg: #{variables.$color-ultramarine-logo}; - } - @include mixins.dark-theme() { - --Inbox__logo__bg: #{variables.$color-white}; - } - - .Inbox__logo__part { - width: 100%; - height: 100%; - position: absolute; - } - - .Inbox__logo__part--base { - @include mixins.color-svg( - '../images/logo-parts/base.svg', - var(--Inbox__logo__bg) - ); - & { - z-index: 1; - } - } - - .Inbox__logo__part--segment { - opacity: 0; - z-index: 2; - } - - .Inbox__logo__part--animated { - transition: - opacity 250ms, - transform 250ms; - } - - @for $i from 1 through 16 { - .Inbox__logo__part--segment:nth-child(#{$i + 1}) { - @include mixins.color-svg( - '../images/logo-parts/p#{$i}.svg', - var(--Inbox__logo__bg) - ); - & { - transform: rotate(#{(16 - $i) * 22.5}deg); - } - } - } - - .Inbox__logo__part--segment:nth-child(n).Inbox__logo__part--visible { - transform: rotate(0deg); - opacity: 1; - } -} - .Inbox__welcome { margin-block: 20px 6px; diff --git a/ts/components/Inbox.dom.stories.tsx b/ts/components/Inbox.dom.stories.tsx deleted file mode 100644 index 0818897995..0000000000 --- a/ts/components/Inbox.dom.stories.tsx +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2023 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import React, { useState, useEffect, useMemo } from 'react'; -import type { Meta, StoryFn } from '@storybook/react'; -import lodash from 'lodash'; - -import { Inbox } from './Inbox.dom.tsx'; -import type { PropsType } from './Inbox.dom.tsx'; -import { DAY, SECOND } from '../util/durations/index.std.ts'; - -const { noop } = lodash; - -const { i18n } = window.SignalContext; - -export default { - title: 'Components/Inbox', - args: { - i18n, - hasInitialLoadCompleted: false, - isNightly: false, - isCustomizingPreferredReactions: false, - }, - argTypes: { - daysAgo: { control: { type: 'number' } }, - isNightly: { control: { type: 'boolean' } }, - }, -} satisfies Meta; - -const Template: StoryFn = ({ - daysAgo, - ...args -}) => { - const now = useMemo(() => Date.now(), []); - const [dayOffset, setDayOffset] = useState(0); - - useEffect(() => { - if (!daysAgo) { - setDayOffset(0); - return noop; - } - - const interval = setInterval(() => { - // Increment day offset by 1 / 24 of a day (an hour), and wrap it when it - // reaches `daysAgo` value. - setDayOffset(prevValue => (prevValue + 1 / 24) % daysAgo); - }, SECOND / 10); - - return () => clearInterval(interval); - }, [now, daysAgo]); - - const firstEnvelopeTimestamp = - daysAgo === undefined ? undefined : now - daysAgo * DAY; - const envelopeTimestamp = - firstEnvelopeTimestamp === undefined - ? undefined - : firstEnvelopeTimestamp + dayOffset * DAY; - - return ( -
} - /> - ); -}; - -export const Default = Template.bind({}); - -export const FourDaysAgo = Template.bind({}); -FourDaysAgo.args = { - daysAgo: 4, -}; diff --git a/ts/components/Inbox.dom.tsx b/ts/components/Inbox.dom.tsx index 0bd8fe2c31..a6bdafb37c 100644 --- a/ts/components/Inbox.dom.tsx +++ b/ts/components/Inbox.dom.tsx @@ -2,22 +2,11 @@ // SPDX-License-Identifier: AGPL-3.0-only import type { ReactNode } from 'react'; -import React, { useEffect, useState, useMemo } from 'react'; -import classNames from 'classnames'; -import type { LocalizerType } from '../types/Util.std.ts'; -import { createLogger } from '../logging/log.std.ts'; -import { SECOND, DAY } from '../util/durations/index.std.ts'; +import React from 'react'; import type { SmartNavTabsProps } from '../state/smart/NavTabs.preload.tsx'; import { TitlebarDragArea } from './TitlebarDragArea.dom.tsx'; -const log = createLogger('Inbox'); - export type PropsType = { - firstEnvelopeTimestamp: number | undefined; - envelopeTimestamp: number | undefined; - hasInitialLoadCompleted: boolean; - i18n: LocalizerType; - isNightly: boolean; isCustomizingPreferredReactions: boolean; navTabsCollapsed: boolean; onToggleNavTabsCollapse: (navTabsCollapsed: boolean) => unknown; @@ -29,14 +18,7 @@ export type PropsType = { renderSettingsTab: () => React.JSX.Element; }; -const PART_COUNT = 16; - export function Inbox({ - firstEnvelopeTimestamp, - envelopeTimestamp, - hasInitialLoadCompleted, - i18n, - isNightly, isCustomizingPreferredReactions, navTabsCollapsed, onToggleNavTabsCollapse, @@ -47,149 +29,6 @@ export function Inbox({ renderStoriesTab, renderSettingsTab, }: PropsType): React.JSX.Element { - const [internalHasInitialLoadCompleted, setInternalHasInitialLoadCompleted] = - useState(hasInitialLoadCompleted); - - const now = useMemo(() => Date.now(), []); - const midnight = useMemo(() => { - const date = new Date(now); - date.setHours(0); - date.setMinutes(0); - date.setSeconds(0); - date.setMilliseconds(0); - return date.getTime(); - }, [now]); - - useEffect(() => { - if (internalHasInitialLoadCompleted) { - return; - } - - const interval = setInterval(() => { - const { status } = window.getSocketStatus().authenticated; - switch (status) { - case 'CONNECTING': - break; - case 'OPEN': - // if we've connected, we can wait for real empty event - clearInterval(interval); - break; - case 'CLOSING': - case 'CLOSED': - clearInterval(interval); - // if we failed to connect, we pretend we loaded - setInternalHasInitialLoadCompleted(true); - break; - default: - log.warn( - `startConnectionListener: Found unexpected socket status ${status}; setting load to done manually.` - ); - setInternalHasInitialLoadCompleted(true); - break; - } - }, SECOND); - - return () => { - clearInterval(interval); - }; - }, [internalHasInitialLoadCompleted]); - - useEffect(() => { - setInternalHasInitialLoadCompleted(hasInitialLoadCompleted); - }, [hasInitialLoadCompleted]); - - if (!internalHasInitialLoadCompleted) { - let loadingProgress = 100; - if ( - firstEnvelopeTimestamp !== undefined && - envelopeTimestamp !== undefined - ) { - loadingProgress = - Math.max( - 0, - Math.min( - 1, - Math.max(0, envelopeTimestamp - firstEnvelopeTimestamp) / - Math.max(1e-23, now - firstEnvelopeTimestamp) - ) - ) * 100; - } - - let message: string | undefined; - if (envelopeTimestamp !== undefined) { - const daysBeforeMidnight = Math.ceil( - (midnight - envelopeTimestamp) / DAY - ); - - if (daysBeforeMidnight <= 0) { - message = i18n('icu:loadingMessages--today'); - } else if (daysBeforeMidnight === 1) { - message = i18n('icu:loadingMessages--yesterday'); - } else { - message = i18n('icu:loadingMessages--other', { - daysAgo: daysBeforeMidnight, - }); - } - } - - let logo: React.JSX.Element; - if (isNightly) { - const parts = new Array(); - parts.push( - - ); - for (let i = 0; i < PART_COUNT; i += 1) { - const isVisible = i <= (loadingProgress * PART_COUNT) / 100; - parts.push( - - ); - } - logo =
{parts}
; - } else { - logo = ( -
- ); - } - - return ( -
- - - {logo} - - {envelopeTimestamp === undefined ? ( -
- - - -
- ) : ( -
-
-
- )} - {message === undefined ? ( -
- ) : ( -
{message}
- )} -
-
- ); - } - let activeModal: ReactNode; if (isCustomizingPreferredReactions) { activeModal = renderCustomizingPreferredReactionsModal(); diff --git a/ts/state/selectors/inbox.std.ts b/ts/state/selectors/inbox.std.ts deleted file mode 100644 index ca2cfcbb78..0000000000 --- a/ts/state/selectors/inbox.std.ts +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2024 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import { createSelector } from 'reselect'; -import type { StateType } from '../reducer.preload.ts'; - -const getInboxState = (state: StateType) => state.inbox; - -export const getInboxEnvelopeTimestamp = createSelector( - getInboxState, - ({ envelopeTimestamp }) => envelopeTimestamp -); - -export const getInboxFirstEnvelopeTimestamp = createSelector( - getInboxState, - ({ firstEnvelopeTimestamp }) => firstEnvelopeTimestamp -); diff --git a/ts/state/smart/Inbox.preload.tsx b/ts/state/smart/Inbox.preload.tsx index 64972b7f4d..7d45f70ebe 100644 --- a/ts/state/smart/Inbox.preload.tsx +++ b/ts/state/smart/Inbox.preload.tsx @@ -4,8 +4,6 @@ import React, { memo } from 'react'; import { useSelector } from 'react-redux'; import { Inbox } from '../../components/Inbox.dom.tsx'; -import { isNightly } from '../../util/version.std.ts'; -import { getIntl } from '../selectors/user.std.ts'; import { SmartCustomizingPreferredReactionsModal } from './CustomizingPreferredReactionsModal.preload.tsx'; import { getIsCustomizingPreferredReactions } from '../selectors/preferredReactions.std.ts'; import type { SmartNavTabsProps } from './NavTabs.preload.tsx'; @@ -15,11 +13,6 @@ import { SmartCallsTab } from './CallsTab.preload.tsx'; import { useItemsActions } from '../ducks/items.preload.ts'; import { getNavTabsCollapsed } from '../selectors/items.dom.ts'; import { SmartChatsTab } from './ChatsTab.preload.tsx'; -import { getHasInitialLoadCompleted } from '../selectors/app.std.ts'; -import { - getInboxEnvelopeTimestamp, - getInboxFirstEnvelopeTimestamp, -} from '../selectors/inbox.std.ts'; import { SmartPreferences } from './Preferences.preload.tsx'; function renderChatsTab() { @@ -47,24 +40,15 @@ function renderSettingsTab() { } export const SmartInbox = memo(function SmartInbox(): React.JSX.Element { - const i18n = useSelector(getIntl); const isCustomizingPreferredReactions = useSelector( getIsCustomizingPreferredReactions ); - const envelopeTimestamp = useSelector(getInboxEnvelopeTimestamp); - const firstEnvelopeTimestamp = useSelector(getInboxFirstEnvelopeTimestamp); - const hasInitialLoadCompleted = useSelector(getHasInitialLoadCompleted); const navTabsCollapsed = useSelector(getNavTabsCollapsed); const { toggleNavTabsCollapse } = useItemsActions(); return (