forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			105 lines
		
	
	
		
			No EOL
		
	
	
		
			4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			105 lines
		
	
	
		
			No EOL
		
	
	
		
			4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import Combine from "../Base/Combine";
 | |
| import BaseUIElement from "../BaseUIElement";
 | |
| import Svg from "../../Svg";
 | |
| import Link from "../Base/Link";
 | |
| import {FixedUiElement} from "../Base/FixedUiElement";
 | |
| import Translations from "../i18n/Translations";
 | |
| import {Utils} from "../../Utils";
 | |
| import Img from "../Base/Img";
 | |
| import {SlideShow} from "../Image/SlideShow";
 | |
| import {UIEventSource} from "../../Logic/UIEventSource";
 | |
| import {OsmConnection} from "../../Logic/Osm/OsmConnection";
 | |
| import {UIElement} from "../UIElement";
 | |
| import {VariableUiElement} from "../Base/VariableUIElement";
 | |
| 
 | |
| export default class NoteCommentElement extends Combine {
 | |
| 
 | |
| 
 | |
|     constructor(comment: {
 | |
|         "date": string,
 | |
|         "uid": number,
 | |
|         "user": string,
 | |
|         "user_url": string,
 | |
|         "action": "closed" | "opened" | "reopened" | "commented",
 | |
|         "text": string, "html": string
 | |
|     }) {
 | |
|         const t = Translations.t.notes;
 | |
| 
 | |
|         let actionIcon: BaseUIElement = undefined;
 | |
|         if (comment.action === "opened" || comment.action === "reopened") {
 | |
|             actionIcon = Svg.note_svg()
 | |
|         } else if (comment.action === "closed") {
 | |
|             actionIcon = Svg.resolved_svg()
 | |
|         } else {
 | |
|             actionIcon = Svg.speech_bubble_svg()
 | |
|         }
 | |
| 
 | |
|         let user: BaseUIElement
 | |
|         if (comment.user === undefined) {
 | |
|             user = t.anonymous
 | |
|         } else {
 | |
|             user = new Link(comment.user, comment.user_url ?? "", true)
 | |
|         }
 | |
| 
 | |
|         let userinfo = UIEventSource.FromPromise( Utils.downloadJsonCached("https://www.openstreetmap.org/api/0.6/user/"+comment.uid, 24*60*60*1000))
 | |
|         let userImg = new VariableUiElement( userinfo.map(userinfo => {
 | |
|             const href = userinfo?.user?.img?.href;
 | |
|             if(href !== undefined){
 | |
|                 return new Img(href).SetClass("rounded-full w-8 h-8 mr-4")
 | |
|             }
 | |
|             return undefined
 | |
|         }))
 | |
|         
 | |
|         const htmlElement = document.createElement("div")
 | |
|         htmlElement.innerHTML = comment.html
 | |
|         const images = Array.from(htmlElement.getElementsByTagName("a"))
 | |
|             .map(link => link.href)
 | |
|             .filter(link => {
 | |
|                 link = link.toLowerCase()
 | |
|                 const lastDotIndex = link.lastIndexOf('.')
 | |
|                 const extension = link.substring(lastDotIndex + 1, link.length)
 | |
|                 return Utils.imageExtensions.has(extension)
 | |
|             })
 | |
|         let imagesEl: BaseUIElement = undefined;
 | |
|         if (images.length > 0) {
 | |
|             const imageEls = images.map(i => new Img(i)
 | |
|                 .SetClass("w-full block")
 | |
|                 .SetStyle("min-width: 50px; background: grey;"));
 | |
|             imagesEl = new SlideShow(new UIEventSource<BaseUIElement[]>(imageEls)).SetClass("mb-1")
 | |
|         }
 | |
| 
 | |
|         super([
 | |
|             new Combine([
 | |
|                 actionIcon.SetClass("mr-4 w-6").SetStyle("flex-shrink: 0"),
 | |
|                 new FixedUiElement(comment.html).SetClass("flex flex-col").SetStyle("margin: 0"),
 | |
|             ]).SetClass("flex"),
 | |
|             imagesEl,
 | |
|             new Combine([userImg, user.SetClass("mr-2"), comment.date]).SetClass("flex justify-end items-center subtle")
 | |
|         ])
 | |
|         this.SetClass("flex flex-col pb-2 mb-2 border-gray-500 border-b")
 | |
| 
 | |
|     }
 | |
| 
 | |
|     public static addCommentTo(txt: string, tags: UIEventSource<any>, state: { osmConnection: OsmConnection }) {
 | |
|         const comments: any[] = JSON.parse(tags.data["comments"])
 | |
|         const username = state.osmConnection.userDetails.data.name
 | |
| 
 | |
|         var urlRegex = /(https?:\/\/[^\s]+)/g;
 | |
|         const html = txt.replace(urlRegex, function (url) {
 | |
|             return '<a href="' + url + '">' + url + '</a>';
 | |
|         })
 | |
| 
 | |
|         comments.push({
 | |
|             "date": new Date().toISOString(),
 | |
|             "uid": state.osmConnection.userDetails.data.uid,
 | |
|             "user": username,
 | |
|             "user_url": "https://www.openstreetmap.org/user/" + username,
 | |
|             "action": "commented",
 | |
|             "text": txt,
 | |
|             "html": html
 | |
|         })
 | |
|         tags.data["comments"] = JSON.stringify(comments)
 | |
|         tags.ping()
 | |
|     }
 | |
| 
 | |
| } |