[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. */ /* TODO: Store DAG relationships, somehow. */
pdu_json = PduV1ToJson(&pdu); pdu_json = PduV1ToJson(&pdu);
{ {
CommonID *sid= UserIdParse(pdu.sender, NULL); HashMap *state = StateCurrent(room);
User *suser = UserLock(room->db, sid->local); char *type, *state_key, *event_id;
if (StrEquals(pdu.type, "m.room.member")) if (StrEquals(pdu.type, "m.room.member"))
{ {
CommonID *id = UserIdParse(pdu.state_key, NULL); CommonID *id = UserIdParse(pdu.state_key, NULL);
@ -1846,9 +1847,24 @@ RoomAddEventV1(Room *room, PduV1 pdu)
UserUnlock(user); UserUnlock(user);
} }
UserPushEvent(suser, pdu_json); while (StateIterate(state, &type, &state_key, (void **) &event_id))
UserIdFree(sid); {
UserUnlock(suser); 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); JsonFree(pdu_json);

View file

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

View file

@ -1360,3 +1360,38 @@ UserGetJoins(User *user, char *batch)
DbUnlock(user->db, syncRef); DbUnlock(user->db, syncRef);
return keys; 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 *); 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 * Drops a sync diff, denoted by it's previous batch ID, if it
* exists. * exists.