mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-13 15:51:00 +00:00
74 lines
2.9 KiB
TypeScript
74 lines
2.9 KiB
TypeScript
import { hasNativeFeature } from './capabilities';
|
|
import { GL_MAPS_THROUGH_APP_SCHEMES } from './glSchemes';
|
|
import { isNativeApp, isNativeIos } from './platform';
|
|
|
|
/**
|
|
* The iOS app's own tile store (TrekTileSchemeHandler.swift), reached through
|
|
* the trek-tile:// scheme.
|
|
*
|
|
* WKWebView runs no service worker for a self-hosted server, so on iOS nothing
|
|
* kept the map tiles a user had looked at. Binaries that report the tileCache
|
|
* feature serve every trek-tile:// request from a store on disk, filled as the
|
|
* tiles are viewed and kept for at most 30 days (Mapbox's limit for a device
|
|
* cache, applied to every provider alike), and from the network otherwise. The
|
|
* URL keeps its host and path, only the scheme changes, so the handler knows
|
|
* where the tile really lives.
|
|
*
|
|
* Nothing is prefetched through here: Mapbox forbids bulk downloads, and the
|
|
* OpenFreeMap region a trip stores goes through Cache Storage (offlineTiles.ts).
|
|
*/
|
|
const TILE_CACHE_SCHEME = 'trek-tile';
|
|
|
|
/**
|
|
* Whether the app keeps the Mapbox map's resources itself, so a Mapbox map works
|
|
* offline where it was viewed. On Android the app's WebView client takes those
|
|
* requests as they are (tiles/TrekTileStore.kt), so only iOS rewrites URLs.
|
|
*/
|
|
export function tileCacheActive(): boolean {
|
|
return isNativeApp() && hasNativeFeature('tileCache');
|
|
}
|
|
|
|
/** Whether a GL map keeps what it showed in the store (see glSchemes.ts for why not, for now). */
|
|
export function glTileStoreActive(): boolean {
|
|
return GL_MAPS_THROUGH_APP_SCHEMES && tileSchemeActive();
|
|
}
|
|
|
|
/** Whether URLs go through the trek-tile:// scheme: the iOS store only. */
|
|
function tileSchemeActive(): boolean {
|
|
return isNativeIos() && hasNativeFeature('tileCache');
|
|
}
|
|
|
|
/** https://host/path?query -> trek-tile://host/path?query. Anything else stays. */
|
|
export function toTileCacheUrl(url: string): string {
|
|
return url.startsWith('https://') ? `${TILE_CACHE_SCHEME}://${url.slice('https://'.length)}` : url;
|
|
}
|
|
|
|
/** A raster tile template for Leaflet, through the store where the app has one. */
|
|
export function nativeRasterTemplate(template: string): string {
|
|
return tileSchemeActive() ? toTileCacheUrl(template) : template;
|
|
}
|
|
|
|
const MAPBOX_HOST = /^https:\/\/(?:api\.mapbox\.com|[a-z0-9-]+\.tiles\.mapbox\.com)\//i;
|
|
/** What a map draws; telemetry and anything else keeps going straight out. */
|
|
const CACHED_RESOURCES = new Set([
|
|
'Style',
|
|
'Source',
|
|
'Tile',
|
|
'Glyphs',
|
|
'SpriteImage',
|
|
'SpriteJSON',
|
|
'Image',
|
|
'Iconset',
|
|
'Model',
|
|
]);
|
|
|
|
/**
|
|
* Mapbox GL's transformRequest for the iOS app: the map's own resources from
|
|
* Mapbox's servers go through the store, events and sessions never do.
|
|
*/
|
|
export function mapboxTileCacheRequest(url: string, resourceType?: string): { url: string } {
|
|
if (!glTileStoreActive() || !MAPBOX_HOST.test(url)) return { url };
|
|
if (resourceType && !CACHED_RESOURCES.has(resourceType)) return { url };
|
|
return { url: toTileCacheUrl(url) };
|
|
}
|