Refactoring: overhaul of the visual style with CSS

This commit is contained in:
Pieter Vander Vennet 2023-05-11 02:17:41 +02:00
parent a1f5032232
commit 7f1e8d3f9c
37 changed files with 1280 additions and 741 deletions

View file

@ -3,36 +3,30 @@
import {UIEventSource} from "../../Logic/UIEventSource"
import Constants from "../../Models/Constants"
import Svg from "../../Svg"
import SubtleButton from "../Base/SubtleButton.svelte"
import ToSvelte from "../Base/ToSvelte.svelte"
import Translations from "../i18n/Translations"
import SubtleLink from "../Base/SubtleLink.svelte";
import Tr from "../Base/Tr.svelte";
export let userDetails: UIEventSource<UserDetails>
const t = Translations.t.general.morescreen
console.log($userDetails.csCount < 50)
</script>
<div>
{#if $userDetails.csCount < Constants.userJourney.themeGeneratorReadOnlyUnlock}
<SubtleButton
options={{
url: "https://github.com/pietervdvn/MapComplete/issues",
newTab: true,
}}
<SubtleLink
url="https://github.com/pietervdvn/MapComplete/issues"
newTab={true}
>
<span slot="message">{t.requestATheme.toString()}</span>
</SubtleButton>
<Tr t={t.requestATheme}/>
</SubtleLink>
{:else}
<SubtleButton
options={{
url: "https://pietervdvn.github.io/mc/legacy/070/customGenerator.html",
}}
>
<span slot="image">
<ToSvelte construct={Svg.pencil_svg().SetClass("h-11 w-11 mx-4 bg-red")}/>
</span>
<span slot="message">{t.createYourOwnTheme.toString()}</span>
</SubtleButton>
<SubtleLink href="https://pietervdvn.github.io/mc/legacy/070/customGenerator.html">
<span slot="image">
<ToSvelte construct={Svg.pencil_svg().SetClass("h-11 w-11 mx-4 bg-red")}/>
</span>
<Tr t={t.createYourOwnTheme}/>
</SubtleLink>
{/if}
</div>

View file

@ -109,51 +109,6 @@ export default class MoreScreen extends Combine {
])
}
/**
* Creates a button linking to the given theme
* @private
*/
public static createLinkButton(
state: {
locationControl?: UIEventSource<Loc>
layoutToUse?: LayoutConfig
},
layout: {
id: string
icon: string
title: any
shortDescription: any
definition?: any
mustHaveLanguage?: boolean
},
isCustom: boolean = false
): BaseUIElement {
const url = MoreScreen.createUrlFor(layout, isCustom, state)
let content = new Combine([
new Translation(
layout.title,
!isCustom && !layout.mustHaveLanguage ? "themes:" + layout.id + ".title" : undefined
),
new Translation(layout.shortDescription)?.SetClass("subtle") ?? "",
]).SetClass("overflow-hidden flex flex-col")
if (state.layoutToUse === undefined) {
// Currently on the index screen: we style the buttons equally large
content = new Combine([content]).SetClass("flex flex-col justify-center h-24")
}
return new SubtleButton(layout.icon, content, { url, newTab: false })
}
public static CreateProffessionalSerivesButton() {
const t = Translations.t.professional.indexPage
return new Combine([
new Title(t.hook, 4),
t.hookMore,
new SubtleButton(undefined, t.button, { url: "./professional.html" }),
]).SetClass("flex flex-col border border-gray-300 p-2 rounded-lg")
}
public static MatchesLayout(
layout: {
id: string

View file

@ -17,6 +17,7 @@
import SubtleButton from "../Base/SubtleButton.svelte"
import ToSvelte from "../Base/ToSvelte.svelte"
import Translations from "../i18n/Translations"
import Tr from "../Base/Tr.svelte";
export let search: UIEventSource<string>
@ -30,14 +31,12 @@
search.setData("")
}}
>
<span>
<SubtleButton>
<span slot="image">
<ToSvelte construct={Svg.search_disable_svg().SetClass("w-6 mr-2")} />
</span>
<span slot="message">{t.noSearch.toString()}</span>
<Tr t={t.noSearch} slot="message"/>
</SubtleButton>
</span>
</button>
</span>

View file

@ -1,8 +1,9 @@
<script lang="ts">
import SubtleButton from "../Base/SubtleButton.svelte"
import Title from "../Base/Title"
import ToSvelte from "../Base/ToSvelte.svelte"
import Translations from "../i18n/Translations"
import SubtleLink from "../Base/SubtleLink.svelte";
import Tr from "../Base/Tr.svelte";
const t = Translations.t.professional.indexPage
</script>
@ -12,9 +13,9 @@
<span>
{t.hookMore.toString()}
</span>
<SubtleButton options={{ url: "./professional.html" }}>
<span slot="message">{t.button.toString()}</span>
</SubtleButton>
<SubtleLink href="./professional.html">
<Tr slot="message" t={t.button} />
</SubtleLink>
</div>
<style lang="scss">

View file

@ -1,114 +1,94 @@
<script lang="ts">
import SubtleButton from "../Base/SubtleButton.svelte"
import { Translation } from "../i18n/Translation"
import * as personal from "../../assets/themes/personal/personal.json"
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
import UserDetails, { OsmConnection } from "../../Logic/Osm/OsmConnection"
import Constants from "../../Models/Constants"
import type Loc from "../../Models/Loc"
import type { LayoutInformation } from "../../Models/ThemeConfig/LayoutConfig"
import Tr from "../Base/Tr.svelte"
import {Translation} from "../i18n/Translation"
import * as personal from "../../assets/themes/personal/personal.json"
import {ImmutableStore, Store, UIEventSource} from "../../Logic/UIEventSource"
import UserDetails, {OsmConnection} from "../../Logic/Osm/OsmConnection"
import Constants from "../../Models/Constants"
import type Loc from "../../Models/Loc"
import type {LayoutInformation} from "../../Models/ThemeConfig/LayoutConfig"
import Tr from "../Base/Tr.svelte"
import SubtleLink from "../Base/SubtleLink.svelte";
export let theme: LayoutInformation
export let isCustom: boolean = false
export let userDetails: UIEventSource<UserDetails>
export let state: { osmConnection: OsmConnection; locationControl?: UIEventSource<Loc> }
export let theme: LayoutInformation
export let isCustom: boolean = false
export let userDetails: UIEventSource<UserDetails>
export let state: { osmConnection: OsmConnection; locationControl?: UIEventSource<Loc> }
$: title = new Translation(
theme.title,
!isCustom && !theme.mustHaveLanguage ? "themes:" + theme.id + ".title" : undefined
)
$: description = new Translation(theme.shortDescription)
// TODO: Improve this function
function createUrl(
layout: { id: string; definition?: string },
isCustom: boolean,
state?: { locationControl?: UIEventSource<{ lat; lon; zoom }>; layoutToUse?: { id } }
): Store<string> {
if (layout === undefined) {
return undefined
}
if (layout.id === undefined) {
console.error("ID is undefined for layout", layout)
return undefined
}
if (layout.id === state?.layoutToUse?.id) {
return undefined
}
const currentLocation = state?.locationControl
let path = window.location.pathname
// Path starts with a '/' and contains everything, e.g. '/dir/dir/page.html'
path = path.substr(0, path.lastIndexOf("/"))
// Path will now contain '/dir/dir', or empty string in case of nothing
if (path === "") {
path = "."
}
let linkPrefix = `${path}/${layout.id.toLowerCase()}.html?`
if (location.hostname === "localhost" || location.hostname === "127.0.0.1" || location.port === "1234") {
// Redirect to 'theme.html?layout=* instead of 'layout.html'. This is probably a debug run, where the routing does not work
linkPrefix = `${path}/theme.html?layout=${layout.id}&`
}
if (isCustom) {
linkPrefix = `${path}/theme.html?userlayout=${layout.id}&`
}
let hash = ""
if (layout.definition !== undefined) {
hash = "#" + btoa(JSON.stringify(layout.definition))
}
return (
currentLocation?.map((currentLocation) => {
const params = [
["z", currentLocation?.zoom],
["lat", currentLocation?.lat],
["lon", currentLocation?.lon],
]
.filter((part) => part[1] !== undefined)
.map((part) => part[0] + "=" + part[1])
.join("&")
return `${linkPrefix}${params}${hash}`
}) ?? new ImmutableStore<string>(`${linkPrefix}`)
$: title = new Translation(
theme.title,
!isCustom && !theme.mustHaveLanguage ? "themes:" + theme.id + ".title" : undefined
)
}
$: description = new Translation(theme.shortDescription)
// TODO: Improve this function
function createUrl(
layout: { id: string; definition?: string },
isCustom: boolean,
state?: { locationControl?: UIEventSource<{ lat; lon; zoom }>; layoutToUse?: { id } }
): Store<string> {
if (layout === undefined) {
return undefined
}
if (layout.id === undefined) {
console.error("ID is undefined for layout", layout)
return undefined
}
if (layout.id === state?.layoutToUse?.id) {
return undefined
}
const currentLocation = state?.locationControl
let path = window.location.pathname
// Path starts with a '/' and contains everything, e.g. '/dir/dir/page.html'
path = path.substr(0, path.lastIndexOf("/"))
// Path will now contain '/dir/dir', or empty string in case of nothing
if (path === "") {
path = "."
}
let linkPrefix = `${path}/${layout.id.toLowerCase()}.html?`
if (location.hostname === "localhost" || location.hostname === "127.0.0.1" || location.port === "1234") {
// Redirect to 'theme.html?layout=* instead of 'layout.html'. This is probably a debug run, where the routing does not work
linkPrefix = `${path}/theme.html?layout=${layout.id}&`
}
if (isCustom) {
linkPrefix = `${path}/theme.html?userlayout=${layout.id}&`
}
let hash = ""
if (layout.definition !== undefined) {
hash = "#" + btoa(JSON.stringify(layout.definition))
}
return (
currentLocation?.map((currentLocation) => {
const params = [
["z", currentLocation?.zoom],
["lat", currentLocation?.lat],
["lon", currentLocation?.lon],
]
.filter((part) => part[1] !== undefined)
.map((part) => part[0] + "=" + part[1])
.join("&")
return `${linkPrefix}${params}${hash}`
}) ?? new ImmutableStore<string>(`${linkPrefix}`)
)
}
let href = createUrl(theme, isCustom, state)
</script>
{#if theme.id !== personal.id || $userDetails.csCount > Constants.userJourney.personalLayoutUnlock}
<div>
<SubtleButton options={{ url: createUrl(theme, isCustom, state) }}>
<img slot="image" src={theme.icon} class="block h-11 w-11 bg-red mx-4" alt="" />
<span slot="message" class="message">
<span>
<Tr t={title}></Tr>
<span class="subtle">
<Tr t={description}></Tr>
<SubtleLink href={ $href }>
<img slot="image" src={theme.icon} class="block h-11 w-11 bg-red mx-4" alt=""/>
<span class="flex flex-col text-ellipsis overflow-hidden">
<Tr t={title}/>
<span class="subtle max-h-12">
<Tr t={description}/>
</span>
</span>
</span>
</SubtleButton>
</div>
</SubtleLink>
{/if}
<style lang="scss">
div {
@apply h-32 min-h-[8rem] max-h-32 text-ellipsis overflow-hidden;
span.message {
@apply flex flex-col justify-center h-24;
& > span {
@apply flex flex-col overflow-hidden;
span:nth-child(2) {
@apply text-[#999];
}
}
}
}
</style>

View file

@ -17,7 +17,9 @@
const t = Translations.t.general
const currentIds: Store<string[]> = state.installedUserThemes
const stableIds = Stores.ListStabilized<string>(currentIds)
let customThemes
$: customThemes = Utils.NoNull($stableIds.map((id) => state.GetUnofficialTheme(id)))
$: console.log("Custom themes are", customThemes)
</script>
<ThemesList