Allow to show public routes only (#262)

* speedup loading some pages (reduce data amount of trail lists)

* optimize code

* fix save bio, if no tileset defined

* improve/fix visibility filter

* radio buttons -> checkboxes

---------

Co-authored-by: Christian Beutel <>
This commit is contained in:
slothful-vassal
2025-04-30 15:29:27 +02:00
committed by GitHub
parent b1fa6d3a3d
commit 742a6d9d30
16 changed files with 96 additions and 9 deletions

View File

@@ -3,6 +3,7 @@
import type { TrailFilter } from "$lib/models/trail";
import { searchLocations } from "$lib/stores/search_store";
import { tags_index } from "$lib/stores/tag_store";
import { currentUser } from "$lib/stores/user_store";
import { formatDistance, formatElevation } from "$lib/util/format_util";
import { getIconForLocation } from "$lib/util/icon_util";
import { _ } from "svelte-i18n";
@@ -17,7 +18,6 @@
import type { SelectItem } from "../base/select.svelte";
import Slider from "../base/slider.svelte";
import UserSearch from "../user_search.svelte";
import { currentUser } from "$lib/stores/user_store";
interface Props {
categories: Category[];
@@ -44,7 +44,7 @@
})),
);
const radioGroupItems: RadioItem[] = [
const radioGroupCompletenessItems: RadioItem[] = [
{ text: $_("completed"), value: "completed" },
{ text: $_("not-completed"), value: "not_completed" },
{ text: $_("no-preference"), value: "no_preference" },
@@ -82,11 +82,6 @@
update();
}
function setPublicFilter(e: Event) {
filter.public = (e.target as HTMLInputElement).checked;
update();
}
function setSharedFilter(e: Event) {
filter.shared = (e.target as HTMLInputElement).checked;
update();
@@ -111,6 +106,16 @@
update();
}
function setPrivateFilter(e: Event) {
filter.private = (e.target as HTMLInputElement).checked;
update();
}
function setPublicFilter(e: Event) {
filter.public = (e.target as HTMLInputElement).checked;
update();
}
async function searchCities(q: string) {
if (q.length == 0) {
filter.near.lat = undefined;
@@ -150,6 +155,20 @@
filter.tags = tags.map((t) => t.text);
update();
}
function getVisibiltyStatus(): number {
const isPublic = filter.public !== undefined && filter.public === true;
const isPrivate =
filter.private !== undefined && filter.private === true;
if (isPublic === true && isPrivate === true) {
return 2;
} else if (isPublic === true) {
return 1;
} else {
return 0;
}
}
</script>
<div class="trail-filter p-8 border border-input-border rounded-xl">
@@ -207,6 +226,22 @@
clearAfterSelect={false}
label={$_("author")}
></UserSearch>
<hr class="my-4 border-separator" />
<p class="text-sm font-medium">{$_("visibilty-status")}</p>
<div class="flex items-center mt-2 mb-4">
<input
id="private-checkbox"
type="checkbox"
checked={filter.private}
class="w-4 h-4 bg-input-background accent-primary border-input-border focus:ring-input-ring focus:ring-2"
onchange={setPrivateFilter}
/>
<label for="private-checkbox" class="ms-2 text-sm"
>{$_("private")}</label
>
</div>
<div class="flex items-center my-4">
<input
id="public-checkbox"
@@ -231,6 +266,7 @@
>{$_("shared")}</label
>
</div>
<hr class="my-4 border-separator" />
{/if}
<MultiSelect
@@ -339,8 +375,12 @@
<p class="text-sm font-medium pb-4">{$_("completion-status")}</p>
<RadioGroup
name="completed"
items={radioGroupItems}
selected={2}
items={radioGroupCompletenessItems}
selected={filter.completed === undefined
? 2
: filter.completed === true
? 0
: 1}
onchange={(item) => setCompletedFilter(item)}
></RadioGroup>
</div>

View File

@@ -325,6 +325,7 @@
"use-roads": "Nutze Straßen",
"username": "Nutzername",
"view": "Ansehen",
"visibilty-status": "Sichtbarkeit",
"walking-speed": "Laufgeschwindigkeit",
"waypoints": "{n, plural, =1 {Wegpunkt} other {Wegpunkte}}",
"welcome_to": "Willkommen bei",

View File

@@ -325,6 +325,7 @@
"use-roads": "Use Roads",
"username": "Username",
"view": "View",
"visibilty-status": "Visibilty",
"walking-speed": "",
"waypoints": "{n, plural, =1 {Waypoint} other {Waypoints}}",
"welcome_to": "Welcome to",

View File

@@ -325,6 +325,7 @@
"use-roads": "Use Roads",
"username": "Nombre de usuario",
"view": "Ver",
"visibilty-status": "Visibilidad",
"walking-speed": "",
"waypoints": "{n, plural, one {}=1 {Punto de Interés} other {Puntos de Interés}}",
"welcome_to": "Bienvenid@ a",

View File

@@ -325,6 +325,7 @@
"use-roads": "Use Roads",
"username": "Nom d'utilisateur",
"view": "Afficher",
"visibilty-status": "Visibilité",
"walking-speed": "",
"waypoints": "{n, plural, =1 {Point de passage} other {Points de passage}}",
"welcome_to": "Bienvenue sur",

View File

@@ -325,6 +325,7 @@
"use-roads": "Use Roads",
"username": "Felhasználónév",
"view": "View",
"visibilty-status": "Láthatóság",
"walking-speed": "",
"waypoints": "{n, plural, =1 {Waypoint} other {Waypoints}}",
"welcome_to": "Üdvözöljük a",

View File

@@ -325,6 +325,7 @@
"use-roads": "Use Roads",
"username": "Nome utente",
"view": "Visualizza",
"visibilty-status": "Visibilità",
"walking-speed": "",
"waypoints": "{n, plural, =1 {Punto di passaggio} other {Punti di passaggio}}",
"welcome_to": "Benvenuti a",

View File

@@ -325,6 +325,7 @@
"use-roads": "Use Roads",
"username": "Gebruikersnaam",
"view": "View",
"visibilty-status": "Zichtbaarheid",
"walking-speed": "",
"waypoints": "{n, plural, =1 {Waypoint} other {Waypoints}}",
"welcome_to": "Welkom bij",

View File

@@ -325,6 +325,7 @@
"use-roads": "Use Roads",
"username": "Nazwa Użytkownika",
"view": "Widok",
"visibilty-status": "Widoczność",
"walking-speed": "",
"waypoints": "{n, plural, one {Punkt} few {Punkty} many {Punktów}=1 {Punkt} other {Punktów}}",
"welcome_to": "Witaj w",

View File

@@ -325,6 +325,7 @@
"use-roads": "Use Roads",
"username": "Nome de utilizador",
"view": "Ver",
"visibilty-status": "Visibilidade",
"walking-speed": "",
"waypoints": "{n, plural, =1 {Ponto de passagem} other {Pontos de passagem}}",
"welcome_to": "Bem-vindo ao",

View File

@@ -325,6 +325,7 @@
"use-roads": "Use Roads",
"username": "用户名",
"view": "查看",
"visibilty-status": "可性见",
"walking-speed": "",
"waypoints": "{n, plural, =1 {路点} other {路点}}",
"welcome_to": "欢迎",

View File

@@ -107,6 +107,7 @@ interface TrailFilter {
author?: string;
public?: boolean;
shared?: boolean;
private?: boolean;
near: {
lat?: number,
lon?: number,

View File

@@ -532,6 +532,38 @@ function buildFilterText(user: AuthRecord, filter: TrailFilter, includeGeo: bool
filterText += ` AND author = ${filter.author}`
}
if (filter.public !== undefined || filter.private !== undefined || filter.shared !== undefined) {
filterText += " AND ("
const showPublic = filter.public === undefined || filter.public === true;
const showPrivate = filter.private === undefined || filter.private === true;
const showShared = filter.shared !== undefined && filter.shared === true;
if (showPublic === true) {
filterText += "(public = TRUE";
if (showPrivate === true && (!filter.author?.length || filter.author == user?.id)) {
filterText += ` OR author = ${user?.id}`;
}
filterText += ")";
}
else if (!filter.author?.length || filter.author == user?.id) {
filterText += "public = FALSE";
filterText += ` AND author = ${user?.id}`;
}
if (filter.shared !== undefined) {
if (filter.shared === true) {
filterText += ` OR shares = ${user?.id}`
} else {
filterText += ` AND NOT shares = ${user?.id}`
}
}
filterText += ")";
}
/*
if (filter.public !== undefined || filter.shared !== undefined) {
filterText += " AND ("
if (filter.public !== undefined) {
@@ -553,6 +585,7 @@ function buildFilterText(user: AuthRecord, filter: TrailFilter, includeGeo: bool
}
filterText += ")"
}
*/
if (filter.startDate) {
filterText += ` AND date >= ${new Date(filter.startDate).getTime() / 1000}`