adds profile timeline and follows

This commit is contained in:
Christian Beutel
2024-12-14 21:14:02 +01:00
parent e315c4d58a
commit b0d136ccea
27 changed files with 635 additions and 36 deletions

View File

@@ -23,12 +23,13 @@
on:click
{type}
>
{#if !loading}
<div class:invisible={loading}>
{#if icon}
<i class="fa fa-{icon} mr-2"></i>
{/if}
<slot />
{:else}
<div class="spinner"></div>
</div>
{#if loading}
<div class="absolute aspect-square spinner"></div>
{/if}
</button>

View File

@@ -24,8 +24,7 @@
/>
<div>
<a class="underline" href="/profile/{user.id}"> {user.username} </a>
{activity.type === "trail" ? "planned" : "completed"}
a trail
{activity.type === "trail" ? $_("planned-a-trail") : $_("completed-a-trail")}
<p class="text-xs text-gray-500 mb-3">
{new Date(activity.date).toLocaleDateString(undefined, {
month: "long",

View File

@@ -11,6 +11,7 @@
import { pb } from "$lib/pocketbase";
export let trail: Trail;
export let fullWidth: boolean = false;
$: thumbnail = trail.photos.length
? getFileURL(trail, trail.photos[trail.thumbnail])
@@ -20,7 +21,9 @@
</script>
<div
class="trail-card relative rounded-2xl border border-input-border min-w-72 cursor-pointer"
class="trail-card relative rounded-2xl border border-input-border {fullWidth
? 'min-w-72'
: 'w-72'} cursor-pointer"
on:mouseenter
on:mouseleave
role="listitem"
@@ -65,7 +68,8 @@
{/if}
{#if trail.expand.author}
<p class="text-xs text-gray-500 mb-3">
{$_("by")} <img
{$_("by")}
<img
class="rounded-full w-5 aspect-square mx-1 inline"
src={getFileURL(
trail.expand.author,

View File

@@ -17,8 +17,8 @@
page: 1,
totalPages: 1,
};
export let loading: boolean = false;
export let fullWidthCards: boolean = false;
const displayOptions: SelectItem[] = [
{ text: $_("card", { values: { n: 2 } }), value: "cards" },
@@ -180,7 +180,7 @@
data-sveltekit-preload-data="off"
>
{#if selectedDisplayOption === "cards"}
<TrailCard {trail}></TrailCard>
<TrailCard fullWidth={fullWidthCards} {trail}></TrailCard>
{:else}
<TrailListItem {trail}></TrailListItem>
{/if}

View File

@@ -8,6 +8,7 @@
"about": "Über",
"account-delete-confirm": "Du bist dabei, dein Konto zu löschen. Alle deine Routen werden ebenfalls gelöscht. Möchtest du fortfahren?",
"activity": "{n, plural, =1 {Aktivität} other {Aktivitäten}}",
"add-bio": "Bio hinzufügen",
"add-entry": "Eintrag hinzufügen",
"add-to-list": "Zu Liste hinzufügen",
"add-waypoint": "Wegpunkt hinzufügen",
@@ -39,10 +40,11 @@
"close": "Schließen",
"comment": "{n, plural, =1 {Kommentar} other {Kommentare}}",
"completed": "Abgeschlossen",
"completed-a-trail": "hat eine Route abgeschlossen",
"completion-status": "Abschlussstatus",
"confirm": "Bestätigen",
"confirm-deletion": "Löschen bestätigen",
"confirm-publish": "",
"confirm-publish": "Veröffentlichen bestätigen",
"confirm-share": "Teilen bestätigen",
"contribute": "Mitwirken",
"copy-link": "Link kopieren",
@@ -80,6 +82,9 @@
"elevation-gain": "Höhenunterschied (aufw.)",
"elevation-loss": "Höhenunterschied (abw.)",
"email": "Email",
"empty-activities": "{username} hat noch keine Aktivitäten",
"empty-bio": "{username} hat noch keine Biographie hinzugefügt",
"empty-lists": "{username} hat keine öffentlichen Listen",
"english": "Englisch",
"entry": "Eintrag",
"error-creating-user": "Fehler beim Erstellen des Nutzers",
@@ -96,13 +101,16 @@
"explore-some-trails": "Erkunden Sie einige Routen",
"export": "Exportieren",
"export-all-trails": "Alle Routen exportieren",
"favourite-sport": "",
"favourite-sport": "Lieblingssportart",
"features": "Features",
"file-format": "Dateiformat",
"file-too-big": "Datei {file} ist zu groß (max. {size})",
"filter-categories": "Kategorien filtern",
"filter-difficulty": "Schwierigkeit filtern",
"focus-map-on": "Karte fokussieren auf",
"follow": "Folgen",
"followers": "Folgen dir",
"following": "Du folgst",
"forgot-your-password": "Passwort vergessen?",
"french": "Französisch",
"german": "Deutsch",
@@ -124,13 +132,14 @@
"invalid-date": "Ungültiges Datum",
"invalid-username": "Ungültiger Nutzername",
"italian": "Italienisch",
"joined": "Beigetreten",
"language": "Sprache",
"latitude": "Breitengrad",
"license": "Lizenz",
"link-copied": "Link kopiert",
"list": "{n, plural, =1 {Liste} other {Listen}}",
"list-not-shared": "Mit niemandem geteilt",
"list-public-warning": "",
"list-public-warning": "Alle routen in dieser liste werden veröffentlicht.",
"list-saved-successfully": "Liste gespeichert",
"list-share-warning": "Durch das Teilen einer Liste werden automatisch alle darin enthaltenen Routen freigegeben.",
"list-share-warning-update": "Hinzugefügte Routen werden mit allen geteilt, die Zugriff auf diese Liste haben.",
@@ -179,6 +188,7 @@
"passwords-must-match": "Passwörter müssen übereinstimmen",
"photos": "Fotos",
"pick-a-trail": "Route auswählen",
"planned-a-trail": "hat eine Route geplant",
"polish": "Polnisch",
"portuguese": "Portugiesisch",
"print": "Drucken",
@@ -211,6 +221,7 @@
"slope": "Steigung",
"sort": "Sortieren",
"speed": "Geschwindigkeit",
"statistics": "Statistiken",
"stop-drawing": "Zeichnen beenden",
"summit-book": "Gipfelbuch",
"table": "Tabelle",

View File

@@ -8,6 +8,7 @@
"about": "About",
"account-delete-confirm": "You are about to delete your account. All your trails will also be deleted. Do you want to proceed?",
"activity": "{n, plural, =1 {Activity} other {Activities}}",
"add-bio": "Add Bio",
"add-entry": "Add Entry",
"add-to-list": "Add to list",
"add-waypoint": "Add Waypoint",
@@ -39,6 +40,7 @@
"close": "Close",
"comment": "{n, plural, =1 {Comment} other {Comments}}",
"completed": "Completed",
"completed-a-trail": "completed a trail",
"completion-status": "Completion Status",
"confirm": "Confirm",
"confirm-deletion": "Confirm Deletion",
@@ -80,6 +82,9 @@
"elevation-gain": "Elevation Gain",
"elevation-loss": "Elevation Loss",
"email": "Email",
"empty-activities": "{username} has no activity yet",
"empty-bio": "{username} has not added a bio yet",
"empty-lists": "{username} has no public lists",
"english": "English",
"entry": "Entry",
"error-creating-user": "Error creating user",
@@ -103,6 +108,9 @@
"filter-categories": "Filter categories",
"filter-difficulty": "Filter difficulty",
"focus-map-on": "Focus map on",
"follow": "Follow",
"followers": "Followers",
"following": "Following",
"forgot-your-password": "Forgot your password?",
"french": "French",
"german": "German",
@@ -124,6 +132,7 @@
"invalid-date": "Invalid Date",
"invalid-username": "Invalid username",
"italian": "Italian",
"joined": "Joined",
"language": "Language",
"latitude": "Latitude",
"license": "License",
@@ -179,6 +188,7 @@
"passwords-must-match": "Passwords must match",
"photos": "Photos",
"pick-a-trail": "Pick a trail",
"planned-a-trail": "planned a trail",
"polish": "Polish",
"portuguese": "Portuguese",
"print": "Print",
@@ -211,6 +221,7 @@
"slope": "Slope",
"sort": "Sort",
"speed": "Speed",
"statistics": "Statistics",
"stop-drawing": "Stop drawing",
"summit-book": "Summit Book",
"table": "Table",

View File

@@ -8,6 +8,7 @@
"about": "Informations",
"account-delete-confirm": "Vous êtes sur le point de supprimer votre compte. Toutes vos trails seront également supprimées. Voulez-vous continuer ?",
"activity": "",
"add-bio": "",
"add-entry": "Ajouter une entrée",
"add-to-list": "Ajouter à une liste",
"add-waypoint": "Ajouter un point de repère",
@@ -39,6 +40,7 @@
"close": "",
"comment": "{n, plural, =1 {Commentaire} other {Commentaires}}",
"completed": "Compléter",
"completed-a-trail": "",
"completion-status": "L'état d'achèvement",
"confirm": "",
"confirm-deletion": "",
@@ -80,6 +82,9 @@
"elevation-gain": "Gain d'altitude",
"elevation-loss": "",
"email": "Email",
"empty-activities": "",
"empty-bio": "",
"empty-lists": "",
"english": "Anglais",
"entry": "Entrée",
"error-creating-user": "Erreur durant la création de l'utilisateur",
@@ -103,6 +108,9 @@
"filter-categories": "",
"filter-difficulty": "",
"focus-map-on": "",
"follow": "",
"followers": "",
"following": "",
"forgot-your-password": "",
"french": "Français",
"german": "Allemand",
@@ -124,6 +132,7 @@
"invalid-date": "Date invalide",
"invalid-username": "Nom d'utilisateur invalide",
"italian": "Italien",
"joined": "",
"language": "Langue",
"latitude": "Latitude",
"license": "Licence",
@@ -179,6 +188,7 @@
"passwords-must-match": "",
"photos": "Photos",
"pick-a-trail": "Choisir un itinéraire",
"planned-a-trail": "",
"polish": "polonais",
"portuguese": "Portugais",
"print": "Imprimer",
@@ -211,6 +221,7 @@
"slope": "",
"sort": "Trier",
"speed": "",
"statistics": "",
"stop-drawing": "",
"summit-book": "Livre du sommet",
"table": "Tableau",

View File

@@ -8,6 +8,7 @@
"about": "A programról",
"account-delete-confirm": "Ön most a profilját készül törölni. Minden nyomvonala törlődik. Szeretné folytatni?",
"activity": "",
"add-bio": "",
"add-entry": "Bejegyzés hozzáadása",
"add-to-list": "Hozzáadás a listához",
"add-waypoint": "Útvonalpont hozzáadása",
@@ -39,6 +40,7 @@
"close": "",
"comment": "{n, plural, =1 {Megjegyzés} other {Megjegyzés}}",
"completed": "Teljesítve",
"completed-a-trail": "",
"completion-status": "Befejezés állapota",
"confirm": "",
"confirm-deletion": "",
@@ -80,6 +82,9 @@
"elevation-gain": "Magasságnövekedés",
"elevation-loss": "",
"email": "Email",
"empty-activities": "",
"empty-bio": "",
"empty-lists": "",
"english": "Angol",
"entry": "Bejegyzés",
"error-creating-user": "Hiba felhasználó hozzáadása közben",
@@ -103,6 +108,9 @@
"filter-categories": "",
"filter-difficulty": "",
"focus-map-on": "",
"follow": "",
"followers": "",
"following": "",
"forgot-your-password": "",
"french": "Francia",
"german": "Német",
@@ -124,6 +132,7 @@
"invalid-date": "Érvénytelen dátum",
"invalid-username": "Érvénytelen felhasználó",
"italian": "Olasz",
"joined": "",
"language": "Nyelf",
"latitude": "Szélesség",
"license": "License",
@@ -179,6 +188,7 @@
"passwords-must-match": "",
"photos": "Képek",
"pick-a-trail": "Válasszon útvonalat",
"planned-a-trail": "",
"polish": "Lengyel",
"portuguese": "Portugál",
"print": "",
@@ -211,6 +221,7 @@
"slope": "",
"sort": "Rendezés",
"speed": "",
"statistics": "",
"stop-drawing": "",
"summit-book": "Csúcspont könyv",
"table": "Táblázat",

View File

@@ -8,6 +8,7 @@
"about": "Su di noi",
"account-delete-confirm": "Stai per eliminare il tuo account. Tutti i tuoi percorsi saranno cancellati. Vuoi procedere?",
"activity": "",
"add-bio": "",
"add-entry": "Aggiungi voce",
"add-to-list": "Aggiungi alla lista",
"add-waypoint": "Aggiungere un waypoint",
@@ -39,6 +40,7 @@
"close": "Chiudi",
"comment": "{n, plural, =1 {Commento} other {Commenti}}",
"completed": "Completato",
"completed-a-trail": "",
"completion-status": "Stato di completamento",
"confirm": "",
"confirm-deletion": "",
@@ -80,6 +82,9 @@
"elevation-gain": "Guadagno di quota",
"elevation-loss": "",
"email": "Email",
"empty-activities": "",
"empty-bio": "",
"empty-lists": "",
"english": "Inglese",
"entry": "Voce",
"error-creating-user": "Errore durante la creazione dell'utente",
@@ -103,6 +108,9 @@
"filter-categories": "",
"filter-difficulty": "",
"focus-map-on": "",
"follow": "",
"followers": "",
"following": "",
"forgot-your-password": "",
"french": "Francese",
"german": "Tedesco",
@@ -124,6 +132,7 @@
"invalid-date": "Data non valida",
"invalid-username": "Nome utente non valido",
"italian": "",
"joined": "",
"language": "Lingua",
"latitude": "Latitudine",
"license": "Licenza",
@@ -179,6 +188,7 @@
"passwords-must-match": "",
"photos": "Foto",
"pick-a-trail": "Scegli un percorso",
"planned-a-trail": "",
"polish": "Polacco",
"portuguese": "Portoghese",
"print": "Stampa",
@@ -211,6 +221,7 @@
"slope": "Pendenza",
"sort": "Ordina",
"speed": "Velocità",
"statistics": "",
"stop-drawing": "Smettere di disegnare",
"summit-book": "Libro di vetta",
"table": "Tavolo",

View File

@@ -8,6 +8,7 @@
"about": "Over",
"account-delete-confirm": "Je staat op het punt je account te verwijderen. Al je wandelroutes worden hierdoor eveneens verwijderd. Wil je doorgaan?",
"activity": "",
"add-bio": "",
"add-entry": "Item toevoegen",
"add-to-list": "Toevoegen aan lijst",
"add-waypoint": "Routepunt toevoegen",
@@ -39,6 +40,7 @@
"close": "",
"comment": "{n, plural, =1 {Opmerking} other {Opmerkingen}}",
"completed": "Voltooid",
"completed-a-trail": "",
"completion-status": "Voltooiingsstatus",
"confirm": "",
"confirm-deletion": "",
@@ -80,6 +82,9 @@
"elevation-gain": "Hoogteverschil",
"elevation-loss": "",
"email": "E-mail",
"empty-activities": "",
"empty-bio": "",
"empty-lists": "",
"english": "Engels",
"entry": "Item",
"error-creating-user": "Het account kan niet worden aangemaakt",
@@ -103,6 +108,9 @@
"filter-categories": "",
"filter-difficulty": "",
"focus-map-on": "",
"follow": "",
"followers": "",
"following": "",
"forgot-your-password": "",
"french": "Frans",
"german": "Duits",
@@ -124,6 +132,7 @@
"invalid-date": "Ongeldige datum",
"invalid-username": "Ongeldige gebruikersnaam",
"italian": "Italiaans",
"joined": "",
"language": "Taal",
"latitude": "Breedtegraad",
"license": "Licentie",
@@ -179,6 +188,7 @@
"passwords-must-match": "",
"photos": "Foto's",
"pick-a-trail": "Kies een wandelroute",
"planned-a-trail": "",
"polish": "Pools",
"portuguese": "Portugees",
"print": "Afdrukken",
@@ -211,6 +221,7 @@
"slope": "",
"sort": "Sorteren",
"speed": "",
"statistics": "",
"stop-drawing": "",
"summit-book": "Bergtopboek",
"table": "Tabel",

View File

@@ -8,6 +8,7 @@
"about": "Na temat",
"account-delete-confirm": "Usuniesz swoje konto. Wszystkie twoje ścieżki zostaną usunięte. Czy chcesz kontynuować?",
"activity": "",
"add-bio": "",
"add-entry": "Dodaj Pozycję",
"add-to-list": "Dodaj do listy",
"add-waypoint": "Dodaj Punkt",
@@ -39,6 +40,7 @@
"close": "",
"comment": "{n, plural, =1 {Komentarz} other {Komentarze}}",
"completed": "Zakończono",
"completed-a-trail": "",
"completion-status": "Stan ukończenia",
"confirm": "",
"confirm-deletion": "",
@@ -80,6 +82,9 @@
"elevation-gain": "Wzrost Wysokości",
"elevation-loss": "",
"email": "Email",
"empty-activities": "",
"empty-bio": "",
"empty-lists": "",
"english": "Angielski",
"entry": "Pozycja",
"error-creating-user": "Błąd tworzenia użytkownika",
@@ -103,6 +108,9 @@
"filter-categories": "",
"filter-difficulty": "",
"focus-map-on": "",
"follow": "",
"followers": "",
"following": "",
"forgot-your-password": "",
"french": "Francuski",
"german": "Niemiecki",
@@ -124,6 +132,7 @@
"invalid-date": "Nieprawidłowa data",
"invalid-username": "Błędna nazwa użytkownika",
"italian": "Włoski",
"joined": "",
"language": "Język",
"latitude": "Szerokość",
"license": "Licencja",
@@ -179,6 +188,7 @@
"passwords-must-match": "",
"photos": "Zdjęcia",
"pick-a-trail": "Wybierz ścieżkę",
"planned-a-trail": "",
"polish": "Polski",
"portuguese": "Portugalski",
"print": "",
@@ -211,6 +221,7 @@
"slope": "",
"sort": "Sortowanie",
"speed": "",
"statistics": "",
"stop-drawing": "",
"summit-book": "Logbook",
"table": "Tabela",

View File

@@ -8,6 +8,7 @@
"about": "Sobre",
"account-delete-confirm": "Você está prestes a excluir sua conta. Todas as suas trilhas também serão excluídas. Queres prosseguir?",
"activity": "",
"add-bio": "",
"add-entry": "Adicionar entrada",
"add-to-list": "Adicionar à lista",
"add-waypoint": "Adicionar ponto de vista",
@@ -39,6 +40,7 @@
"close": "",
"comment": "{n, plural, =1 {Comentário} other {Comentários}}",
"completed": "Completada",
"completed-a-trail": "",
"completion-status": "Status de conclusão",
"confirm": "",
"confirm-deletion": "",
@@ -80,6 +82,9 @@
"elevation-gain": "Ganho de elevação",
"elevation-loss": "",
"email": "Email",
"empty-activities": "",
"empty-bio": "",
"empty-lists": "",
"english": "Inglês",
"entry": "Entrada",
"error-creating-user": "Erro ao criar usuário",
@@ -103,6 +108,9 @@
"filter-categories": "",
"filter-difficulty": "",
"focus-map-on": "",
"follow": "",
"followers": "",
"following": "",
"forgot-your-password": "",
"french": "Francês",
"german": "Alemão",
@@ -124,6 +132,7 @@
"invalid-date": "Data inválida",
"invalid-username": "Nome de usuário inválido",
"italian": "Italiano",
"joined": "",
"language": "Língua",
"latitude": "Latitude",
"license": "Licença",
@@ -179,6 +188,7 @@
"passwords-must-match": "",
"photos": "Fotos",
"pick-a-trail": "Escolha uma trilha",
"planned-a-trail": "",
"polish": "Polonês",
"portuguese": "Português",
"print": "",
@@ -211,6 +221,7 @@
"slope": "",
"sort": "Ordenar",
"speed": "",
"statistics": "",
"stop-drawing": "",
"summit-book": "Livro da cimeira",
"table": "Tabela",

View File

@@ -8,6 +8,7 @@
"about": "关于",
"account-delete-confirm": "您现在要删除当前账户,所有的路线都会删除无法恢复,确认继续操作吗?",
"activity": "",
"add-bio": "",
"add-entry": "添加日程",
"add-to-list": "添加到列表",
"add-waypoint": "添加坐标",
@@ -39,6 +40,7 @@
"close": "",
"comment": "{n, plural, =1 {评论} other {评论}}",
"completed": "已完成",
"completed-a-trail": "",
"completion-status": "完成状态",
"confirm": "",
"confirm-deletion": "",
@@ -80,6 +82,9 @@
"elevation-gain": "上升海拔",
"elevation-loss": "",
"email": "电子邮箱",
"empty-activities": "",
"empty-bio": "",
"empty-lists": "",
"english": "英语",
"entry": "日程",
"error-creating-user": "创建用户错误",
@@ -103,6 +108,9 @@
"filter-categories": "",
"filter-difficulty": "",
"focus-map-on": "",
"follow": "",
"followers": "",
"following": "",
"forgot-your-password": "",
"french": "法语",
"german": "德语",
@@ -124,6 +132,7 @@
"invalid-date": "无效日期",
"invalid-username": "无效用户名",
"italian": "意大利语",
"joined": "",
"language": "语言",
"latitude": "维度",
"license": "开源协议",
@@ -179,6 +188,7 @@
"passwords-must-match": "",
"photos": "图片",
"pick-a-trail": "选择一个路线",
"planned-a-trail": "",
"polish": "波兰语",
"portuguese": "葡萄牙语",
"print": "",
@@ -211,6 +221,7 @@
"slope": "",
"sort": "排序",
"speed": "",
"statistics": "",
"stop-drawing": "",
"summit-book": "详细日程",
"table": "表格",

View File

@@ -0,0 +1,16 @@
import type { User, UserAnonymous } from "./user";
export class Follow {
id?: string;
follower: string;
followee: string;
expand?: {
follower: UserAnonymous,
followee: UserAnonymous
}
constructor(follower: string, followee: string) {
this.follower = follower;
this.followee = followee;
}
}

View File

@@ -0,0 +1,88 @@
import type { Follow } from "$lib/models/follow";
import { ClientResponseError, type ListResult } from "pocketbase";
let follows: Follow[] = [];
export async function follows_index(data: { follower?: string, followee?: string }, page: number = 1, perPage: number = 10, f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> = fetch) {
const r = await f('/api/v1/follow?' + new URLSearchParams({
filter: data.follower ? `follower='${data.follower}'` : data.followee ? `followee='${data.followee}'` : '',
page: page.toString(),
"per-page": perPage.toString()
}), {
method: 'GET',
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
const fetchedFollows: ListResult<Follow> = await r.json();
const result = page > 1 ? [...follows, ...fetchedFollows.items] : fetchedFollows.items
follows = result;
return { ...fetchedFollows, items: result };
}
export async function follows_a_b(a: string, b: string, f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> = fetch) {
const r = await f('/api/v1/follow?' + new URLSearchParams({
filter: `follower='${a}'&&followee='${b}'`,
}), {
method: 'GET',
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
const response: ListResult<Follow> = await r.json();
return response.items.at(0);
}
export async function follows_counts(id: string, f: (url: RequestInfo | URL, config?: RequestInit) => Promise<Response> = fetch) {
const r = await f('/api/v1/follow/count/' + id, {
method: 'GET',
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
const response: { followers: number, following: number } = await r.json();
return response;
}
export async function follows_create(follow: Follow) {
let r = await fetch('/api/v1/follow', {
method: 'PUT',
body: JSON.stringify(follow),
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
}
export async function follows_update(follow: Follow) {
let r = await fetch('/api/v1/follow/' + follow.id, {
method: 'POST',
body: JSON.stringify(follow),
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
}
export async function follows_delete(follow: Follow) {
const r = await fetch('/api/v1/follow/' + follow.id, {
method: 'DELETE',
})
if (!r.ok) {
throw new ClientResponseError(await r.json())
}
}