forked from MapComplete/MapComplete
		
	Small fixes to link, shows own reviews
This commit is contained in:
		
							parent
							
								
									ef70c17393
								
							
						
					
					
						commit
						0855f46c49
					
				
					 7 changed files with 85 additions and 62 deletions
				
			
		|  | @ -5,6 +5,7 @@ import {Review} from "./Review"; | |||
| export class MangroveIdentity { | ||||
|     private readonly _mangroveIdentity: UIEventSource<string>; | ||||
|     public keypair: any = undefined; | ||||
|     public readonly kid: UIEventSource<string> = new UIEventSource<string>(undefined); | ||||
| 
 | ||||
|     constructor(mangroveIdentity: UIEventSource<string>) { | ||||
|         const self = this; | ||||
|  | @ -13,10 +14,12 @@ export class MangroveIdentity { | |||
|             if (str === undefined || str === "") { | ||||
|                 return; | ||||
|             } | ||||
|             console.log("JWK ", JSON.parse(str)); | ||||
|             mangrove.jwkToKeypair(JSON.parse(str)).then(keypair => { | ||||
|                 self.keypair = keypair; | ||||
|                 console.log("Identity loaded") | ||||
|                 mangrove.publicToPem(keypair.publicKey).then(pem => { | ||||
|                     console.log("Identity loaded") | ||||
|                     self.kid.setData(pem); | ||||
|                 }) | ||||
|             }) | ||||
|         }) | ||||
|         if ((mangroveIdentity.data ?? "") === "") { | ||||
|  | @ -117,9 +120,10 @@ export default class MangroveReviews { | |||
|                 const reviewsByUser = []; | ||||
|                 for (const review of data.reviews) { | ||||
|                     const r = review.payload; | ||||
|                     console.log("PublicKey is ",self._mangroveIdentity.keypair, "reviews is",review.signature); | ||||
|                     const byUser = self._mangroveIdentity.keypair.publicKey === review.signature; | ||||
|                     console.log("IS SAME: ", byUser); | ||||
| 
 | ||||
| 
 | ||||
|                     console.log("PublicKey is ", self._mangroveIdentity.kid.data, "reviews.kid is", review.kid); | ||||
|                     const byUser = self._mangroveIdentity.kid.map(data => data === review.signature); | ||||
|                     const rev: Review = { | ||||
|                         made_by_user: byUser, | ||||
|                         date: new Date(r.iat * 1000), | ||||
|  | @ -133,7 +137,7 @@ export default class MangroveReviews { | |||
| 
 | ||||
|                     (rev.made_by_user ? reviewsByUser : reviews).push(rev); | ||||
|                 } | ||||
|                 self._reviews.setData(reviews) | ||||
|                 self._reviews.setData(reviewsByUser.concat(reviews)) | ||||
|             } | ||||
|         ); | ||||
|         return this._reviews; | ||||
|  |  | |||
|  | @ -1,3 +1,5 @@ | |||
| import {UIEventSource} from "../UIEventSource"; | ||||
| 
 | ||||
| export interface Review { | ||||
|     comment?: string, | ||||
|     author: string, | ||||
|  | @ -7,5 +9,5 @@ export interface Review { | |||
|     /** | ||||
|      * True if the current logged in user is the creator of this comment | ||||
|      */ | ||||
|     made_by_user: boolean | ||||
|     made_by_user: UIEventSource<boolean> | ||||
| } | ||||
|  | @ -4,10 +4,9 @@ | |||
| import {UIEventSource} from "../../Logic/UIEventSource"; | ||||
| import {Review} from "../../Logic/Web/Review"; | ||||
| import {UIElement} from "../UIElement"; | ||||
| import {Utils} from "../../Utils"; | ||||
| import Combine from "../Base/Combine"; | ||||
| import {FixedUiElement} from "../Base/FixedUiElement"; | ||||
| import Translations from "../i18n/Translations"; | ||||
| import SingleReview from "./SingleReview"; | ||||
| 
 | ||||
| export default class ReviewElement extends UIElement { | ||||
|     private readonly _reviews: UIEventSource<Review[]>; | ||||
|  | @ -17,37 +16,25 @@ export default class ReviewElement extends UIElement { | |||
|     constructor(subject: string, reviews: UIEventSource<Review[]>, middleElement: UIElement) { | ||||
|         super(reviews); | ||||
|         this._middleElement = middleElement; | ||||
|         if(reviews === undefined){ | ||||
|         if (reviews === undefined) { | ||||
|             throw "No reviews UIEVentsource Given!" | ||||
|         } | ||||
|         this._reviews = reviews; | ||||
|         this._subject = subject; | ||||
|     } | ||||
| 
 | ||||
|     InnerRender(): string { | ||||
|     | ||||
| 
 | ||||
|         function genStars(rating: number) { | ||||
|             if(rating === undefined){ | ||||
|                 return Translations.t.reviews.no_rating; | ||||
|             } | ||||
|             if(rating < 10){ | ||||
|                 rating = 10; | ||||
|             } | ||||
|             const scoreTen = Math.round(rating / 10); | ||||
|             return new Combine([ | ||||
|                 "<img src='./assets/svg/star.svg' />".repeat(Math.floor(scoreTen / 2)), | ||||
|                 scoreTen % 2 == 1 ? "<img src='./assets/svg/star_half.svg' />" : "" | ||||
|             ]) | ||||
|         } | ||||
|     InnerRender(): string { | ||||
| 
 | ||||
|         const elements = []; | ||||
|         const revs = this._reviews.data; | ||||
|         revs.sort((a,b) => (b.date.getTime() - a.date.getTime())); // Sort with most recent first
 | ||||
|         revs.sort((a, b) => (b.date.getTime() - a.date.getTime())); // Sort with most recent first
 | ||||
|         const avg = (revs.map(review => review.rating).reduce((a, b) => a + b, 0) / revs.length); | ||||
|         elements.push( | ||||
|             new Combine([ | ||||
|                 genStars(avg).SetClass("stars"), | ||||
|                 `<a href='https://mangrove.reviews/search?sub=${this._subject}'>`, | ||||
|                 SingleReview.GenStars(avg).SetClass("stars"), | ||||
|                 `<a target="_blank" href='https://mangrove.reviews/search?sub=${encodeURIComponent(this._subject)}'>`, | ||||
|                 Translations.t.reviews.title | ||||
|                     .Subs({count: "" + revs.length}), | ||||
|                 "</a>" | ||||
|  | @ -57,29 +44,7 @@ export default class ReviewElement extends UIElement { | |||
|          | ||||
|         elements.push(this._middleElement); | ||||
| 
 | ||||
|         elements.push(...revs.map(review => { | ||||
|             const d = review.date; | ||||
|             return new Combine( | ||||
|                 [ | ||||
|                     new Combine([ | ||||
|                         genStars(review.rating) | ||||
|                             .SetClass("review-rating"), | ||||
|                         new FixedUiElement(review.comment).SetClass("review-comment") | ||||
|                     ]).SetClass("review-stars-comment"), | ||||
| 
 | ||||
|                     new Combine([ | ||||
|                         new Combine([ | ||||
| 
 | ||||
|                             new FixedUiElement(review.author).SetClass("review-author"), | ||||
|                             review.affiliated ? Translations.t.reviews.affiliated_reviewer_warning : "", | ||||
|                         ]).SetStyle("margin-right: 0.5em"), | ||||
|                         new FixedUiElement(`${d.getFullYear()}-${Utils.TwoDigits(d.getMonth() + 1)}-${Utils.TwoDigits(d.getDate())} ${Utils.TwoDigits(d.getHours())}:${Utils.TwoDigits(d.getMinutes())}`) | ||||
|                             .SetClass("review-date") | ||||
|                     ]).SetClass("review-author-date") | ||||
| 
 | ||||
|                 ] | ||||
|             ).SetClass("review-element") | ||||
|         })); | ||||
|         elements.push(...revs.map(review => new SingleReview(review))); | ||||
|         elements.push( | ||||
|             new Combine([ | ||||
|                 Translations.t.reviews.attribution, | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ export default class ReviewForm extends InputElement<Review> { | |||
|         this.userDetails = userDetails; | ||||
|         const t = Translations.t.reviews; | ||||
|         this._value  = new UIEventSource({ | ||||
|             made_by_user: false, | ||||
|             made_by_user: new UIEventSource<boolean>(true), | ||||
|             rating: undefined, | ||||
|             comment: undefined, | ||||
|             author: userDetails.data.name, | ||||
|  |  | |||
|  | @ -1,11 +0,0 @@ | |||
| import {UIElement} from "../UIElement"; | ||||
| 
 | ||||
| export default class ReviewPanel extends UIElement { | ||||
|      | ||||
|      | ||||
|      | ||||
|     InnerRender(): string { | ||||
|         return ""; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										59
									
								
								UI/Reviews/SingleReview.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								UI/Reviews/SingleReview.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | |||
| import {UIElement} from "../UIElement"; | ||||
| import {Review} from "../../Logic/Web/Review"; | ||||
| import Combine from "../Base/Combine"; | ||||
| import {FixedUiElement} from "../Base/FixedUiElement"; | ||||
| import Translations from "../i18n/Translations"; | ||||
| import {Utils} from "../../Utils"; | ||||
| import ReviewElement from "./ReviewElement"; | ||||
| 
 | ||||
| export default class SingleReview extends UIElement{ | ||||
|     private _review: Review; | ||||
|     constructor(review: Review) { | ||||
|         super(review.made_by_user); | ||||
|         this._review = review; | ||||
|        | ||||
|     } | ||||
|     public static GenStars(rating: number): UIElement { | ||||
|         if (rating === undefined) { | ||||
|             return Translations.t.reviews.no_rating; | ||||
|         } | ||||
|         if (rating < 10) { | ||||
|             rating = 10; | ||||
|         } | ||||
|         const scoreTen = Math.round(rating / 10); | ||||
|         return new Combine([ | ||||
|             "<img src='./assets/svg/star.svg' />".repeat(Math.floor(scoreTen / 2)), | ||||
|             scoreTen % 2 == 1 ? "<img src='./assets/svg/star_half.svg' />" : "" | ||||
|         ]) | ||||
|     } | ||||
|     InnerRender(): string { | ||||
|         const d = this._review.date; | ||||
|         let review = this._review; | ||||
|         const el=  new Combine( | ||||
|             [ | ||||
|                 new Combine([ | ||||
|                   SingleReview.GenStars(review.rating) | ||||
|                         .SetClass("review-rating"), | ||||
|                     new FixedUiElement(review.comment).SetClass("review-comment") | ||||
|                 ]).SetClass("review-stars-comment"), | ||||
| 
 | ||||
|                 new Combine([ | ||||
|                     new Combine([ | ||||
| 
 | ||||
|                         new FixedUiElement(review.author).SetClass("review-author"), | ||||
|                         review.affiliated ? Translations.t.reviews.affiliated_reviewer_warning : "", | ||||
|                     ]).SetStyle("margin-right: 0.5em"), | ||||
|                     new FixedUiElement(`${d.getFullYear()}-${Utils.TwoDigits(d.getMonth() + 1)}-${Utils.TwoDigits(d.getDate())} ${Utils.TwoDigits(d.getHours())}:${Utils.TwoDigits(d.getMinutes())}`) | ||||
|                         .SetClass("review-date") | ||||
|                 ]).SetClass("review-author-date") | ||||
| 
 | ||||
|             ] | ||||
|         ); | ||||
|         el.SetClass("review-element"); | ||||
|         if(review.made_by_user){ | ||||
|             el.SetClass("review-by-current-user") | ||||
|         } | ||||
|         return el.Render(); | ||||
|     } | ||||
|      | ||||
| } | ||||
|  | @ -23,6 +23,10 @@ | |||
|     height: 1em; | ||||
| } | ||||
| 
 | ||||
| .review-by-current-user { | ||||
|     border: 5px solid var(--catch-detail-color); | ||||
| } | ||||
| 
 | ||||
| .review-rating { | ||||
|     display: flex; | ||||
|     flex-direction: row; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue