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> | ||||
|     }) { | ||||
|         this.perLayer = state.perLayer | ||||
|         const self = this | ||||
|         state.mapProperties.bounds.mapD( | ||||
|             (bbox) => { | ||||
|                 self.update(bbox) | ||||
|                 this.update(bbox) | ||||
|             }, | ||||
|             [state.dataIsLoading] | ||||
|         ) | ||||
|  |  | |||
|  | @ -44,9 +44,9 @@ export class MenuState { | |||
|         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 | ||||
|         // Note: this class is _not_ responsible to update the Hash, @see ThemeViewStateHashActor for this
 | ||||
|         const states = {} | ||||
|  | @ -118,7 +118,7 @@ export class MenuState { | |||
|         if (MenuState.previewedImage.data !== undefined) { | ||||
|             return true | ||||
|         } | ||||
|         if (this._selectedElement.data) { | ||||
|         if (this._selectedElement?.data) { | ||||
|             return true | ||||
|         } | ||||
|         return Object.values(this.pageStates).some((t) => t.data) | ||||
|  |  | |||
|  | @ -27,6 +27,11 @@ | |||
|   import { AndroidPolyfill } from "../Logic/Web/AndroidPolyfill" | ||||
|   import Forgejo from "../assets/svg/Forgejo.svelte" | ||||
|   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")) | ||||
|   const featureSwitches = new OsmConnectionFeatureSwitches() | ||||
|  | @ -39,6 +44,13 @@ | |||
|     ) | ||||
|   }) | ||||
|   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 tu = Translations.t.general | ||||
|   const tr = Translations.t.general.morescreen | ||||
|  | @ -138,20 +150,36 @@ | |||
| </script> | ||||
| 
 | ||||
| <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="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 | ||||
|         clss="self-end max-w-full" | ||||
|         assignTo={state.language} | ||||
|         availableLanguages={t.title.SupportedLanguages()} | ||||
|         preferredLanguages={userLanguages} | ||||
|       /> | ||||
|     </div> | ||||
| 
 | ||||
|     <div class="mt-4 flex"> | ||||
|       <div class="m-3 flex-none"> | ||||
|         <Logo alt="MapComplete Logo" class="h-12 w-12 sm:h-24 sm:w-24" /> | ||||
|       </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"> | ||||
|           <Tr t={t.title} /> | ||||
|         </h1> | ||||
|  | @ -159,10 +187,12 @@ | |||
|           cls="mr-4 text-base font-semibold sm:text-lg md:mt-5 md:text-xl lg:mx-0" | ||||
|           t={Translations.t.index.intro} | ||||
|         /> | ||||
|         <a href="#about"> | ||||
|           <Tr t={Translations.t.index.learnMore} /> | ||||
|           <ChevronDoubleRight class="inline h-4 w-4" /> | ||||
|         </a> | ||||
| 
 | ||||
|         <AccordionSingle> | ||||
|           <Tr slot="header" t={Translations.t.index.about} /> | ||||
|           <Tr cls="link-underline" t={Translations.t.general.aboutMapComplete.intro} /> | ||||
|           <Tr t={tr.streetcomplete} /> | ||||
|         </AccordionSingle> | ||||
|       </div> | ||||
|     </div> | ||||
| 
 | ||||
|  | @ -229,65 +259,15 @@ | |||
|       {/if} | ||||
|     </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"> | ||||
|       v{Constants.vNumber} | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
|   <div class="absolute top-0 w-0 h-0" style="margin-left: -10em"> | ||||
|     <MenuDrawer onlyLink={false} state={menuDrawerState} /> | ||||
|   </div> | ||||
| 
 | ||||
| </main> | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ | |||
|   if (fullscreen) { | ||||
|     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) { | ||||
|     dialogClass += " h-full-child" | ||||
|   } | ||||
|  |  | |||
|  | @ -1,5 +1,4 @@ | |||
| <script lang="ts"> | ||||
|   import type { SpecialVisualizationState } from "../SpecialVisualization" | ||||
|   import Translations from "../i18n/Translations" | ||||
|   import contributors from "../../assets/contributors.json" | ||||
|   import translators from "../../assets/translators.json" | ||||
|  | @ -14,18 +13,21 @@ | |||
|   import { UserGroupIcon } from "@babeard/svelte-heroicons/solid" | ||||
|   import Marker from "../Map/Marker.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 layoutToUse = state.theme | ||||
| 
 | ||||
|   let maintainer: Translation = undefined | ||||
|   if (layoutToUse.credits !== undefined && layoutToUse.credits !== "") { | ||||
|   if (layoutToUse?.credits !== undefined && 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 attrUrl = props.attribution?.url | ||||
|     const attrText = props.attribution?.text | ||||
|  | @ -45,7 +47,7 @@ | |||
|       }) | ||||
|     } | ||||
|     return Translations.t.general.attribution.attributionBackgroundLayer.Subs(props) | ||||
|   }) | ||||
|   }) ?? new ImmutableStore(undefined) | ||||
| 
 | ||||
|   function calculateDataContributions(contributions: Map<string, number>): Translation { | ||||
|     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) | ||||
|   ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,10 +1,7 @@ | |||
| <script lang="ts"> | ||||
|   import Hotkeys from "../Base/Hotkeys" | ||||
|   import { Translation } from "../i18n/Translation" | ||||
|   import { Utils } from "../../Utils" | ||||
|   import Translations from "../i18n/Translations" | ||||
|   import Tr from "../Base/Tr.svelte" | ||||
|   import AccordionSingle from "../Flowbite/AccordionSingle.svelte" | ||||
| 
 | ||||
|   let keys = Hotkeys._docs | ||||
|   const t = Translations.t.hotkeyDocumentation | ||||
|  |  | |||
|  | @ -1,6 +1,4 @@ | |||
| <script lang="ts"> | ||||
|   // All the relevant links | ||||
|   import ThemeViewState from "../../Models/ThemeViewState" | ||||
|   import Translations from "../i18n/Translations" | ||||
|   import { CogIcon, EyeIcon, HeartIcon, TranslateIcon } from "@rgossiaux/svelte-heroicons/solid" | ||||
|   import Page from "../Base/Page.svelte" | ||||
|  | @ -17,7 +15,6 @@ | |||
|   import Mastodon from "../../assets/svg/Mastodon.svelte" | ||||
|   import Liberapay from "../../assets/svg/Liberapay.svelte" | ||||
|   import DocumentMagnifyingGlass from "@babeard/svelte-heroicons/outline/DocumentMagnifyingGlass" | ||||
|   import DocumentChartBar from "@babeard/svelte-heroicons/outline/DocumentChartBar" | ||||
|   import OpenIdEditor from "./OpenIdEditor.svelte" | ||||
|   import OpenJosm from "../Base/OpenJosm.svelte" | ||||
|   import MapillaryLink from "./MapillaryLink.svelte" | ||||
|  | @ -53,20 +50,37 @@ | |||
|   import MagnifyingGlassCircle from "@babeard/svelte-heroicons/mini/MagnifyingGlassCircle" | ||||
|   import { AndroidPolyfill } from "../../Logic/Web/AndroidPolyfill" | ||||
|   import Forgejo from "../../assets/svg/Forgejo.svelte" | ||||
|   import DocumentArrowUp from "@babeard/svelte-heroicons/mini/DocumentArrowUp" | ||||
|   import ChartBar from "@babeard/svelte-heroicons/solid/ChartBar" | ||||
|   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 usersettingslayer = new LayerConfig(<LayerConfigJson>usersettings, "usersettings", true) | ||||
| 
 | ||||
|   let theme = state.theme | ||||
|   let featureSwitches = state.featureSwitches | ||||
|   let showHome = featureSwitches.featureSwitchBackToThemeOverview | ||||
|   let showHome = featureSwitches?.featureSwitchBackToThemeOverview | ||||
|   let pg = state.guistate.pageStates | ||||
|   let location = state.mapProperties.location | ||||
|   let location = state.mapProperties?.location | ||||
|   export let onlyLink: boolean | ||||
|   const t = Translations.t.general.menu | ||||
|   let shown = new UIEventSource(state.guistate.pageStates.menu.data || !onlyLink) | ||||
|  | @ -143,6 +157,7 @@ | |||
|     </Page> | ||||
| 
 | ||||
|     <LoginToggle {state} silentFail> | ||||
|       {#if state.favourites} | ||||
|         <Page {onlyLink} shown={pg.favourites}> | ||||
|           <svelte:fragment slot="header"> | ||||
|             <HeartIcon /> | ||||
|  | @ -160,6 +175,8 @@ | |||
|             <ReviewsOverview {state} /> | ||||
|           </div> | ||||
|         </Page> | ||||
|       {/if} | ||||
|       {#if $hotkeys.length > 0} | ||||
|         <div class="hidden-on-mobile w-full"> | ||||
|           <Page {onlyLink} shown={pg.hotkeys}> | ||||
|             <svelte:fragment slot="header"> | ||||
|  | @ -169,6 +186,7 @@ | |||
|             <HotkeyTable /> | ||||
|           </Page> | ||||
|         </div> | ||||
|       {/if} | ||||
| 
 | ||||
|       <div class="self-end"> | ||||
|         <LogoutButton osmConnection={state.osmConnection} /> | ||||
|  | @ -178,6 +196,7 @@ | |||
|   </SidebarUnit> | ||||
| 
 | ||||
|   <!-- Theme related: documentation links, download, ... --> | ||||
|   {#if state.theme} | ||||
|     <SidebarUnit> | ||||
|       <h3> | ||||
|         <Tr t={t.aboutCurrentThemeTitle} /> | ||||
|  | @ -207,7 +226,7 @@ | |||
|         <ShareScreen {state} /> | ||||
|       </Page> | ||||
| 
 | ||||
|     {#if state.featureSwitches.featureSwitchEnableExport} | ||||
|       {#if state.featureSwitches?.featureSwitchEnableExport} | ||||
|         <Page {onlyLink} shown={pg.download}> | ||||
|           <svelte:fragment slot="header"> | ||||
|             <ArrowDownTray /> | ||||
|  | @ -244,8 +263,10 @@ | |||
|         </a> | ||||
|       {/if} | ||||
|     </SidebarUnit> | ||||
|   {/if} | ||||
| 
 | ||||
|   <!-- Other links and tools for the given location: open iD/JOSM; community index, ... --> | ||||
|   {#if state.mapProperties?.location} | ||||
|     <SidebarUnit> | ||||
|       <h3> | ||||
|         <Tr t={t.moreUtilsTitle} /> | ||||
|  | @ -259,7 +280,7 @@ | |||
|         <CommunityIndexView location={state.mapProperties.location} /> | ||||
|       </Page> | ||||
| 
 | ||||
|     <If condition={featureSwitches.featureSwitchEnableLogin}> | ||||
|       <If condition={featureSwitches?.featureSwitchEnableLogin}> | ||||
|         <OpenIdEditor mapProperties={state.mapProperties} /> | ||||
|         <OpenJosm {state} /> | ||||
|         <PanoramaxLink large={false} mapProperties={state.mapProperties} /> | ||||
|  | @ -270,16 +291,8 @@ | |||
|         <ShareIcon /> | ||||
|         <Tr t={t.openHereDifferentApp} /> | ||||
|       </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> | ||||
|   {/if} | ||||
| 
 | ||||
|   <!-- About MC: various outward links, legal info, ... --> | ||||
|   <SidebarUnit> | ||||
|  | @ -293,8 +306,6 @@ | |||
|     </a> | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     <a class="flex" href="mailto:info@mapcomplete.org"> | ||||
|       <EnvelopeOpen class="h-6 w-6" /> | ||||
|       <Tr t={Translations.t.general.attribution.emailCreators} /> | ||||
|  | @ -329,6 +340,27 @@ | |||
|       <Tr t={Translations.t.translations.activateButton} /> | ||||
|     </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> | ||||
|     <h3> | ||||
|  | @ -341,6 +373,7 @@ | |||
|       </svelte:fragment> | ||||
|       <CopyrightPanel {state} /> | ||||
|     </Page> | ||||
|     {#if state?.theme} | ||||
|       <Page {onlyLink} shown={pg.copyright_icons}> | ||||
|         <svelte:fragment slot="header"> | ||||
|           <Copyright /> | ||||
|  | @ -348,6 +381,7 @@ | |||
|         </svelte:fragment> | ||||
|         <CopyrightAllIcons {state} /> | ||||
|       </Page> | ||||
|     {/if} | ||||
| 
 | ||||
|     <Page {onlyLink} shown={pg.privacy}> | ||||
|       <svelte:fragment slot="header"> | ||||
|  | @ -355,6 +389,9 @@ | |||
|         <Tr t={Translations.t.privacy.title} /> | ||||
|       </svelte:fragment> | ||||
|       <PrivacyPolicy {state} /> | ||||
|       <a href="./privacy.html" class="button w-fit float-right" target="_blank"> | ||||
|         <ArrowTopRightOnSquare class="w-8 h-8" /> | ||||
|       </a> | ||||
|     </Page> | ||||
| 
 | ||||
|   </SidebarUnit> | ||||
|  |  | |||
|  | @ -11,11 +11,11 @@ | |||
|   export let compact: boolean = true | ||||
| 
 | ||||
|   const changes: Changes = state.changes | ||||
|   const isUploading: Store<boolean> = changes.isUploading | ||||
|   const errors = changes.errors | ||||
|   const pending = changes.pendingChanges | ||||
|   const isUploading: Store<boolean> = changes?.isUploading | ||||
|   const errors = changes?.errors | ||||
|   const pending = changes?.pendingChanges | ||||
| </script> | ||||
| 
 | ||||
| {#if changes} | ||||
|   <div | ||||
|     class="pointer-events-auto flex flex-col" | ||||
|     on:click={() => changes.flushChanges("Pending changes indicator clicked")} | ||||
|  | @ -56,3 +56,4 @@ | |||
|       </ul> | ||||
|     {/if} | ||||
|   </div> | ||||
| {/if} | ||||
|  |  | |||
|  | @ -3,21 +3,21 @@ | |||
|   import { Stores } from "../../Logic/UIEventSource" | ||||
|   import Tr from "../Base/Tr.svelte" | ||||
|   import Translations from "../i18n/Translations" | ||||
|   import type { SpecialVisualizationState } from "../SpecialVisualization" | ||||
|   import ThemeViewState from "../../Models/ThemeViewState" | ||||
| 
 | ||||
|   /** | ||||
|    * Shows _all_ disabled questions | ||||
|    */ | ||||
|   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>( | ||||
|     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)) | ||||
|   const t = Translations.t.general.questions | ||||
| </script> | ||||
| 
 | ||||
| {#if state.theme} | ||||
|   <h3> | ||||
|     <Tr t={t.disabledTitle} /> | ||||
|   </h3> | ||||
|  | @ -29,3 +29,4 @@ | |||
|       <DisabledQuestionsLayer {state} {layer} /> | ||||
|     {/each} | ||||
|   {/if} | ||||
| {/if} | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ export class SettingsVisualisations { | |||
|                 docs: "A component to set the language of the user interface", | ||||
|                 constr(state: SpecialVisualizationState): SvelteUIElement { | ||||
|                     const availableLanguages = Locale.showLinkToWeblate.map((showTranslations) => | ||||
|                         showTranslations ? LanguageUtils.usedLanguagesSorted : state.theme.language | ||||
|                         showTranslations ? LanguageUtils.usedLanguagesSorted : (state?.theme?.language ?? LanguageUtils.usedLanguagesSorted) | ||||
|                     ) | ||||
|                     return new SvelteUIElement(LanguagePicker, { | ||||
|                         assignTo: state.userRelatedState.language, | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue