forked from MapComplete/MapComplete
Feature(reviews): fix #2457, add report functionality with reason
This commit is contained in:
parent
dc62db7dcf
commit
7ce320075d
3 changed files with 89 additions and 10 deletions
|
@ -817,6 +817,9 @@
|
|||
"question_opinion": "How was your experience?",
|
||||
"rate": "Rate {n} stars",
|
||||
"rated": "Rated {n} stars",
|
||||
"reportReason": "Why should this report be reported?",
|
||||
"reportReview": "Report this review as inappropriate",
|
||||
"reportReviewTitle": "Report this review as inappropriate?",
|
||||
"reviewPlaceholder": "Describe your experience…",
|
||||
"reviewing_as": "Reviewing as {nickname}",
|
||||
"reviewing_as_anonymous": "Reviewing as anonymous",
|
||||
|
@ -942,4 +945,4 @@
|
|||
"startsWithQ": "A wikidata identifier starts with Q and is followed by a number"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -452,9 +452,14 @@ export default class FeatureReviews {
|
|||
|
||||
public async deleteReview(review: Review & {signature: string}){
|
||||
await MangroveReviews.deleteReview(await this._identity.getKeypair(), review)
|
||||
this.removeReviewLocally(review)
|
||||
}
|
||||
|
||||
public removeReviewLocally(review: Review){
|
||||
this._reviews.set(
|
||||
this._reviews.data.filter(r => r !== review)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<script lang="ts">
|
||||
import { MangroveReviews, Review } from "mangrove-reviews-typescript"
|
||||
|
||||
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import StarsBar from "./StarsBar.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
|
@ -7,7 +8,6 @@
|
|||
import { ariaLabel } from "../../Utils/ariaLabel"
|
||||
import ThemeViewState from "../../Models/ThemeViewState"
|
||||
import Markdown from "../Base/Markdown.svelte"
|
||||
import AccordionSingle from "../Flowbite/AccordionSingle.svelte"
|
||||
import AttributedImage from "../Image/AttributedImage.svelte"
|
||||
import DotMenu from "../Base/DotMenu.svelte"
|
||||
import { TrashIcon } from "@rgossiaux/svelte-heroicons/solid"
|
||||
|
@ -17,7 +17,11 @@
|
|||
import ReviewForm from "./ReviewForm.svelte"
|
||||
import type { Feature } from "geojson"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import FeatureReviews from "../../Logic/Web/MangroveReviews"
|
||||
import FeatureReviews, { MangroveIdentity } from "../../Logic/Web/MangroveReviews"
|
||||
import ShieldExclamation from "@babeard/svelte-heroicons/solid/ShieldExclamation"
|
||||
import Delete_icon from "../../assets/svg/Delete_icon.svelte"
|
||||
import ValidatedInput from "../InputElement/ValidatedInput.svelte"
|
||||
|
||||
|
||||
export let state: ThemeViewState = undefined
|
||||
export let tags: UIEventSource<Record<string, string>> = undefined
|
||||
|
@ -53,21 +57,39 @@
|
|||
|
||||
let isTesting = state?.featureSwitchIsTesting ?? new ImmutableStore(false)
|
||||
|
||||
function report() {
|
||||
MangroveReviews.reportAbuseReview(identity, review, "This review was reported by a MapComplete user")
|
||||
async function report() {
|
||||
let reason = reportReason.data
|
||||
if (!reason) {
|
||||
reason = "This review was reported by a MapComplete user"
|
||||
}
|
||||
const identity: CryptoKeyPair = await state?.userRelatedState?.mangroveIdentity.getKeypair()
|
||||
if (!isTesting.data) {
|
||||
|
||||
try {
|
||||
await MangroveReviews.reportAbuseReview(identity, review, reason)
|
||||
} catch (e) {
|
||||
console.error("Could not report review due to", e)
|
||||
await state.reportError(e)
|
||||
}
|
||||
} else {
|
||||
console.log("Not actually reporting, test mode")
|
||||
}
|
||||
showReport.set(false)
|
||||
reviews.removeReviewLocally(review)
|
||||
}
|
||||
|
||||
let deleted = new UIEventSource(false)
|
||||
|
||||
async function deleteR() {
|
||||
const identity: MangroveIdentity = await state?.userRelatedState?.mangroveIdentity.getKeypair()
|
||||
const identity: CryptoKeyPair = await state?.userRelatedState?.mangroveIdentity.getKeypair()
|
||||
console.log("Deleting review...", identity)
|
||||
if (!isTesting.data) {
|
||||
|
||||
try {
|
||||
reviews.deleteReview(review)
|
||||
await reviews.deleteReview(review)
|
||||
} catch (e) {
|
||||
console.log("Could not delete review... ", e)
|
||||
await state.reportError(e)
|
||||
}
|
||||
} else {
|
||||
console.log("Not really deleting the review, testing")
|
||||
|
@ -76,8 +98,10 @@
|
|||
deleted.setData(true)
|
||||
}
|
||||
|
||||
let reportReason = new UIEventSource("")
|
||||
let showDelete = new UIEventSource(false)
|
||||
let showEdit = new UIEventSource(false)
|
||||
let showReport = new UIEventSource(false)
|
||||
let isDebugging = state?.featureSwitches?.featureSwitchIsDebugging
|
||||
const t = Translations.t.reviews
|
||||
</script>
|
||||
|
@ -87,20 +111,62 @@
|
|||
<Tr t={t.deleteTitle} />
|
||||
</svelte:fragment>
|
||||
|
||||
<div class="flex gap-x-4 items-center m-8">
|
||||
<Delete_icon class="w-16" />
|
||||
<div class="p-4 low-interaction border-interactive">
|
||||
<StarsBar starSize="w-4 h-4 md:w-6 md:h-6" readonly={true} score={review.rating} />
|
||||
<div class="disable-links">
|
||||
<Markdown src={review.opinion} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Tr t={t.deleteText} />
|
||||
|
||||
<NextButton clss="primary" on:click={() => deleteR()}>
|
||||
<NextButton clss="primary float-right" on:click={() => deleteR()}>
|
||||
<TrashIcon class="w-12 text-red-600" />
|
||||
<Tr t={t.deleteConfirm} />
|
||||
</NextButton>
|
||||
</Popup>
|
||||
|
||||
|
||||
<Popup shown={showReport}>
|
||||
<svelte:fragment slot="header">
|
||||
<Tr t={t.reportReviewTitle} />
|
||||
</svelte:fragment>
|
||||
|
||||
<div class="flex gap-x-4 items-center m-8">
|
||||
<ShieldExclamation class="w-16" />
|
||||
<div class="p-4 low-interaction border-interactive">
|
||||
<StarsBar starSize="w-4 h-4 md:w-6 md:h-6" readonly={true} score={review.rating} />
|
||||
<div class="disable-links">
|
||||
<Markdown src={review.opinion} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>
|
||||
<Tr t={t.reportReason} />
|
||||
</h3>
|
||||
<div class="w-full">
|
||||
|
||||
<ValidatedInput type="text" value={reportReason} />
|
||||
</div>
|
||||
|
||||
<Tr t={t.deleteText} />
|
||||
|
||||
<NextButton clss="primary float-right" on:click={() => {report()}}>
|
||||
<TrashIcon class="w-12 text-red-600" />
|
||||
<Tr t={t.reportReview} />
|
||||
</NextButton>
|
||||
</Popup>
|
||||
|
||||
<Popup shown={showEdit}>
|
||||
<svelte:fragment slot="header">
|
||||
<Tr t={t.edit} />
|
||||
</svelte:fragment>
|
||||
|
||||
<ReviewForm {state} editReview={review} {reviews} />
|
||||
<ReviewForm {tags} {feature} {layer} {state} editReview={review} {reviews} />
|
||||
|
||||
</Popup>
|
||||
|
||||
|
@ -149,7 +215,7 @@
|
|||
{#if review.signature}
|
||||
<div class="self-start">
|
||||
<DotMenu>
|
||||
{#if byLoggedInUser}
|
||||
{#if $byLoggedInUser}
|
||||
<button on:click={() => showEdit.set(true)}>
|
||||
<PencilIcon />
|
||||
<Tr t={t.edit} />
|
||||
|
@ -158,6 +224,11 @@
|
|||
<TrashIcon />
|
||||
<Tr t={t.delete} />
|
||||
</button>
|
||||
{:else}
|
||||
<button on:click={() => showReport.set(true)}>
|
||||
<ShieldExclamation />
|
||||
<Tr t={t.reportReview} />
|
||||
</button>
|
||||
{/if}
|
||||
</DotMenu>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue