Merge branch 'feature'
This commit is contained in:
64
web/src/lib/components/comment/comment_card.svelte
Normal file
64
web/src/lib/components/comment/comment_card.svelte
Normal file
@@ -0,0 +1,64 @@
|
||||
<script lang="ts">
|
||||
import type { Comment } from "$lib/models/comment";
|
||||
import { getFileURL } from "$lib/util/file_util";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
import TextField from "../base/text_field.svelte";
|
||||
import { fade } from "svelte/transition";
|
||||
|
||||
export let comment: Comment;
|
||||
export let mode: "show" | "edit" = "show";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
|
||||
let editing: boolean = false;
|
||||
|
||||
let editedComment = comment.text;
|
||||
|
||||
const avatarSrc =
|
||||
comment.expand && comment.expand.author
|
||||
? getFileURL(comment.expand?.author, comment.expand?.author.avatar)
|
||||
: "https://api.dicebear.com/7.x/initials/svg?seed=comment&backgroundType=gradientLinear";
|
||||
|
||||
function deleteComment() {
|
||||
dispatch("delete", comment);
|
||||
}
|
||||
|
||||
function toggleEdit() {
|
||||
if (editing) {
|
||||
dispatch("edit", { comment: comment, text: editedComment });
|
||||
}
|
||||
editing = !editing;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="flex gap-4 items-center" in:fade={{duration: 150}} out:fade={{duration: 150}}>
|
||||
<img class="rounded-full w-10 aspect-square" src={avatarSrc} alt="avatar" />
|
||||
<div>
|
||||
<div class="flex items-center">
|
||||
<p class="text-sm font-semibold">
|
||||
{comment.expand?.author.username}
|
||||
</p>
|
||||
{#if mode == "edit"}
|
||||
<button
|
||||
type="button"
|
||||
class="btn-icon ml-2"
|
||||
style="font-size: 0.75rem;"
|
||||
on:click={toggleEdit}
|
||||
><i class="fa fa-{editing ? 'check' : 'pen'}"></i></button
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
class="btn-icon text-xs"
|
||||
style="font-size: 0.75rem;"
|
||||
on:click={deleteComment}><i class="fa fa-trash"></i></button
|
||||
>
|
||||
{/if}
|
||||
</div>
|
||||
{#if editing}
|
||||
<TextField extraClasses="mt-2" bind:value={editedComment}
|
||||
></TextField>
|
||||
{:else}
|
||||
<p>{comment.text}</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,10 +1,17 @@
|
||||
<script lang="ts">
|
||||
import { goto } from "$app/navigation";
|
||||
import SummitLogCard from "$lib/components/summit_log/summit_log_card.svelte";
|
||||
import Tabs from "$lib/components/base/tabs.svelte";
|
||||
import SummitLogCard from "$lib/components/summit_log/summit_log_card.svelte";
|
||||
import TrailDropdown from "$lib/components/trail/trail_dropdown.svelte";
|
||||
import WaypointCard from "$lib/components/waypoint/waypoint_card.svelte";
|
||||
import { Comment } from "$lib/models/comment";
|
||||
import type { Trail } from "$lib/models/trail";
|
||||
|
||||
import {
|
||||
comments_create,
|
||||
comments_delete,
|
||||
comments_update,
|
||||
} from "$lib/stores/comment_store";
|
||||
import { currentUser } from "$lib/stores/user_store";
|
||||
import { getFileURL } from "$lib/util/file_util";
|
||||
import {
|
||||
@@ -20,6 +27,9 @@
|
||||
import "photoswipe/style.css";
|
||||
import { onMount } from "svelte";
|
||||
import { _ } from "svelte-i18n";
|
||||
import Button from "../base/button.svelte";
|
||||
import Textarea from "../base/textarea.svelte";
|
||||
import CommentCard from "../comment/comment_card.svelte";
|
||||
import PhotoGallery from "../photo_gallery.svelte";
|
||||
|
||||
export let trail: Trail;
|
||||
@@ -31,6 +41,7 @@
|
||||
$_("waypoints"),
|
||||
$_("photos"),
|
||||
$_("summit-book"),
|
||||
$_("comments"),
|
||||
];
|
||||
|
||||
let map: Map;
|
||||
@@ -43,6 +54,10 @@
|
||||
|
||||
let openGallery: (idx?: number) => void;
|
||||
|
||||
let newComment: Comment = new Comment("", 0, "", trail.id ?? "");
|
||||
let commentCreateLoading: boolean = false;
|
||||
let commentDeleteLoading: boolean = false;
|
||||
|
||||
onMount(async () => {
|
||||
if (mode == "overview") {
|
||||
const L = (await import("leaflet")).default;
|
||||
@@ -98,6 +113,42 @@
|
||||
async function toggleMapFullScreen() {
|
||||
goto(`/map/trail/${trail.id!}`);
|
||||
}
|
||||
|
||||
async function createComment() {
|
||||
if (!$currentUser || !trail.id) {
|
||||
return;
|
||||
}
|
||||
commentCreateLoading = true;
|
||||
newComment.author = $currentUser.id;
|
||||
newComment.trail = trail.id;
|
||||
|
||||
comments_create(newComment).then((c) => {
|
||||
newComment.text = "";
|
||||
c.expand = {
|
||||
author: $currentUser!,
|
||||
};
|
||||
|
||||
trail.expand.comments_via_trail = [
|
||||
c,
|
||||
...(trail.expand.comments_via_trail ?? []),
|
||||
];
|
||||
});
|
||||
|
||||
commentCreateLoading = false;
|
||||
}
|
||||
|
||||
async function editComment(data: { comment: Comment; text: string }) {
|
||||
data.comment.text = data.text;
|
||||
await comments_update(data.comment);
|
||||
}
|
||||
|
||||
async function deleteComment(comment: Comment) {
|
||||
commentDeleteLoading = true;
|
||||
await comments_delete(comment);
|
||||
trail.expand.comments_via_trail =
|
||||
trail.expand.comments_via_trail.filter((c) => c.id !== comment.id);
|
||||
commentDeleteLoading = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
@@ -228,6 +279,53 @@
|
||||
{/each}
|
||||
</ul>
|
||||
{/if}
|
||||
{#if activeTab == 4}
|
||||
<div>
|
||||
{#if $currentUser}
|
||||
<div class="flex items-center gap-4">
|
||||
<img
|
||||
class="rounded-full w-10 aspect-square"
|
||||
src={getFileURL(
|
||||
$currentUser,
|
||||
$currentUser.avatar,
|
||||
) ||
|
||||
`https://api.dicebear.com/7.x/initials/svg?seed=${$currentUser.username}&backgroundType=gradientLinear`}
|
||||
alt="avatar"
|
||||
/>
|
||||
<div class="basis-full">
|
||||
<Textarea
|
||||
bind:value={newComment.text}
|
||||
rows={2}
|
||||
placeholder="Add comment..."
|
||||
></Textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end mt-3">
|
||||
<Button
|
||||
on:click={createComment}
|
||||
loading={commentCreateLoading}
|
||||
secondary={true}
|
||||
disabled={newComment.text.length == 0}
|
||||
>Comment</Button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
<ul>
|
||||
{#each trail.expand.comments_via_trail ?? [] as comment}
|
||||
<li>
|
||||
<CommentCard
|
||||
{comment}
|
||||
mode={comment.author == $currentUser?.id
|
||||
? "edit"
|
||||
: "show"}
|
||||
on:delete={(e) => deleteComment(e.detail)}
|
||||
on:edit={(e) => editComment(e.detail)}
|
||||
></CommentCard>
|
||||
</li>
|
||||
{/each}
|
||||
</ul>
|
||||
</div>
|
||||
{/if}
|
||||
{#if mode == "overview"}
|
||||
<div class="relative">
|
||||
<div class="rounded-xl h-72" id="map">
|
||||
|
||||
Reference in New Issue
Block a user