adds trail link sharing

This commit is contained in:
Christian Beutel
2025-08-20 16:51:33 +02:00
parent b3d44f3b78
commit 1e22c78c22
36 changed files with 598 additions and 36 deletions

View File

@@ -22,6 +22,7 @@
import TrailShareModal from "./trail_share_modal.svelte";
import { handleFromRecordWithIRI } from "$lib/util/activitypub_util";
import type { Snippet } from "svelte";
import { page } from "$app/state";
interface Props {
trails?: Set<Trail> | undefined;
@@ -44,6 +45,7 @@
return (
hasTrail() &&
!isMultiselectMode() &&
Boolean($currentUser) &&
(trail()!.expand?.author?.id === $currentUser?.actor ||
trail()!.expand?.trail_share_via_trail?.some(
(s) => s.permission == "edit",
@@ -143,6 +145,9 @@
}
function isFromCurrentUser(uTrail?: Trail): boolean {
if (!$currentUser) {
return false;
}
if (uTrail !== undefined) {
return uTrail.expand?.author?.id === $currentUser?.actor;
} else if (trails !== undefined && trails.size > 0) {
@@ -169,14 +174,16 @@
return;
}
const handle = handleFromRecordWithIRI(trail());
const handle = page.params.handle
if (item.value == "show") {
if (hasTrail()) {
goto(
mode == "overview" || mode == "multi-select"
const url = mode == "overview" || mode == "multi-select"
? `/map/trail/${handle}/${trailId()}`
: `/trail/view/${handle}/${trailId()}`,
: `/trail/view/${handle}/${trailId()}`
goto(
url + '?' + page.url.searchParams
);
}
} else if (item.value == "list") {
@@ -199,7 +206,7 @@
}
} else if (item.value == "print") {
if (hasTrail()) {
goto(`/map/trail/${handle}/${trailId()}/print`);
goto(`/map/trail/${handle}/${trailId()}/print?${page.url.searchParams}`);
}
} else if (item.value == "share") {
trailShareModal.openModal();

View File

@@ -398,19 +398,17 @@
</h3>
</div>
</div>
{#if ($currentUser && $currentUser.actor == trail.author) || trail.expand?.trail_share_via_trail?.length || trail.public}
<div class="flex flex-col items-center gap-y-2">
<div class="flex flex-col items-center gap-y-2">
{#if ($currentUser && $currentUser.actor == trail.author) || trail.expand?.trail_share_via_trail?.length || trail.public}
<LikeButton {trail}></LikeButton>
<TrailDropdown
trails={new Set<Trail>([trail])}
onDelete={() =>
history.length
? history.back()
: goto("/trails")}
{mode}
></TrailDropdown>
</div>
{/if}
{/if}
<TrailDropdown
trails={new Set<Trail>([trail])}
onDelete={() =>
history.length ? history.back() : goto("/trails")}
{mode}
></TrailDropdown>
</div>
</div>
</section>
<section
@@ -520,7 +518,7 @@
<div class="mb-6 mt-12 flex justify-between flex-wrap gap-y-4">
<Tabs {tabs} bind:activeTab></Tabs>
{#if activeTab == 0 && mode != "list"}
{#if $currentUser && activeTab == 0 && mode != "list"}
<Button
secondary
type="button"

View File

@@ -14,6 +14,15 @@
import Button from "../base/button.svelte";
import type { SelectItem } from "../base/select.svelte";
import Select from "../base/select.svelte";
import type { RadioItem } from "../base/radio_group.svelte";
import RadioGroup from "../base/radio_group.svelte";
import { TrailLinkShare } from "$lib/models/trail_link_share";
import {
linkShares,
trail_link_share_create,
trail_link_share_delete,
trail_link_share_index,
} from "$lib/stores/trail_link_share_store";
interface Props {
trail?: Trail;
@@ -30,8 +39,8 @@
openShareModalLocal();
}
async function openShareModalLocal() {
modal.openModal();
await fetchShares();
modal.openModal();
}
let copyButtonText = $state($_("copy-link"));
@@ -43,8 +52,25 @@
{ text: $_("edit"), value: "edit" },
];
const publicShareItems: RadioItem[] = [
{
text: $_("limited"),
value: "limited",
description: $_("public-share-limited"),
},
{
text: $_("everyone-with-the-link"),
value: "everyone",
description: $_("public-share-everyone"),
},
];
function copyURLToClipboard() {
navigator.clipboard.writeText(window.location.href);
let link = window.location.href;
if ($linkShares.length > 0) {
link = link + "?share=" + $linkShares[0].token;
}
navigator.clipboard.writeText(link);
copyButtonText = $_("link-copied");
setTimeout(() => (copyButtonText = $_("copy-link")), 3000);
@@ -88,8 +114,24 @@
sharesLoading = true;
await trail_share_index({ trail: trail.id! });
await trail_link_share_index(trail.id);
sharesLoading = false;
}
async function handlePublicAccessChange(e: RadioItem) {
if (trail === undefined) {
return;
}
if (e.value === "everyone") {
const share = new TrailLinkShare(trail.id!, "view");
await trail_link_share_create(share);
} else if (e.value === "limited" && $linkShares.length > 0) {
const share = $linkShares[0];
await trail_link_share_delete(share);
}
await trail_link_share_index(trail.id);
}
</script>
<Modal
@@ -159,6 +201,14 @@
{/if}
{/each}
{/if}
<h4 class="font-semibold mt-4 mb-2">{$_("public-access")}</h4>
<RadioGroup
name="account"
items={publicShareItems}
selected={$linkShares.length == 0 ? 0 : 1}
onchange={handlePublicAccessChange}
></RadioGroup>
</div>
{/snippet}
{#snippet footer()}