forked from MapComplete/MapComplete
Reviews: hopefully fix #1782, add review overview
This commit is contained in:
parent
8be41571fa
commit
592adfdf2a
11 changed files with 172 additions and 32 deletions
|
|
@ -29,7 +29,7 @@
|
|||
center()
|
||||
}
|
||||
|
||||
const titleIconBlacklist = ["osmlink", "sharelink", "favourite_title_icon"]
|
||||
let titleIconBlacklist = ["osmlink", "sharelink", "favourite_title_icon"]
|
||||
</script>
|
||||
|
||||
{#if favLayer !== undefined}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@
|
|||
|
||||
<div class="flex flex-col" on:keypress={(e) => console.log("Got keypress", e)}>
|
||||
<Tr t={Translations.t.favouritePoi.intro.Subs({ length: $favourites?.length ?? 0 })} />
|
||||
<Tr t={Translations.t.favouritePoi.priintroPrivacyvacy} />
|
||||
<Tr t={Translations.t.favouritePoi.introPrivacy} />
|
||||
|
||||
{#each $favourites as feature (feature.properties.id)}
|
||||
<FavouriteSummary {feature} {state} />
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@
|
|||
|
||||
let _state: "ask" | "saving" | "done" = "ask"
|
||||
|
||||
const connection = state.osmConnection
|
||||
let connection = state.osmConnection
|
||||
|
||||
const hasError: Store<undefined | "too_long"> = opinion.mapD(op => {
|
||||
let hasError: Store<undefined | "too_long"> = opinion.mapD(op => {
|
||||
const tooLong = op.length > FeatureReviews.REVIEW_OPINION_MAX_LENGTH
|
||||
if (tooLong) {
|
||||
return "too_long"
|
||||
|
|
@ -45,6 +45,8 @@
|
|||
return undefined
|
||||
})
|
||||
|
||||
let uploadFailed: string = undefined
|
||||
|
||||
async function save() {
|
||||
if (hasError.data) {
|
||||
return
|
||||
|
|
@ -63,13 +65,24 @@
|
|||
console.log("Testing - not actually saving review", review)
|
||||
await Utils.waitFor(1000)
|
||||
} else {
|
||||
await reviews.createReview(review)
|
||||
try {
|
||||
|
||||
await reviews.createReview(review)
|
||||
} catch (e) {
|
||||
console.error("Could not create review due to", e)
|
||||
uploadFailed = "" + e
|
||||
}
|
||||
}
|
||||
_state = "done"
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if _state === "done"}
|
||||
{#if uploadFailed}
|
||||
<div class="alert flex">
|
||||
<ExclamationTriangle class="w-6 h-6" />
|
||||
<Tr t={Translations.t.general.error}/>
|
||||
{uploadFailed}
|
||||
</div>
|
||||
{:else if _state === "done"}
|
||||
<Tr cls="thanks w-full" t={t.saved} />
|
||||
{:else if _state === "saving"}
|
||||
<Loading>
|
||||
|
|
@ -109,8 +122,9 @@
|
|||
/>
|
||||
{#if $hasError === "too_long"}
|
||||
<div class="alert flex items-center px-2">
|
||||
<ExclamationTriangle class="w-12 h-12"/>
|
||||
<Tr t={t.too_long.Subs({max: FeatureReviews.REVIEW_OPINION_MAX_LENGTH, amount: $opinion?.length ?? 0})}> </Tr>
|
||||
<ExclamationTriangle class="w-12 h-12" />
|
||||
<Tr
|
||||
t={t.too_long.Subs({max: FeatureReviews.REVIEW_OPINION_MAX_LENGTH, amount: $opinion?.length ?? 0})}></Tr>
|
||||
</div>
|
||||
{/if}
|
||||
</label>
|
||||
|
|
|
|||
40
src/UI/Reviews/ReviewsOverview.svelte
Normal file
40
src/UI/Reviews/ReviewsOverview.svelte
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<script lang="ts">
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
import Translations from "../i18n/Translations"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import LoginToggle from "../Base/LoginToggle.svelte"
|
||||
import LoginButton from "../Base/LoginButton.svelte"
|
||||
import SingleReview from "./SingleReview.svelte"
|
||||
import Mangrove_logo from "../../assets/svg/Mangrove_logo.svelte"
|
||||
|
||||
/**
|
||||
* A panel showing all the reviews by the logged-in user
|
||||
*/
|
||||
export let state: SpecialVisualizationState
|
||||
let reviews = state.userRelatedState.mangroveIdentity.getAllReviews()
|
||||
const t = Translations.t.reviews
|
||||
</script>
|
||||
|
||||
<LoginToggle {state}>
|
||||
<div slot="not-logged-in">
|
||||
<LoginButton osmConnection={state.osmConnection}>
|
||||
<Tr t={Translations.t.favouritePoi.loginToSeeList} />
|
||||
</LoginButton>
|
||||
</div>
|
||||
|
||||
|
||||
{#if $reviews?.length > 0}
|
||||
<div class="flex flex-col" on:keypress={(e) => console.log("Got keypress", e)}>
|
||||
{#each $reviews as review (review.sub)}
|
||||
<SingleReview {review} showSub={true} {state} />
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<Tr t={t.your_reviews_empty} />
|
||||
{/if}
|
||||
<a class="link-underline" href="https://github.com/pietervdvn/MapComplete/issues/1782" target="_blank" rel="noopener noreferrer"><Tr t={t.reviews_bug}/></a>
|
||||
<div class="flex justify-end">
|
||||
<Mangrove_logo class="h-12 w-12 shrink-0 p-1" />
|
||||
<Tr cls="text-sm subtle" t={t.attribution} />
|
||||
</div>
|
||||
</LoginToggle>
|
||||
|
|
@ -1,22 +1,43 @@
|
|||
<script lang="ts">
|
||||
import { Review } from "mangrove-reviews-typescript"
|
||||
import { Store } from "../../Logic/UIEventSource"
|
||||
import { ImmutableStore, Store } from "../../Logic/UIEventSource"
|
||||
import StarsBar from "./StarsBar.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
import Tr from "../Base/Tr.svelte"
|
||||
import { ariaLabel } from "../../Utils/ariaLabel"
|
||||
import type { SpecialVisualizationState } from "../SpecialVisualization"
|
||||
|
||||
export let review: Review & { kid: string; signature: string; madeByLoggedInUser: Store<boolean> }
|
||||
export let state: SpecialVisualizationState = undefined
|
||||
export let review: Review & { kid: string; signature: string; madeByLoggedInUser?: Store<boolean> }
|
||||
let name = review.metadata.nickname
|
||||
name ??= ((review.metadata.given_name ?? "") + " " + (review.metadata.family_name ?? "")).trim()
|
||||
let d = new Date()
|
||||
d.setTime(review.iat * 1000)
|
||||
let date = d.toDateString()
|
||||
let byLoggedInUser = review.madeByLoggedInUser
|
||||
let byLoggedInUser = review.madeByLoggedInUser ?? ImmutableStore.FALSE
|
||||
|
||||
export let showSub = false
|
||||
let subUrl = new URL(review.sub)
|
||||
let [lat, lon] = subUrl.pathname.split(",").map(l => Number(l))
|
||||
let sub = subUrl.searchParams.get("q")
|
||||
|
||||
function selectFeature(){
|
||||
console.log("Selecting and zooming to", {lon, lat})
|
||||
state?.mapProperties?.location?.setData({lon, lat})
|
||||
state?.mapProperties?.zoom?.setData(Math.max(16, state?.mapProperties?.zoom?.data))
|
||||
|
||||
state?.guistate?.closeAll()
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div class={"low-interaction rounded-lg p-1 px-2 " + ($byLoggedInUser ? "border-interactive" : "")}>
|
||||
<div class="flex items-center justify-between">
|
||||
<div class={"low-interaction rounded-lg p-1 px-2 flex flex-col" + ($byLoggedInUser ? "border-interactive" : "")}>
|
||||
{#if showSub}
|
||||
<button class="link" on:click={() => selectFeature()}>
|
||||
<h3>{sub}</h3>
|
||||
</button>
|
||||
{/if}
|
||||
<div class="flex items-center justify-between w-full">
|
||||
<div
|
||||
tabindex="0"
|
||||
use:ariaLabel={Translations.t.reviews.rated.Subs({
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@
|
|||
import FilterPanel from "./BigComponents/FilterPanel.svelte"
|
||||
import PrivacyPolicy from "./BigComponents/PrivacyPolicy.svelte"
|
||||
import { BBox } from "../Logic/BBox"
|
||||
import ReviewsOverview from "./Reviews/ReviewsOverview.svelte"
|
||||
|
||||
export let state: ThemeViewState
|
||||
let layout = state.layout
|
||||
|
|
@ -588,6 +589,10 @@
|
|||
<Tr t={Translations.t.favouritePoi.title} />
|
||||
</h3>
|
||||
<Favourites {state} />
|
||||
<h3>
|
||||
<Tr t={Translations.t.reviews.your_reviews} />
|
||||
</h3>
|
||||
<ReviewsOverview {state}/>
|
||||
</div>
|
||||
</TabbedGroup>
|
||||
</FloatOver>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue