forked from MapComplete/MapComplete
131 lines
4 KiB
Svelte
131 lines
4 KiB
Svelte
<script lang="ts">
|
|
import type { SpecialVisualizationState } from "../../SpecialVisualization"
|
|
import { Store, UIEventSource } from "../../../Logic/UIEventSource"
|
|
import { placeholder } from "../../../Utils/placeholder"
|
|
import Translations from "../../i18n/Translations"
|
|
import Speech_bubble from "../../../assets/svg/Speech_bubble.svelte"
|
|
import Tr from "../../Base/Tr.svelte"
|
|
import NoteCommentElement from "./NoteCommentElement"
|
|
import Resolved from "../../../assets/svg/Resolved.svelte"
|
|
import Note from "../../../assets/svg/Note.svelte"
|
|
import LoginToggle from "../../Base/LoginToggle.svelte"
|
|
import { writable } from "svelte/store"
|
|
import Loading from "../../Base/Loading.svelte"
|
|
import { onDestroy } from "svelte"
|
|
|
|
export let state: SpecialVisualizationState
|
|
export let tags: UIEventSource<Record<string, string>>
|
|
let id = tags.data.id
|
|
$: {
|
|
id = $tags.id
|
|
}
|
|
|
|
let txt: UIEventSource<string> = new UIEventSource(undefined)
|
|
let _txt: string = undefined
|
|
txt.addCallbackD((t) => {
|
|
_txt = t
|
|
})
|
|
$: {
|
|
txt.setData(_txt)
|
|
}
|
|
const t = Translations.t.notes
|
|
|
|
let isClosed: Store<boolean> = tags.map((tags) => (tags?.["closed_at"] ?? "") !== "", onDestroy)
|
|
|
|
let isProcessing = writable(false)
|
|
async function addComment() {
|
|
if ((txt.data ?? "") == "") {
|
|
return
|
|
}
|
|
|
|
isProcessing.set(true)
|
|
|
|
if (isClosed.data) {
|
|
await state.osmConnection.reopenNote(id, txt.data)
|
|
await state.osmConnection.closeNote(id)
|
|
NoteCommentElement.mimickStatusChange(tags, false)
|
|
} else {
|
|
await state.osmConnection.addCommentToNote(id, txt.data)
|
|
}
|
|
NoteCommentElement.addCommentTo(txt.data, tags, state)
|
|
txt.setData("")
|
|
isProcessing.set(false)
|
|
}
|
|
|
|
async function closeNote() {
|
|
isProcessing.set(true)
|
|
await state.osmConnection.closeNote(id, txt.data)
|
|
NoteCommentElement.addCommentTo(txt.data, tags, state)
|
|
NoteCommentElement.mimickStatusChange(tags, false) // Will ping
|
|
isProcessing.set(false)
|
|
}
|
|
|
|
async function reopenNote() {
|
|
isProcessing.set(true)
|
|
await state.osmConnection.reopenNote(id, txt.data)
|
|
NoteCommentElement.mimickStatusChange(tags, true)
|
|
NoteCommentElement.addCommentTo(txt.data, tags, state)
|
|
tags.ping()
|
|
txt.set(undefined)
|
|
isProcessing.set(false)
|
|
}
|
|
</script>
|
|
|
|
<LoginToggle ignoreLoading={true} {state}>
|
|
<Tr slot="not-logged-in" t={t.loginToAddComment} />
|
|
|
|
<form
|
|
class="interactive border-interactive m-0 flex flex-col rounded-xl border-2 border-black px-2 py-1"
|
|
on:submit|preventDefault={() => addComment()}
|
|
>
|
|
<label class="neutral-label font-bold">
|
|
<Tr t={t.addAComment} />
|
|
<textarea
|
|
bind:value={_txt}
|
|
class="border-grey h-24 w-full rounded-l border"
|
|
rows="3"
|
|
use:placeholder={t.addCommentPlaceholder}
|
|
/>
|
|
</label>
|
|
|
|
{#if $isProcessing}
|
|
<Loading />
|
|
{:else}
|
|
<div class="flex flex-col">
|
|
{#if $txt?.length > 0}
|
|
<button class="primary flex" on:click|preventDefault={() => addComment()}>
|
|
<!-- Add a comment -->
|
|
<Speech_bubble class="h-7 w-7 pr-2" />
|
|
<Tr t={t.addCommentPlaceholder} />
|
|
</button>
|
|
{:else}
|
|
<div class="alert w-full">
|
|
<Tr t={t.typeText} />
|
|
</div>
|
|
{/if}
|
|
|
|
{#if !$isClosed}
|
|
<button class="flex items-center" on:click|preventDefault={() => closeNote()}>
|
|
<Resolved class="h-8 w-8 pr-2" />
|
|
<!-- Close note -->
|
|
{#if $txt === undefined || $txt === ""}
|
|
<Tr t={t.closeNote} />
|
|
{:else}
|
|
<Tr t={t.addCommentAndClose} />
|
|
{/if}
|
|
</button>
|
|
{:else}
|
|
<button class="flex items-center" on:click|preventDefault={() => reopenNote()}>
|
|
<!-- Reopen -->
|
|
<Note class="h-7 w-7 pr-2" />
|
|
{#if $txt === undefined || $txt === ""}
|
|
<Tr t={t.reopenNote} />
|
|
{:else}
|
|
<Tr t={t.reopenNoteAndComment} />
|
|
{/if}
|
|
</button>
|
|
{/if}
|
|
</div>
|
|
{/if}
|
|
</form>
|
|
</LoginToggle>
|