Multi-Account: Fix cache load (#5854)

This commit is contained in:
zubiden 2025-04-23 18:59:31 +02:00 committed by Alexander Zinchuk
parent f1297f877b
commit 76ee31229e
15 changed files with 83 additions and 45 deletions

View File

@ -14,8 +14,9 @@ import { IS_INSTALL_PROMPT_SUPPORTED, PLATFORM_ENV } from '../util/browser/windo
import buildClassName from '../util/buildClassName';
import { setupBeforeInstallPrompt } from '../util/installPrompt';
import { ACCOUNT_SLOT, getAccountsInfo, getAccountSlotUrl } from '../util/multiaccount';
import { hasEncryptedSession } from '../util/passcode';
import { getInitialLocationHash, parseInitialLocationHash } from '../util/routing';
import { hasStoredSession } from '../util/sessions';
import { checkSessionLocked, hasStoredSession } from '../util/sessions';
import { updateSizes } from '../util/windowSize';
import useAppLayout from '../hooks/useAppLayout';
@ -76,15 +77,27 @@ const App: FC<StateProps> = ({
// If there is no stored session on first slot, navigate to any other slot with stored session
if (!hasStoredSession() && !ACCOUNT_SLOT && !hash) {
const accounts = getAccountsInfo();
Object.keys(accounts).forEach((key) => {
const slot = Number(key);
const account = accounts[slot];
if (account) {
const url = getAccountSlotUrl(slot);
window.location.href = `${url}#${hash || 'login'}`;
}
});
Object.keys(accounts)
.map(Number)
.sort((a, b) => b - a)
.forEach((key) => {
const slot = Number(key);
const account = accounts[slot];
if (account) {
const url = getAccountSlotUrl(slot);
window.location.href = `${url}#${hash || 'login'}`;
}
});
}
// TODO[Passcode]: Remove when multiacc passcode is implemented
const checkMultiaccPasscode = async () => {
if (checkSessionLocked() && ACCOUNT_SLOT && await hasEncryptedSession()) {
const url = getAccountSlotUrl(1);
window.location.href = url;
}
};
checkMultiaccPasscode();
}, []);
// Prevent drop on elements that do not accept it

View File

@ -27,7 +27,6 @@ import {
selectTabState,
selectTheme,
} from '../../../global/selectors';
import { selectSharedSettings } from '../../../global/selectors/sharedState';
import { IS_ANDROID, IS_ELECTRON, IS_FLUID_BACKGROUND_SUPPORTED } from '../../../util/browser/windowEnvironment';
import buildClassName from '../../../util/buildClassName';
import { isLocalMessageId } from '../../../util/keys/messageKey';
@ -461,7 +460,7 @@ const ActionMessage = ({
export default memo(withGlobal<OwnProps>(
(global, { message, threadId }): StateProps => {
const tabState = selectTabState(global);
const { themes } = selectSharedSettings(global);
const { themes } = global.settings;
const chat = selectChat(global, message.chatId);

View File

@ -1,6 +1,7 @@
import type { ActionReturnType } from '../../types';
import { SettingsScreens } from '../../../types';
import { IS_SCREEN_LOCKED_CACHE_KEY } from '../../../config';
import { getCurrentTabId, signalPasscodeHash } from '../../../util/establishMultitabRole';
import { cloneDeep } from '../../../util/iteratees';
import {
@ -72,6 +73,7 @@ addActionHandler('setPasscode', async (global, actions, payload): Promise<void>
addActionHandler('clearPasscode', (global): ActionReturnType => {
void clearEncryptedSession();
localStorage.removeItem(IS_SCREEN_LOCKED_CACHE_KEY);
return clearPasscodeSettings(global);
});

View File

@ -321,7 +321,6 @@ function unsafeMigrateCache(cached: GlobalState, initialState: GlobalState) {
messageTextSize: untypedCached.settings.byKey.messageTextSize,
performance: untypedCached.settings.performance,
theme: untypedCached.settings.byKey.theme,
themes: untypedCached.settings.themes,
timeFormat: untypedCached.settings.byKey.timeFormat,
wasTimeFormatSetManually: untypedCached.settings.byKey.wasTimeFormatSetManually,
shouldUseSystemTheme: untypedCached.settings.byKey.shouldUseSystemTheme,
@ -338,6 +337,10 @@ function unsafeMigrateCache(cached: GlobalState, initialState: GlobalState) {
shouldWarnAboutSvg: untypedCached.settings.byKey.shouldWarnAboutSvg,
};
}
if (!cached.settings.themes) {
cached.settings.themes = initialState.settings.themes;
}
}
function updateCache(force?: boolean) {
@ -706,7 +709,7 @@ function omitLocalMedia(message: ApiMessage): ApiMessage {
function reduceSettings<T extends GlobalState>(global: T): GlobalState['settings'] {
const {
byKey, botVerificationShownPeerIds, notifyDefaults, lastPremiumBandwithNotificationDate,
byKey, botVerificationShownPeerIds, notifyDefaults, lastPremiumBandwithNotificationDate, themes,
} = global.settings;
return {
@ -715,6 +718,7 @@ function reduceSettings<T extends GlobalState>(global: T): GlobalState['settings
botVerificationShownPeerIds,
lastPremiumBandwithNotificationDate,
notifyDefaults,
themes,
};
}

View File

@ -78,16 +78,6 @@ export const INITIAL_SHARED_STATE: SharedState = {
: (IS_MAC_OS ? MACOS_DEFAULT_MESSAGE_TEXT_SIZE_PX : DEFAULT_MESSAGE_TEXT_SIZE_PX),
animationLevel: ANIMATION_LEVEL_DEFAULT,
messageSendKeyCombo: 'enter',
themes: {
light: {
isBlurred: true,
patternColor: DEFAULT_PATTERN_COLOR,
},
dark: {
isBlurred: true,
patternColor: DARK_THEME_PATTERN_COLOR,
},
},
performance: INITIAL_PERFORMANCE_STATE_MAX,
shouldSkipWebAppCloseConfirmation: false,
language: 'en',
@ -308,6 +298,16 @@ export const INITIAL_GLOBAL_STATE: GlobalState = {
},
privacy: {},
botVerificationShownPeerIds: [],
themes: {
light: {
isBlurred: true,
patternColor: DEFAULT_PATTERN_COLOR,
},
dark: {
isBlurred: true,
patternColor: DARK_THEME_PATTERN_COLOR,
},
},
},
serviceNotifications: [],

View File

@ -5,7 +5,7 @@ import type {
} from '../../types';
import type { GlobalState, SharedState } from '../types';
import { selectSharedSettings, selectSharedState } from '../selectors/sharedState';
import { selectSharedSettings } from '../selectors/sharedState';
import { updateSharedState } from './sharedState';
import { updateUserBlockedState } from './users';
@ -37,18 +37,22 @@ export function updateSharedSettings<T extends GlobalState>(
export function updateThemeSettings<T extends GlobalState>(
global: T, theme: ThemeKey, newSettings?: Partial<IThemeSettings>,
): T {
const settings = selectSharedState(global).settings;
const settings = global.settings;
const current = settings.themes[theme];
return updateSharedSettings(global, {
themes: {
...settings.themes,
[theme]: {
...current,
...newSettings,
return {
...global,
settings: {
...global.settings,
themes: {
...settings.themes,
[theme]: {
...current,
...newSettings,
},
},
},
});
};
}
export function addNotifyExceptions<T extends GlobalState>(

View File

@ -1,5 +1,6 @@
import type { GlobalState } from '../types';
import { ACCOUNT_SLOT, getAccountsInfo } from '../../util/multiaccount';
import { selectSharedSettings } from './sharedState';
export function selectNotifySettings<T extends GlobalState>(global: T) {
@ -19,7 +20,9 @@ export function selectLanguageCode<T extends GlobalState>(global: T) {
}
export function selectCanSetPasscode<T extends GlobalState>(global: T) {
return global.authRememberMe;
// TODO[passcode]: remove this when multiacc passcode is implemented
const accounts = getAccountsInfo();
return global.authRememberMe && !ACCOUNT_SLOT && Object.keys(accounts).length === 1;
}
export function selectTranslationLanguage<T extends GlobalState>(global: T) {

View File

@ -76,7 +76,7 @@ export function selectTheme<T extends GlobalState>(global: T) {
}
export function selectThemeValues<T extends GlobalState>(global: T, themeKey: ThemeKey) {
return selectSharedSettings(global).themes[themeKey];
return global.settings.themes[themeKey];
}
export function selectIsForumPanelOpen<T extends GlobalState>(

View File

@ -54,11 +54,13 @@ import type {
ChatListType,
ChatTranslatedMessages,
EmojiKeywords,
IThemeSettings,
ServiceNotification,
SimilarBotsInfo,
StarGiftCategory,
StarsSubscriptions,
StarsTransactionHistory,
ThemeKey,
Thread,
ThreadId,
TopicsInfo,
@ -412,6 +414,7 @@ export type GlobalState = {
lastPremiumBandwithNotificationDate?: number;
paidReactionPrivacy?: ApiPaidReactionPrivacyType;
botVerificationShownPeerIds: string[];
themes: Partial<Record<ThemeKey, IThemeSettings>>;
};
push?: {

View File

@ -1,7 +1,6 @@
import type { ApiLanguage } from '../../api/types';
import type {
AnimationLevel,
IThemeSettings,
PerformanceType,
Point,
Size,
@ -13,7 +12,6 @@ export type SharedState = {
settings: {
shouldUseSystemTheme: boolean;
theme: ThemeKey;
themes: Partial<Record<ThemeKey, IThemeSettings>>;
language: string;
languages?: ApiLanguage[];
performance: PerformanceType;

View File

@ -31,6 +31,7 @@ const requestStates = new Map<string, RequestStates>();
export async function respondForProgressive(e: FetchEvent) {
const { url } = e.request;
const accountSlot = getAccountSlot(url);
const range = e.request.headers.get('range');
const bytes = /^bytes=(\d+)-(\d+)?$/g.exec(range || '')!;
const start = Number(bytes[1]);
@ -66,7 +67,8 @@ export async function respondForProgressive(e: FetchEvent) {
parsedUrl.searchParams.set('start', String(start));
parsedUrl.searchParams.set('end', String(end));
const cacheKey = parsedUrl.href;
const [cachedArrayBuffer, cachedHeaders] = !MEDIA_PROGRESSIVE_CACHE_DISABLED ? await fetchFromCache(cacheKey) : [];
const [cachedArrayBuffer, cachedHeaders] = !MEDIA_PROGRESSIVE_CACHE_DISABLED
? await fetchFromCache(accountSlot, cacheKey) : [];
if (DEBUG) {
// eslint-disable-next-line no-console
@ -113,7 +115,7 @@ export async function respondForProgressive(e: FetchEvent) {
];
if (!MEDIA_PROGRESSIVE_CACHE_DISABLED && partSize <= MEDIA_CACHE_MAX_BYTES && end < MAX_END_TO_CACHE) {
saveToCache(cacheKey, arrayBufferPart, headers);
saveToCache(accountSlot, cacheKey, arrayBufferPart, headers);
}
return new Response(arrayBufferPart, {
@ -124,8 +126,9 @@ export async function respondForProgressive(e: FetchEvent) {
}
// We can not cache 206 responses: https://github.com/GoogleChrome/workbox/issues/1644#issuecomment-638741359
async function fetchFromCache(cacheKey: string) {
const cache = await self.caches.open(MEDIA_PROGRESSIVE_CACHE_NAME);
async function fetchFromCache(accountSlot: number | undefined, cacheKey: string) {
const cacheName = !accountSlot ? MEDIA_PROGRESSIVE_CACHE_NAME : `${MEDIA_PROGRESSIVE_CACHE_NAME}_${accountSlot}`;
const cache = await self.caches.open(cacheName);
return Promise.all([
cache.match(`${cacheKey}&type=arrayBuffer`).then((r) => (r ? r.arrayBuffer() : undefined)),
@ -133,8 +136,11 @@ async function fetchFromCache(cacheKey: string) {
]);
}
async function saveToCache(cacheKey: string, arrayBuffer: ArrayBuffer, headers: HeadersInit) {
const cache = await self.caches.open(MEDIA_PROGRESSIVE_CACHE_NAME);
async function saveToCache(
accountSlot: number | undefined, cacheKey: string, arrayBuffer: ArrayBuffer, headers: HeadersInit,
) {
const cacheName = !accountSlot ? MEDIA_PROGRESSIVE_CACHE_NAME : `${MEDIA_PROGRESSIVE_CACHE_NAME}_${accountSlot}`;
const cache = await self.caches.open(cacheName);
return Promise.all([
cache.put(new Request(`${cacheKey}&type=arrayBuffer`), new Response(arrayBuffer)),

View File

@ -97,6 +97,7 @@ export async function save(cacheName: string, key: string, data: AnyLiteral | Bl
const response = new Response(cacheData);
const cache = await cacheApi.open(`${cacheName}${SUFFIX}`);
await cache.put(request, response);
return true;
} catch (err) {
// eslint-disable-next-line no-console

View File

@ -15,8 +15,9 @@ const WORKER_NAME = typeof WorkerGlobalScope !== 'undefined' && globalThis.self
? globalThis.self.name : undefined;
const WORKER_ACCOUNT_SLOT = WORKER_NAME ? Number(new URLSearchParams(WORKER_NAME).get(ACCOUNT_QUERY)) : undefined;
export const ACCOUNT_SLOT = IS_MULTIACCOUNT_SUPPORTED
? (WORKER_ACCOUNT_SLOT || getAccountSlot(globalThis.location.href)) : undefined;
export const ACCOUNT_SLOT = WORKER_ACCOUNT_SLOT || (
IS_MULTIACCOUNT_SUPPORTED ? getAccountSlot(globalThis.location.href) : undefined
);
export const DATA_BROADCAST_CHANNEL_NAME = `${DATA_BROADCAST_CHANNEL_PREFIX}_${ACCOUNT_SLOT || 1}`;
export const ESTABLISH_BROADCAST_CHANNEL_NAME = `${ESTABLISH_BROADCAST_CHANNEL_PREFIX}_${ACCOUNT_SLOT || 1}`;

View File

@ -125,6 +125,10 @@ function store(key: string, value: ArrayBuffer) {
PASSCODE_IDB_STORE.set(key, asArray);
}
export function hasEncryptedSession() {
return PASSCODE_IDB_STORE.get('sessionEncrypted');
}
async function load(key: string) {
const cached = await PASSCODE_IDB_STORE.get<number[]>(key);
if (cached) {

View File

@ -183,6 +183,6 @@ export function importTestSession() {
}
}
function checkSessionLocked() {
export function checkSessionLocked() {
return localStorage.getItem(IS_SCREEN_LOCKED_CACHE_KEY) === 'true';
}