Sprint 11: Freunde & Chat + Phosphor-Icon-Vollmigration

- Freundschaften (pending/accepted), Nutzersuche, Anfragen per Push
- Direktnachrichten mit Polling, iMessage-Stil, Deep-Links aus Push
- Alle Seiten (map, places, diary, health, dog-profile, sitting, knigge,
  forum, wiki, walks) vollständig auf Phosphor-Icons migriert
- Wikidata-Rassen-Scraper (~833 neue Rassen, lokal gespiegelte Fotos)
- TheDogAPI lokal gespiegelt (169 Rassen + Fotos)
- Quiz-Result-Cards horizontal (korrekte Bildproportionen)
- SW by-v89
This commit is contained in:
rene 2026-04-15 21:33:53 +02:00
parent 96bd57f0ad
commit 097295c628
44 changed files with 9980 additions and 300 deletions

View file

@ -248,6 +248,73 @@ const API = (() => {
updateRequest(id, status) { return patch(`/sitting/requests/${id}`, { status }); },
};
// ----------------------------------------------------------
// FORUM
// ----------------------------------------------------------
const forum = {
threads(params = {}) {
const q = new URLSearchParams(params).toString();
return get(`/forum/threads${q ? '?' + q : ''}`);
},
thread(id) { return get(`/forum/threads/${id}`); },
create(data) { return post('/forum/threads', data); },
deleteThread(id) { return del(`/forum/threads/${id}`); },
patchThread(id, data) { return patch(`/forum/threads/${id}`, data); },
addPost(threadId, data){ return post(`/forum/threads/${threadId}/posts`, data); },
deletePost(id) { return del(`/forum/posts/${id}`); },
uploadThreadFoto(id, file) {
const fd = new FormData(); fd.append('file', file);
return upload(`/forum/threads/${id}/fotos`, fd);
},
uploadPostFoto(id, file) {
const fd = new FormData(); fd.append('file', file);
return upload(`/forum/posts/${id}/fotos`, fd);
},
like(targetType, targetId) {
return post('/forum/like', { target_type: targetType, target_id: targetId });
},
report(targetType, targetId, grund) {
return post('/forum/report', { target_type: targetType, target_id: targetId, grund });
},
reports() { return get('/forum/reports'); },
resolveReport(id) { return patch(`/forum/reports/${id}`, { resolved: 1 }); },
membersMap() { return get('/forum/members/map'); },
setLocation(lat, lon, show) {
return patch('/forum/members/location', { lat, lon, show });
},
search(q) { return get(`/forum/search?q=${encodeURIComponent(q)}`); },
// Legacy aliases (keep old names working)
listThreads(params = {}) { return forum.threads(params); },
getThread(id) { return forum.thread(id); },
createThread(data) { return forum.create(data); },
createPost(tid, data) { return forum.addPost(tid, data); },
};
// ----------------------------------------------------------
// VERLORENER HUND
// ----------------------------------------------------------
const lost = {
list(lat = null, lon = null, radius_km = 25) {
const params = new URLSearchParams({ radius_km });
if (lat !== null) { params.set('lat', lat); params.set('lon', lon); }
return get(`/lost?${params}`);
},
report(data) { return post('/lost', data); },
uploadFoto(id, form) { return upload(`/lost/${id}/foto`, form); },
markFound(id) { return post(`/lost/${id}/found`); },
delete(id) { return del(`/lost/${id}`); },
};
// ----------------------------------------------------------
// KNIGGE
// ----------------------------------------------------------
const knigge = {
vote: (szenario_id, answer) => post('/knigge/vote', { szenario_id, answer }),
votes: (szenario_id) => get(`/knigge/votes?szenario_id=${encodeURIComponent(szenario_id)}`),
kiRat: (situation) => post('/knigge/ki-rat', { situation }),
};
// ----------------------------------------------------------
// WETTER
// ----------------------------------------------------------
@ -255,6 +322,30 @@ const API = (() => {
alerts(lat, lon) { return get(`/weather/alerts?lat=${lat}&lon=${lon}`); },
};
// ----------------------------------------------------------
// FREUNDE
// ----------------------------------------------------------
const friends = {
list() { return get('/friends/'); },
search(q) { return get(`/friends/search?q=${encodeURIComponent(q)}`); },
sendRequest(userId) { return post(`/friends/request/${userId}`, {}); },
accept(friendshipId) { return post(`/friends/${friendshipId}/accept`, {}); },
decline(friendshipId) { return post(`/friends/${friendshipId}/decline`, {}); },
remove(friendUserId) { return del(`/friends/${friendUserId}`); },
};
// ----------------------------------------------------------
// DIREKTNACHRICHTEN
// ----------------------------------------------------------
const chat = {
conversations() { return get('/chat/conversations'); },
start(partnerId) { return post('/chat/conversations', { partner_id: partnerId }); },
messages(convId, offset=0) { return get(`/chat/conversations/${convId}?offset=${offset}`); },
send(convId, text) { return post(`/chat/conversations/${convId}/messages`, { text }); },
markRead(convId) { return post(`/chat/conversations/${convId}/read`, {}); },
deleteMessage(msgId) { return del(`/chat/messages/${msgId}`); },
};
// ----------------------------------------------------------
// PUSH NOTIFICATIONS
// ----------------------------------------------------------
@ -325,7 +416,8 @@ const API = (() => {
return {
get, post, put, patch, del, upload,
auth, dogs, diary, health, tieraerzte, poison,
places, routes, walks, events, sitting, weather, push,
places, routes, walks, events, sitting, forum, lost, knigge, weather, push,
friends, chat,
subscribeToPush, getLocation,
APIError,
};