forked from MapComplete/MapComplete
		
	Android: docs, app landing page
This commit is contained in:
		
							parent
							
								
									8b43c63a31
								
							
						
					
					
						commit
						15caadbd3d
					
				
					 5 changed files with 67 additions and 10 deletions
				
			
		|  | @ -1,9 +1,12 @@ | ||||||
| import { defineConfig } from "vite" | import { defineConfig } from "vite" | ||||||
| import { svelte } from "@sveltejs/vite-plugin-svelte" | import { svelte } from "@sveltejs/vite-plugin-svelte" | ||||||
| import fs from "fs" |  | ||||||
| import basicSsl from "@vitejs/plugin-basic-ssl" | import basicSsl from "@vitejs/plugin-basic-ssl" | ||||||
| 
 | 
 | ||||||
| const input = { "land": "./app/land.html", passthrough: "./app/passthrough.html" } | const input = { | ||||||
|  |   land: "./app/land.html", | ||||||
|  |   index: "./app/index.html", | ||||||
|  |   passthrough: "./app/passthrough.html" | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| console.log("Args:", process.argv) | console.log("Args:", process.argv) | ||||||
|  |  | ||||||
							
								
								
									
										18
									
								
								app/index.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								app/index.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | ||||||
|  | <!DOCTYPE html> | ||||||
|  | <html lang="en"> | ||||||
|  | <head> | ||||||
|  |   <meta charset="UTF-8"> | ||||||
|  |   <title>MapComplete App</title> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | 
 | ||||||
|  | Hi! | ||||||
|  | 
 | ||||||
|  | MapComplete will soon (TM) be available as Android App in the play store and on FDroid. | ||||||
|  | 
 | ||||||
|  | In the meantime, there isn't a lot to see here. | ||||||
|  | 
 | ||||||
|  | <a href="https://mapcomplete.org">Go back to mapcomplete</a> | ||||||
|  | 
 | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
|  | @ -22,6 +22,7 @@ const config: CapacitorConfig = { | ||||||
| export default config; | export default config; | ||||||
| ''' > capacitor.config.ts | ''' > capacitor.config.ts | ||||||
| 
 | 
 | ||||||
|  | # copy distribution files | ||||||
| rm -rf dist-full | rm -rf dist-full | ||||||
| mkdir dist-full | mkdir dist-full | ||||||
| cp dist/*.html dist-full/ | cp dist/*.html dist-full/ | ||||||
|  |  | ||||||
|  | @ -14,10 +14,12 @@ const DatabridgePluginSingleton = registerPlugin<DatabridgePlugin>("Databridge", | ||||||
|     web: () => { |     web: () => { | ||||||
|         return <DatabridgePlugin>{ |         return <DatabridgePlugin>{ | ||||||
|             async request(options: { key: string }): Promise<{ value: string | object }> { |             async request(options: { key: string }): Promise<{ value: string | object }> { | ||||||
|                 return { value: "web" } |                 if (options.key === "meta") { | ||||||
|             }, |                     return { value: "web" } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     }, |     } | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| export class AndroidPolyfill { | export class AndroidPolyfill { | ||||||
|  | @ -32,7 +34,6 @@ export class AndroidPolyfill { | ||||||
|      * @private |      * @private | ||||||
|      */ |      */ | ||||||
|     private backfillGeolocation(databridgePlugin: DatabridgePlugin) { |     private backfillGeolocation(databridgePlugin: DatabridgePlugin) { | ||||||
|         const origQueryFunc = navigator?.permissions?.query |  | ||||||
|         const src = UIEventSource.FromPromise(databridgePlugin.request({ key: "location:request-permission" })) |         const src = UIEventSource.FromPromise(databridgePlugin.request({ key: "location:request-permission" })) | ||||||
|         src.addCallbackAndRunD(permission => { |         src.addCallbackAndRunD(permission => { | ||||||
|             AndroidPolyfill._geolocationPermission.set(<"granted" | "denied">permission.value) |             AndroidPolyfill._geolocationPermission.set(<"granted" | "denied">permission.value) | ||||||
|  | @ -57,5 +58,23 @@ export class AndroidPolyfill { | ||||||
|         console.log("AndroidPolyfill: received oauth_token; trying to pass them to the oauth lib",token) |         console.log("AndroidPolyfill: received oauth_token; trying to pass them to the oauth lib",token) | ||||||
|         return token |         return token | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     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) | ||||||
|  |             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 = "/" | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  | 
 | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| import ThemeViewState from "../../Models/ThemeViewState" | import ThemeViewState from "../../Models/ThemeViewState" | ||||||
| import Hash from "./Hash" | import Hash from "./Hash" | ||||||
| import { MenuState } from "../../Models/MenuState" | import { MenuState } from "../../Models/MenuState" | ||||||
|  | import { AndroidPolyfill } from "./AndroidPolyfill" | ||||||
| 
 | 
 | ||||||
| export default class ThemeViewStateHashActor { | export default class ThemeViewStateHashActor { | ||||||
|     private readonly _state: ThemeViewState |     private readonly _state: ThemeViewState | ||||||
|  | @ -22,7 +23,7 @@ export default class ThemeViewStateHashActor { | ||||||
|     /** |     /** | ||||||
|      * Converts the hash to the appropriate theme-view state and, vice versa, sets the hash. |      * Converts the hash to the appropriate theme-view state and, vice versa, sets the hash. | ||||||
|      * |      * | ||||||
|      * As the navigator-back-button changes the hash first, this class thus also handles the 'back'-button events. |      * As the navigator-back-button changes the hash first, this class thus also handles the (browser) 'back'-button events. | ||||||
|      * |      * | ||||||
|      * Note that there is no "real" way to intercept the back button, we can only detect the removal of the hash. |      * Note that there is no "real" way to intercept the back button, we can only detect the removal of the hash. | ||||||
|      * As such, we use a change in the hash to close the appropriate windows |      * As such, we use a change in the hash to close the appropriate windows | ||||||
|  | @ -30,6 +31,9 @@ export default class ThemeViewStateHashActor { | ||||||
|      */ |      */ | ||||||
|     constructor(state: ThemeViewState) { |     constructor(state: ThemeViewState) { | ||||||
|         this._state = state |         this._state = state | ||||||
|  |         AndroidPolyfill.onBackButton(() => this.back(), { | ||||||
|  |             returnToIndex: state.featureSwitches.featureSwitchBackToThemeOverview | ||||||
|  |         }) | ||||||
| 
 | 
 | ||||||
|         const hashOnLoad = Hash.hash.data |         const hashOnLoad = Hash.hash.data | ||||||
|         const containsMenu = this.loadStateFromHash(hashOnLoad) |         const containsMenu = this.loadStateFromHash(hashOnLoad) | ||||||
|  | @ -66,6 +70,7 @@ export default class ThemeViewStateHashActor { | ||||||
| 
 | 
 | ||||||
|         // When all is done, set the hash. This must happen last to give the code above correct info
 |         // When all is done, set the hash. This must happen last to give the code above correct info
 | ||||||
|         this.setHash() |         this.setHash() | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|  | @ -137,15 +142,26 @@ export default class ThemeViewStateHashActor { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Returns 'true' if an action was taken | ||||||
|  |      * @private | ||||||
|  |      */ | ||||||
|     private back() { |     private back() { | ||||||
|  |         console.log("Received back!") | ||||||
|         const state = this._state |         const state = this._state | ||||||
|         if (state.previewedImage.data) { |         if (state.previewedImage.data) { | ||||||
|             state.previewedImage.setData(undefined) |             state.previewedImage.setData(undefined) | ||||||
|             return |             return true | ||||||
|         } |         } | ||||||
|         if (state.guistate.closeAll()) { |         if (state.guistate.closeAll()) { | ||||||
|             return |             return true | ||||||
|         } |         } | ||||||
|         state.selectedElement.setData(undefined) |         if (state.selectedElement.data) { | ||||||
|  |             state.selectedElement.setData(undefined) | ||||||
|  |             return true | ||||||
|  |         } | ||||||
|  |         return false | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue