mirror of
https://github.com/Roslund/sthlm-mesh.git
synced 2026-08-07 09:23:02 +02:00
Update rsvp-tracker
This commit is contained in:
@@ -1,9 +1,104 @@
|
||||
{
|
||||
"messagePattern": "AW 1/10",
|
||||
"description": "Meetup 1 Oktober - Sundbyberg",
|
||||
"exportedAt": "2025-09-28T10:59:49.506Z",
|
||||
"attendees": {
|
||||
"yes": [],
|
||||
"maybe": [],
|
||||
"no": []
|
||||
"yes": [
|
||||
{
|
||||
"nodeId": "2665944228",
|
||||
"shortName": "TPH1",
|
||||
"longName": "TPH-1 Täby",
|
||||
"response": "yes",
|
||||
"timestamp": "2025-09-27T11:18:40.725Z"
|
||||
},
|
||||
{
|
||||
"nodeId": "1422344156",
|
||||
"shortName": "TELE",
|
||||
"longName": "MDG Telefonplan",
|
||||
"response": "yes",
|
||||
"timestamp": "2025-09-26T23:07:19.802Z"
|
||||
},
|
||||
{
|
||||
"nodeId": "2718571204",
|
||||
"shortName": "DXD3",
|
||||
"longName": "DXD3 Ruggen",
|
||||
"response": "yes",
|
||||
"timestamp": "2025-09-26T20:14:58.613Z"
|
||||
},
|
||||
{
|
||||
"nodeId": "2947306466",
|
||||
"shortName": "CVK",
|
||||
"longName": "SA0CVK Primary",
|
||||
"response": "yes",
|
||||
"timestamp": "2025-09-26T19:53:44.302Z"
|
||||
},
|
||||
{
|
||||
"nodeId": "2879616005",
|
||||
"shortName": "JlyT",
|
||||
"longName": "Jelly Test",
|
||||
"response": "yes",
|
||||
"timestamp": "2025-09-26T14:25:11.116Z"
|
||||
},
|
||||
{
|
||||
"nodeId": "1128157388",
|
||||
"shortName": "varg",
|
||||
"longName": "vargtastic",
|
||||
"response": "yes",
|
||||
"timestamp": "2025-09-25T16:47:09.777Z"
|
||||
},
|
||||
{
|
||||
"nodeId": "3681979732",
|
||||
"shortName": "Ros",
|
||||
"longName": "Ros Mobil",
|
||||
"response": "yes",
|
||||
"timestamp": "2025-09-24T16:02:08.895Z"
|
||||
},
|
||||
{
|
||||
"nodeId": "1978245180",
|
||||
"shortName": "CVK",
|
||||
"longName": "SA0CVK 0 (Ny Router)",
|
||||
"response": "yes",
|
||||
"timestamp": "2025-09-22T17:06:11.296Z"
|
||||
},
|
||||
{
|
||||
"nodeId": "3677336824",
|
||||
"shortName": "Chip",
|
||||
"longName": "Chip",
|
||||
"response": "yes",
|
||||
"timestamp": "2025-09-22T17:00:53.857Z"
|
||||
},
|
||||
{
|
||||
"nodeId": "3655315140",
|
||||
"shortName": "Ros9",
|
||||
"longName": "Roslund9",
|
||||
"response": "yes",
|
||||
"timestamp": "2025-09-22T05:37:43.576Z"
|
||||
},
|
||||
{
|
||||
"nodeId": "1222480744",
|
||||
"shortName": "JwKL",
|
||||
"longName": "JwK LF",
|
||||
"response": "yes",
|
||||
"timestamp": "2025-09-21T20:54:17.235Z"
|
||||
}
|
||||
],
|
||||
"maybe": [
|
||||
{
|
||||
"nodeId": "364861217",
|
||||
"shortName": "KAKd",
|
||||
"longName": "Kladdkakd",
|
||||
"response": "maybe",
|
||||
"timestamp": "2025-09-22T22:00:55.197Z"
|
||||
}
|
||||
],
|
||||
"no": [
|
||||
{
|
||||
"nodeId": "3946133666",
|
||||
"shortName": "phPi",
|
||||
"longName": "ph Raspberry Pi",
|
||||
"response": "no",
|
||||
"timestamp": "2025-09-26T20:11:29.025Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ function parseRSVPMessage(messageText, messagePattern) {
|
||||
}
|
||||
|
||||
async function fetchMessages() {
|
||||
const response = await fetch('https://map.sthlm-mesh.se/api/v1/text-messages?order=desc&count=1000');
|
||||
const response = await fetch('https://map.sthlm-mesh.se/api/v1/text-messages?order=desc&count=3000');
|
||||
const data = await response.json();
|
||||
return data.text_messages;
|
||||
}
|
||||
@@ -159,6 +159,49 @@ function generateRSVPHTML(summary) {
|
||||
}
|
||||
|
||||
|
||||
function mergeRSVPSummaries(primarySummary, manualAttendees) {
|
||||
const latestByNode = new Map();
|
||||
|
||||
const addFrom = (collection, fallbackType) => {
|
||||
if (!Array.isArray(collection)) return;
|
||||
for (const attendee of collection) {
|
||||
const nodeId = attendee.nodeId ?? attendee.node_id ?? attendee.id;
|
||||
if (!nodeId) continue;
|
||||
const responseType = attendee.response ?? fallbackType;
|
||||
if (!responseType) continue;
|
||||
const timestampString = attendee.timestamp ?? null;
|
||||
const ts = timestampString ? new Date(timestampString).getTime() : -Infinity;
|
||||
|
||||
const existing = latestByNode.get(nodeId);
|
||||
if (!existing || ts > existing.ts) {
|
||||
latestByNode.set(nodeId, {
|
||||
nodeId: nodeId,
|
||||
shortName: attendee.shortName ?? attendee.short_name ?? '?',
|
||||
longName: attendee.longName ?? attendee.long_name ?? `!${parseInt(nodeId).toString(16)}`,
|
||||
response: responseType,
|
||||
timestamp: timestampString ?? existing?.timestamp ?? new Date(0).toISOString(),
|
||||
ts
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
['yes', 'maybe', 'no'].forEach(type => addFrom(primarySummary?.[type], type));
|
||||
['yes', 'maybe', 'no'].forEach(type => addFrom(manualAttendees?.[type], type));
|
||||
|
||||
const merged = { yes: [], maybe: [], no: [] };
|
||||
for (const { ts, ...attendee } of latestByNode.values()) {
|
||||
if (merged[attendee.response]) merged[attendee.response].push(attendee);
|
||||
}
|
||||
|
||||
Object.values(merged).forEach(arr =>
|
||||
arr.sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp))
|
||||
);
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize RSVP tracking for a specific event
|
||||
* Supports both active events (parse messages + JSON) and archived events (JSON only)
|
||||
@@ -192,10 +235,8 @@ async function initRSVPTracker(eventId) {
|
||||
const responses = parseRSVPResponses(messages, eventData.messagePattern);
|
||||
summary = createRSVPSummary(responses);
|
||||
|
||||
// Add manual attendees
|
||||
Object.entries(eventData.attendees).forEach(([type, attendees]) => {
|
||||
summary[type].push(...attendees);
|
||||
});
|
||||
// Merge manual attendees with message-derived ones, keeping the latest response per attendee
|
||||
summary = mergeRSVPSummaries(summary, eventData.attendees);
|
||||
}
|
||||
|
||||
// Display results
|
||||
|
||||
Reference in New Issue
Block a user