Further fixing the refactoring

This commit is contained in:
Pieter Vander Vennet 2021-06-13 15:04:55 +02:00
parent 3943100e54
commit 49c821268e
8 changed files with 66 additions and 86 deletions

View file

@ -1,4 +1,3 @@
import {UIElement} from "../UIElement";
import State from "../../State"; import State from "../../State";
import ThemeIntroductionPanel from "./ThemeIntroductionPanel"; import ThemeIntroductionPanel from "./ThemeIntroductionPanel";
import * as personal from "../../assets/themes/personalLayout/personalLayout.json"; import * as personal from "../../assets/themes/personalLayout/personalLayout.json";
@ -7,16 +6,15 @@ import Svg from "../../Svg";
import Translations from "../i18n/Translations"; import Translations from "../i18n/Translations";
import ShareScreen from "./ShareScreen"; import ShareScreen from "./ShareScreen";
import MoreScreen from "./MoreScreen"; import MoreScreen from "./MoreScreen";
import {VariableUiElement} from "../Base/VariableUIElement";
import Constants from "../../Models/Constants"; import Constants from "../../Models/Constants";
import Combine from "../Base/Combine"; import Combine from "../Base/Combine";
import Locale from "../i18n/Locale";
import {TabbedComponent} from "../Base/TabbedComponent"; import {TabbedComponent} from "../Base/TabbedComponent";
import {UIEventSource} from "../../Logic/UIEventSource"; import {UIEventSource} from "../../Logic/UIEventSource";
import LayoutConfig from "../../Customizations/JSON/LayoutConfig"; import LayoutConfig from "../../Customizations/JSON/LayoutConfig";
import UserDetails from "../../Logic/Osm/OsmConnection"; import UserDetails from "../../Logic/Osm/OsmConnection";
import ScrollableFullScreen from "../Base/ScrollableFullScreen"; import ScrollableFullScreen from "../Base/ScrollableFullScreen";
import BaseUIElement from "../BaseUIElement"; import BaseUIElement from "../BaseUIElement";
import Toggle from "../Input/Toggle";
export default class FullWelcomePaneWithTabs extends ScrollableFullScreen { export default class FullWelcomePaneWithTabs extends ScrollableFullScreen {
@ -32,11 +30,11 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen {
private static GenerateContents(layoutToUse: LayoutConfig, userDetails: UIEventSource<UserDetails>) { private static GenerateContents(layoutToUse: LayoutConfig, userDetails: UIEventSource<UserDetails>) {
let welcome: UIElement = new ThemeIntroductionPanel(); let welcome: BaseUIElement = new ThemeIntroductionPanel();
if (layoutToUse.id === personal.id) { if (layoutToUse.id === personal.id) {
welcome = new PersonalLayersPanel(); welcome = new PersonalLayersPanel();
} }
const tabs : {header: string | BaseUIElement, content: BaseUIElement}[] = [ const tabs: { header: string | BaseUIElement, content: BaseUIElement }[] = [
{header: `<img src='${layoutToUse.icon}'>`, content: welcome}, {header: `<img src='${layoutToUse.icon}'>`, content: welcome},
{ {
header: Svg.osm_logo_img, header: Svg.osm_logo_img,
@ -58,19 +56,20 @@ export default class FullWelcomePaneWithTabs extends ScrollableFullScreen {
} }
tabs.push({ const tabsWithAboutMc = [...tabs]
tabsWithAboutMc.push({
header: Svg.help, header: Svg.help,
content: new VariableUiElement(userDetails.map(userdetails => { content: new Combine([Translations.t.general.aboutMapcomplete.Clone(), "<br/>Version " + Constants.vNumber])
if (userdetails.csCount < Constants.userJourney.mapCompleteHelpUnlock) { .SetClass("link-underline")
return ""
}
return new Combine([Translations.t.general.aboutMapcomplete, "<br/>Version " + Constants.vNumber]).SetClass("link-underline");
}, [Locale.language]))
} }
); );
return new TabbedComponent(tabs, State.state.welcomeMessageOpenedTab); return new Toggle(
new TabbedComponent(tabs, State.state.welcomeMessageOpenedTab),
new TabbedComponent(tabsWithAboutMc, State.state.welcomeMessageOpenedTab),
userDetails.map(userdetails =>
userdetails.csCount < Constants.userJourney.mapCompleteHelpUnlock)
)
} }
} }

View file

@ -21,7 +21,7 @@ export default class MoreScreen extends Combine {
private static Init(onMainScreen: boolean, state: State): BaseUIElement [] { private static Init(onMainScreen: boolean, state: State): BaseUIElement [] {
const tr = Translations.t.general.morescreen; const tr = Translations.t.general.morescreen;
let intro: BaseUIElement = tr.intro; let intro: BaseUIElement = tr.intro.Clone();
let themeButtonStyle = "" let themeButtonStyle = ""
let themeListStyle = "" let themeListStyle = ""
if (onMainScreen) { if (onMainScreen) {
@ -38,7 +38,7 @@ export default class MoreScreen extends Combine {
intro, intro,
MoreScreen.createOfficialThemesList(state, themeButtonStyle).SetClass(themeListStyle), MoreScreen.createOfficialThemesList(state, themeButtonStyle).SetClass(themeListStyle),
MoreScreen.createUnofficialThemeList(themeButtonStyle)?.SetClass(themeListStyle), MoreScreen.createUnofficialThemeList(themeButtonStyle)?.SetClass(themeListStyle),
tr.streetcomplete.SetClass("block text-base mx-10 my-3 mb-10") tr.streetcomplete.Clone().SetClass("block text-base mx-10 my-3 mb-10")
]; ];
} }
@ -77,12 +77,12 @@ export default class MoreScreen extends Combine {
return new VariableUiElement( return new VariableUiElement(
state.osmConnection.userDetails.map(userDetails => { state.osmConnection.userDetails.map(userDetails => {
if (userDetails.csCount < Constants.userJourney.themeGeneratorReadOnlyUnlock) { if (userDetails.csCount < Constants.userJourney.themeGeneratorReadOnlyUnlock) {
return new SubtleButton(null, tr.requestATheme, { return new SubtleButton(null, tr.requestATheme.Clone(), {
url: "https://github.com/pietervdvn/MapComplete/issues", url: "https://github.com/pietervdvn/MapComplete/issues",
newTab: true newTab: true
}); });
} }
return new SubtleButton(Svg.pencil_ui(), tr.createYourOwnTheme, { return new SubtleButton(Svg.pencil_ui(), tr.createYourOwnTheme.Clone(), {
url: "./customGenerator.html", url: "./customGenerator.html",
newTab: false newTab: false
}); });
@ -146,14 +146,14 @@ export default class MoreScreen extends Combine {
let description = Translations.W(layout.shortDescription); let description = Translations.WT(layout.shortDescription).Clone();
return new SubtleButton(layout.icon, return new SubtleButton(layout.icon,
new Combine([ new Combine([
`<dt class='text-lg leading-6 font-medium text-gray-900 group-hover:text-blue-800'>`, `<dt class='text-lg leading-6 font-medium text-gray-900 group-hover:text-blue-800'>`,
Translations.W(layout.title), Translations.WT(layout.title).Clone(),
`</dt>`, `</dt>`,
`<dd class='mt-1 text-base text-gray-500 group-hover:text-blue-900 overflow-ellipsis'>`, `<dd class='mt-1 text-base text-gray-500 group-hover:text-blue-900 overflow-ellipsis'>`,
description ?? "", description.Clone().SetClass("subtle") ?? "",
`</dd>`, `</dd>`,
]), {url: linkText, newTab: false}); ]), {url: linkText, newTab: false});
} }

View file

@ -1,4 +1,3 @@
import {UIElement} from "../UIElement";
import {VariableUiElement} from "../Base/VariableUIElement"; import {VariableUiElement} from "../Base/VariableUIElement";
import {Translation} from "../i18n/Translation"; import {Translation} from "../i18n/Translation";
import LayoutConfig from "../../Customizations/JSON/LayoutConfig"; import LayoutConfig from "../../Customizations/JSON/LayoutConfig";
@ -15,23 +14,16 @@ import Constants from "../../Models/Constants";
import LayerConfig from "../../Customizations/JSON/LayerConfig"; import LayerConfig from "../../Customizations/JSON/LayerConfig";
import BaseUIElement from "../BaseUIElement"; import BaseUIElement from "../BaseUIElement";
export default class ShareScreen extends UIElement { export default class ShareScreen extends Combine {
private readonly _options: BaseUIElement;
private readonly _iframeCode: BaseUIElement;
public iframe: UIEventSource<string>;
private readonly _link: BaseUIElement;
private readonly _linkStatus: UIEventSource<string | BaseUIElement>;
private readonly _editLayout: BaseUIElement;
constructor(layout: LayoutConfig = undefined, layoutDefinition: string = undefined) { constructor(layout: LayoutConfig = undefined, layoutDefinition: string = undefined) {
super(undefined)
layout = layout ?? State.state?.layoutToUse?.data; layout = layout ?? State.state?.layoutToUse?.data;
layoutDefinition = layoutDefinition ?? State.state?.layoutDefinition; layoutDefinition = layoutDefinition ?? State.state?.layoutDefinition;
const tr = Translations.t.general.sharescreen; const tr = Translations.t.general.sharescreen;
const optionCheckboxes: BaseUIElement[] = [] const optionCheckboxes: BaseUIElement[] = []
const optionParts: (UIEventSource<string>)[] = []; const optionParts: (UIEventSource<string>)[] = [];
this.SetClass("link-underline")
function check() { function check() {
return Svg.checkmark_svg().SetStyle("width: 1.5em; display:inline-block;"); return Svg.checkmark_svg().SetStyle("width: 1.5em; display:inline-block;");
} }
@ -41,8 +33,8 @@ export default class ShareScreen extends UIElement {
} }
const includeLocation = new Toggle( const includeLocation = new Toggle(
new Combine([check(), tr.fsIncludeCurrentLocation]), new Combine([check(), tr.fsIncludeCurrentLocation.Clone()]),
new Combine([nocheck(), tr.fsIncludeCurrentLocation]), new Combine([nocheck(), tr.fsIncludeCurrentLocation.Clone()]),
new UIEventSource<boolean>(true) new UIEventSource<boolean>(true)
) )
optionCheckboxes.push(includeLocation); optionCheckboxes.push(includeLocation);
@ -91,8 +83,8 @@ export default class ShareScreen extends UIElement {
const includeLayerChoices = new Toggle( const includeLayerChoices = new Toggle(
new Combine([check(), tr.fsIncludeCurrentLayers]), new Combine([check(), tr.fsIncludeCurrentLayers.Clone()]),
new Combine([nocheck(), tr.fsIncludeCurrentLayers]), new Combine([nocheck(), tr.fsIncludeCurrentLayers.Clone()]),
new UIEventSource<boolean>(true) new UIEventSource<boolean>(true)
) )
optionCheckboxes.push(includeLayerChoices); optionCheckboxes.push(includeLayerChoices);
@ -121,8 +113,8 @@ export default class ShareScreen extends UIElement {
for (const swtch of switches) { for (const swtch of switches) {
const checkbox = new Toggle( const checkbox = new Toggle(
new Combine([check(), Translations.W(swtch.human)]), new Combine([check(), Translations.W(swtch.human.Clone())]),
new Combine([nocheck(), Translations.W(swtch.human)]), new Combine([nocheck(), Translations.W(swtch.human.Clone())]),
new UIEventSource<boolean>(!swtch.reverse) new UIEventSource<boolean>(!swtch.reverse)
); );
optionCheckboxes.push(checkbox); optionCheckboxes.push(checkbox);
@ -144,7 +136,7 @@ export default class ShareScreen extends UIElement {
} }
this._options = new Combine(optionCheckboxes).SetClass("flex flex-col") const options = new Combine(optionCheckboxes).SetClass("flex flex-col")
const url = (currentLocation ?? new UIEventSource(undefined)).map(() => { const url = (currentLocation ?? new UIEventSource(undefined)).map(() => {
const host = window.location.host; const host = window.location.host;
@ -174,12 +166,12 @@ export default class ShareScreen extends UIElement {
}, optionParts); }, optionParts);
this.iframe = url.map(url => `&lt;iframe src="${url}" width="100%" height="100%" title="${layout?.title?.txt ?? "MapComplete"} with MapComplete"&gt;&lt;/iframe&gt`); const iframe = url.map(url => `&lt;iframe src="${url}" width="100%" height="100%" title="${layout?.title?.txt ?? "MapComplete"} with MapComplete"&gt;&lt;/iframe&gt`);
this._iframeCode = new VariableUiElement( const iframeCode = new VariableUiElement(
url.map((url) => { url.map((url) => {
return `<span class='literal-code iframe-code-block'> return `<span class='literal-code iframe-code-block'>
&lt;iframe src="${url}" width="100%" height="100%" title="${layout.title?.txt ?? "MapComplete"} with MapComplete"&gt;&lt;/iframe&gt &lt;iframe src="${url}" width="100%" height="100%" style="min-width: 25Opx; min-height: 250ox" title="${layout.title?.txt ?? "MapComplete"} with MapComplete"&gt;&lt;/iframe&gt
</span>` </span>`
}) })
); );
@ -187,9 +179,9 @@ export default class ShareScreen extends UIElement {
this._editLayout = new FixedUiElement(""); let editLayout : BaseUIElement= new FixedUiElement("");
if ((layoutDefinition !== undefined && State.state?.osmConnection !== undefined)) { if ((layoutDefinition !== undefined && State.state?.osmConnection !== undefined)) {
this._editLayout = editLayout =
new VariableUiElement( new VariableUiElement(
State.state.osmConnection.userDetails.map( State.state.osmConnection.userDetails.map(
userDetails => { userDetails => {
@ -198,8 +190,8 @@ export default class ShareScreen extends UIElement {
} }
return new SubtleButton(Svg.pencil_ui(), return new SubtleButton(Svg.pencil_ui(),
new Combine([tr.editThisTheme.SetClass("bold"), "<br/>", new Combine([tr.editThisTheme.Clone().SetClass("bold"), "<br/>",
tr.editThemeDescription]), tr.editThemeDescription.Clone()]),
{url: `./customGenerator.html#${State.state.layoutDefinition}`, newTab: true}); {url: `./customGenerator.html#${State.state.layoutDefinition}`, newTab: true});
} }
@ -207,13 +199,9 @@ export default class ShareScreen extends UIElement {
} }
this._linkStatus = new UIEventSource<string | Translation>(""); const linkStatus = new UIEventSource<string | Translation>("");
this.ListenTo(this._linkStatus); const link = new VariableUiElement(
const self = this; url.map((url) => `<input type="text" value=" ${url}" id="code-link--copyable" style="width:90%">`)
this._link = new VariableUiElement(
url.map((url) => {
return `<input type="text" value=" ${url}" id="code-link--copyable" style="width:90%">`
})
).onClick(async () => { ).onClick(async () => {
const shareData = { const shareData = {
@ -231,17 +219,17 @@ export default class ShareScreen extends UIElement {
copyText.setSelectionRange(0, 99999); /*For mobile devices*/ copyText.setSelectionRange(0, 99999); /*For mobile devices*/
document.execCommand("copy"); document.execCommand("copy");
const copied = tr.copiedToClipboard; const copied = tr.copiedToClipboard.Clone();
copied.SetClass("thanks") copied.SetClass("thanks")
self._linkStatus.setData(copied); linkStatus.setData(copied);
} }
try { try {
navigator.share(shareData) navigator.share(shareData)
.then(() => { .then(() => {
const thx = tr.thanksForSharing; const thx = tr.thanksForSharing.Clone();
thx.SetClass("thanks"); thx.SetClass("thanks");
this._linkStatus.setData(thx); linkStatus.setData(thx);
}, rejected) }, rejected)
.catch(rejected) .catch(rejected)
} catch (err) { } catch (err) {
@ -250,22 +238,19 @@ export default class ShareScreen extends UIElement {
}); });
}
InnerRender(): BaseUIElement { super ([
editLayout,
tr.intro.Clone(),
link,
new VariableUiElement(linkStatus),
tr.addToHomeScreen.Clone(),
tr.embedIntro.Clone(),
options,
iframeCode,
])
this.SetClass("flex flex-col link-underline")
const tr = Translations.t.general.sharescreen;
return new Combine([
this._editLayout,
tr.intro,
this._link,
Translations.W(this._linkStatus.data),
tr.addToHomeScreen,
tr.embedIntro,
this._options,
this._iframeCode,
]).SetClass("flex flex-col")
} }
} }

View file

@ -11,18 +11,19 @@ export default class ThemeIntroductionPanel extends VariableUiElement {
const languagePicker = const languagePicker =
new VariableUiElement( new VariableUiElement(
State.state.layoutToUse.map(layout => LanguagePicker.CreateLanguagePicker(layout.language, Translations.t.general.pickLanguage)) State.state.layoutToUse.map(layout => LanguagePicker.CreateLanguagePicker(layout.language, Translations.t.general.pickLanguage.Clone()))
) )
; ;
const plzLogIn = const plzLogIn =
Translations.t.general.loginWithOpenStreetMap Translations.t.general.loginWithOpenStreetMap
.Clone()
.onClick(() => { .onClick(() => {
State.state.osmConnection.AttemptLogin() State.state.osmConnection.AttemptLogin()
}); });
const welcomeBack = Translations.t.general.welcomeBack; const welcomeBack = Translations.t.general.welcomeBack.Clone();
const loginStatus = const loginStatus =
new Toggle( new Toggle(
@ -37,10 +38,10 @@ export default class ThemeIntroductionPanel extends VariableUiElement {
super(State.state.layoutToUse.map (layout => new Combine([ super(State.state.layoutToUse.map (layout => new Combine([
layout.description, layout.description.Clone(),
"<br/><br/>", "<br/><br/>",
loginStatus, loginStatus,
layout.descriptionTail, layout.descriptionTail.Clone(),
"<br/>", "<br/>",
languagePicker, languagePicker,
...layout.CustomCodeSnippets() ...layout.CustomCodeSnippets()

View file

@ -40,6 +40,7 @@ export class DropDown<T> extends InputElement<T> {
const labelHtml = document.createElement("label") const labelHtml = document.createElement("label")
labelHtml.appendChild(labelEl) labelHtml.appendChild(labelEl)
labelHtml.htmlFor = el.id; labelHtml.htmlFor = el.id;
el.appendChild(labelHtml)
} }
} }
@ -52,7 +53,10 @@ export class DropDown<T> extends InputElement<T> {
const option = document.createElement("option") const option = document.createElement("option")
option.value = "" + i option.value = "" + i
option.appendChild(Translations.W(values[i].shown).ConstructElement()) option.appendChild(Translations.W(values[i].shown).ConstructElement())
select.appendChild(option)
} }
el.appendChild(select)
select.onchange = (() => { select.onchange = (() => {
var index = select.selectedIndex; var index = select.selectedIndex;

View file

@ -3,7 +3,7 @@ import Locale from "./i18n/Locale";
import BaseUIElement from "./BaseUIElement"; import BaseUIElement from "./BaseUIElement";
export default class LanguagePicker { export default class LanguagePicker {
public static CreateLanguagePicker( public static CreateLanguagePicker(
languages : string[] , languages : string[] ,

View file

@ -12,16 +12,6 @@
overflow-x: hidden; overflow-x: hidden;
} }
#userbadge a {
text-decoration: none;
color: var(--foreground-color);
}
#userbadge form {
width: unset !important;
}
.userstats { .userstats {
display: flex; display: flex;
align-items: center; align-items: center;

View file

@ -1,6 +1,7 @@
import GeoLocationHandler from "./Logic/Actors/GeoLocationHandler"; import GeoLocationHandler from "./Logic/Actors/GeoLocationHandler";
import LayoutConfig from "./Customizations/JSON/LayoutConfig"; import LayoutConfig from "./Customizations/JSON/LayoutConfig";
import {UIEventSource} from "./Logic/UIEventSource"; import {UIEventSource} from "./Logic/UIEventSource";
import LanguagePicker from "./UI/LanguagePicker";
new GeoLocationHandler(new UIEventSource<{latlng: any; accuracy: number}>(undefined), undefined, new UIEventSource<LayoutConfig>(undefined)).AttachTo("maindiv") LanguagePicker.CreateLanguagePicker(["nl","en"]).AttachTo("maindiv")