Federation (#327)

* initial commit federation

* more federation

* more federation

* more federation

* completes follow, accept, undo

* add trail create activity

* process trail create activity

* more trail create activity

* adds missing endpoints

* adds update and delete activity

* adds comment activities

* adds activities back

* adds summit logs activities

* deletes follow counts table

* fixes migrations

* fixes migrations

* fixes migrations

* fixes migrations

* adds remote profiles

* ctd

* ctd

* we are getting closer...

* adds public summit logs

* fixes federated trails in lists

* adds remote lists

* adds list activites

* fixes lists

* adds notifications

* adds iri redirect

* fixes comments and summitlogs

* fixes follows and profiles

* adds asynchronous send

* fixes list search

* adds encryption key

* bug fixes

* fixes activity signing

* removes custon activity object types

* adds html editor

* fixes html editor

* fixes display issues on mastodon

* adds federated sharing

* finishes announcements

* fixes small summit log issues

* adds trail likes

* finalizes likes

* fixes images for komoot

* add disable federation option

* adds private profiles

* updates docs

* adds federated comments

* adds trail and comments actvitiypub routes

* adds mentions to editor

* adds mentions to trails, comments, summit logs

* updates theme

* updates theme

* update docs

* update docs

* updates docs

* fixes various frontend problems

* fixes activitypub follows api

* updates docs

* updates docs

---------

Co-authored-by: Christian Beutel <>
This commit is contained in:
Flomp
2025-06-21 10:09:22 +02:00
committed by GitHub
parent 742a6d9d30
commit 9276690d60
356 changed files with 57150 additions and 35470 deletions

View File

@@ -1,16 +1,17 @@
<script lang="ts">
import type { Comment } from "$lib/models/comment";
import { getFileURL } from "$lib/util/file_util";
import TextField from "../base/text_field.svelte";
import { fade } from "svelte/transition";
import { formatTimeSince } from "$lib/util/format_util";
import { _ } from "svelte-i18n";
import { fade } from "svelte/transition";
import TextField from "../base/text_field.svelte";
import { handleFromRecordWithIRI } from "$lib/util/activitypub_util";
import Editor from "../base/editor.svelte";
interface Props {
comment: Comment;
mode?: "show" | "edit";
ondelete?: (comment: Comment) => void
onedit?: (data: {comment: Comment, text: string}) => void
ondelete?: (comment: Comment) => void;
onedit?: (data: { comment: Comment; text: string }) => void;
}
let { comment, mode = "show", ondelete, onedit }: Props = $props();
@@ -24,15 +25,15 @@
});
let avatarSrc = $derived(
comment.expand?.author.avatar
? getFileURL(comment.expand.author, comment.expand.author.avatar)
comment.expand?.author.icon
? comment.expand?.author.icon
: `https://api.dicebear.com/7.x/initials/svg?seed=${comment.expand?.author.username ?? ""}&backgroundType=gradientLinear`,
);
let timeSince = $derived(formatTimeSince(new Date(comment.created ?? "")));
function deleteComment() {
ondelete?.(comment)
ondelete?.(comment);
}
function toggleEdit() {
@@ -48,38 +49,24 @@
in:fade={{ duration: 150 }}
out:fade={{ duration: 150 }}
>
{#if comment.expand?.author.private}
<a
href="/profile/{handleFromRecordWithIRI(comment)}"
class="text-sm font-semibold shrink-0"
>
<img
class="rounded-full w-10 aspect-square shrink-0"
class="rounded-full w-10 aspect-square"
src={avatarSrc}
alt="avatar"
/>
{:else}
<a
href="/profile/{comment.expand?.author.id}"
class="text-sm font-semibold shrink-0"
>
<img
class="rounded-full w-10 aspect-square"
src={avatarSrc}
alt="avatar"
/>
</a>
{/if}
</a>
<div>
<div class="flex items-center">
<p class="">
{#if comment.expand?.author.private}
<span class="text-sm font-semibold"
>{comment.expand?.author.username}</span
>
{:else}
<a
href="/profile/{comment.expand?.author.id}"
class="text-sm font-semibold"
>{comment.expand?.author.username}</a
>
{/if}
<a
href="/profile/{handleFromRecordWithIRI(comment)}"
class="text-sm font-semibold"
>{handleFromRecordWithIRI(comment)}</a
>
<span class="text-xs text-gray-500 ml-2"
>{$_(`n-${timeSince.unit}-ago`, {
values: { n: timeSince.value },
@@ -103,15 +90,20 @@
type="button"
class="btn-icon text-xs"
style="font-size: 0.75rem;"
onclick={deleteComment}><i class="fa fa-trash"></i></button
onclick={() => {
if (editing) {
editing = false;
} else {
deleteComment();
}
}}><i class="fa {editing ? 'fa-close' : 'fa-trash'}"></i></button
>
{/if}
</div>
{#if editing}
<TextField extraClasses="mt-2" bind:value={editedComment}
></TextField>
<Editor extraClasses="mt-2" bind:value={editedComment}></Editor>
{:else}
<p class="whitespace-pre-wrap text-sm">{comment.text}</p>
{@html comment.text}
{/if}
</div>
</div>