forked from MapComplete/MapComplete
		
	UX: enable menu drawer on index page, slightly reorder index page
This commit is contained in:
		
							parent
							
								
									b71f07974e
								
							
						
					
					
						commit
						383eebfdca
					
				
					 10 changed files with 280 additions and 263 deletions
				
			
		|  | @ -16,10 +16,9 @@ export default class ContributorCount { | ||||||
|         perLayer: ReadonlyMap<string, GeoIndexedStore> |         perLayer: ReadonlyMap<string, GeoIndexedStore> | ||||||
|     }) { |     }) { | ||||||
|         this.perLayer = state.perLayer |         this.perLayer = state.perLayer | ||||||
|         const self = this |  | ||||||
|         state.mapProperties.bounds.mapD( |         state.mapProperties.bounds.mapD( | ||||||
|             (bbox) => { |             (bbox) => { | ||||||
|                 self.update(bbox) |                 this.update(bbox) | ||||||
|             }, |             }, | ||||||
|             [state.dataIsLoading] |             [state.dataIsLoading] | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|  | @ -44,9 +44,9 @@ export class MenuState { | ||||||
|         undefined |         undefined | ||||||
|     ) |     ) | ||||||
|     public highlightedUserSetting: UIEventSource<string> = new UIEventSource<string>(undefined) |     public highlightedUserSetting: UIEventSource<string> = new UIEventSource<string>(undefined) | ||||||
|     private readonly _selectedElement: UIEventSource<any> |     private readonly _selectedElement: UIEventSource<any> | undefined | ||||||
| 
 | 
 | ||||||
|     constructor(selectedElement: UIEventSource<any>) { |     constructor(selectedElement: UIEventSource<any> | undefined) { | ||||||
|         this._selectedElement = selectedElement |         this._selectedElement = selectedElement | ||||||
|         // Note: this class is _not_ responsible to update the Hash, @see ThemeViewStateHashActor for this
 |         // Note: this class is _not_ responsible to update the Hash, @see ThemeViewStateHashActor for this
 | ||||||
|         const states = {} |         const states = {} | ||||||
|  | @ -118,7 +118,7 @@ export class MenuState { | ||||||
|         if (MenuState.previewedImage.data !== undefined) { |         if (MenuState.previewedImage.data !== undefined) { | ||||||
|             return true |             return true | ||||||
|         } |         } | ||||||
|         if (this._selectedElement.data) { |         if (this._selectedElement?.data) { | ||||||
|             return true |             return true | ||||||
|         } |         } | ||||||
|         return Object.values(this.pageStates).some((t) => t.data) |         return Object.values(this.pageStates).some((t) => t.data) | ||||||
|  |  | ||||||
|  | @ -27,6 +27,11 @@ | ||||||
|   import { AndroidPolyfill } from "../Logic/Web/AndroidPolyfill" |   import { AndroidPolyfill } from "../Logic/Web/AndroidPolyfill" | ||||||
|   import Forgejo from "../assets/svg/Forgejo.svelte" |   import Forgejo from "../assets/svg/Forgejo.svelte" | ||||||
|   import Locale from "./i18n/Locale" |   import Locale from "./i18n/Locale" | ||||||
|  |   import DrawerLeft from "./Base/DrawerLeft.svelte" | ||||||
|  |   import MenuDrawer from "./BigComponents/MenuDrawer.svelte" | ||||||
|  |   import { MenuState } from "../Models/MenuState" | ||||||
|  |   import { MenuIcon } from "@rgossiaux/svelte-heroicons/solid" | ||||||
|  |   import AccordionSingle from "./Flowbite/AccordionSingle.svelte" | ||||||
| 
 | 
 | ||||||
|   AndroidPolyfill.init().then(() => console.log("Android polyfill setup completed")) |   AndroidPolyfill.init().then(() => console.log("Android polyfill setup completed")) | ||||||
|   const featureSwitches = new OsmConnectionFeatureSwitches() |   const featureSwitches = new OsmConnectionFeatureSwitches() | ||||||
|  | @ -39,6 +44,13 @@ | ||||||
|     ) |     ) | ||||||
|   }) |   }) | ||||||
|   const state = new UserRelatedState(osmConnection) |   const state = new UserRelatedState(osmConnection) | ||||||
|  |   const guistate = new MenuState(undefined) | ||||||
|  |   const menuDrawerState = { | ||||||
|  |     guistate, osmConnection, | ||||||
|  |     userRelatedState: state, | ||||||
|  |     featureSwitches: { featureSwitchEnableLogin: new UIEventSource(true) } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   const t = Translations.t.index |   const t = Translations.t.index | ||||||
|   const tu = Translations.t.general |   const tu = Translations.t.general | ||||||
|   const tr = Translations.t.general.morescreen |   const tr = Translations.t.general.morescreen | ||||||
|  | @ -138,20 +150,36 @@ | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <main> | <main> | ||||||
|  |   <div class="absolute h-screen w-screen bg-white top-0 left-0" style="z-index: -1;"></div> | ||||||
|  | 
 | ||||||
|  |   <div class="h-full overflow-hidden"> | ||||||
|  |     <DrawerLeft shown={guistate.pageStates.menu}> | ||||||
|  |       <div class="h-screen overflow-y-auto"> | ||||||
|  |         <MenuDrawer onlyLink={true} state={menuDrawerState} /> | ||||||
|  |       </div> | ||||||
|  |     </DrawerLeft> | ||||||
|  |   </div> | ||||||
|  | 
 | ||||||
|   <div class="m-4 flex flex-col"> |   <div class="m-4 flex flex-col"> | ||||||
|  |     <div class="w-ful flex justify-between"> | ||||||
|  |       <button on:click={() => guistate.pageStates.menu.set(true)} class="rounded-full m-0 p-2"> | ||||||
|  |         <MenuIcon class="h-6 w-6 cursor-pointer" /> | ||||||
|  |       </button> | ||||||
|  | 
 | ||||||
|       <LanguagePicker |       <LanguagePicker | ||||||
|         clss="self-end max-w-full" |         clss="self-end max-w-full" | ||||||
|         assignTo={state.language} |         assignTo={state.language} | ||||||
|         availableLanguages={t.title.SupportedLanguages()} |         availableLanguages={t.title.SupportedLanguages()} | ||||||
|         preferredLanguages={userLanguages} |         preferredLanguages={userLanguages} | ||||||
|       /> |       /> | ||||||
|  |     </div> | ||||||
| 
 | 
 | ||||||
|     <div class="mt-4 flex"> |     <div class="mt-4 flex"> | ||||||
|       <div class="m-3 flex-none"> |       <div class="m-3 flex-none"> | ||||||
|         <Logo alt="MapComplete Logo" class="h-12 w-12 sm:h-24 sm:w-24" /> |         <Logo alt="MapComplete Logo" class="h-12 w-12 sm:h-24 sm:w-24" /> | ||||||
|       </div> |       </div> | ||||||
| 
 | 
 | ||||||
|       <div class="link-underline flex flex-col"> |       <div class="link-underline flex flex-col w-full"> | ||||||
|         <h1 class="m-0 font-extrabold tracking-tight md:text-6xl"> |         <h1 class="m-0 font-extrabold tracking-tight md:text-6xl"> | ||||||
|           <Tr t={t.title} /> |           <Tr t={t.title} /> | ||||||
|         </h1> |         </h1> | ||||||
|  | @ -159,10 +187,12 @@ | ||||||
|           cls="mr-4 text-base font-semibold sm:text-lg md:mt-5 md:text-xl lg:mx-0" |           cls="mr-4 text-base font-semibold sm:text-lg md:mt-5 md:text-xl lg:mx-0" | ||||||
|           t={Translations.t.index.intro} |           t={Translations.t.index.intro} | ||||||
|         /> |         /> | ||||||
|         <a href="#about"> | 
 | ||||||
|           <Tr t={Translations.t.index.learnMore} /> |         <AccordionSingle> | ||||||
|           <ChevronDoubleRight class="inline h-4 w-4" /> |           <Tr slot="header" t={Translations.t.index.about} /> | ||||||
|         </a> |           <Tr cls="link-underline" t={Translations.t.general.aboutMapComplete.intro} /> | ||||||
|  |           <Tr t={tr.streetcomplete} /> | ||||||
|  |         </AccordionSingle> | ||||||
|       </div> |       </div> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|  | @ -229,65 +259,15 @@ | ||||||
|       {/if} |       {/if} | ||||||
|     </LoginToggle> |     </LoginToggle> | ||||||
| 
 | 
 | ||||||
|     <a |  | ||||||
|       class="button flex" |  | ||||||
|       href={window.location.protocol + "//" + window.location.host + "/studio.html"} |  | ||||||
|     > |  | ||||||
|       <Pencil class="mr-2 h-6 w-6" /> |  | ||||||
|       <Tr t={Translations.t.general.morescreen.createYourOwnTheme} /> |  | ||||||
|     </a> |  | ||||||
| 
 | 
 | ||||||
|     <h3 id="about"> |  | ||||||
|       <Tr t={Translations.t.index.about} /> |  | ||||||
|     </h3> |  | ||||||
|     <Tr cls="link-underline" t={Translations.t.general.aboutMapComplete.intro} /> |  | ||||||
| 
 |  | ||||||
|     <span class="link-underline flex flex-col gap-y-1"> |  | ||||||
|       <a |  | ||||||
|         class="flex" |  | ||||||
|         href="https://source.mapcomplete.org/MapComplete/MapComplete/" |  | ||||||
|         target="_blank" |  | ||||||
|       > |  | ||||||
|         <Forgejo class="mr-2 h-6 w-6" /> |  | ||||||
|         <Tr t={Translations.t.general.attribution.gotoSourceCode} /> |  | ||||||
|       </a> |  | ||||||
|       <a |  | ||||||
|         class="flex" |  | ||||||
|         href="https://source.mapcomplete.org/MapComplete/MapComplete/issues" |  | ||||||
|         target="_blank" |  | ||||||
|       > |  | ||||||
|         <Bug class="mr-2 h-6 w-6" /> |  | ||||||
|         <Tr t={Translations.t.general.attribution.openIssueTracker} /> |  | ||||||
|       </a> |  | ||||||
| 
 |  | ||||||
|       <a class="flex" href={Utils.OsmChaLinkFor(7)} target="_blank"> |  | ||||||
|         <ArrowTrendingUp class="mr-2 h-6 w-6" /> |  | ||||||
|         <Tr t={Translations.t.general.attribution.openOsmchaLastWeek} /> |  | ||||||
|       </a> |  | ||||||
| 
 |  | ||||||
|       <a class="flex" href="https://en.osm.town/@MapComplete" target="_blank"> |  | ||||||
|         <Mastodon class="mr-2 h-6 w-6" /> |  | ||||||
|         <Tr t={Translations.t.general.attribution.followOnMastodon} /> |  | ||||||
|       </a> |  | ||||||
| 
 |  | ||||||
|       <a class="flex" href="https://liberapay.com/pietervdvn/" target="_blank"> |  | ||||||
|         <Liberapay class="mr-2 h-6 w-6" /> |  | ||||||
|         <Tr t={Translations.t.general.attribution.donate} /> |  | ||||||
|       </a> |  | ||||||
| 
 |  | ||||||
|       <a |  | ||||||
|         class="flex" |  | ||||||
|         href={window.location.protocol + "//" + window.location.host + "/privacy.html"} |  | ||||||
|       > |  | ||||||
|         <Eye class="mr-2 h-6 w-6" /> |  | ||||||
|         <Tr t={Translations.t.privacy.title} /> |  | ||||||
|       </a> |  | ||||||
|     </span> |  | ||||||
| 
 |  | ||||||
|     <Tr t={tr.streetcomplete} /> |  | ||||||
| 
 | 
 | ||||||
|     <div class="subtle mb-16 self-end"> |     <div class="subtle mb-16 self-end"> | ||||||
|       v{Constants.vNumber} |       v{Constants.vNumber} | ||||||
|     </div> |     </div> | ||||||
|   </div> |   </div> | ||||||
|  | 
 | ||||||
|  |   <div class="absolute top-0 w-0 h-0" style="margin-left: -10em"> | ||||||
|  |     <MenuDrawer onlyLink={false} state={menuDrawerState} /> | ||||||
|  |   </div> | ||||||
|  | 
 | ||||||
| </main> | </main> | ||||||
|  |  | ||||||
|  | @ -21,7 +21,7 @@ | ||||||
|   if (fullscreen) { |   if (fullscreen) { | ||||||
|     defaultClass = shared |     defaultClass = shared | ||||||
|   } |   } | ||||||
|   let dialogClass = "fixed top-0 start-0 end-0 h-modal inset-0 w-full p-4 flex " + zIndex |   let dialogClass = "fixed top-0 start-0 end-0 h-modal inset-0 w-full p-4 flex class-marker-dialog " + zIndex | ||||||
|   if (fullscreen) { |   if (fullscreen) { | ||||||
|     dialogClass += " h-full-child" |     dialogClass += " h-full-child" | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,4 @@ | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
|   import type { SpecialVisualizationState } from "../SpecialVisualization" |  | ||||||
|   import Translations from "../i18n/Translations" |   import Translations from "../i18n/Translations" | ||||||
|   import contributors from "../../assets/contributors.json" |   import contributors from "../../assets/contributors.json" | ||||||
|   import translators from "../../assets/translators.json" |   import translators from "../../assets/translators.json" | ||||||
|  | @ -14,18 +13,21 @@ | ||||||
|   import { UserGroupIcon } from "@babeard/svelte-heroicons/solid" |   import { UserGroupIcon } from "@babeard/svelte-heroicons/solid" | ||||||
|   import Marker from "../Map/Marker.svelte" |   import Marker from "../Map/Marker.svelte" | ||||||
|   import Forgejo from "../../assets/svg/Forgejo.svelte" |   import Forgejo from "../../assets/svg/Forgejo.svelte" | ||||||
|  |   import type { MapProperties } from "../../Models/MapProperties" | ||||||
|  |   import ThemeConfig from "../../Models/ThemeConfig/ThemeConfig" | ||||||
|  |   import { ImmutableStore } from "../../Logic/UIEventSource" | ||||||
| 
 | 
 | ||||||
|   export let state: SpecialVisualizationState |   export let state: { theme?: ThemeConfig, mapProperties?: MapProperties } | ||||||
| 
 | 
 | ||||||
|   const t = Translations.t.general.attribution |   const t = Translations.t.general.attribution | ||||||
|   const layoutToUse = state.theme |   const layoutToUse = state.theme | ||||||
| 
 | 
 | ||||||
|   let maintainer: Translation = undefined |   let maintainer: Translation = undefined | ||||||
|   if (layoutToUse.credits !== undefined && layoutToUse.credits !== "") { |   if (layoutToUse?.credits !== undefined && layoutToUse?.credits !== "") { | ||||||
|     maintainer = t.themeBy.Subs({ author: layoutToUse.credits }) |     maintainer = t.themeBy.Subs({ author: layoutToUse.credits }) | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   const bgMapAttribution = state.mapProperties.rasterLayer.mapD((layer) => { |   const bgMapAttribution = state.mapProperties?.rasterLayer?.mapD((layer) => { | ||||||
|     const props = layer.properties |     const props = layer.properties | ||||||
|     const attrUrl = props.attribution?.url |     const attrUrl = props.attribution?.url | ||||||
|     const attrText = props.attribution?.text |     const attrText = props.attribution?.text | ||||||
|  | @ -45,7 +47,7 @@ | ||||||
|       }) |       }) | ||||||
|     } |     } | ||||||
|     return Translations.t.general.attribution.attributionBackgroundLayer.Subs(props) |     return Translations.t.general.attribution.attributionBackgroundLayer.Subs(props) | ||||||
|   }) |   }) ?? new ImmutableStore(undefined) | ||||||
| 
 | 
 | ||||||
|   function calculateDataContributions(contributions: Map<string, number>): Translation { |   function calculateDataContributions(contributions: Map<string, number>): Translation { | ||||||
|     if (contributions === undefined) { |     if (contributions === undefined) { | ||||||
|  | @ -81,7 +83,7 @@ | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   const datacontributions = new ContributorCount(state).Contributors.map((counts) => |   const datacontributions = (state.mapProperties ? new ContributorCount(<any>state).Contributors : new ImmutableStore([])).map((counts) => | ||||||
|     calculateDataContributions(counts) |     calculateDataContributions(counts) | ||||||
|   ) |   ) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,10 +1,7 @@ | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
|   import Hotkeys from "../Base/Hotkeys" |   import Hotkeys from "../Base/Hotkeys" | ||||||
|   import { Translation } from "../i18n/Translation" |  | ||||||
|   import { Utils } from "../../Utils" |  | ||||||
|   import Translations from "../i18n/Translations" |   import Translations from "../i18n/Translations" | ||||||
|   import Tr from "../Base/Tr.svelte" |   import Tr from "../Base/Tr.svelte" | ||||||
|   import AccordionSingle from "../Flowbite/AccordionSingle.svelte" |  | ||||||
| 
 | 
 | ||||||
|   let keys = Hotkeys._docs |   let keys = Hotkeys._docs | ||||||
|   const t = Translations.t.hotkeyDocumentation |   const t = Translations.t.hotkeyDocumentation | ||||||
|  |  | ||||||
|  | @ -1,6 +1,4 @@ | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
|   // All the relevant links |  | ||||||
|   import ThemeViewState from "../../Models/ThemeViewState" |  | ||||||
|   import Translations from "../i18n/Translations" |   import Translations from "../i18n/Translations" | ||||||
|   import { CogIcon, EyeIcon, HeartIcon, TranslateIcon } from "@rgossiaux/svelte-heroicons/solid" |   import { CogIcon, EyeIcon, HeartIcon, TranslateIcon } from "@rgossiaux/svelte-heroicons/solid" | ||||||
|   import Page from "../Base/Page.svelte" |   import Page from "../Base/Page.svelte" | ||||||
|  | @ -17,7 +15,6 @@ | ||||||
|   import Mastodon from "../../assets/svg/Mastodon.svelte" |   import Mastodon from "../../assets/svg/Mastodon.svelte" | ||||||
|   import Liberapay from "../../assets/svg/Liberapay.svelte" |   import Liberapay from "../../assets/svg/Liberapay.svelte" | ||||||
|   import DocumentMagnifyingGlass from "@babeard/svelte-heroicons/outline/DocumentMagnifyingGlass" |   import DocumentMagnifyingGlass from "@babeard/svelte-heroicons/outline/DocumentMagnifyingGlass" | ||||||
|   import DocumentChartBar from "@babeard/svelte-heroicons/outline/DocumentChartBar" |  | ||||||
|   import OpenIdEditor from "./OpenIdEditor.svelte" |   import OpenIdEditor from "./OpenIdEditor.svelte" | ||||||
|   import OpenJosm from "../Base/OpenJosm.svelte" |   import OpenJosm from "../Base/OpenJosm.svelte" | ||||||
|   import MapillaryLink from "./MapillaryLink.svelte" |   import MapillaryLink from "./MapillaryLink.svelte" | ||||||
|  | @ -53,20 +50,37 @@ | ||||||
|   import MagnifyingGlassCircle from "@babeard/svelte-heroicons/mini/MagnifyingGlassCircle" |   import MagnifyingGlassCircle from "@babeard/svelte-heroicons/mini/MagnifyingGlassCircle" | ||||||
|   import { AndroidPolyfill } from "../../Logic/Web/AndroidPolyfill" |   import { AndroidPolyfill } from "../../Logic/Web/AndroidPolyfill" | ||||||
|   import Forgejo from "../../assets/svg/Forgejo.svelte" |   import Forgejo from "../../assets/svg/Forgejo.svelte" | ||||||
|   import DocumentArrowUp from "@babeard/svelte-heroicons/mini/DocumentArrowUp" |  | ||||||
|   import ChartBar from "@babeard/svelte-heroicons/solid/ChartBar" |   import ChartBar from "@babeard/svelte-heroicons/solid/ChartBar" | ||||||
|   import QueueList from "@babeard/svelte-heroicons/solid/QueueList" |   import QueueList from "@babeard/svelte-heroicons/solid/QueueList" | ||||||
|  |   import { MenuState } from "../../Models/MenuState" | ||||||
|  |   import { OsmConnection } from "../../Logic/Osm/OsmConnection" | ||||||
|  |   import FeatureSwitchState from "../../Logic/State/FeatureSwitchState" | ||||||
|  |   import ThemeConfig from "../../Models/ThemeConfig/ThemeConfig" | ||||||
|  |   import type { MapProperties } from "../../Models/MapProperties" | ||||||
|  |   import FavouritesFeatureSource from "../../Logic/FeatureSource/Sources/FavouritesFeatureSource" | ||||||
|  |   import Hotkeys from "../Base/Hotkeys" | ||||||
|  |   import { ArrowTrendingUp } from "@babeard/svelte-heroicons/solid/ArrowTrendingUp" | ||||||
|  |   import ArrowTopRightOnSquare from "@babeard/svelte-heroicons/mini/ArrowTopRightOnSquare" | ||||||
| 
 | 
 | ||||||
|   export let state: ThemeViewState |   export let state: { | ||||||
|  |     favourites: FavouritesFeatureSource | ||||||
|  |     guistate: MenuState, | ||||||
|  |     osmConnection: OsmConnection, | ||||||
|  |     theme?: ThemeConfig, | ||||||
|  |     featureSwitches: Partial<FeatureSwitchState>, | ||||||
|  |     mapProperties?: MapProperties, | ||||||
|  |     userRelatedState?: UserRelatedState | ||||||
|  |   } | ||||||
|  |   let hotkeys = Hotkeys._docs | ||||||
|   let userdetails = state.osmConnection.userDetails |   let userdetails = state.osmConnection.userDetails | ||||||
| 
 | 
 | ||||||
|   let usersettingslayer = new LayerConfig(<LayerConfigJson>usersettings, "usersettings", true) |   let usersettingslayer = new LayerConfig(<LayerConfigJson>usersettings, "usersettings", true) | ||||||
| 
 | 
 | ||||||
|   let theme = state.theme |   let theme = state.theme | ||||||
|   let featureSwitches = state.featureSwitches |   let featureSwitches = state.featureSwitches | ||||||
|   let showHome = featureSwitches.featureSwitchBackToThemeOverview |   let showHome = featureSwitches?.featureSwitchBackToThemeOverview | ||||||
|   let pg = state.guistate.pageStates |   let pg = state.guistate.pageStates | ||||||
|   let location = state.mapProperties.location |   let location = state.mapProperties?.location | ||||||
|   export let onlyLink: boolean |   export let onlyLink: boolean | ||||||
|   const t = Translations.t.general.menu |   const t = Translations.t.general.menu | ||||||
|   let shown = new UIEventSource(state.guistate.pageStates.menu.data || !onlyLink) |   let shown = new UIEventSource(state.guistate.pageStates.menu.data || !onlyLink) | ||||||
|  | @ -143,6 +157,7 @@ | ||||||
|     </Page> |     </Page> | ||||||
| 
 | 
 | ||||||
|     <LoginToggle {state} silentFail> |     <LoginToggle {state} silentFail> | ||||||
|  |       {#if state.favourites} | ||||||
|         <Page {onlyLink} shown={pg.favourites}> |         <Page {onlyLink} shown={pg.favourites}> | ||||||
|           <svelte:fragment slot="header"> |           <svelte:fragment slot="header"> | ||||||
|             <HeartIcon /> |             <HeartIcon /> | ||||||
|  | @ -160,6 +175,8 @@ | ||||||
|             <ReviewsOverview {state} /> |             <ReviewsOverview {state} /> | ||||||
|           </div> |           </div> | ||||||
|         </Page> |         </Page> | ||||||
|  |       {/if} | ||||||
|  |       {#if $hotkeys.length > 0} | ||||||
|         <div class="hidden-on-mobile w-full"> |         <div class="hidden-on-mobile w-full"> | ||||||
|           <Page {onlyLink} shown={pg.hotkeys}> |           <Page {onlyLink} shown={pg.hotkeys}> | ||||||
|             <svelte:fragment slot="header"> |             <svelte:fragment slot="header"> | ||||||
|  | @ -169,6 +186,7 @@ | ||||||
|             <HotkeyTable /> |             <HotkeyTable /> | ||||||
|           </Page> |           </Page> | ||||||
|         </div> |         </div> | ||||||
|  |       {/if} | ||||||
| 
 | 
 | ||||||
|       <div class="self-end"> |       <div class="self-end"> | ||||||
|         <LogoutButton osmConnection={state.osmConnection} /> |         <LogoutButton osmConnection={state.osmConnection} /> | ||||||
|  | @ -178,6 +196,7 @@ | ||||||
|   </SidebarUnit> |   </SidebarUnit> | ||||||
| 
 | 
 | ||||||
|   <!-- Theme related: documentation links, download, ... --> |   <!-- Theme related: documentation links, download, ... --> | ||||||
|  |   {#if state.theme} | ||||||
|     <SidebarUnit> |     <SidebarUnit> | ||||||
|       <h3> |       <h3> | ||||||
|         <Tr t={t.aboutCurrentThemeTitle} /> |         <Tr t={t.aboutCurrentThemeTitle} /> | ||||||
|  | @ -207,7 +226,7 @@ | ||||||
|         <ShareScreen {state} /> |         <ShareScreen {state} /> | ||||||
|       </Page> |       </Page> | ||||||
| 
 | 
 | ||||||
|     {#if state.featureSwitches.featureSwitchEnableExport} |       {#if state.featureSwitches?.featureSwitchEnableExport} | ||||||
|         <Page {onlyLink} shown={pg.download}> |         <Page {onlyLink} shown={pg.download}> | ||||||
|           <svelte:fragment slot="header"> |           <svelte:fragment slot="header"> | ||||||
|             <ArrowDownTray /> |             <ArrowDownTray /> | ||||||
|  | @ -244,8 +263,10 @@ | ||||||
|         </a> |         </a> | ||||||
|       {/if} |       {/if} | ||||||
|     </SidebarUnit> |     </SidebarUnit> | ||||||
|  |   {/if} | ||||||
| 
 | 
 | ||||||
|   <!-- Other links and tools for the given location: open iD/JOSM; community index, ... --> |   <!-- Other links and tools for the given location: open iD/JOSM; community index, ... --> | ||||||
|  |   {#if state.mapProperties?.location} | ||||||
|     <SidebarUnit> |     <SidebarUnit> | ||||||
|       <h3> |       <h3> | ||||||
|         <Tr t={t.moreUtilsTitle} /> |         <Tr t={t.moreUtilsTitle} /> | ||||||
|  | @ -259,7 +280,7 @@ | ||||||
|         <CommunityIndexView location={state.mapProperties.location} /> |         <CommunityIndexView location={state.mapProperties.location} /> | ||||||
|       </Page> |       </Page> | ||||||
| 
 | 
 | ||||||
|     <If condition={featureSwitches.featureSwitchEnableLogin}> |       <If condition={featureSwitches?.featureSwitchEnableLogin}> | ||||||
|         <OpenIdEditor mapProperties={state.mapProperties} /> |         <OpenIdEditor mapProperties={state.mapProperties} /> | ||||||
|         <OpenJosm {state} /> |         <OpenJosm {state} /> | ||||||
|         <PanoramaxLink large={false} mapProperties={state.mapProperties} /> |         <PanoramaxLink large={false} mapProperties={state.mapProperties} /> | ||||||
|  | @ -270,16 +291,8 @@ | ||||||
|         <ShareIcon /> |         <ShareIcon /> | ||||||
|         <Tr t={t.openHereDifferentApp} /> |         <Tr t={t.openHereDifferentApp} /> | ||||||
|       </a> |       </a> | ||||||
| 
 |  | ||||||
|     <a |  | ||||||
|       class="flex" |  | ||||||
|       href={window.location.protocol + "//" + window.location.host + "/inspector.html"} |  | ||||||
|     > |  | ||||||
|       <MagnifyingGlassCircle class="mr-2 h-6 w-6" /> |  | ||||||
|       <Tr t={Translations.t.inspector.menu} /> |  | ||||||
|     </a> |  | ||||||
| 
 |  | ||||||
|     </SidebarUnit> |     </SidebarUnit> | ||||||
|  |   {/if} | ||||||
| 
 | 
 | ||||||
|   <!-- About MC: various outward links, legal info, ... --> |   <!-- About MC: various outward links, legal info, ... --> | ||||||
|   <SidebarUnit> |   <SidebarUnit> | ||||||
|  | @ -293,8 +306,6 @@ | ||||||
|     </a> |     </a> | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     <a class="flex" href="mailto:info@mapcomplete.org"> |     <a class="flex" href="mailto:info@mapcomplete.org"> | ||||||
|       <EnvelopeOpen class="h-6 w-6" /> |       <EnvelopeOpen class="h-6 w-6" /> | ||||||
|       <Tr t={Translations.t.general.attribution.emailCreators} /> |       <Tr t={Translations.t.general.attribution.emailCreators} /> | ||||||
|  | @ -329,6 +340,27 @@ | ||||||
|       <Tr t={Translations.t.translations.activateButton} /> |       <Tr t={Translations.t.translations.activateButton} /> | ||||||
|     </a> |     </a> | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |     <a | ||||||
|  |       class="flex" | ||||||
|  |       href={window.location.protocol + "//" + window.location.host + "/inspector.html"} | ||||||
|  |     > | ||||||
|  |       <MagnifyingGlassCircle class="mr-2 h-6 w-6" /> | ||||||
|  |       <Tr t={Translations.t.inspector.menu} /> | ||||||
|  |     </a> | ||||||
|  | 
 | ||||||
|  |     {#if !state.theme} | ||||||
|  |       <a class="flex" href={`./statistics.html"}`} | ||||||
|  |          target="_blank"> | ||||||
|  |         <ChartBar class="h-6 w-6" /> | ||||||
|  |         <Tr t={Translations.t.general.attribution.openStatistics.Subs({theme: "MapComplete"})} /> | ||||||
|  |       </a> | ||||||
|  |     {/if} | ||||||
|  | 
 | ||||||
|  |     <a class="flex" href={Utils.OsmChaLinkFor(7)} target="_blank"> | ||||||
|  |       <ArrowTrendingUp class="mr-2 h-6 w-6" /> | ||||||
|  |       <Tr t={Translations.t.general.attribution.openOsmchaLastWeek} /> | ||||||
|  |     </a> | ||||||
|   </SidebarUnit> |   </SidebarUnit> | ||||||
|   <SidebarUnit> |   <SidebarUnit> | ||||||
|     <h3> |     <h3> | ||||||
|  | @ -341,6 +373,7 @@ | ||||||
|       </svelte:fragment> |       </svelte:fragment> | ||||||
|       <CopyrightPanel {state} /> |       <CopyrightPanel {state} /> | ||||||
|     </Page> |     </Page> | ||||||
|  |     {#if state?.theme} | ||||||
|       <Page {onlyLink} shown={pg.copyright_icons}> |       <Page {onlyLink} shown={pg.copyright_icons}> | ||||||
|         <svelte:fragment slot="header"> |         <svelte:fragment slot="header"> | ||||||
|           <Copyright /> |           <Copyright /> | ||||||
|  | @ -348,6 +381,7 @@ | ||||||
|         </svelte:fragment> |         </svelte:fragment> | ||||||
|         <CopyrightAllIcons {state} /> |         <CopyrightAllIcons {state} /> | ||||||
|       </Page> |       </Page> | ||||||
|  |     {/if} | ||||||
| 
 | 
 | ||||||
|     <Page {onlyLink} shown={pg.privacy}> |     <Page {onlyLink} shown={pg.privacy}> | ||||||
|       <svelte:fragment slot="header"> |       <svelte:fragment slot="header"> | ||||||
|  | @ -355,6 +389,9 @@ | ||||||
|         <Tr t={Translations.t.privacy.title} /> |         <Tr t={Translations.t.privacy.title} /> | ||||||
|       </svelte:fragment> |       </svelte:fragment> | ||||||
|       <PrivacyPolicy {state} /> |       <PrivacyPolicy {state} /> | ||||||
|  |       <a href="./privacy.html" class="button w-fit float-right" target="_blank"> | ||||||
|  |         <ArrowTopRightOnSquare class="w-8 h-8" /> | ||||||
|  |       </a> | ||||||
|     </Page> |     </Page> | ||||||
| 
 | 
 | ||||||
|   </SidebarUnit> |   </SidebarUnit> | ||||||
|  |  | ||||||
|  | @ -11,15 +11,15 @@ | ||||||
|   export let compact: boolean = true |   export let compact: boolean = true | ||||||
| 
 | 
 | ||||||
|   const changes: Changes = state.changes |   const changes: Changes = state.changes | ||||||
|   const isUploading: Store<boolean> = changes.isUploading |   const isUploading: Store<boolean> = changes?.isUploading | ||||||
|   const errors = changes.errors |   const errors = changes?.errors | ||||||
|   const pending = changes.pendingChanges |   const pending = changes?.pendingChanges | ||||||
| </script> | </script> | ||||||
| 
 | {#if changes} | ||||||
| <div |   <div | ||||||
|     class="pointer-events-auto flex flex-col" |     class="pointer-events-auto flex flex-col" | ||||||
|     on:click={() => changes.flushChanges("Pending changes indicator clicked")} |     on:click={() => changes.flushChanges("Pending changes indicator clicked")} | ||||||
| > |   > | ||||||
|     {#if $isUploading} |     {#if $isUploading} | ||||||
|       <Loading> |       <Loading> | ||||||
|         <Tr cls="thx" t={Translations.t.general.uploadingChanges} /> |         <Tr cls="thx" t={Translations.t.general.uploadingChanges} /> | ||||||
|  | @ -55,4 +55,5 @@ | ||||||
|         {/each} |         {/each} | ||||||
|       </ul> |       </ul> | ||||||
|     {/if} |     {/if} | ||||||
| </div> |   </div> | ||||||
|  | {/if} | ||||||
|  |  | ||||||
|  | @ -3,29 +3,30 @@ | ||||||
|   import { Stores } from "../../Logic/UIEventSource" |   import { Stores } from "../../Logic/UIEventSource" | ||||||
|   import Tr from "../Base/Tr.svelte" |   import Tr from "../Base/Tr.svelte" | ||||||
|   import Translations from "../i18n/Translations" |   import Translations from "../i18n/Translations" | ||||||
|   import type { SpecialVisualizationState } from "../SpecialVisualization" |  | ||||||
|   import ThemeViewState from "../../Models/ThemeViewState" |   import ThemeViewState from "../../Models/ThemeViewState" | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|    * Shows _all_ disabled questions |    * Shows _all_ disabled questions | ||||||
|    */ |    */ | ||||||
|   export let state: ThemeViewState |   export let state: ThemeViewState | ||||||
|   let layers = state.theme.layers.filter((l) => l.isNormal()) |   let layers = state.theme?.layers?.filter((l) => l.isNormal()) | ||||||
| 
 | 
 | ||||||
|   let allDisabled = Stores.concat<string>( |   let allDisabled = Stores.concat<string>( | ||||||
|     layers.map((l) => state.userRelatedState.getThemeDisabled(state.theme.id, l.id)) |     layers?.map((l) => state.userRelatedState.getThemeDisabled(state.theme.id, l.id)) ?? [] | ||||||
|   ).map((l) => [].concat(...l)) |   ).map((l) => [].concat(...l)) | ||||||
|   const t = Translations.t.general.questions |   const t = Translations.t.general.questions | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <h3> | {#if state.theme} | ||||||
|  |   <h3> | ||||||
|     <Tr t={t.disabledTitle} /> |     <Tr t={t.disabledTitle} /> | ||||||
| </h3> |   </h3> | ||||||
| {#if $allDisabled.length === 0} |   {#if $allDisabled.length === 0} | ||||||
|     <Tr t={t.noneDisabled} /> |     <Tr t={t.noneDisabled} /> | ||||||
| {:else} |   {:else} | ||||||
|     <Tr t={t.disabledIntro} /> |     <Tr t={t.disabledIntro} /> | ||||||
|     {#each layers as layer (layer.id)} |     {#each layers as layer (layer.id)} | ||||||
|       <DisabledQuestionsLayer {state} {layer} /> |       <DisabledQuestionsLayer {state} {layer} /> | ||||||
|     {/each} |     {/each} | ||||||
|  |   {/if} | ||||||
| {/if} | {/if} | ||||||
|  |  | ||||||
|  | @ -24,7 +24,7 @@ export class SettingsVisualisations { | ||||||
|                 docs: "A component to set the language of the user interface", |                 docs: "A component to set the language of the user interface", | ||||||
|                 constr(state: SpecialVisualizationState): SvelteUIElement { |                 constr(state: SpecialVisualizationState): SvelteUIElement { | ||||||
|                     const availableLanguages = Locale.showLinkToWeblate.map((showTranslations) => |                     const availableLanguages = Locale.showLinkToWeblate.map((showTranslations) => | ||||||
|                         showTranslations ? LanguageUtils.usedLanguagesSorted : state.theme.language |                         showTranslations ? LanguageUtils.usedLanguagesSorted : (state?.theme?.language ?? LanguageUtils.usedLanguagesSorted) | ||||||
|                     ) |                     ) | ||||||
|                     return new SvelteUIElement(LanguagePicker, { |                     return new SvelteUIElement(LanguagePicker, { | ||||||
|                         assignTo: state.userRelatedState.language, |                         assignTo: state.userRelatedState.language, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue