mapcomplete/Logic/State/UserRelatedState.ts
2022-07-13 08:03:09 +00:00

192 lines
No EOL
6.9 KiB
TypeScript

import LayoutConfig from "../../Models/ThemeConfig/LayoutConfig";
import {OsmConnection} from "../Osm/OsmConnection";
import {MangroveIdentity} from "../Web/MangroveReviews";
import {Store, UIEventSource} from "../UIEventSource";
import {QueryParameters} from "../Web/QueryParameters";
import {LocalStorageSource} from "../Web/LocalStorageSource";
import {Utils} from "../../Utils";
import Locale from "../../UI/i18n/Locale";
import ElementsState from "./ElementsState";
import SelectedElementTagsUpdater from "../Actors/SelectedElementTagsUpdater";
import {Changes} from "../Osm/Changes";
import ChangeToElementsActor from "../Actors/ChangeToElementsActor";
import PendingChangesUploader from "../Actors/PendingChangesUploader";
import * as translators from "../../assets/translators.json"
import {post} from "jquery";
import Maproulette from "../Maproulette";
/**
* The part of the state which keeps track of user-related stuff, e.g. the OSM-connection,
* which layers they enabled, ...
*/
export default class UserRelatedState extends ElementsState {
/**
The user credentials
*/
public osmConnection: OsmConnection;
/**
THe change handler
*/
public changes: Changes;
/**
* The key for mangrove
*/
public mangroveIdentity: MangroveIdentity;
/**
* Maproulette connection
*/
public maprouletteConnection: Maproulette;
public readonly isTranslator : Store<boolean>;
public readonly installedUserThemes: Store<string[]>
constructor(layoutToUse: LayoutConfig, options?: { attemptLogin: true | boolean }) {
super(layoutToUse);
this.osmConnection = new OsmConnection({
dryRun: this.featureSwitchIsTesting,
fakeUser: this.featureSwitchFakeUser.data,
oauth_token: QueryParameters.GetQueryParameter(
"oauth_token",
undefined,
"Used to complete the login"
),
osmConfiguration: <'osm' | 'osm-test'>this.featureSwitchApiURL.data,
attemptLogin: options?.attemptLogin
})
const translationMode = this.osmConnection.GetPreference("translation-mode").sync(str => str === undefined ? undefined : str === "true", [], b => b === undefined ? undefined : b+"")
translationMode.syncWith(Locale.showLinkToWeblate)
this.isTranslator = this.osmConnection.userDetails.map(ud => {
if(!ud.loggedIn){
return false;
}
const name= ud.name.toLowerCase().replace(/\s+/g, '')
return translators.contributors.some(c => c.contributor.toLowerCase().replace(/\s+/g, '') === name)
})
this.isTranslator.addCallbackAndRunD(ud => {
if(ud){
Locale.showLinkToWeblate.setData(true)
}
});
this.changes = new Changes(this, layoutToUse?.isLeftRightSensitive() ?? false)
new ChangeToElementsActor(this.changes, this.allElements)
new PendingChangesUploader(this.changes, this.selectedElement);
this.mangroveIdentity = new MangroveIdentity(
this.osmConnection.GetLongPreference("identity", "mangrove")
);
this.maprouletteConnection = new Maproulette();
if (layoutToUse?.hideFromOverview) {
this.osmConnection.isLoggedIn.addCallbackAndRunD(loggedIn => {
if (loggedIn) {
this.osmConnection
.GetPreference("hidden-theme-" + layoutToUse?.id + "-enabled")
.setData("true");
return true;
}
})
}
if (this.layoutToUse !== undefined && !this.layoutToUse.official) {
console.log("Marking unofficial theme as visited")
this.osmConnection.GetLongPreference("unofficial-theme-" + this.layoutToUse.id)
.setData(JSON.stringify({
id: this.layoutToUse.id,
icon: this.layoutToUse.icon,
title: this.layoutToUse.title.translations,
shortDescription: this.layoutToUse.shortDescription.translations,
definition: this.layoutToUse["definition"]
}))
}
this.InitializeLanguage();
new SelectedElementTagsUpdater(this)
this.installedUserThemes = this.InitInstalledUserThemes();
}
private InitializeLanguage() {
const layoutToUse = this.layoutToUse;
Locale.language.syncWith(this.osmConnection.GetPreference("language"));
Locale.language
.addCallback((currentLanguage) => {
if (layoutToUse === undefined) {
return;
}
if(Locale.showLinkToWeblate.data){
return true; // Disable auto switching as we are in translators mode
}
if (this.layoutToUse.language.indexOf(currentLanguage) < 0) {
console.log(
"Resetting language to",
layoutToUse.language[0],
"as",
currentLanguage,
" is unsupported"
);
// The current language is not supported -> switch to a supported one
Locale.language.setData(layoutToUse.language[0]);
}
})
Locale.language.ping();
}
private InitInstalledUserThemes(): Store<string[]>{
const prefix = "mapcomplete-unofficial-theme-";
const postfix = "-combined-length"
return this.osmConnection.preferencesHandler.preferences.map(prefs =>
Object.keys(prefs)
.filter(k => k.startsWith(prefix) && k.endsWith(postfix))
.map(k => k.substring(prefix.length, k.length - postfix.length))
)
}
public GetUnofficialTheme(id: string): {
id: string
icon: string,
title: any,
shortDescription: any,
definition?: any,
isOfficial: boolean
} | undefined {
console.log("GETTING UNOFFICIAL THEME")
const pref = this.osmConnection.GetLongPreference("unofficial-theme-"+id)
const str = pref.data
if (str === undefined || str === "undefined" || str === "") {
pref.setData(null)
return undefined
}
try {
const value: {
id: string
icon: string,
title: any,
shortDescription: any,
definition?: any,
isOfficial: boolean
} = JSON.parse(str)
value.isOfficial = false
return value;
} catch (e) {
console.warn("Removing theme " + id + " as it could not be parsed from the preferences; the content is:", str)
pref.setData(null)
return undefined
}
}
}