2020-10-09 20:10:21 +02:00
import { UIElement } from "./UIElement" ;
import { UIEventSource } from "../Logic/UIEventSource" ;
2020-10-12 01:25:27 +02:00
import { VariableUiElement } from "./Base/VariableUIElement" ;
import LiveQueryHandler from "../Logic/Web/LiveQueryHandler" ;
2020-10-14 12:15:09 +02:00
import { ImageCarousel } from "./Image/ImageCarousel" ;
import Combine from "./Base/Combine" ;
import { FixedUiElement } from "./Base/FixedUiElement" ;
import { ImageUploadFlow } from "./Image/ImageUploadFlow" ;
2021-01-03 13:50:18 +01:00
2021-01-04 04:06:21 +01:00
import ShareButton from "./BigComponents/ShareButton" ;
2020-11-22 03:50:09 +01:00
import Svg from "../Svg" ;
2020-12-08 23:44:34 +01:00
import ReviewElement from "./Reviews/ReviewElement" ;
import MangroveReviews from "../Logic/Web/MangroveReviews" ;
import Translations from "./i18n/Translations" ;
import ReviewForm from "./Reviews/ReviewForm" ;
2021-01-02 16:04:16 +01:00
import OpeningHoursVisualization from "./OpeningHours/OhVisualization" ;
2020-10-14 12:15:09 +02:00
2021-01-03 13:50:18 +01:00
import State from "../State" ;
2021-01-29 03:23:53 +01:00
import { ImageSearcher } from "../Logic/Actors/ImageSearcher" ;
2021-01-03 13:50:18 +01:00
2020-10-09 20:10:21 +02:00
export default class SpecialVisualizations {
2020-10-11 22:37:55 +02:00
public static specialVisualizations : {
funcName : string ,
2021-01-03 13:50:18 +01:00
constr : ( ( state : State , tagSource : UIEventSource < any > , argument : string [ ] ) = > UIElement ) ,
2020-10-11 22:37:55 +02:00
docs : string ,
2020-10-17 02:37:53 +02:00
example? : string ,
2020-10-12 01:25:27 +02:00
args : { name : string , defaultValue? : string , doc : string } [ ]
2020-10-11 22:37:55 +02:00
} [ ] =
2020-10-09 20:10:21 +02:00
2020-11-17 16:29:51 +01:00
[ {
funcName : "all_tags" ,
docs : "Prints all key-value pairs of the object - used for debugging" ,
args : [ ] ,
2021-01-03 13:50:18 +01:00
constr : ( ( state : State , tags : UIEventSource < any > ) = > {
2020-11-17 16:29:51 +01:00
return new VariableUiElement ( tags . map ( tags = > {
const parts = [ ] ;
for ( const key in tags ) {
parts . push ( key + "=" + tags [ key ] ) ;
}
return parts . join ( "<br/>" )
} ) ) . SetStyle ( "border: 1px solid black; border-radius: 1em;padding:1em;display:block;" )
} )
} ,
2020-12-08 23:44:34 +01:00
2020-10-14 12:15:09 +02:00
{
funcName : "image_carousel" ,
docs : "Creates an image carousel for the given sources. An attempt will be made to guess what source is used. Supported: Wikidata identifiers, Wikipedia pages, Wikimedia categories, IMGUR (with attribution, direct links)" ,
args : [ {
2020-10-17 02:37:53 +02:00
name : "image key/prefix" ,
defaultValue : "image" ,
doc : "The keys given to the images, e.g. if <span class='literal-code'>image</span> is given, the first picture URL will be added as <span class='literal-code'>image</span>, the second as <span class='literal-code'>image:0</span>, the third as <span class='literal-code'>image:1</span>, etc... "
} ,
{
name : "smart search" ,
defaultValue : "true" ,
doc : "Also include images given via 'Wikidata', 'wikimedia_commons' and 'mapillary"
} ] ,
2021-01-03 13:50:18 +01:00
constr : ( state : State , tags , args ) = > {
2021-01-29 03:23:53 +01:00
const imagePrefix = args [ 0 ] ;
const loadSpecial = args [ 1 ] . toLowerCase ( ) === "true" ;
const searcher : UIEventSource < { key : string , url : string } [ ] > = new ImageSearcher ( tags , imagePrefix , loadSpecial ) ;
return new ImageCarousel ( searcher , tags ) ;
2020-10-11 22:37:55 +02:00
}
2020-10-14 12:15:09 +02:00
} ,
{
funcName : "image_upload" ,
docs : "Creates a button where a user can upload an image to IMGUR" ,
args : [ {
2020-10-17 02:37:53 +02:00
name : "image-key" ,
2020-10-14 12:15:09 +02:00
doc : "Image tag to add the URL to (or image-tag:0, image-tag:1 when multiple images are added)" ,
2020-10-17 02:37:53 +02:00
defaultValue : "image"
2020-10-14 12:15:09 +02:00
} ] ,
2021-01-03 13:50:18 +01:00
constr : ( state : State , tags , args ) = > {
2020-10-17 02:37:53 +02:00
return new ImageUploadFlow ( tags , args [ 0 ] )
2020-10-14 12:15:09 +02:00
}
} ,
2020-12-08 23:44:34 +01:00
{
funcName : "reviews" ,
docs : "Adds an overview of the mangrove-reviews of this object. IMPORTANT: the _name_ of the object should be defined for this to work!" ,
2020-12-31 22:41:52 +01:00
args : [ {
name : "subject" ,
doc : "The identifier used for this value; by default the name of the reviewed object"
} ] ,
2021-01-03 13:50:18 +01:00
constr : ( state : State , tags , args ) = > {
2020-12-08 23:44:34 +01:00
const tgs = tags . data ;
2021-01-01 01:27:14 +01:00
let subject = tgs . name ? ? "" ;
2020-12-31 22:41:52 +01:00
if ( args [ 0 ] !== undefined && args [ 0 ] !== "" ) {
subject = args [ 0 ] ;
}
2020-12-31 21:09:22 +01:00
if ( subject === "" ) {
2020-12-08 23:44:34 +01:00
return Translations . t . reviews . name_required ;
}
2020-12-31 21:13:16 +01:00
const mangrove = MangroveReviews . Get ( Number ( tgs . _lon ) , Number ( tgs . _lat ) ,
encodeURIComponent ( subject ) ,
2021-01-03 13:50:18 +01:00
state . mangroveIdentity ,
state . osmConnection . _dryRun
2020-12-08 23:44:34 +01:00
) ;
2021-01-03 13:50:18 +01:00
const form = new ReviewForm ( ( r , whenDone ) = > mangrove . AddReview ( r , whenDone ) , state . osmConnection . userDetails ) ;
2020-12-08 23:44:34 +01:00
return new ReviewElement ( mangrove . GetSubjectUri ( ) , mangrove . GetReviews ( ) , form ) ;
}
} ,
2020-10-14 12:15:09 +02:00
{
funcName : "opening_hours_table" ,
docs : "Creates an opening-hours table. Usage: {opening_hours_table(opening_hours)} to create a table of the tag 'opening_hours'." ,
args : [ {
name : "key" ,
defaultValue : "opening_hours" ,
2020-10-17 02:37:53 +02:00
doc : "The tagkey from which the table is constructed."
2020-10-14 12:15:09 +02:00
} ] ,
2021-01-03 13:50:18 +01:00
constr : ( state : State , tagSource : UIEventSource < any > , args ) = > {
2020-10-14 12:15:09 +02:00
let keyname = args [ 0 ] ;
if ( keyname === undefined || keyname === "" ) {
keyname = keyname ? ? "opening_hours"
}
return new OpeningHoursVisualization ( tagSource , keyname )
}
} ,
2020-10-11 22:37:55 +02:00
2020-10-12 01:25:27 +02:00
{
funcName : "live" ,
docs : "Downloads a JSON from the given URL, e.g. '{live(example.org/data.json, shorthand:x.y.z, other:a.b.c, shorthand)}' will download the given file, will create an object {shorthand: json[x][y][z], other: json[a][b][c] out of it and will return 'other' or 'json[a][b][c]. This is made to use in combination with tags, e.g. {live({url}, {url:format}, needed_value)}" ,
2020-10-17 02:37:53 +02:00
example : "{live({url},{url:format},hour)} {live(https://data.mobility.brussels/bike/api/counts/?request=live&featureID=CB2105,hour:data.hour_cnt;day:data.day_cnt;year:data.year_cnt,hour)}" ,
2020-10-12 01:25:27 +02:00
args : [ {
name : "Url" , doc : "The URL to load"
} , {
name : "Shorthands" ,
doc : "A list of shorthands, of the format 'shorthandname:path.path.path'. Seperated by ;"
} , {
name : "path" , doc : "The path (or shorthand) that should be returned"
} ] ,
2021-01-03 13:50:18 +01:00
constr : ( state : State , tagSource : UIEventSource < any > , args ) = > {
2020-10-12 01:25:27 +02:00
const url = args [ 0 ] ;
const shorthands = args [ 1 ] ;
const neededValue = args [ 2 ] ;
const source = LiveQueryHandler . FetchLiveData ( url , shorthands . split ( ";" ) ) ;
return new VariableUiElement ( source . map ( data = > data [ neededValue ] ? ? "Loading..." ) ) ;
}
2020-10-19 12:08:42 +02:00
} ,
2020-11-21 16:44:48 +01:00
{
funcName : "share_link" ,
docs : "Creates a link that (attempts to) open the native 'share'-screen" ,
example : "{share_link()} to share the current page, {share_link(<some_url>)} to share the given url" ,
args : [
{
name : "url" ,
2020-11-23 02:55:18 +01:00
doc : "The url to share (defualt: current URL)" ,
2020-11-21 16:44:48 +01:00
}
] ,
2021-01-03 13:50:18 +01:00
constr : ( state : State , tagSource : UIEventSource < any > , args ) = > {
2020-11-24 12:52:01 +01:00
if ( window . navigator . share ) {
2021-01-03 13:50:18 +01:00
const title = state . layoutToUse . data . title . txt ;
2020-11-22 03:50:09 +01:00
let name = tagSource . data . name ;
2020-11-23 12:54:10 +01:00
if ( name ) {
2020-11-23 02:55:18 +01:00
name = ` ${ name } ( ${ title } ) `
2020-11-23 12:54:10 +01:00
} else {
2020-11-22 03:50:09 +01:00
name = title ;
}
2020-11-23 12:54:10 +01:00
let url = args [ 0 ] ? ? ""
if ( url === "" ) {
url = window . location . href
}
2021-02-21 01:36:31 +01:00
return new ShareButton ( Svg . share_ui ( ) , {
2020-11-23 12:54:10 +01:00
title : name ,
url : url ,
2021-01-03 13:50:18 +01:00
text : state.layoutToUse.data.shortDescription.txt
2020-11-23 12:54:10 +01:00
} )
2020-11-21 16:44:48 +01:00
} else {
2020-11-23 02:55:18 +01:00
return new FixedUiElement ( "" )
2020-11-21 16:44:48 +01:00
}
2020-11-17 16:29:51 +01:00
2020-11-21 16:44:48 +01:00
}
}
2020-10-12 01:25:27 +02:00
2020-10-11 22:37:55 +02:00
]
2020-10-17 02:37:53 +02:00
static HelpMessage : UIElement = SpecialVisualizations . GenHelpMessage ( ) ;
private static GenHelpMessage() {
const helpTexts =
SpecialVisualizations . specialVisualizations . map ( viz = > new Combine (
[
` <h3> ${ viz . funcName } </h3> ` ,
viz . docs ,
"<ol>" ,
. . . viz . args . map ( arg = > new Combine ( [
"<li>" ,
"<b>" + arg . name + "</b>: " ,
arg . doc ,
arg . defaultValue === undefined ? "" : ( " Default: <span class='literal-code'>" + arg . defaultValue + "</span>" ) ,
"</li>"
] ) ) ,
"</ol>" ,
"<b>Example usage: </b>" ,
new FixedUiElement (
viz . example ? ? "{" + viz . funcName + "(" + viz . args . map ( arg = > arg . defaultValue ) . join ( "," ) + ")}"
) . SetClass ( "literal-code" ) ,
]
) ) ;
return new Combine ( [
"In a tagrendering, some special values are substituted by an advanced UI-element. This allows advanced features and visualizations to be reused by custom themes or even to query third-party API's." ,
. . . helpTexts
]
) ;
}
2020-10-09 20:10:21 +02:00
}