2024-11-18 20:43:19 +01:00
/ * *
* The Android Polyfill will attempt to communicate with the Anrdoid Shell .
* If this is successful , it will patch some webAPIs
* /
import { registerPlugin } from "@capacitor/core"
2024-12-12 00:46:24 +01:00
import { Store , UIEventSource } from "../UIEventSource"
import { OsmConnection } from "../Osm/OsmConnection"
2024-12-10 04:28:50 +01:00
export interface DatabridgePlugin {
2024-12-19 13:49:14 +01:00
request < T extends ( string | object ) = string | object > ( options : { key : string } ) : Promise < { value : T } > ;
2024-12-10 04:28:50 +01:00
}
const DatabridgePluginSingleton = registerPlugin < DatabridgePlugin > ( "Databridge" , {
web : ( ) = > {
return < DatabridgePlugin > {
2024-12-12 00:46:24 +01:00
async request ( options : { key : string } ) : Promise < { value : string | object } > {
2025-01-21 21:06:50 +01:00
console . log ( "Android polyfill got request for" , options . key )
2025-01-12 01:53:58 +01:00
if ( options . key === "meta" ) {
return { value : "web" }
}
2025-01-21 21:06:50 +01:00
return null
2025-01-22 01:26:12 +01:00
} ,
2024-12-10 04:28:50 +01:00
}
2025-01-22 01:26:12 +01:00
} ,
2024-12-10 04:28:50 +01:00
} )
2024-11-18 20:43:19 +01:00
export class AndroidPolyfill {
2024-12-10 04:28:50 +01:00
private readonly databridgePlugin : DatabridgePlugin = DatabridgePluginSingleton
2024-12-12 00:46:24 +01:00
private static readonly _inAndroid : UIEventSource < boolean > = new UIEventSource < boolean > ( false )
public static readonly inAndroid : Store < boolean > = AndroidPolyfill . _inAndroid
private static readonly _geolocationPermission : UIEventSource < "granted" | "denied" | "prompt" > = new UIEventSource ( "prompt" )
public static readonly geolocationPermission : Store < "granted" | "denied" | "prompt" > = this . _geolocationPermission
2024-12-10 04:28:50 +01:00
/ * *
* Registers 'navigator.'
* @private
* /
private backfillGeolocation ( databridgePlugin : DatabridgePlugin ) {
2025-01-22 01:26:12 +01:00
const src = UIEventSource . FromPromise ( databridgePlugin . request ( { key : "location:has-permission" } ) )
2024-12-12 00:46:24 +01:00
src . addCallbackAndRunD ( permission = > {
2025-01-22 01:26:12 +01:00
console . log ( "> Checking geopermission gave: " , JSON . stringify ( permission ) , permission . value )
const granted = permission . value === "true"
AndroidPolyfill . _geolocationPermission . set ( granted ? "granted" : "denied" )
2024-12-12 00:46:24 +01:00
} )
2024-11-18 20:43:19 +01:00
}
2025-01-22 01:26:12 +01:00
public static async requestGeoPermission ( ) : Promise < { value : string | object } > {
return DatabridgePluginSingleton . request ( { key : "location:request-permission" } )
}
2024-12-10 04:28:50 +01:00
public async init() {
console . log ( "Sniffing shell version" )
2024-11-18 20:43:19 +01:00
const shell = await this . databridgePlugin . request ( { key : "meta" } )
2024-12-10 04:28:50 +01:00
if ( shell . value === "web" ) {
console . log ( "Not initing Android polyfill as not in a shell; web detected" )
2024-11-18 20:43:19 +01:00
return
}
2024-12-12 00:46:24 +01:00
AndroidPolyfill . _inAndroid . set ( true )
2024-11-18 20:43:19 +01:00
console . log ( "Detected shell:" , shell . value )
2024-12-10 04:28:50 +01:00
this . backfillGeolocation ( this . databridgePlugin )
2024-11-18 20:43:19 +01:00
}
2024-12-31 19:55:08 +01:00
public static async requestLoginCodes() {
2025-01-22 01:26:12 +01:00
const result = await DatabridgePluginSingleton . request < { oauth_token : string } > ( { key : "request:login" } )
2024-12-19 13:49:14 +01:00
const token : string = result . value . oauth_token
2025-01-22 01:26:12 +01:00
console . log ( "AndroidPolyfill: received oauth_token; trying to pass them to the oauth lib" , token )
2024-12-31 19:55:08 +01:00
return token
2024-12-12 00:46:24 +01:00
}
2025-01-12 01:53:58 +01:00
public static onBackButton ( callback : ( ) = > boolean , options : {
returnToIndex : Store < boolean >
} ) {
console . log ( "Registering back button callback" , callback )
DatabridgePluginSingleton . request ( { key : "backbutton" } ) . then ( ev = > {
console . log ( "AndroidPolyfill: received backbutton: " , ev )
2025-01-22 01:26:12 +01:00
if ( ev === null ) {
2025-01-21 21:06:50 +01:00
// Probably in web environment
return
}
// We have to re-register every time
AndroidPolyfill . onBackButton ( callback , options )
2025-01-12 01:53:58 +01:00
if ( callback ( ) ) {
return
}
// Nothing more to close - we return (if not a single theme) to the index
if ( options . returnToIndex ) {
console . log ( "Back to the index!" )
window . location . href = "/"
}
} )
}
2025-01-22 01:26:12 +01:00
public static watchLocation ( writeInto : UIEventSource < GeolocationCoordinates > , callback : ( location ) = > void ) {
DatabridgePluginSingleton . request ( {
key : "location:watch" ,
} ) . then ( ( l : {
value : { latitude : number , longitude : number , accuraccy : number , altidude : number , heading : number , speed :number }
} ) = > {
// example l: {"value":{"latitude":51.0618627,"longitude":3.730468566666667,"accuracy":2.0393495559692383,"altitude":46.408,"heading":168.2969970703125}}
console . log ( "Received location from Android:" , JSON . stringify ( l ) )
const loc = l . value
writeInto . set ( {
latitude : loc.latitude ,
longitude : loc.longitude ,
heading : loc.heading ,
accuracy : loc.accuraccy ,
altitude : loc.altidude ,
altitudeAccuracy : undefined ,
speed : loc.speed ,
} )
} )
}
2024-11-18 20:43:19 +01:00
}
2024-12-19 13:49:14 +01:00