mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-14 15:22:21 +00:00
Merge main into viewport diagnostics PR (#835)
This commit is contained in:
commit
2193c2116e
8 files changed
+127
-9
No files matched your search
@@ -126,8 +126,17 @@ export function createStreetLevelLayer({
|
||||
});
|
||||
}
|
||||
|
||||
// One source at a time: the first provider that defaults on.
|
||||
const startsOn = defs.find((def) => def.defaultOn !== false);
|
||||
/** `def` if its key is ready, else the first keyless provider not refused. */
|
||||
function keylessInstead(def, refused = () => false) {
|
||||
if (def.keyReady?.() !== false) return def;
|
||||
return defs.find((d) => !d.requiresKeyId && !refused(d.id)) || def;
|
||||
}
|
||||
|
||||
// One source at a time: the first provider that defaults on. Without its
|
||||
// key, the first keyless source instead, so a fresh keyless install opens
|
||||
// on coverage rather than KEY REQUIRED.
|
||||
const preferred = defs.find((def) => def.defaultOn !== false);
|
||||
const startsOn = preferred && keylessInstead(preferred);
|
||||
for (const def of defs) {
|
||||
const entry = {
|
||||
def,
|
||||
@@ -585,7 +594,17 @@ export function createStreetLevelLayer({
|
||||
providerIds: state.providers.keys(),
|
||||
filter: state.filter,
|
||||
});
|
||||
const lit = litByParams(decoded.providers);
|
||||
// A restored "Mapillary on" (the codec default) would light a source a
|
||||
// keyless install cannot draw. Only redirect a provider the params switch
|
||||
// on: a filter-only update keeps whatever the user chose.
|
||||
const asked = litByParams(decoded.providers);
|
||||
const lit =
|
||||
asked && decoded.providers.get(asked) === true
|
||||
? keylessInstead(
|
||||
state.providers.get(asked).def,
|
||||
(id) => decoded.providers.get(id) === false,
|
||||
).id
|
||||
: asked;
|
||||
const before = litIds();
|
||||
for (const [id, entry] of state.providers)
|
||||
if (id !== lit) switchProvider(entry, false);
|
||||
|
||||
@@ -1127,3 +1127,59 @@ test('the panel says why a lit Street View draws nothing off Google 3D', async (
|
||||
const view = presentStreetLevelPanel(layer.getUIState());
|
||||
assert.match(view.meta, /Google Street View needs the Google 3D map/);
|
||||
});
|
||||
|
||||
/** Mapillary (keyless unless `mapillary` says otherwise) plus KartaView. */
|
||||
function keylessLayer(t, mapillary = { hasToken: () => false }) {
|
||||
const layer = createStreetLevelLayer({
|
||||
providers: [
|
||||
createMapillaryProvider({
|
||||
source: fakeMapillarySource(mapillary),
|
||||
photoViewer: fakePhotoViewer(),
|
||||
}),
|
||||
createKartaViewProvider(),
|
||||
],
|
||||
});
|
||||
t.after(() => layer.destroy());
|
||||
return layer;
|
||||
}
|
||||
const litProviders = (layer) =>
|
||||
layer
|
||||
.getUIState()
|
||||
.providers.filter((provider) => provider.on)
|
||||
.map((provider) => provider.id);
|
||||
|
||||
test('without a Mapillary key the first keyless source is lit instead', (t) => {
|
||||
assert.deepEqual(litProviders(keylessLayer(t)), ['kartaview']);
|
||||
assert.deepEqual(litProviders(keylessLayer(t, {})), ['mapillary']);
|
||||
// A token-adding Graph proxy counts as a key.
|
||||
const proxied = keylessLayer(t, {
|
||||
hasToken: () => false,
|
||||
graphEndpoint: '/api/mapillary/graph',
|
||||
});
|
||||
assert.deepEqual(litProviders(proxied), ['mapillary']);
|
||||
});
|
||||
|
||||
test('restoring the default "Mapillary on" without its key keeps a keyless source', (t) => {
|
||||
const layer = keylessLayer(t);
|
||||
layer.setParams({ mapillary: true, providerSwitches: '' });
|
||||
assert.deepEqual(litProviders(layer), ['kartaview']);
|
||||
// A link that switches KartaView off keeps its word.
|
||||
layer.setParams({ mapillary: true, providerSwitches: 'kartaview-0' });
|
||||
assert.deepEqual(litProviders(layer), ['mapillary']);
|
||||
});
|
||||
|
||||
test('filter-only updates keep the lit source, even a chosen keyless Mapillary', (t) => {
|
||||
const layer = keylessLayer(t);
|
||||
layer.setParams({ pano: 'pano' });
|
||||
assert.deepEqual(litProviders(layer), ['kartaview']);
|
||||
// What the MAPILLARY chip sends, and what stored state restores.
|
||||
layer.setParams({ mapillary: true, providerSwitches: 'kartaview-0' });
|
||||
for (const params of [{ pano: 'pano' }, { sinceDays: 365 }, {}]) {
|
||||
layer.setParams(params);
|
||||
assert.deepEqual(
|
||||
litProviders(layer),
|
||||
['mapillary'],
|
||||
JSON.stringify(params),
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -74,6 +74,9 @@ export function createMapillaryProvider({ source, photoViewer = null }) {
|
||||
name: MAPILLARY_NAME,
|
||||
label: MAPILLARY_LABEL,
|
||||
requiresKeyId: MAPILLARY_KEY_ID,
|
||||
/** A browser token, or a Graph proxy that adds one server-side. */
|
||||
keyReady: () =>
|
||||
source.hasToken?.() !== false || Boolean(source.graphEndpoint),
|
||||
pickPrefix: PICK_PREFIX.root,
|
||||
colors: COLORS,
|
||||
credit: Object.freeze({ html: MAPILLARY_CREDIT_HTML }),
|
||||
|
||||
@@ -20,6 +20,8 @@ export function filtersOf(provider) {
|
||||
* @property {boolean} [groundClick] No coverage: a ground click at street zoom opens its nearest image.
|
||||
* @property {string} [requiresMapStack] Usable only on this map stack.
|
||||
* @property {boolean} [defaultOn] Default true; the first that defaults on is lit.
|
||||
* @property {() => boolean} [keyReady] False when its key is missing now; the
|
||||
* first keyless provider is lit instead of a default that cannot draw.
|
||||
* @property {{kind: 'view-cone', color: string}} [marker] Default: GEV's pin.
|
||||
* @property {Array<'pano'|'since'>} [filters] Filters it honours (default both).
|
||||
* @property {{noun: string, action: string}} [coverageLabel] How the panel counts its lines and says what a click does (default: sequences, "click a line for its photos").
|
||||
|
||||
Reference in new issue
Block a user