Files
Kontrollverlust/web/js/user.js
T
irrlicht 15ef7db5f7 Profilbilder: Avatar-Upload, Anzeige auf Profil & Feed
- user.avatar-Spalte (Schema, migrate.sh, Migrationsdoku)
- POST /user/avatar (geschützt): Upload via storeImage, ersetzt/löscht altes Bild
- avatar in /u/{name}/info, /user/info und im entrySelect-Join (Feed-Karten)
- Account-Löschung entfernt auch das Avatar-File
- Frontend: Avatar im Profilkopf + Byline der Karten (50px), Upload-Form,
  Platzhalterbild no_profile_pic.jpg als Fallback
- .card img per :not(.avatar) von Beitragsbildern getrennt

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 18:20:14 +02:00

68 lines
2.3 KiB
JavaScript

"use strict";
// Nutzername aus dem Pfad /u/<name>.
const username = decodeURIComponent(location.pathname.split("/")[2] || "");
document.getElementById("rename-form").addEventListener("submit", async (e) => {
e.preventDefault();
const res = await api.post("/user/rename", new FormData(e.target));
if (res.ok) {
location.href = `/u/${encodeURIComponent(res.data.username)}`;
} else {
document.getElementById("rename-msg").textContent =
res.data.error || "Umbenennen fehlgeschlagen.";
}
});
document.getElementById("avatar-form").addEventListener("submit", async (e) => {
e.preventDefault();
const res = await api.post("/user/avatar", new FormData(e.target));
if (res.ok) {
// Cache umgehen, damit das neue Bild sofort erscheint.
document.getElementById("profile-avatar").src = `${avatarUrl(res.data.avatar)}?t=${Date.now()}`;
e.target.reset();
document.getElementById("avatar-msg").textContent = "";
} else {
document.getElementById("avatar-msg").textContent =
res.data.error || "Hochladen fehlgeschlagen.";
}
});
document.getElementById("delete-form").addEventListener("submit", async (e) => {
e.preventDefault();
if (!confirm("Konto wirklich unwiderruflich löschen?")) return;
const res = await api.post("/user/delete", new FormData(e.target));
if (res.ok) {
location.href = "/";
} else {
document.getElementById("delete-msg").textContent =
res.data.error || "Löschen fehlgeschlagen.";
}
});
async function init() {
const info = await api.get(`/u/${encodeURIComponent(username)}/info`);
if (info.error) {
document.getElementById("profile-name").textContent = "Nutzer nicht gefunden";
return;
}
document.getElementById("profile-name").textContent = info.username;
document.getElementById("profile-avatar").src = avatarUrl(info.avatar);
const since = new Date(info.created_at * 1000).toLocaleDateString("de-DE");
document.getElementById("profile-info").textContent = `Mitglied seit ${since}`;
// Eigene Seite? -> Einstellungen einblenden.
const me = await api.get("/user/info");
const isOwner = me.username === info.username;
document.getElementById("settings").hidden = !isOwner;
createFeed(
document.getElementById("feed"),
document.getElementById("sentinel"),
(page) => `/u/${encodeURIComponent(username)}/feed/${page}`
);
}
init();