mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-04 02:14:01 +00:00
refactor(street-level): open the panel from the switch-on request's origin only
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
94049c5667
commit
209dda5507
2 files changed
+31
-76
No files matched your search
@@ -38,12 +38,8 @@ export class StreetLevelControls {
|
||||
this._state = null;
|
||||
this._wasEnabled = null;
|
||||
this._wasOpen = false;
|
||||
// Until the user first touches the app, an off → on is the saved layer
|
||||
// state being restored, not a user switching the layer on.
|
||||
this._restoreWindow = true;
|
||||
// Whether the last switch-on was explicit (user, voice, tool) rather than
|
||||
// a restore; null when the shell does not report request origins.
|
||||
this._explicitEnable = null;
|
||||
// Whether the last switch-on was explicit (user, voice, tool), not a restore.
|
||||
this._explicitEnable = false;
|
||||
this._unsubscribeEnableRequests = null;
|
||||
this._resizeQueued = false;
|
||||
this._elements = this._collect();
|
||||
@@ -147,11 +143,6 @@ export class StreetLevelControls {
|
||||
} catch {
|
||||
/* storage unavailable */
|
||||
}
|
||||
const endRestoreWindow = () => {
|
||||
this._restoreWindow = false;
|
||||
};
|
||||
for (const type of ['pointerdown', 'keydown'])
|
||||
this.listen(document, type, endRestoreWindow, { capture: true });
|
||||
// MapillaryJS only tracks window resizes; the panel resizes on its own.
|
||||
if (typeof ResizeObserver === 'function' && el.viewer) {
|
||||
this._resizeObserver = new ResizeObserver(() => this._requestResize());
|
||||
@@ -212,9 +203,7 @@ export class StreetLevelControls {
|
||||
|
||||
/** Through the data manager, so saved state and share links record it. */
|
||||
_setParams(params) {
|
||||
if (this.actions.setParams)
|
||||
this.actions.setParams(params, { origin: 'user' });
|
||||
else this.layer.setParams?.(params);
|
||||
this.actions.setParams(params, { origin: 'user' });
|
||||
}
|
||||
|
||||
/** Whether EXPAND has the viewer full screen (or, on iPhone, open over the page). */
|
||||
@@ -308,10 +297,11 @@ export class StreetLevelControls {
|
||||
this._unsubscribe = null;
|
||||
if (this.destroyed || !this.root) return;
|
||||
this._unsubscribeEnableRequests?.();
|
||||
this._unsubscribeEnableRequests =
|
||||
this.actions.subscribeEnableRequests?.((origin) => {
|
||||
this._unsubscribeEnableRequests = this.actions.subscribeEnableRequests(
|
||||
(origin) => {
|
||||
this._explicitEnable = isExplicitLayerStateOrigin(origin);
|
||||
}) || null;
|
||||
},
|
||||
);
|
||||
this._unsubscribe = this.layer.subscribe?.((state) => this.render(state));
|
||||
if (this.layer.getUIState) this.render(this.layer.getUIState());
|
||||
}
|
||||
@@ -441,17 +431,9 @@ export class StreetLevelControls {
|
||||
_reactToTransitions(view) {
|
||||
const enabled = view.enabled;
|
||||
if (enabled && this._wasEnabled === false) {
|
||||
// A restore must not reopen a panel the user or a share link kept
|
||||
// collapsed. Without request origins, the restore window decides.
|
||||
const preference = this.root.dataset?.collapsedPreference;
|
||||
const restoring =
|
||||
this._explicitEnable === null
|
||||
? this._restoreWindow &&
|
||||
(preference === 'stored' || preference === 'share')
|
||||
: !this._explicitEnable;
|
||||
if (!restoring) this.setCollapsed(false, { persist: false });
|
||||
this._restoreWindow = false;
|
||||
this._explicitEnable = this._explicitEnable === null ? null : false;
|
||||
// A restore must not reopen a panel the user or a share link kept collapsed.
|
||||
if (this._explicitEnable) this.setCollapsed(false, { persist: false });
|
||||
this._explicitEnable = false;
|
||||
}
|
||||
this._wasEnabled = enabled;
|
||||
// Other size changes reach the viewer through the ResizeObserver; opening
|
||||
|
||||
@@ -293,6 +293,7 @@ async function productionPanel(dom) {
|
||||
manager.setLayerParams('street-level', params, options),
|
||||
setPanelCollapsed() {},
|
||||
showToast() {},
|
||||
subscribeEnableRequests: () => () => {},
|
||||
},
|
||||
});
|
||||
controls.connect();
|
||||
@@ -402,6 +403,8 @@ function stubPanel(dom, state, extraActions = {}) {
|
||||
const layer = stubLayer();
|
||||
const calls = { setParams: [], setEnabled: [], collapsed: [] };
|
||||
let enabled = state.enabled;
|
||||
/** Reports a switch-on request's origin, as the data manager does. */
|
||||
let announce = null;
|
||||
layer.publish(state);
|
||||
const controls = new StreetLevelControls({
|
||||
root: dom.root,
|
||||
@@ -416,11 +419,23 @@ function stubPanel(dom, state, extraActions = {}) {
|
||||
setPanelCollapsed: (collapsed, options) =>
|
||||
calls.collapsed.push([collapsed, options]),
|
||||
showToast() {},
|
||||
subscribeEnableRequests: (listener) => {
|
||||
announce = listener;
|
||||
return () => {
|
||||
announce = null;
|
||||
};
|
||||
},
|
||||
...extraActions,
|
||||
},
|
||||
});
|
||||
controls.connect();
|
||||
return { layer, calls, controls };
|
||||
return {
|
||||
layer,
|
||||
calls,
|
||||
controls,
|
||||
announce: (origin) => announce?.(origin),
|
||||
subscribed: () => announce !== null,
|
||||
};
|
||||
}
|
||||
|
||||
test('the header pill switches the layer, bringing back Mapillary switched off elsewhere', () =>
|
||||
@@ -634,56 +649,12 @@ for (const mode of ['ui-clean-view', 'recording-mode', 'cockpit-mode'])
|
||||
|
||||
/* ── Restores and keyboard rules ───────────────────────────────────────── */
|
||||
|
||||
test('a restored layer does not reopen a panel the user collapsed, and automatic opens are never stored (P2-1)', () =>
|
||||
test('only an explicit switch-on opens the panel, unstored; a restore never does (P2-1)', () =>
|
||||
withDom(async (dom) => {
|
||||
// The panel chrome restored the user's stored "collapsed" before connect.
|
||||
dom.root.dataset.collapsedPreference = 'stored';
|
||||
const { layer, calls, controls } = stubPanel(
|
||||
const { layer, calls, controls, announce, subscribed } = stubPanel(
|
||||
dom,
|
||||
uiState({ enabled: false }),
|
||||
);
|
||||
layer.publish(uiState({ enabled: true })); // saved layer state restored
|
||||
assert.deepEqual(calls.collapsed, [], 'the collapsed panel stays shut');
|
||||
// Later, a user switches the layer off and on: that opens the panel,
|
||||
// without overwriting the stored preference.
|
||||
dom.document.body.dispatchEvent({ type: 'pointerdown', bubbles: true });
|
||||
layer.publish(uiState({ enabled: false }));
|
||||
layer.publish(uiState({ enabled: true }));
|
||||
assert.deepEqual(calls.collapsed, [[false, { persist: false }]]);
|
||||
layer.publish(uiState({ enabled: true, open: true }));
|
||||
assert.deepEqual(calls.collapsed.at(-1), [false, { persist: false }]);
|
||||
controls.destroy();
|
||||
}));
|
||||
|
||||
test('without a stored choice, a restored layer still opens its panel, unstored (P2-1)', () =>
|
||||
withDom(async (dom) => {
|
||||
dom.root.dataset.collapsedPreference = 'default';
|
||||
const { layer, calls, controls } = stubPanel(
|
||||
dom,
|
||||
uiState({ enabled: false }),
|
||||
);
|
||||
layer.publish(uiState({ enabled: true }));
|
||||
assert.deepEqual(calls.collapsed, [[false, { persist: false }]]);
|
||||
controls.destroy();
|
||||
}));
|
||||
|
||||
test('with request origins, only a user switch-on opens the panel; a restore never does (P2-1)', () =>
|
||||
withDom(async (dom) => {
|
||||
// No stored choice: the restore window alone would open the panel.
|
||||
dom.root.dataset.collapsedPreference = 'default';
|
||||
let announce = null;
|
||||
const { layer, calls, controls } = stubPanel(
|
||||
dom,
|
||||
uiState({ enabled: false }),
|
||||
{
|
||||
subscribeEnableRequests: (listener) => {
|
||||
announce = listener;
|
||||
return () => {
|
||||
announce = null;
|
||||
};
|
||||
},
|
||||
},
|
||||
);
|
||||
announce('restore');
|
||||
layer.publish(uiState({ enabled: true }));
|
||||
assert.deepEqual(calls.collapsed, [], 'a restore leaves the panel be');
|
||||
@@ -691,8 +662,10 @@ test('with request origins, only a user switch-on opens the panel; a restore nev
|
||||
announce('user');
|
||||
layer.publish(uiState({ enabled: true }));
|
||||
assert.deepEqual(calls.collapsed, [[false, { persist: false }]]);
|
||||
layer.publish(uiState({ enabled: true, open: true }));
|
||||
assert.equal(calls.collapsed.length, 2, 'a photo opening opens it too');
|
||||
controls.destroy();
|
||||
assert.equal(announce, null, 'destroy unsubscribes');
|
||||
assert.equal(subscribed(), false, 'destroy unsubscribes');
|
||||
}));
|
||||
|
||||
test('FIT / FILL show the selected render mode (P3)', () =>
|
||||
|
||||
Reference in new issue
Block a user