Merge pull request 'fix(location): confirm before sharing, with accuracy and an approximate option (#340)' (#353) from fix/location-confirm into lotus
CI / Build & Quality Checks (push) Successful in 3m8s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 8s
CI / Trigger Desktop Build (push) Successful in 5s
CI / Playwright smoke (e2e) (push) Successful in 12m15s
CI / Build & Quality Checks (push) Successful in 3m8s
CI / Docker image build & smoke test (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 8s
CI / Trigger Desktop Build (push) Successful in 5s
CI / Playwright smoke (e2e) (push) Successful in 12m15s
This commit was merged in pull request #353.
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { buildGeoUri, formatAccuracy } from './geoShare';
|
||||
import { parseGeoUri } from './common';
|
||||
|
||||
test('buildGeoUri: exact share keeps 6 decimals and adds the accuracy as u=', () => {
|
||||
assert.equal(buildGeoUri(40.748817, -73.985428, 12.4), 'geo:40.748817,-73.985428;u=12');
|
||||
assert.equal(buildGeoUri(40.748817, -73.985428), 'geo:40.748817,-73.985428');
|
||||
assert.equal(buildGeoUri(40.748817, -73.985428, Number.NaN), 'geo:40.748817,-73.985428');
|
||||
});
|
||||
|
||||
test('buildGeoUri: approximate share rounds to ~1 km and never claims better than 1 km', () => {
|
||||
assert.equal(buildGeoUri(40.748817, -73.985428, 12, true), 'geo:40.75,-73.99;u=1000');
|
||||
assert.equal(buildGeoUri(40.748817, -73.985428, 3500, true), 'geo:40.75,-73.99;u=3500');
|
||||
});
|
||||
|
||||
test('buildGeoUri output still parses with the renderer', () => {
|
||||
const loc = parseGeoUri(buildGeoUri(51.5, -0.12, 30));
|
||||
assert.ok(loc);
|
||||
assert.equal(parseFloat(loc.latitude), 51.5);
|
||||
assert.equal(parseFloat(loc.longitude), -0.12);
|
||||
});
|
||||
|
||||
test('formatAccuracy', () => {
|
||||
assert.equal(formatAccuracy(12.4), '±12 m');
|
||||
assert.equal(formatAccuracy(3500), '±3.5 km');
|
||||
assert.equal(formatAccuracy(25000), '±25 km');
|
||||
assert.equal(formatAccuracy(undefined), undefined);
|
||||
assert.equal(formatAccuracy(0), undefined);
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* [Gitea #340] Helpers for the "Share location" confirm step: the geo URI to
|
||||
* send (RFC 5870, with the fix's accuracy as `u=` so receivers can draw a
|
||||
* radius) and a human accuracy label, so a ±3 km Wi-Fi/IP fix isn't presented
|
||||
* — or sent — as if it were exact.
|
||||
*/
|
||||
|
||||
/** Decimals kept for an "approximate" share: 2 → ~1.1 km of latitude. */
|
||||
export const APPROXIMATE_DECIMALS = 2;
|
||||
/** Uncertainty reported for an approximate share (half a 0.01° cell, rounded up). */
|
||||
export const APPROXIMATE_UNCERTAINTY_M = 1000;
|
||||
|
||||
const validAccuracy = (accuracy?: number): number | undefined =>
|
||||
typeof accuracy === 'number' && Number.isFinite(accuracy) && accuracy > 0
|
||||
? Math.round(accuracy)
|
||||
: undefined;
|
||||
|
||||
export const buildGeoUri = (
|
||||
latitude: number,
|
||||
longitude: number,
|
||||
accuracy?: number,
|
||||
approximate = false,
|
||||
): string => {
|
||||
const decimals = approximate ? APPROXIMATE_DECIMALS : 6;
|
||||
const u = approximate
|
||||
? Math.max(APPROXIMATE_UNCERTAINTY_M, validAccuracy(accuracy) ?? 0)
|
||||
: validAccuracy(accuracy);
|
||||
const base = `geo:${latitude.toFixed(decimals)},${longitude.toFixed(decimals)}`;
|
||||
return u ? `${base};u=${u}` : base;
|
||||
};
|
||||
|
||||
/** "±12 m", "±3.5 km", or undefined when the browser gave no accuracy. */
|
||||
export const formatAccuracy = (accuracy?: number): string | undefined => {
|
||||
const m = validAccuracy(accuracy);
|
||||
if (m === undefined) return undefined;
|
||||
if (m < 1000) return `±${m} m`;
|
||||
const km = m / 1000;
|
||||
return `±${km < 10 ? km.toFixed(1) : Math.round(km)} km`;
|
||||
};
|
||||
Reference in New Issue
Block a user