Fix bugs with themes, add movement of tag renderings in custom theme generator

This commit is contained in:
Pieter Vander Vennet 2020-09-05 15:27:35 +02:00
parent 80f0dbe6e3
commit b7b1bc13e4
180 changed files with 671 additions and 967 deletions

View file

@ -57,7 +57,7 @@ export class FromJSON {
const layout = new Layout( const layout = new Layout(
json.id, json.id,
typeof (json.language) === "string" ? [json.language] : json.language, typeof (json.language) === "string" ? [json.language] : json.language,
tr(json.title), tr(json.title ?? "Title not defined"),
layers, layers,
json.startZoom, json.startZoom,
json.startLat, json.startLat,

View file

@ -1,5 +1,5 @@
import {LayerDefinition} from "../LayerDefinition"; import {LayerDefinition} from "../LayerDefinition";
import {And, Or, Tag} from "../../Logic/Tags"; import {And, Or, RegexTag, Tag} from "../../Logic/Tags";
import {TagRenderingOptions} from "../TagRenderingOptions"; import {TagRenderingOptions} from "../TagRenderingOptions";
import {FromJSON} from "../JSON/FromJSON"; import {FromJSON} from "../JSON/FromJSON";
@ -36,10 +36,6 @@ export class Widths extends LayerDefinition {
private readonly _oneSideParking = new Or([this._leftSideParking, this._rightSideParking]); private readonly _oneSideParking = new Or([this._leftSideParking, this._rightSideParking]);
private readonly _carfree = new And(
[new Tag("highway", "pedestrian"), new Tag("highway", "living_street"),
new Tag("access","destination"), new Tag("motor_vehicle", "destination")])
private readonly _notCarfree = private readonly _notCarfree =
FromJSON.Tag({"and":[ FromJSON.Tag({"and":[
"highway!~pedestrian|living_street", "highway!~pedestrian|living_street",
@ -130,7 +126,7 @@ export class Widths extends LayerDefinition {
} }
this.name = "widths"; this.name = "widths";
this.overpassFilter = new Tag("width:carriageway", "*"); this.overpassFilter = new RegexTag("width:carriageway", /.*/);
this.title = new TagRenderingOptions({ this.title = new TagRenderingOptions({
freeform: { freeform: {
@ -140,6 +136,8 @@ export class Widths extends LayerDefinition {
} }
}) })
console.log("Not car free: ", this._notCarfree)
const self = this; const self = this;
this.style = (properties) => { this.style = (properties) => {
@ -158,7 +156,7 @@ export class Widths extends LayerDefinition {
c = "#f0f" c = "#f0f"
} }
if (this._carfree.matchesProperties(properties)) { if (!this._notCarfree.matchesProperties(properties)) {
c = "#aaa"; c = "#aaa";
} }
@ -196,7 +194,6 @@ export class Widths extends LayerDefinition {
txt: "Deze straat heeft dwarsparkeren of diagonaalparkeren aan minstens één zijde. Deze parkeerruimte is niet opgenomen in de straatbreedte." txt: "Deze straat heeft dwarsparkeren of diagonaalparkeren aan minstens één zijde. Deze parkeerruimte is niet opgenomen in de straatbreedte."
}, },
{k: this._noSideParking, txt: "Auto's mogen hier niet parkeren"}, {k: this._noSideParking, txt: "Auto's mogen hier niet parkeren"},
// {k: null, txt: "Nog geen parkeerinformatie bekend"}
], ],
freeform: { freeform: {
key: "note:width:carriageway", key: "note:width:carriageway",

View file

@ -127,6 +127,10 @@ export class InitUiElements {
static CreateLanguagePicker(label: string | UIElement = "") { static CreateLanguagePicker(label: string | UIElement = "") {
if (State.state.layoutToUse.data.supportedLanguages.length <= 1) {
return undefined;
}
return new DropDown(label, State.state.layoutToUse.data.supportedLanguages.map(lang => { return new DropDown(label, State.state.layoutToUse.data.supportedLanguages.map(lang => {
return {value: lang, shown: lang} return {value: lang, shown: lang}
} }
@ -203,10 +207,11 @@ export class InitUiElements {
const presets: Preset[] = []; const presets: Preset[] = [];
const state = State.state; const state = State.state;
for (const layer of state.layoutToUse.data.layers) { for (const layer of state.layoutToUse.data.layers) {
if(typeof (layer) === "string"){ if (typeof (layer) === "string") {
throw "Layer "+layer+" was not substituted"; throw "Layer " + layer + " was not substituted";
} }
const generateInfo = (tagsES, feature) => { const generateInfo = (tagsES, feature) => {

View file

@ -34,7 +34,7 @@ export class StrayClickHandler {
uiElement.Update(); uiElement.Update();
uiElement.Activate(); uiElement.Activate();
self._lastMarker.addTo(map); self._lastMarker.addTo(map);
self._lastMarker.bindPopup(popup).openPopup(); self._lastMarker.bindPopup(popup);
self._lastMarker.on("click", () => { self._lastMarker.on("click", () => {
State.state.fullScreenMessage.setData(self._uiToShow()); State.state.fullScreenMessage.setData(self._uiToShow());

View file

@ -49,7 +49,8 @@ export class RegexTag extends TagsFilter {
return RegexTag.doesMatch(tag.v, this.value) != this.invert; return RegexTag.doesMatch(tag.v, this.value) != this.invert;
} }
} }
return false; // The matching key was not found
return this.invert;
} }
substituteValues(tags: any) : TagsFilter{ substituteValues(tags: any) : TagsFilter{

View file

@ -23,7 +23,7 @@ export class State {
// The singleton of the global state // The singleton of the global state
public static state: State; public static state: State;
public static vNumber = "0.0.7f"; public static vNumber = "0.0.7g";
// The user journey states thresholds when a new feature gets unlocked // The user journey states thresholds when a new feature gets unlocked
public static userJourney = { public static userJourney = {

View file

@ -18,6 +18,10 @@ export default class Combine extends UIElement {
InnerRender(): string { InnerRender(): string {
let elements = ""; let elements = "";
for (const element of this.uiElements) { for (const element of this.uiElements) {
if(element === undefined){
continue;
}
if (element instanceof UIElement) { if (element instanceof UIElement) {
elements += element.Render(); elements += element.Render();
} else { } else {

View file

@ -7,6 +7,9 @@ import Combine from "../Base/Combine";
import {GenerateEmpty} from "./GenerateEmpty"; import {GenerateEmpty} from "./GenerateEmpty";
import LayerPanelWithPreview from "./LayerPanelWithPreview"; import LayerPanelWithPreview from "./LayerPanelWithPreview";
import {UserDetails} from "../../Logic/Osm/OsmConnection"; import {UserDetails} from "../../Logic/Osm/OsmConnection";
import {MultiInput} from "../Input/MultiInput";
import TagRenderingPanel from "./TagRenderingPanel";
import SingleSetting from "./SingleSetting";
export default class AllLayersPanel extends UIElement { export default class AllLayersPanel extends UIElement {
@ -14,10 +17,13 @@ export default class AllLayersPanel extends UIElement {
private panel: UIElement; private panel: UIElement;
private readonly _config: UIEventSource<LayoutConfigJson>; private readonly _config: UIEventSource<LayoutConfigJson>;
private readonly languages: UIEventSource<string[]>; private readonly languages: UIEventSource<string[]>;
private readonly userDetails: UserDetails;
private readonly currentlySelected: UIEventSource<SingleSetting<any>>;
constructor(config: UIEventSource<LayoutConfigJson>, constructor(config: UIEventSource<LayoutConfigJson>,
languages: UIEventSource<any>, userDetails: UserDetails) { languages: UIEventSource<any>, userDetails: UserDetails) {
super(undefined); super(undefined);
this.userDetails = userDetails;
this._config = config; this._config = config;
this.languages = languages; this.languages = languages;
@ -32,6 +38,15 @@ export default class AllLayersPanel extends UIElement {
const self = this; const self = this;
const tabs = []; const tabs = [];
const roamingTags = new MultiInput("Add a tagrendering",
() => GenerateEmpty.createEmptyTagRendering(),
() => {
return new TagRenderingPanel(self.languages, self.currentlySelected, self.userDetails)
}, undefined, {allowMovement: true});
new SingleSetting(this._config, roamingTags, "roamingRenderings", "Roaming Renderings", "These tagrenderings are shown everywhere");
const layers = this._config.data.layers; const layers = this._config.data.layers;
for (let i = 0; i < layers.length; i++) { for (let i = 0; i < layers.length; i++) {
@ -43,15 +58,20 @@ export default class AllLayersPanel extends UIElement {
tabs.push({ tabs.push({
header: "<img src='./assets/layersAdd.svg'>", header: "<img src='./assets/layersAdd.svg'>",
content: new Combine([ content: new Combine([
"<h2>Layer editor</h2>", "<h2>Layer editor</h2>",
"In this tab page, you can add and edit the layers of the theme. Click the layers above or add a new layer to get started.", "In this tab page, you can add and edit the layers of the theme. Click the layers above or add a new layer to get started.",
new SubtleButton( new SubtleButton(
"./assets/layersAdd.svg", "./assets/layersAdd.svg",
"Add a new layer" "Add a new layer"
).onClick(() => { ).onClick(() => {
self._config.data.layers.push(GenerateEmpty.createEmptyLayer()) self._config.data.layers.push(GenerateEmpty.createEmptyLayer())
self._config.ping(); self._config.ping();
})]) }),
"<h2>TagRenderings for every layer</h2>",
"Define tag renderings and questions here that should be shown on every layer of the theme.",
roamingTags
]
),
}) })
this.panel = new TabbedComponent(tabs, new UIEventSource<number>(Math.max(0, layers.length - 1))); this.panel = new TabbedComponent(tabs, new UIEventSource<number>(Math.max(0, layers.length - 1)));

View file

@ -120,7 +120,7 @@ export default class LayerPanel extends UIElement {
const tagPanel = new TagRenderingPanel(languages, currentlySelected, userDetails) const tagPanel = new TagRenderingPanel(languages, currentlySelected, userDetails)
self.registerTagRendering(tagPanel); self.registerTagRendering(tagPanel);
return tagPanel; return tagPanel;
}); }, undefined, {allowMovement:true});
tagRenderings.GetValue().addCallback( tagRenderings.GetValue().addCallback(
tagRenderings => { tagRenderings => {
(config.data.layers[index] as LayerConfigJson).tagRenderings = tagRenderings; (config.data.layers[index] as LayerConfigJson).tagRenderings = tagRenderings;
@ -132,7 +132,8 @@ export default class LayerPanel extends UIElement {
const presetPanel = new MultiInput("Add a preset", const presetPanel = new MultiInput("Add a preset",
() => ({tags: [], title: {}}), () => ({tags: [], title: {}}),
() => new PresetInputPanel(currentlySelected, languages)); () => new PresetInputPanel(currentlySelected, languages),
undefined, {allowMovement: true});
new SingleSetting(config, presetPanel, ["layers", index, "presets"], "Presets", "") new SingleSetting(config, presetPanel, ["layers", index, "presets"], "Presets", "")
this.presetsPanel = presetPanel; this.presetsPanel = presetPanel;
} else { } else {

View file

@ -33,7 +33,7 @@ export default class PresetInputPanel extends InputElement<{
s(new MultiTagInput(), "tags","Preset tags","These tags will be applied on the newly created point"), s(new MultiTagInput(), "tags","Preset tags","These tags will be applied on the newly created point"),
s(new MultiLingualTextFields(languages), "title","Preset title","This little text is shown in bold on the 'create new point'-button" ), s(new MultiLingualTextFields(languages), "title","Preset title","This little text is shown in bold on the 'create new point'-button" ),
s(new MultiLingualTextFields(languages), "description","Description", "This text is shown in the button as description when creating a new point") s(new MultiLingualTextFields(languages), "description","Description", "This text is shown in the button as description when creating a new point")
], currentlySelected); ], currentlySelected).SetStyle("display: block; border: 1px solid black; border-radius: 1em;padding: 1em;");
} }

View file

@ -12,14 +12,20 @@ export class MultiInput<T> extends InputElement<T[]> {
private elements: UIElement[] = []; private elements: UIElement[] = [];
private inputELements: InputElement<T>[] = []; private inputELements: InputElement<T>[] = [];
private addTag: UIElement; private addTag: UIElement;
private _options: { allowMovement?: boolean };
constructor( constructor(
addAElement: string, addAElement: string,
newElement: (() => T), newElement: (() => T),
createInput: (() => InputElement<T>), createInput: (() => InputElement<T>),
value: UIEventSource<T[]> = new UIEventSource<T[]>([])) { value: UIEventSource<T[]> = undefined,
options?: {
allowMovement?: boolean
}) {
super(undefined); super(undefined);
this._value = value; this._value = value ?? new UIEventSource<T[]>([]);
value = this._value;
this._options = options ?? {};
this.addTag = new SubtleButton("./assets/addSmall.svg", addAElement) this.addTag = new SubtleButton("./assets/addSmall.svg", addAElement)
.SetClass("small-button") .SetClass("small-button")
@ -54,7 +60,6 @@ export class MultiInput<T> extends InputElement<T[]> {
this.elements = []; this.elements = [];
const self = this; const self = this;
for (let i = 0; i < this._value.data.length; i++) { for (let i = 0; i < this._value.data.length; i++) {
let tag = this._value.data[i];
const input = createInput(); const input = createInput();
input.GetValue().addCallback(tag => { input.GetValue().addCallback(tag => {
self._value.data[i] = tag; self._value.data[i] = tag;
@ -63,12 +68,40 @@ export class MultiInput<T> extends InputElement<T[]> {
); );
this.inputELements.push(input); this.inputELements.push(input);
input.IsSelected.addCallback(() => this.UpdateIsSelected()); input.IsSelected.addCallback(() => this.UpdateIsSelected());
const deleteBtn = new FixedUiElement("<img src='./assets/delete.svg' style='max-width: 1.5em; margin-left: 5px;'>")
const moveUpBtn = new FixedUiElement("<img src='./assets/up.svg' style='max-width: 1.5em; margin-left: 5px;'>")
.onClick(() => {
const v = self._value.data[i];
self._value.data[i] = self._value.data[i - 1];
self._value.data[i - 1] = v;
self._value.ping();
});
const moveDownBtn = new FixedUiElement("<img src='./assets/down.svg' style='max-width: 1.5em; margin-left: 5px;'>")
.onClick(() => {
const v = self._value.data[i];
self._value.data[i] = self._value.data[i + 1];
self._value.data[i + 1] = v;
self._value.ping();
});
const controls = [];
if (i > 0 && this._options.allowMovement) {
controls.push(moveUpBtn);
}
if (i + 1 < this._value.data.length && this._options.allowMovement) {
controls.push(moveDownBtn);
}
const deleteBtn = new FixedUiElement("<img src='./assets/delete.svg' style='max-width: 1.5em;width:1.5em; margin-left: 5px;'>")
.onClick(() => { .onClick(() => {
self._value.data.splice(i, 1); self._value.data.splice(i, 1);
self._value.ping(); self._value.ping();
}); });
this.elements.push(new Combine([input, deleteBtn, "<br/>"]).SetClass("tag-input-row")) controls.push(deleteBtn);
this.elements.push(new Combine([input.SetStyle("width: calc(100% - 2em - 5px)"), new Combine(controls).SetStyle("display:flex;flex-direction:column;width:min-content;")]).SetClass("tag-input-row"))
} }
this.Update(); this.Update();

View file

@ -176,7 +176,7 @@ export class ShareScreen extends UIElement {
new VariableUiElement( new VariableUiElement(
State.state.osmConnection.userDetails.map( State.state.osmConnection.userDetails.map(
userDetails => { userDetails => {
if (userDetails.csCount <= State.userJourney.themeGeneratorUnlock) { if (userDetails.csCount <= State.userJourney.themeGeneratorReadOnlyUnlock) {
return ""; return "";
} }

View file

@ -9,6 +9,7 @@ import {Utils} from "../Utils";
import {UIEventSource} from "../Logic/UIEventSource"; import {UIEventSource} from "../Logic/UIEventSource";
import {SubtleButton} from "./Base/SubtleButton"; import {SubtleButton} from "./Base/SubtleButton";
import {InitUiElements} from "../InitUiElements"; import {InitUiElements} from "../InitUiElements";
import Combine from "./Base/Combine";
/** /**
* Handles and updates the user badge * Handles and updates the user badge
@ -110,14 +111,14 @@ export class UserBadge extends UIElement {
" <a href='https://www.openstreetmap.org/user/" + user.name + "/history' target='_blank'><img class='small-userbadge-icon' src='./assets/star.svg' alt='star'/> " + user.csCount + " <a href='https://www.openstreetmap.org/user/" + user.name + "/history' target='_blank'><img class='small-userbadge-icon' src='./assets/star.svg' alt='star'/> " + user.csCount +
"</a></span> "; "</a></span> ";
const userStats = "<div id='userstats'>" + const userStats = new Combine(["<div id='userstats'>",
this._homeButton.Render() + this._homeButton,
settings + settings,
messageSpan + messageSpan,
csCount + csCount,
this._logout.Render() + this._logout,
this._languagePicker.Render() + this._languagePicker,
"</div>"; "</div>"]).Render();
return userIcon + "<div id='usertext'>" + userName + userStats + "</div>"; return userIcon + "<div id='usertext'>" + userName + userStats + "</div>";

View file

@ -41,8 +41,7 @@ export class WelcomeMessage extends UIElement {
return new Combine([ return new Combine([
this.description, this.description,
"<br/></br>", "<br/><br/>",
// TODO this button is broken - figure out why loginStatus,
loginStatus, loginStatus,
this.tail, this.tail,
"<br/>", "<br/>",

View file

@ -874,7 +874,7 @@ export default class Translations {
en: "<h2>Add a point?</h2>You clicked somewhere where no data is known yet.<br/>", en: "<h2>Add a point?</h2>You clicked somewhere where no data is known yet.<br/>",
ca: "<h2>Vols afegir un punt?</h2>Has marcat un lloc on no coneixem les dades.<br/>", ca: "<h2>Vols afegir un punt?</h2>Has marcat un lloc on no coneixem les dades.<br/>",
es: "<h2>Quieres añadir un punto?</h2>Has marcado un lugar del que no conocemos los datos.<br/>", es: "<h2>Quieres añadir un punto?</h2>Has marcado un lugar del que no conocemos los datos.<br/>",
nl: "<h2>Punt toevoegen?</h2>Je klikte ergens waar er nog geen data is.<br/>", nl: "<h2>Punt toevoegen?</h2>Je klikte ergens waar er nog geen data is. Kies hieronder welk punt je wilt toevoegen<br/>",
fr: "<h2>Pas de données</h2>Vous avez cliqué sur un endroit ou il n'y a pas encore de données. <br/>", fr: "<h2>Pas de données</h2>Vous avez cliqué sur un endroit ou il n'y a pas encore de données. <br/>",
gl: "<h2>Queres engadir un punto?</h2>Marcaches un lugar onde non coñecemos os datos.<br/>" gl: "<h2>Queres engadir un punto?</h2>Marcaches un lugar onde non coñecemos os datos.<br/>"
}), }),

View file

@ -1,70 +0,0 @@
<!DOCTYPE html>
<!-- WARNING: index.html serves as a template. If you want to change something, change it there -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>MapComplete</title>
<link rel="stylesheet" href="./vendor/leaflet.css"/>
<link rel="stylesheet" href="./index.css"/>
<link rel="stylesheet" href="./css/userbadge.css"/>
<link rel="stylesheet" href="./css/slideshow.css"/>
<link rel="manifest" href="./aed.webmanifest">
<link rel="icon" href="./assets/themes/aed/aed.svg" sizes="any" type="image/svg+xml">
<meta property="og:type" content="website">
<meta property="og:image" content="./assets/add.svg">
<meta property="og:title" content="Open AED Map">
<meta property="og:description" content="Easily add and edit geodata with OpenStreetMap">
<style>
#decoration-desktop img {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div style="position: absolute; left: 1em; bottom: 1em; width:35vh; height:35vh;"
id="decoration-desktop">
<!-- A nice decoration while loading or on errors -->
<img src='./assets/themes/aed/aed.svg' width="100%" height="100%">
</div>
<div id="hidden-on-mobile">
<div id="messagesboxmobile">
</div>
</div>
<div id="topleft-tools">
<div id="userbadge-and-search">
<div id="userbadge" class="shadow">
</div>
<div id="searchbox" class="shadow"></div>
</div>
<div id="messagesbox"></div>
<br/>
<div id="help-button-mobile"></div>
</div>
<div id="filter__popup" class="filter__popup">
<div id="filter__selection"></div>
</div>
<div id="centermessage">Loading MapComplete, hang on...</div>
<div id="top-right"></div>
<div id="geolocate-button"></div>
<div id="leafletDiv"></div>
<script src="./index.ts"></script>
<script src="./vendor/Leaflet.AccuratePosition.js"></script>
<script data-goatcounter="https://pietervdvn.goatcounter.com/count"
async src="//gc.zgo.at/count.js"></script>
</body>
</html>

View file

@ -1 +0,0 @@
{"name":"aed","short_name":"Open AED Map","start_url":"/MapComplete/aed.html","display":"standalone","background_color":"#fff","description":"","orientation":"portrait-primary, landscape-primary","icons":[{"src":"assets/generated/themes_aed_aed72.png","sizes":"72x72","type":"image/png"},{"src":"assets/generated/themes_aed_aed96.png","sizes":"96x96","type":"image/png"},{"src":"assets/generated/themes_aed_aed120.png","sizes":"120x120","type":"image/png"},{"src":"assets/generated/themes_aed_aed128.png","sizes":"128x128","type":"image/png"},{"src":"assets/generated/themes_aed_aed144.png","sizes":"144x144","type":"image/png"},{"src":"assets/generated/themes_aed_aed152.png","sizes":"152x152","type":"image/png"},{"src":"assets/generated/themes_aed_aed180.png","sizes":"180x180","type":"image/png"},{"src":"assets/generated/themes_aed_aed192.png","sizes":"192x192","type":"image/png"},{"src":"assets/generated/themes_aed_aed384.png","sizes":"384x384","type":"image/png"},{"src":"assets/generated/themes_aed_aed512.png","sizes":"512x512","type":"image/png"},{"src":"./assets/themes/aed/aed.svg","sizes":"513x513","type":"image/svg"}]}

View file

@ -1,70 +0,0 @@
<!DOCTYPE html>
<!-- WARNING: index.html serves as a template. If you want to change something, change it there -->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>MapComplete</title>
<link rel="stylesheet" href="./vendor/leaflet.css"/>
<link rel="stylesheet" href="./index.css"/>
<link rel="stylesheet" href="./css/userbadge.css"/>
<link rel="stylesheet" href="./css/slideshow.css"/>
<link rel="manifest" href="./artworks.webmanifest">
<link rel="icon" href="./assets/themes/artwork/artwork.svg" sizes="any" type="image/svg+xml">
<meta property="og:type" content="website">
<meta property="og:image" content="./assets/add.svg">
<meta property="og:title" content="Open Artwork Map">
<meta property="og:description" content="Easily add and edit geodata with OpenStreetMap">
<style>
#decoration-desktop img {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div style="position: absolute; left: 1em; bottom: 1em; width:35vh; height:35vh;"
id="decoration-desktop">
<!-- A nice decoration while loading or on errors -->
<img src='./assets/themes/artwork/artwork.svg' width="100%" height="100%">
</div>
<div id="hidden-on-mobile">
<div id="messagesboxmobile">
</div>
</div>
<div id="topleft-tools">
<div id="userbadge-and-search">
<div id="userbadge" class="shadow">
</div>
<div id="searchbox" class="shadow"></div>
</div>
<div id="messagesbox"></div>
<br/>
<div id="help-button-mobile"></div>
</div>
<div id="filter__popup" class="filter__popup">
<div id="filter__selection"></div>
</div>
<div id="centermessage">Loading MapComplete, hang on...</div>
<div id="top-right"></div>
<div id="geolocate-button"></div>
<div id="leafletDiv"></div>
<script src="./index.ts"></script>
<script src="./vendor/Leaflet.AccuratePosition.js"></script>
<script data-goatcounter="https://pietervdvn.goatcounter.com/count"
async src="//gc.zgo.at/count.js"></script>
</body>
</html>

View file

@ -1 +0,0 @@
{"name":"artworks","short_name":"Open Artwork Map","start_url":"/MapComplete/artworks.html","display":"standalone","background_color":"#fff","description":"","orientation":"portrait-primary, landscape-primary","icons":[{"src":"assets/generated/themes_artwork_artwork72.png","sizes":"72x72","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork96.png","sizes":"96x96","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork120.png","sizes":"120x120","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork128.png","sizes":"128x128","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork144.png","sizes":"144x144","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork152.png","sizes":"152x152","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork180.png","sizes":"180x180","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork192.png","sizes":"192x192","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork384.png","sizes":"384x384","type":"image/png"},{"src":"assets/generated/themes_artwork_artwork512.png","sizes":"512x512","type":"image/png"},{"src":"./assets/themes/artwork/artwork.svg","sizes":"513x513","type":"image/svg"}]}

58
assets/down.svg Normal file
View file

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
width="700"
height="700"
id="svg6"
sodipodi:docname="down.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1001"
id="namedview8"
showgrid="false"
inkscape:zoom="0.33714286"
inkscape:cx="477.91309"
inkscape:cy="350"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg6" />
<g
transform="rotate(-180,342.1439,335.17672)"
id="g4">
<path
d="m -20,670.71582 c 0,-1.85843 349.99229,-699.98853 350.57213,-699.28671 1.94549,2.35478 350.06752,699.46087 349.427,699.71927 -0.41837,0.16878 -79.29725,-33.69092 -175.2864,-75.24377 l -174.52574,-75.55065 -174.2421,75.53732 c -95.83317,41.54551 -174.625237,75.5373 -175.093498,75.5373 -0.46826,0 -0.851382,-0.32075 -0.851382,-0.71276 z"
style="fill:#00ff00;stroke:none"
id="path2"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Some files were not shown because too many files have changed in this diff Show more