Make BrowserService and model no longer a singleton.
- Merge browser-service and browser-model.
- Rename BrowserService to BrowserModel
- Move all observables onto BrowserModel.
Google-Bug-Id: b/206459178
Change-Id: I8e3bd48bd169672a4e2bf983501baf3899c0fb28
diff --git a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
index c2c3131..f400814 100644
--- a/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
+++ b/polygerrit-ui/app/elements/change/gr-file-list/gr-file-list.ts
@@ -89,7 +89,6 @@
} from '../../../services/user/user-model';
import {changeComments$} from '../../../services/comments/comments-model';
import {listen} from '../../../services/shortcuts/shortcuts-service';
-import {diffViewMode$} from '../../../services/browser/browser-model';
export const DEFAULT_NUM_FILES_SHOWN = 200;
@@ -320,6 +319,8 @@
private readonly userService = getAppContext().userService;
+ private readonly browserModel = getAppContext().browserModel;
+
private subscriptions: Subscription[] = [];
/** Called in disconnectedCallback. */
@@ -382,7 +383,9 @@
})
);
this.subscriptions.push(
- diffViewMode$.subscribe(diffView => (this.diffViewMode = diffView))
+ this.browserModel.diffViewMode$.subscribe(
+ diffView => (this.diffViewMode = diffView)
+ )
);
this.subscriptions.push(
diffPreferences$.subscribe(diffPreferences => {
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts
index 8c05640..f8fb40c 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host.ts
@@ -87,7 +87,6 @@
import {ChangeComments} from '../gr-comment-api/gr-comment-api';
import {Subscription} from 'rxjs';
import {DisplayLine, RenderPreferences} from '../../../api/diff';
-import {diffViewMode$} from '../../../services/browser/browser-model';
const EMPTY_BLAME = 'No blame information for this diff.';
@@ -265,6 +264,8 @@
num_lines_rendered_at_once: 128,
};
+ private readonly browserModel = getAppContext().browserModel;
+
private readonly reporting = getAppContext().reportingService;
private readonly flags = getAppContext().flagsService;
@@ -309,7 +310,9 @@
override connectedCallback() {
super.connectedCallback();
this.subscriptions.push(
- diffViewMode$.subscribe(diffView => (this.viewMode = diffView))
+ this.browserModel.diffViewMode$.subscribe(
+ diffView => (this.viewMode = diffView)
+ )
);
this._getLoggedIn().then(loggedIn => {
this._loggedIn = loggedIn;
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.ts b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.ts
index 4f6ae14..0d63360 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector.ts
@@ -27,7 +27,6 @@
import {FixIronA11yAnnouncer} from '../../../types/types';
import {getAppContext} from '../../../services/app-context';
import {fireIronAnnounce} from '../../../utils/event-util';
-import {diffViewMode$} from '../../../services/browser/browser-model';
@customElement('gr-diff-mode-selector')
export class GrDiffModeSelector extends PolymerElement {
@@ -48,6 +47,9 @@
@property({type: Boolean})
showTooltipBelow = false;
+ // Private but accessed by tests.
+ readonly browserModel = getAppContext().browserModel;
+
private readonly userService = getAppContext().userService;
private subscriptions: Subscription[] = [];
@@ -62,7 +64,9 @@
IronA11yAnnouncer as unknown as FixIronA11yAnnouncer
).requestAvailability();
this.subscriptions.push(
- diffViewMode$.subscribe(diffView => (this.mode = diffView))
+ this.browserModel.diffViewMode$.subscribe(
+ diffView => (this.mode = diffView)
+ )
);
}
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_test.ts b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_test.ts
index fe5f389..3fafb0c 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_test.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-mode-selector/gr-diff-mode-selector_test.ts
@@ -20,7 +20,6 @@
import {GrDiffModeSelector} from './gr-diff-mode-selector';
import {DiffViewMode} from '../../../constants/constants';
import {stubUsers} from '../../../test/test-utils';
-import {_testOnly_setState} from '../../../services/browser/browser-model';
const basicFixture = fixtureFromElement('gr-diff-mode-selector');
@@ -48,7 +47,7 @@
});
test('setMode', () => {
- _testOnly_setState({screenWidth: 0});
+ element.browserModel.setScreenWidth(0);
const saveStub = stubUsers('updatePreferences');
flush();
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
index 8a681d1..c4e2488 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view.ts
@@ -363,6 +363,9 @@
private readonly changeService = getAppContext().changeService;
+ // Private but used in tests
+ readonly browserModel = getAppContext().browserModel;
+
// We just want to make sure that CommentsService is instantiated.
// Otherwise subscribing to the model won't emit any data.
private readonly _commentsService = getAppContext().commentsService;
diff --git a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js
index 7c4ff12..2367342 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js
+++ b/polygerrit-ui/app/elements/diff/gr-diff-view/gr-diff-view_test.js
@@ -31,7 +31,6 @@
import {EditPatchSetNum} from '../../../types/common.js';
import {CursorMoveResult} from '../../../api/core.js';
import {Side} from '../../../api/diff.js';
-import {_testOnly_setState as browserModelSetState} from '../../../services/browser/browser-model.js';
import {_testOnly_setState as setUserModelState, _testOnly_getState as getUserModelState} from '../../../services/user/user-model.js';
import {_testOnly_setState as setChangeModelState} from '../../../services/change/change-model.js';
import {_testOnly_setState as setCommentState} from '../../../services/comments/comments-model.js';
@@ -415,7 +414,7 @@
test('keyboard shortcuts', () => {
clock = sinon.useFakeTimers();
element._changeNum = '42';
- browserModelSetState({screenWidth: 0});
+ element.browserModel.setScreenWidth(0);
element._patchRange = {
basePatchNum: PARENT,
patchNum: 10,
@@ -1335,7 +1334,7 @@
const select = element.$.modeSelect;
const diffDisplay = element.$.diffHost;
element._userPrefs = {diff_view: DiffViewMode.SIDE_BY_SIDE};
- browserModelSetState({screenWidth: 0});
+ element.browserModel.setScreenWidth(0);
const userStub = stubUsers('updatePreferences');
diff --git a/polygerrit-ui/app/elements/gr-app-element.ts b/polygerrit-ui/app/elements/gr-app-element.ts
index 8c11245..c89fe20 100644
--- a/polygerrit-ui/app/elements/gr-app-element.ts
+++ b/polygerrit-ui/app/elements/gr-app-element.ts
@@ -216,7 +216,7 @@
private readonly restApiService = getAppContext().restApiService;
- private readonly browserService = getAppContext().browserService;
+ private readonly browserModel = getAppContext().browserModel;
override keyboardShortcuts(): ShortcutListener[] {
return [
@@ -258,7 +258,7 @@
this.handleRecreateView(GerritView.DIFF)
);
document.addEventListener(EventType.GR_RPC_LOG, e => this._handleRpcLog(e));
- const resizeObserver = this.browserService.observeWidth();
+ const resizeObserver = this.browserModel.observeWidth();
resizeObserver.observe(this);
}
diff --git a/polygerrit-ui/app/services/app-context-init.ts b/polygerrit-ui/app/services/app-context-init.ts
index 32a4560..47d5f03 100644
--- a/polygerrit-ui/app/services/app-context-init.ts
+++ b/polygerrit-ui/app/services/app-context-init.ts
@@ -29,7 +29,7 @@
import {UserService} from './user/user-service';
import {CommentsService} from './comments/comments-service';
import {ShortcutsService} from './shortcuts/shortcuts-service';
-import {BrowserService} from './browser/browser-service';
+import {BrowserModel} from './browser/browser-model';
import {assertIsDefined} from '../utils/common-util';
/**
@@ -82,7 +82,7 @@
assertIsDefined(ctx.reportingService, 'reportingService');
return new ShortcutsService(ctx.reportingService!);
},
- browserService: (_ctx: Partial<AppContext>) => new BrowserService(),
+ browserModel: (_ctx: Partial<AppContext>) => new BrowserModel(),
};
return create<AppContext>(appRegistry);
}
diff --git a/polygerrit-ui/app/services/app-context.ts b/polygerrit-ui/app/services/app-context.ts
index 49d5bcc..87a18ef 100644
--- a/polygerrit-ui/app/services/app-context.ts
+++ b/polygerrit-ui/app/services/app-context.ts
@@ -28,7 +28,7 @@
import {UserService} from './user/user-service';
import {CommentsService} from './comments/comments-service';
import {ShortcutsService} from './shortcuts/shortcuts-service';
-import {BrowserService} from './browser/browser-service';
+import {BrowserModel} from './browser/browser-model';
export interface AppContext {
flagsService: FlagsService;
@@ -43,7 +43,7 @@
storageService: StorageService;
configService: ConfigService;
userService: UserService;
- browserService: BrowserService;
+ browserModel: BrowserModel;
shortcutsService: ShortcutsService;
}
diff --git a/polygerrit-ui/app/services/browser/browser-model.ts b/polygerrit-ui/app/services/browser/browser-model.ts
index 8cb6575..b15091a 100644
--- a/polygerrit-ui/app/services/browser/browser-model.ts
+++ b/polygerrit-ui/app/services/browser/browser-model.ts
@@ -14,16 +14,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
import {BehaviorSubject, Observable, combineLatest} from 'rxjs';
import {distinctUntilChanged, map} from 'rxjs/operators';
+import {Finalizable} from '../registry';
import {preferenceDiffViewMode$} from '../user/user-model';
import {DiffViewMode} from '../../api/diff';
// This value is somewhat arbitrary and not based on research or calculations.
const MAX_UNIFIED_DEFAULT_WINDOW_WIDTH_PX = 850;
-interface BrowserState {
+export interface BrowserState {
/**
* We maintain the screen width in the state so that the app can react to
* changes in the width such as automatically changing to unified diff view
@@ -33,44 +33,51 @@
const initialState: BrowserState = {};
-const privateState$ = new BehaviorSubject(initialState);
+export class BrowserModel implements Finalizable {
+ private readonly privateState$ = new BehaviorSubject(initialState);
-export function _testOnly_resetState() {
- // We cannot assign a new subject to privateState$, because all the selectors
- // have already subscribed to the original subject. So we have to emit the
- // initial state on the existing subject.
- privateState$.next({...initialState});
+ readonly diffViewMode$: Observable<DiffViewMode>;
+
+ get viewState$(): Observable<BrowserState> {
+ return this.privateState$;
+ }
+
+ constructor() {
+ const screenWidth$ = this.privateState$.pipe(
+ map(
+ state =>
+ !!state.screenWidth &&
+ state.screenWidth < MAX_UNIFIED_DEFAULT_WINDOW_WIDTH_PX
+ ),
+ distinctUntilChanged()
+ );
+ // TODO; Inject the UserModel once preferenceDiffViewMode$ has moved to
+ // the user model.
+ this.diffViewMode$ = combineLatest([
+ screenWidth$,
+ preferenceDiffViewMode$,
+ ]).pipe(
+ map(([isScreenTooSmall, preferenceDiffViewMode]) => {
+ if (isScreenTooSmall) return DiffViewMode.UNIFIED;
+ else return preferenceDiffViewMode;
+ }),
+ distinctUntilChanged()
+ );
+ }
+
+ /* Observe the screen width so that the app can react to changes to it */
+ observeWidth() {
+ return new ResizeObserver(entries => {
+ entries.forEach(entry => {
+ this.setScreenWidth(entry.contentRect.width);
+ });
+ });
+ }
+
+ // Private but used in tests.
+ setScreenWidth(screenWidth: number) {
+ this.privateState$.next({...this.privateState$.getValue(), screenWidth});
+ }
+
+ finalize() {}
}
-
-export function _testOnly_setState(state: BrowserState) {
- privateState$.next(state);
-}
-
-export function _testOnly_getState() {
- return privateState$.getValue();
-}
-
-export const viewState$: Observable<BrowserState> = privateState$;
-
-export function updateStateScreenWidth(screenWidth: number) {
- privateState$.next({...privateState$.getValue(), screenWidth});
-}
-
-export const isScreenTooSmall$ = viewState$.pipe(
- map(
- state =>
- !!state.screenWidth &&
- state.screenWidth < MAX_UNIFIED_DEFAULT_WINDOW_WIDTH_PX
- ),
- distinctUntilChanged()
-);
-
-export const diffViewMode$: Observable<DiffViewMode> = combineLatest([
- isScreenTooSmall$,
- preferenceDiffViewMode$,
-]).pipe(
- map(([isScreenTooSmall, preferenceDiffViewMode]) => {
- if (isScreenTooSmall) return DiffViewMode.UNIFIED;
- else return preferenceDiffViewMode;
- }, distinctUntilChanged())
-);
diff --git a/polygerrit-ui/app/services/browser/browser-service.ts b/polygerrit-ui/app/services/browser/browser-service.ts
deleted file mode 100644
index b80c4df..0000000
--- a/polygerrit-ui/app/services/browser/browser-service.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * @license
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import {updateStateScreenWidth} from './browser-model';
-import {Finalizable} from '../registry';
-
-export class BrowserService implements Finalizable {
- /* Observer the screen width so that the app can react to changes to it */
- observeWidth() {
- return new ResizeObserver(entries => {
- entries.forEach(entry => {
- updateStateScreenWidth(entry.contentRect.width);
- });
- });
- }
-
- finalize() {}
-}
diff --git a/polygerrit-ui/app/test/common-test-setup.ts b/polygerrit-ui/app/test/common-test-setup.ts
index f555e8e..f8fd534 100644
--- a/polygerrit-ui/app/test/common-test-setup.ts
+++ b/polygerrit-ui/app/test/common-test-setup.ts
@@ -49,7 +49,6 @@
import {updatePreferences} from '../services/user/user-model';
import {createDefaultPreferences} from '../constants/constants';
import {getAppContext} from '../services/app-context';
-import {_testOnly_resetState as resetBrowserState} from '../services/browser/browser-model';
import {_testOnly_resetState as resetChangeState} from '../services/change/change-model';
import {_testOnly_resetState as resetChecksState} from '../services/checks/checks-model';
import {_testOnly_resetState as resetCommentsState} from '../services/comments/comments-model';
@@ -119,7 +118,6 @@
initGlobalVariables();
_testOnly_initGerritPluginApi();
- resetBrowserState();
resetChangeState();
resetChecksState();
resetCommentsState();
diff --git a/polygerrit-ui/app/test/test-app-context-init.ts b/polygerrit-ui/app/test/test-app-context-init.ts
index 2817d35..03c5967 100644
--- a/polygerrit-ui/app/test/test-app-context-init.ts
+++ b/polygerrit-ui/app/test/test-app-context-init.ts
@@ -32,7 +32,7 @@
import {UserService} from '../services/user/user-service';
import {CommentsService} from '../services/comments/comments-service';
import {ShortcutsService} from '../services/shortcuts/shortcuts-service';
-import {BrowserService} from '../services/browser/browser-service';
+import {BrowserModel} from '../services/browser/browser-model';
let appContext: (AppContext & Finalizable) | undefined;
@@ -76,7 +76,7 @@
assertIsDefined(ctx.reportingService, 'reportingService');
return new ShortcutsService(ctx.reportingService!);
},
- browserService: (_ctx: Partial<AppContext>) => new BrowserService(),
+ browserModel: (_ctx: Partial<AppContext>) => new BrowserModel(),
};
appContext = create<AppContext>(appRegistry);
injectAppContext(appContext);