[ADD/WIP] Push events into sync

The code is still ugly(still waiting for j2s to support some things
before I can actually get *somewhere* with the schemas, which is my main
complaint), and it's definitely not spec-compliant, but it now means you
can actually see diffs in rooms you joined from the timeline!
This commit is contained in:
lda 2024-06-09 11:46:44 +02:00
parent 046a04e495
commit 97b1e4d723
4 changed files with 82 additions and 10 deletions

View file

@ -1815,8 +1815,9 @@ RoomAddEventV1(Room *room, PduV1 pdu)
/* TODO: Store DAG relationships, somehow. */
pdu_json = PduV1ToJson(&pdu);
{
CommonID *sid= UserIdParse(pdu.sender, NULL);
User *suser = UserLock(room->db, sid->local);
HashMap *state = StateCurrent(room);
char *type, *state_key, *event_id;
if (StrEquals(pdu.type, "m.room.member"))
{
CommonID *id = UserIdParse(pdu.state_key, NULL);
@ -1846,9 +1847,24 @@ RoomAddEventV1(Room *room, PduV1 pdu)
UserUnlock(user);
}
UserPushEvent(suser, pdu_json);
UserIdFree(sid);
UserUnlock(suser);
while (StateIterate(state, &type, &state_key, (void **) &event_id))
{
if (StrEquals(type, "m.room.member"))
{
/* Notify state_key about it.
* Does nothing if the user is not already in the room. */
CommonID *id = UserIdParse(state_key, NULL);
User *user = UserLock(room->db, id->local);
UserPushEvent(user, pdu_json);
UserIdFree(id);
UserUnlock(user);
}
Free(type);
Free(state_key);
}
StateFree(state);
}
JsonFree(pdu_json);

View file

@ -121,14 +121,28 @@ ROUTE_IMPL(RouteSync, path, argp)
{
char *roomId = ArrayGet(joins, i);
HashMap *room = HashMapCreate();
Array *el = UserGetEvents(user, currBatch, roomId);
size_t j;
Room *r = RoomLock(db, roomId);
Array *timeline = ArrayCreate();
/* TODO: Add history. */
for (j = 0; j < ArraySize(el); j++)
{
char *event = ArrayGet(el, j);
HashMap *e = RoomEventFetch(r, event);
HashMap *c = RoomEventClientify(e);
JsonSet(
rooms,
JsonValueObject(room),
2, "join", roomId
);
JsonFree(e);
JsonValueFree(HashMapDelete(c, "room_id"));
ArrayAdd(timeline, JsonValueObject(c));
}
RoomUnlock(r);
UserFreeList(el);
JsonSet(room, JsonValueArray(timeline), 1, "timeline");
JsonSet(rooms, JsonValueObject(room), 2, "join", roomId);
}
UserFreeList(joins);
}

View file

@ -1360,3 +1360,38 @@ UserGetJoins(User *user, char *batch)
DbUnlock(user->db, syncRef);
return keys;
}
Array *
UserGetEvents(User *user, char *batch, char *roomId)
{
DbRef *syncRef;
HashMap *data;
HashMap *joins;
Array *keys, *ret;
size_t i;
if (!user || !batch || !roomId)
{
return NULL;
}
syncRef = DbLock(user->db, 4, "users", user->name, "sync", batch);
if (!syncRef)
{
return NULL;
}
data = DbJson(syncRef);
joins = JsonValueAsObject(JsonGet(data, 2, "joins", roomId));
keys = (JsonValueAsArray(HashMapGet(joins, "timeline")));
ret = ArrayCreate();
for (i = 0; i < ArraySize(keys); i++)
{
char *str = JsonValueAsString(ArrayGet(keys, i));
ArrayAdd(ret, StrDuplicate(str));
}
DbUnlock(user->db, syncRef);
return ret;
}

View file

@ -403,6 +403,13 @@ extern Array * UserGetInvites(User *, char *);
*/
extern Array * UserGetJoins(User *, char *);
/**
* Get a list of event IDs for a diff table(and room ID),
* to be freed by
* .Fn UserFreeList .
*/
extern Array * UserGetEvents(User *, char *, char *);
/**
* Drops a sync diff, denoted by it's previous batch ID, if it
* exists.