Fix font not resetting when logging out (#8670)

* Fix font not resetting when logging out

* Adopt on_logged_in and on_logged_out into DispatcherAction

* Add tests

* Add copyright
This commit is contained in:
Michael Telatynski 2022-05-26 09:56:53 +01:00 committed by GitHub
parent f3b762c1a8
commit d75e2f19c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 97 additions and 39 deletions

View file

@ -70,7 +70,7 @@ export default abstract class BasePlatform {
protected onAction = (payload: ActionPayload) => { protected onAction = (payload: ActionPayload) => {
switch (payload.action) { switch (payload.action) {
case 'on_client_not_viable': case 'on_client_not_viable':
case 'on_logged_out': case Action.OnLoggedOut:
this.setNotificationCount(0); this.setNotificationCount(0);
break; break;
} }

View file

@ -192,7 +192,7 @@ export default class DeviceListener {
}; };
private onAction = ({ action }: ActionPayload) => { private onAction = ({ action }: ActionPayload) => {
if (action !== "on_logged_in") return; if (action !== Action.OnLoggedIn) return;
this.recheck(); this.recheck();
}; };

View file

@ -632,7 +632,7 @@ async function doSetLoggedIn(
logger.warn("No local storage available: can't persist session!"); logger.warn("No local storage available: can't persist session!");
} }
dis.dispatch({ action: 'on_logged_in' }); dis.fire(Action.OnLoggedIn);
await startMatrixClient(/*startSyncing=*/!softLogout); await startMatrixClient(/*startSyncing=*/!softLogout);
return client; return client;
@ -857,15 +857,15 @@ async function startMatrixClient(startSyncing = true): Promise<void> {
*/ */
export async function onLoggedOut(): Promise<void> { export async function onLoggedOut(): Promise<void> {
_isLoggingOut = false; _isLoggingOut = false;
// Ensure that we dispatch a view change **before** stopping the client so // Ensure that we dispatch a view change **before** stopping the client,
// so that React components unmount first. This avoids React soft crashes // so that React components unmount first. This avoids React soft crashes
// that can occur when components try to use a null client. // that can occur when components try to use a null client.
dis.dispatch({ action: 'on_logged_out' }, true); dis.fire(Action.OnLoggedOut, true);
stopMatrixClient(); stopMatrixClient();
await clearStorage({ deleteEverything: true }); await clearStorage({ deleteEverything: true });
LifecycleCustomisations.onLoggedOutAndStorageCleared?.(); LifecycleCustomisations.onLoggedOutAndStorageCleared?.();
// Do this last so we can make sure all storage has been cleared and all // Do this last, so we can make sure all storage has been cleared and all
// customisations got the memo. // customisations got the memo.
if (SdkConfig.get().logout_redirect_url) { if (SdkConfig.get().logout_redirect_url) {
logger.log("Redirecting to external provider to finish logout"); logger.log("Redirecting to external provider to finish logout");

View file

@ -743,7 +743,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
case Action.OpenDialPad: case Action.OpenDialPad:
Modal.createTrackedDialog('Dial pad', '', DialPadModal, {}, "mx_Dialog_dialPadWrapper"); Modal.createTrackedDialog('Dial pad', '', DialPadModal, {}, "mx_Dialog_dialPadWrapper");
break; break;
case 'on_logged_in': case Action.OnLoggedIn:
if ( if (
// Skip this handling for token login as that always calls onLoggedIn itself // Skip this handling for token login as that always calls onLoggedIn itself
!this.tokenLogin && !this.tokenLogin &&
@ -759,7 +759,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
case 'on_client_not_viable': case 'on_client_not_viable':
this.onSoftLogout(); this.onSoftLogout();
break; break;
case 'on_logged_out': case Action.OnLoggedOut:
this.onLoggedOut(); this.onLoggedOut();
break; break;
case 'will_start_client': case 'will_start_client':

View file

@ -317,5 +317,15 @@ export enum Action {
/** /**
* Show current room topic * Show current room topic
*/ */
ShowRoomTopic = "show_room_topic" ShowRoomTopic = "show_room_topic",
/**
* Fired when the client was logged out. No additional payload information required.
*/
OnLoggedOut = "on_logged_out",
/**
* Fired when the client was logged in. No additional payload information required.
*/
OnLoggedIn = "on_logged_in",
} }

View file

@ -42,6 +42,7 @@ import { ImageSize } from "./enums/ImageSize";
import { MetaSpace } from "../stores/spaces"; import { MetaSpace } from "../stores/spaces";
import SdkConfig from "../SdkConfig"; import SdkConfig from "../SdkConfig";
import ThreadBetaController from './controllers/ThreadBetaController'; import ThreadBetaController from './controllers/ThreadBetaController';
import { FontWatcher } from "./watchers/FontWatcher";
// These are just a bunch of helper arrays to avoid copy/pasting a bunch of times // These are just a bunch of helper arrays to avoid copy/pasting a bunch of times
const LEVELS_ROOM_SETTINGS = [ const LEVELS_ROOM_SETTINGS = [
@ -420,7 +421,7 @@ export const SETTINGS: {[setting: string]: ISetting} = {
"baseFontSize": { "baseFontSize": {
displayName: _td("Font size"), displayName: _td("Font size"),
supportedLevels: LEVELS_ACCOUNT_SETTINGS, supportedLevels: LEVELS_ACCOUNT_SETTINGS,
default: 10, default: FontWatcher.DEFAULT_SIZE,
controller: new FontSizeController(), controller: new FontSizeController(),
}, },
"useCustomFontSize": { "useCustomFontSize": {

View file

@ -20,9 +20,12 @@ import IWatcher from "./Watcher";
import { toPx } from '../../utils/units'; import { toPx } from '../../utils/units';
import { Action } from '../../dispatcher/actions'; import { Action } from '../../dispatcher/actions';
import { SettingLevel } from "../SettingLevel"; import { SettingLevel } from "../SettingLevel";
import { UpdateSystemFontPayload } from "../../dispatcher/payloads/UpdateSystemFontPayload";
import { ActionPayload } from "../../dispatcher/payloads";
export class FontWatcher implements IWatcher { export class FontWatcher implements IWatcher {
public static readonly MIN_SIZE = 8; public static readonly MIN_SIZE = 8;
public static readonly DEFAULT_SIZE = 10;
public static readonly MAX_SIZE = 15; public static readonly MAX_SIZE = 15;
// Externally we tell the user the font is size 15. Internally we use 10. // Externally we tell the user the font is size 15. Internally we use 10.
public static readonly SIZE_DIFF = 5; public static readonly SIZE_DIFF = 5;
@ -34,11 +37,7 @@ export class FontWatcher implements IWatcher {
} }
public start() { public start() {
this.setRootFontSize(SettingsStore.getValue("baseFontSize")); this.updateFont();
this.setSystemFont({
useSystemFont: SettingsStore.getValue("useSystemFont"),
font: SettingsStore.getValue("systemFont"),
});
this.dispatcherRef = dis.register(this.onAction); this.dispatcherRef = dis.register(this.onAction);
} }
@ -46,15 +45,33 @@ export class FontWatcher implements IWatcher {
dis.unregister(this.dispatcherRef); dis.unregister(this.dispatcherRef);
} }
private onAction = (payload) => { private updateFont() {
this.setRootFontSize(SettingsStore.getValue("baseFontSize"));
this.setSystemFont({
useSystemFont: SettingsStore.getValue("useSystemFont"),
font: SettingsStore.getValue("systemFont"),
});
}
private onAction = (payload: ActionPayload) => {
if (payload.action === Action.UpdateFontSize) { if (payload.action === Action.UpdateFontSize) {
this.setRootFontSize(payload.size); this.setRootFontSize(payload.size);
} else if (payload.action === Action.UpdateSystemFont) { } else if (payload.action === Action.UpdateSystemFont) {
this.setSystemFont(payload); this.setSystemFont(payload as UpdateSystemFontPayload);
} else if (payload.action === Action.OnLoggedOut) {
// Clear font overrides when logging out
this.setRootFontSize(FontWatcher.DEFAULT_SIZE);
this.setSystemFont({
useSystemFont: false,
font: "",
});
} else if (payload.action === Action.OnLoggedIn) {
// Font size can be saved on the account, so grab value when logging in
this.updateFont();
} }
}; };
private setRootFontSize = (size) => { private setRootFontSize = (size: number) => {
const fontSize = Math.max(Math.min(FontWatcher.MAX_SIZE, size), FontWatcher.MIN_SIZE); const fontSize = Math.max(Math.min(FontWatcher.MAX_SIZE, size), FontWatcher.MIN_SIZE);
if (fontSize !== size) { if (fontSize !== size) {
@ -63,7 +80,7 @@ export class FontWatcher implements IWatcher {
document.querySelector<HTMLElement>(":root").style.fontSize = toPx(fontSize); document.querySelector<HTMLElement>(":root").style.fontSize = toPx(fontSize);
}; };
private setSystemFont = ({ useSystemFont, font }) => { private setSystemFont = ({ useSystemFont, font }: Pick<UpdateSystemFontPayload, "useSystemFont" | "font">) => {
if (useSystemFont) { if (useSystemFont) {
// Make sure that fonts with spaces in their names get interpreted properly // Make sure that fonts with spaces in their names get interpreted properly
document.body.style.fontFamily = font document.body.style.fontFamily = font

View file

@ -71,7 +71,7 @@ class LifecycleStore extends Store<ActionPayload> {
break; break;
} }
case 'on_client_not_viable': case 'on_client_not_viable':
case 'on_logged_out': case Action.OnLoggedOut:
this.reset(); this.reset();
break; break;
} }

View file

@ -22,6 +22,7 @@ import { EventEmitter } from "events";
import { MatrixClientPeg } from "../MatrixClientPeg"; import { MatrixClientPeg } from "../MatrixClientPeg";
import { ActionPayload } from "../dispatcher/payloads"; import { ActionPayload } from "../dispatcher/payloads";
import { IDestroyable } from "../utils/IDestroyable"; import { IDestroyable } from "../utils/IDestroyable";
import { Action } from "../dispatcher/actions";
export abstract class ReadyWatchingStore extends EventEmitter implements IDestroyable { export abstract class ReadyWatchingStore extends EventEmitter implements IDestroyable {
protected matrixClient: MatrixClient; protected matrixClient: MatrixClient;
@ -83,7 +84,7 @@ export abstract class ReadyWatchingStore extends EventEmitter implements IDestro
this.matrixClient = payload.matrixClient; this.matrixClient = payload.matrixClient;
await this.onReady(); await this.onReady();
} }
} else if (payload.action === 'on_client_not_viable' || payload.action === 'on_logged_out') { } else if (payload.action === 'on_client_not_viable' || payload.action === Action.OnLoggedOut) {
if (this.matrixClient) { if (this.matrixClient) {
await this.onNotReady(); await this.onNotReady();
this.matrixClient = null; this.matrixClient = null;

View file

@ -241,7 +241,7 @@ export class RoomViewStore extends Store<ActionPayload> {
break; break;
} }
case 'on_client_not_viable': case 'on_client_not_viable':
case 'on_logged_out': case Action.OnLoggedOut:
this.reset(); this.reset();
break; break;
case 'reply_to_event': case 'reply_to_event':

View file

@ -1,5 +1,6 @@
/* /*
Copyright 2022 r00ster91 <r00ster91@proton.me> Copyright 2022 r00ster91 <r00ster91@proton.me>
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -21,34 +22,62 @@ import { SettingLevel } from '../../../src/settings/SettingLevel';
import { FontWatcher } from "../../../src/settings/watchers/FontWatcher"; import { FontWatcher } from "../../../src/settings/watchers/FontWatcher";
import { Action } from "../../../src/dispatcher/actions"; import { Action } from "../../../src/dispatcher/actions";
import { untilDispatch } from "../../test-utils"; import { untilDispatch } from "../../test-utils";
import defaultDispatcher from "../../../src/dispatcher/dispatcher";
async function setSystemFont(font: string): Promise<void> { async function setSystemFont(font: string): Promise<void> {
await SettingsStore.setValue("useSystemFont", null, SettingLevel.DEVICE, !!font);
await SettingsStore.setValue("systemFont", null, SettingLevel.DEVICE, font); await SettingsStore.setValue("systemFont", null, SettingLevel.DEVICE, font);
await untilDispatch(Action.UpdateSystemFont); await untilDispatch(Action.UpdateSystemFont);
await sleep(1); // await the FontWatcher doing its action await sleep(1); // await the FontWatcher doing its action
} }
describe('FontWatcher', function() { describe('FontWatcher', function() {
let fontWatcher: FontWatcher; it("should load font on start()", async () => {
beforeEach(() => { const watcher = new FontWatcher();
fontWatcher = new FontWatcher(); await setSystemFont("Font Name");
fontWatcher.start(); expect(document.body.style.fontFamily).toBe("");
return SettingsStore.setValue("useSystemFont", null, SettingLevel.DEVICE, true); watcher.start();
}); expect(document.body.style.fontFamily).toBe('"Font Name"');
afterEach(() => {
fontWatcher.stop();
}); });
it('encloses the fonts by double quotes and sets them as the system font', async () => { it("should load font on Action.OnLoggedIn", async () => {
await setSystemFont("Fira Sans Thin, Commodore 64"); await setSystemFont("Font Name");
expect(document.body.style.fontFamily).toBe(`"Fira Sans Thin","Commodore 64"`); new FontWatcher().start();
document.body.style.fontFamily = ""; // clear the fontFamily which was set by start which we tested already
defaultDispatcher.fire(Action.OnLoggedIn, true);
expect(document.body.style.fontFamily).toBe('"Font Name"');
}); });
it('does not add double quotes if already present and sets the font as the system font', async () => {
await setSystemFont(`"Commodore 64"`); it("should reset font on Action.OnLoggedOut", async () => {
expect(document.body.style.fontFamily).toBe(`"Commodore 64"`); await setSystemFont("Font Name");
const watcher = new FontWatcher();
watcher.start();
expect(document.body.style.fontFamily).toBe('"Font Name"');
defaultDispatcher.fire(Action.OnLoggedOut, true);
expect(document.body.style.fontFamily).toBe("");
}); });
it('trims whitespace, encloses the fonts by double quotes, and sets them as the system font', async () => {
await setSystemFont(` Fira Code , "Commodore 64" `); describe("Sets font as expected", () => {
expect(document.body.style.fontFamily).toBe(`"Fira Code","Commodore 64"`); let fontWatcher: FontWatcher;
beforeEach(() => {
fontWatcher = new FontWatcher();
fontWatcher.start();
});
afterEach(() => {
fontWatcher.stop();
});
it('encloses the fonts by double quotes and sets them as the system font', async () => {
await setSystemFont("Fira Sans Thin, Commodore 64");
expect(document.body.style.fontFamily).toBe(`"Fira Sans Thin","Commodore 64"`);
});
it('does not add double quotes if already present and sets the font as the system font', async () => {
await setSystemFont(`"Commodore 64"`);
expect(document.body.style.fontFamily).toBe(`"Commodore 64"`);
});
it('trims whitespace, encloses the fonts by double quotes, and sets them as the system font', async () => {
await setSystemFont(` Fira Code , "Commodore 64" `);
expect(document.body.style.fontFamily).toBe(`"Fira Code","Commodore 64"`);
});
}); });
}); });