forked from MapComplete/MapComplete
Unofficial themes are remembered now
This commit is contained in:
parent
3305d108c7
commit
dd68cc39e7
4 changed files with 71 additions and 72 deletions
|
@ -103,7 +103,8 @@ export default class AvailableBaseLayersImplementation implements AvailableBaseL
|
||||||
id: id,
|
id: id,
|
||||||
name: name,
|
name: name,
|
||||||
layer: () => L.tileLayer.provider(id, {
|
layer: () => L.tileLayer.provider(id, {
|
||||||
maxNativeZoom: layer.options?.maxZoom
|
maxNativeZoom: layer.options?.maxZoom,
|
||||||
|
maxZoom: Math.max(layer.options?.maxZoom ?? 19, 21)
|
||||||
}),
|
}),
|
||||||
min_zoom: 1,
|
min_zoom: 1,
|
||||||
max_zoom: layer.options.maxZoom,
|
max_zoom: layer.options.maxZoom,
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {Utils} from "../../Utils";
|
||||||
export class OsmPreferences {
|
export class OsmPreferences {
|
||||||
|
|
||||||
public preferences = new UIEventSource<any>({}, "all-osm-preferences");
|
public preferences = new UIEventSource<any>({}, "all-osm-preferences");
|
||||||
public preferenceSources: any = {}
|
private readonly preferenceSources = new Map<string, UIEventSource<string>>()
|
||||||
private auth: any;
|
private auth: any;
|
||||||
private userDetails: UIEventSource<UserDetails>;
|
private userDetails: UIEventSource<UserDetails>;
|
||||||
private longPreferences = {};
|
private longPreferences = {};
|
||||||
|
@ -29,6 +29,7 @@ export class OsmPreferences {
|
||||||
return this.longPreferences[prefix + key];
|
return this.longPreferences[prefix + key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const source = new UIEventSource<string>(undefined, "long-osm-preference:" + prefix + key);
|
const source = new UIEventSource<string>(undefined, "long-osm-preference:" + prefix + key);
|
||||||
this.longPreferences[prefix + key] = source;
|
this.longPreferences[prefix + key] = source;
|
||||||
|
|
||||||
|
@ -36,6 +37,10 @@ export class OsmPreferences {
|
||||||
// Gives the number of combined preferences
|
// Gives the number of combined preferences
|
||||||
const length = this.GetPreference(allStartWith + "-length", "");
|
const length = this.GetPreference(allStartWith + "-length", "");
|
||||||
|
|
||||||
|
if( (allStartWith + "-length").length > 255){
|
||||||
|
throw "This preference key is too long, it has "+key.length+" characters, but at most "+(255 - "-length".length - "-combined".length - prefix.length)+" characters are allowed"
|
||||||
|
}
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
source.addCallback(str => {
|
source.addCallback(str => {
|
||||||
if (str === undefined || str === "") {
|
if (str === undefined || str === "") {
|
||||||
|
@ -101,24 +106,21 @@ export class OsmPreferences {
|
||||||
if (key.length >= 255) {
|
if (key.length >= 255) {
|
||||||
throw "Preferences: key length to big";
|
throw "Preferences: key length to big";
|
||||||
}
|
}
|
||||||
if (this.preferenceSources[key] !== undefined) {
|
const cached = this.preferenceSources.get(key)
|
||||||
return this.preferenceSources[key];
|
if (cached !== undefined) {
|
||||||
|
return cached;
|
||||||
}
|
}
|
||||||
if (this.userDetails.data.loggedIn && this.preferences.data[key] === undefined) {
|
if (this.userDetails.data.loggedIn && this.preferences.data[key] === undefined) {
|
||||||
this.UpdatePreferences();
|
this.UpdatePreferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
const pref = new UIEventSource<string>(this.preferences.data[key], "osm-preference:" + key);
|
const pref = new UIEventSource<string>(this.preferences.data[key], "osm-preference:" + key);
|
||||||
pref.addCallback((v) => {
|
pref.addCallback((v) => {
|
||||||
this.SetPreference(key, v);
|
this.UploadPreference(key, v);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.preferences.addCallback((prefs) => {
|
|
||||||
if (prefs[key] !== undefined) {
|
this.preferenceSources.set(key, pref)
|
||||||
pref.setData(prefs[key]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.preferenceSources[key] = pref;
|
|
||||||
return pref;
|
return pref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,11 +169,25 @@ export class OsmPreferences {
|
||||||
const v = pref.getAttribute("v");
|
const v = pref.getAttribute("v");
|
||||||
self.preferences.data[k] = v;
|
self.preferences.data[k] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We merge all the preferences: new keys are uploaded
|
||||||
|
// For differing values, the server overrides local changes
|
||||||
|
self.preferenceSources.forEach((preference, key) => {
|
||||||
|
const osmValue = self.preferences[key]
|
||||||
|
if(osmValue === undefined){
|
||||||
|
// OSM doesn't know this value yet
|
||||||
|
self.UploadPreference(key, preference.data)
|
||||||
|
} else {
|
||||||
|
// OSM does have a value - set it
|
||||||
|
preference.setData(osmValue)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
self.preferences.ping();
|
self.preferences.ping();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private SetPreference(k: string, v: string) {
|
private UploadPreference(k: string, v: string) {
|
||||||
if (!this.userDetails.data.loggedIn) {
|
if (!this.userDetails.data.loggedIn) {
|
||||||
console.debug(`Not saving preference ${k}: user not logged in`);
|
console.debug(`Not saving preference ${k}: user not logged in`);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -29,17 +29,6 @@ export default class UserRelatedState extends ElementsState {
|
||||||
*/
|
*/
|
||||||
public favouriteLayers: UIEventSource<string[]>;
|
public favouriteLayers: UIEventSource<string[]>;
|
||||||
|
|
||||||
/**
|
|
||||||
* WHich other themes the user previously visited
|
|
||||||
*/
|
|
||||||
public installedThemes: UIEventSource<{
|
|
||||||
id: string, // The id doubles as the URL
|
|
||||||
icon: string,
|
|
||||||
title: any,
|
|
||||||
shortDescription: any
|
|
||||||
}[]>;
|
|
||||||
|
|
||||||
|
|
||||||
constructor(layoutToUse: LayoutConfig, options?: { attemptLogin: true | boolean }) {
|
constructor(layoutToUse: LayoutConfig, options?: { attemptLogin: true | boolean }) {
|
||||||
super(layoutToUse);
|
super(layoutToUse);
|
||||||
|
|
||||||
|
@ -73,50 +62,15 @@ export default class UserRelatedState extends ElementsState {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
this.installedThemes = this.osmConnection.GetLongPreference("installed-themes").map(
|
if (this.layoutToUse !== undefined && !this.layoutToUse.official) {
|
||||||
str => {
|
console.log("Marking unofficial theme as visited")
|
||||||
if (str === undefined || str === "") {
|
this.osmConnection.GetLongPreference("unofficial-theme-" + this.layoutToUse.id)
|
||||||
return []
|
.setData(JSON.stringify({
|
||||||
}
|
id: this.layoutToUse.id,
|
||||||
try {
|
icon: this.layoutToUse.icon,
|
||||||
return JSON.parse(str);
|
title: this.layoutToUse.title.translations,
|
||||||
} catch (e) {
|
shortDescription: this.layoutToUse.shortDescription.translations
|
||||||
console.warn("Could not parse preference with installed themes due to ", e, "\nThe offending string is", str)
|
}))
|
||||||
return []
|
|
||||||
}
|
|
||||||
}, [], (installed) => JSON.stringify(installed)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
const self = this;
|
|
||||||
|
|
||||||
if (this.layoutToUse?.id?.startsWith("http")) {
|
|
||||||
this.installedThemes.addCallbackAndRun(currentThemes => {
|
|
||||||
if (currentThemes === undefined) {
|
|
||||||
// We wait till we are logged in
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.osmConnection.isLoggedIn.data == false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentThemes.some(installed => installed.id === this.layoutToUse.id)) {
|
|
||||||
// Already added to the 'installed theme' list
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("Current installed themes are", this.installedThemes.data)
|
|
||||||
currentThemes.push({
|
|
||||||
id: self.layoutToUse.id,
|
|
||||||
icon: self.layoutToUse.icon,
|
|
||||||
title: self.layoutToUse.title.translations,
|
|
||||||
shortDescription: self.layoutToUse.shortDescription.translations
|
|
||||||
})
|
|
||||||
self.installedThemes.ping()
|
|
||||||
console.log("Registered " + self.layoutToUse.id + " as installed themes")
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -120,14 +120,42 @@ export default class MoreScreen extends Combine {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static createUnofficialThemeList(buttonClass: string, state: UserRelatedState, themeListClasses): BaseUIElement {
|
private static createUnofficialThemeList(buttonClass: string, state: UserRelatedState, themeListClasses): BaseUIElement {
|
||||||
return new VariableUiElement(state.installedThemes.map(customThemes => {
|
const prefix = "mapcomplete-unofficial-theme-";
|
||||||
if (customThemes.length <= 0) {
|
return new VariableUiElement(state.osmConnection.preferencesHandler.preferences.map(allPreferences => {
|
||||||
|
console.log("All preferences are ", allPreferences)
|
||||||
|
const allThemes: BaseUIElement[] = []
|
||||||
|
for (const key in allPreferences) {
|
||||||
|
if (key.startsWith(prefix) && key.endsWith("-combined-length")) {
|
||||||
|
const id = key.substring(0, key.length - "-length".length)
|
||||||
|
const length = Number(allPreferences[key])
|
||||||
|
|
||||||
|
let str = "";
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
str += allPreferences[id + "-" + i]
|
||||||
|
}
|
||||||
|
console.log("Theme " + id + " has settings ", str)
|
||||||
|
try {
|
||||||
|
const value: {
|
||||||
|
id: string
|
||||||
|
icon: string,
|
||||||
|
title: any,
|
||||||
|
shortDescription: any
|
||||||
|
} = JSON.parse(str)
|
||||||
|
|
||||||
|
const link = MoreScreen.createLinkButton(state, value, true).SetClass(buttonClass)
|
||||||
|
allThemes.push(link)
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Could not parse unofficial theme information for " + id, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allThemes.length <= 0) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
const customThemeButtons = customThemes.map(theme => MoreScreen.createLinkButton(state, theme, true)?.SetClass(buttonClass))
|
|
||||||
return new Combine([
|
return new Combine([
|
||||||
Translations.t.general.customThemeIntro.Clone(),
|
Translations.t.general.customThemeIntro.Clone(),
|
||||||
new Combine(customThemeButtons).SetClass(themeListClasses)
|
new Combine(allThemes).SetClass(themeListClasses)
|
||||||
]);
|
]);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue