forked from MapComplete/MapComplete
		
	Refactoring: port PlantNet-detection to svelte, re-integrate wikipedia component
This commit is contained in:
		
							parent
							
								
									d1aa751e18
								
							
						
					
					
						commit
						5f04a69517
					
				
					 18 changed files with 297 additions and 210 deletions
				
			
		
							
								
								
									
										123
									
								
								src/UI/PlantNet/PlantNet.svelte
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										123
									
								
								src/UI/PlantNet/PlantNet.svelte
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,123 @@ | |||
| <script lang="ts"> | ||||
|   import Translations from "../i18n/Translations"; | ||||
|   import Tr from "../Base/Tr.svelte"; | ||||
|   import PlantNetSpeciesList from "./PlantNetSpeciesList.svelte"; | ||||
|   import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"; | ||||
|   import type { PlantNetSpeciesMatch } from "../../Logic/Web/PlantNet"; | ||||
|   import PlantNet from "../../Logic/Web/PlantNet"; | ||||
|   import { XCircleIcon } from "@babeard/svelte-heroicons/solid"; | ||||
|   import BackButton from "../Base/BackButton.svelte"; | ||||
|   import NextButton from "../Base/NextButton.svelte"; | ||||
|   import WikipediaPanel from "../Wikipedia/WikipediaPanel.svelte"; | ||||
|   import { createEventDispatcher } from "svelte"; | ||||
|   import ToSvelte from "../Base/ToSvelte.svelte"; | ||||
|   import Svg from "../../Svg"; | ||||
| 
 | ||||
|   /** | ||||
|    * The main entry point for the plantnet wizard | ||||
|    */ | ||||
|   const t = Translations.t.plantDetection; | ||||
| 
 | ||||
| 
 | ||||
|   /** | ||||
|    * All the URLs pointing to images of the selected feature. | ||||
|    * We need to feed them into Plantnet when applicable | ||||
|    */ | ||||
|   export let imageUrls: Store<string[]>; | ||||
|   export let onConfirm: (wikidataId: string) => void; | ||||
|   const dispatch = createEventDispatcher<{ selected: string }>(); | ||||
|   let collapsedMode = true; | ||||
|   let options: UIEventSource<PlantNetSpeciesMatch[]> = new UIEventSource<PlantNetSpeciesMatch[]>(undefined); | ||||
| 
 | ||||
|   let error: string = undefined; | ||||
| 
 | ||||
|   /** | ||||
|    * The Wikidata-id of the species to apply | ||||
|    */ | ||||
|   let selectedOption: string; | ||||
| 
 | ||||
|   let done = false; | ||||
| 
 | ||||
|   function speciesSelected(species: PlantNetSpeciesMatch) { | ||||
|     console.log("Selected:", species); | ||||
|     selectedOption = species; | ||||
|   } | ||||
| 
 | ||||
|   async function detectSpecies() { | ||||
|     collapsedMode = false; | ||||
| 
 | ||||
|     try { | ||||
| 
 | ||||
|       const result = await PlantNet.query(imageUrls.data.slice(0, 5)); | ||||
|       options.set(result.results.filter(r => r.score > 0.005).slice(0, 8)); | ||||
|     } catch (e) { | ||||
|       error = e; | ||||
|     } | ||||
|   } | ||||
| </script> | ||||
| 
 | ||||
| <div class="flex flex-col"> | ||||
| 
 | ||||
|   {#if collapsedMode} | ||||
|     <button class="w-full" on:click={detectSpecies}> | ||||
|       <Tr t={t.button} /> | ||||
|     </button> | ||||
|   {:else if $error !== undefined} | ||||
|     <Tr cls="alert" t={t.error.Subs({error})} /> | ||||
|   {:else if $imageUrls.length === 0} | ||||
|     <!-- No urls are available, show the explanation instead--> | ||||
|     <div class=" border-region p-2 mb-1 relative"> | ||||
|       <XCircleIcon class="absolute top-0 right-0 w-8 h-8 m-4 cursor-pointer" | ||||
|                    on:click={() => {collapsedMode = true}}></XCircleIcon> | ||||
|       <Tr t={t.takeImages} /> | ||||
|       <Tr t={ t.howTo.intro} /> | ||||
|       <ul> | ||||
|         <li> | ||||
|           <Tr t={t.howTo.li0} /> | ||||
|         </li> | ||||
|         <li> | ||||
|           <Tr t={t.howTo.li1} /> | ||||
|         </li> | ||||
|         <li> | ||||
|           <Tr t={t.howTo.li2} /> | ||||
|         </li> | ||||
|         <li> | ||||
|           <Tr t={t.howTo.li3} /> | ||||
|         </li> | ||||
|       </ul> | ||||
|     </div> | ||||
|   {:else if selectedOption === undefined} | ||||
|     <PlantNetSpeciesList {options} numberOfImages={$imageUrls.length} | ||||
|                          on:selected={(species) => speciesSelected(species.detail)}> | ||||
|       <XCircleIcon slot="upper-right" class="w-8 h-8 m-4 cursor-pointer" | ||||
|                    on:click={() => {collapsedMode = true}}></XCircleIcon> | ||||
| 
 | ||||
|     </PlantNetSpeciesList> | ||||
|   {:else if !done} | ||||
|     <div class="flex flex-col border-interactive"> | ||||
|       <div class="m-2"> | ||||
| 
 | ||||
|         <WikipediaPanel wikiIds={new ImmutableStore([selectedOption])} /> | ||||
|       </div> | ||||
|       <div class="flex justify-between"> | ||||
|         <BackButton on:click={() => {selectedOption = undefined}}> | ||||
|           <Tr t={t.back} /> | ||||
|         </BackButton> | ||||
|         <NextButton clss="primary shrink-0" on:click={() => { done = true; onConfirm(selectedOption); }} > | ||||
|           <Tr t={t.confirm} /> | ||||
|         </NextButton> | ||||
|       </div> | ||||
|     </div> | ||||
|   {:else} | ||||
|     <!-- done ! --> | ||||
|     <Tr t={t.done} cls="thanks w-full" /> | ||||
|     <BackButton imageClass="w-6 h-6 shrink-0" clss="p-1 m-0" on:click={() => {done = false; selectedOption = undefined}}> | ||||
|       <Tr t={t.tryAgain} /> | ||||
|     </BackButton> | ||||
|   {/if} | ||||
|   <div class="flex p-2 bg-gray-200 rounded-xl self-end"> | ||||
|     <ToSvelte construct={Svg.plantnet_logo_svg().SetClass("w-10 h-10 pr-1 mr-1 bg-white rounded-full")} /> | ||||
|     <Tr t={t.poweredByPlantnet} /> | ||||
|   </div> | ||||
| 
 | ||||
| </div> | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue