frontend client for gemstone. decentralised workplace app

feat: restore history from shard

serenity eed792ad 02a6ca56

Changed files
+46 -3
src
lib
+44 -3
src/lib/hooks/useChannel.ts
···
import type { AtUri } from "@/lib/types/atproto";
-
import { shardMessageSchema, type ShardMessage } from "@/lib/types/messages";
import { atUriEquals, atUriToString, stringToAtUri } from "@/lib/utils/atproto";
import { sendShardMessage } from "@/lib/utils/messages";
import {
···
// attach handlers here
-
socket.addEventListener("open", () => {
console.log("Connected to WebSocket");
setIsConnected(true);
-
});
socket.addEventListener("message", (event) => {
console.log("received message", event);
···
setMessages((prev) => [...prev, shardMessage]);
break;
}
}
});
···
console.log("Disconnected from WebSocket");
setIsConnected(false);
});
}, [socket, sessionInfo, channel]);
if (!oAuthSession) throw new Error("No OAuth session");
···
import type { AtUri } from "@/lib/types/atproto";
+
import type { RequestHistoryMessage, ShardMessage } from "@/lib/types/messages";
+
import { historyMessageSchema, shardMessageSchema } from "@/lib/types/messages";
import { atUriEquals, atUriToString, stringToAtUri } from "@/lib/utils/atproto";
import { sendShardMessage } from "@/lib/utils/messages";
import {
···
// attach handlers here
+
const handleOpen = () => {
console.log("Connected to WebSocket");
setIsConnected(true);
+
const requestHistoryMessage: RequestHistoryMessage = {
+
type: "shard/requestHistory",
+
channel: atUriToString(channel),
+
requestedBy: sessionInfo.clientDid,
+
};
+
console.log(
+
"requested history from lattice",
+
requestHistoryMessage,
+
);
+
socket.send(JSON.stringify(requestHistoryMessage));
+
};
+
+
if (socket.readyState === WebSocket.OPEN) {
+
handleOpen();
+
}
+
+
socket.addEventListener("open", handleOpen);
socket.addEventListener("message", (event) => {
console.log("received message", event);
···
setMessages((prev) => [...prev, shardMessage]);
break;
}
+
case "shard/history": {
+
console.log(
+
"received history from lattice",
+
validateTypeResult.data,
+
);
+
const { success, data: historyMessage } =
+
historyMessageSchema.safeParse(validateTypeResult.data);
+
if (!success) return;
+
if (!historyMessage.messages) return;
+
+
const parseChannelResult = stringToAtUri(
+
historyMessage.channel,
+
);
+
+
if (!parseChannelResult.ok) return;
+
const { data: channelAtUri } = parseChannelResult;
+
+
if (atUriEquals(channelAtUri, channel))
+
setMessages([...historyMessage.messages]);
+
}
}
});
···
console.log("Disconnected from WebSocket");
setIsConnected(false);
});
+
socket.addEventListener("open", handleOpen);
+
return () => {
+
socket.removeEventListener("open", handleOpen);
+
};
}, [socket, sessionInfo, channel]);
if (!oAuthSession) throw new Error("No OAuth session");
+2
src/lib/types/messages.ts
···
type: z.literal("shard/history"),
messages: z.optional(z.array(shardMessageSchema)),
channel: z.string(),
})
.strict();
export type HistoryMessage = z.infer<typeof historyMessageSchema>;
···
.safeExtend({
type: z.literal("shard/requestHistory"),
channel: z.string(),
})
.strict();
export type RequestHistoryMessage = z.infer<typeof requestHistoryMessageSchema>;
···
type: z.literal("shard/history"),
messages: z.optional(z.array(shardMessageSchema)),
channel: z.string(),
+
forClient: didSchema,
})
.strict();
export type HistoryMessage = z.infer<typeof historyMessageSchema>;
···
.safeExtend({
type: z.literal("shard/requestHistory"),
channel: z.string(),
+
requestedBy: didSchema,
})
.strict();
export type RequestHistoryMessage = z.infer<typeof requestHistoryMessageSchema>;