table and reducer updates
This commit is contained in:
+51
-21
@@ -212,7 +212,7 @@ export const register = spacetimedb.reducer(
|
||||
(ctx, { username, password }) => {
|
||||
validateName(username);
|
||||
if (!password || password.length < 4) throw new SenderError('Password must be at least 4 characters');
|
||||
|
||||
|
||||
for (const u of ctx.db.user.iter()) {
|
||||
if (u.username === username) {
|
||||
throw new SenderError('Username already taken');
|
||||
@@ -221,11 +221,11 @@ export const register = spacetimedb.reducer(
|
||||
|
||||
const user = ctx.db.user.identity.find(ctx.sender);
|
||||
if (user) {
|
||||
ctx.db.user.identity.update({
|
||||
...user,
|
||||
username,
|
||||
ctx.db.user.identity.update({
|
||||
...user,
|
||||
username,
|
||||
password,
|
||||
name: user.name || username
|
||||
name: user.name || username
|
||||
});
|
||||
} else {
|
||||
ctx.db.user.insert({
|
||||
@@ -302,12 +302,12 @@ export const join_server = spacetimedb.reducer(
|
||||
}
|
||||
const s = ctx.db.server.id.find(serverId);
|
||||
if (!s) throw new SenderError('Server not found');
|
||||
|
||||
|
||||
// Check if already a member
|
||||
for (const m of ctx.db.server_member.by_identity.filter(ctx.sender)) {
|
||||
if (m.server_id === serverId) return;
|
||||
}
|
||||
|
||||
|
||||
ctx.db.server_member.insert({ id: 0n, identity: ctx.sender, server_id: serverId });
|
||||
}
|
||||
);
|
||||
@@ -317,7 +317,7 @@ export const leave_server = spacetimedb.reducer(
|
||||
(ctx, { serverId }) => {
|
||||
const user = ctx.db.user.identity.find(ctx.sender);
|
||||
if (!user) return;
|
||||
|
||||
|
||||
for (const m of ctx.db.server_member.by_identity.filter(ctx.sender)) {
|
||||
if (m.server_id === serverId) {
|
||||
ctx.db.server_member.id.delete(m.id);
|
||||
@@ -336,11 +336,11 @@ export const create_channel = spacetimedb.reducer(
|
||||
}
|
||||
const s = ctx.db.server.id.find(serverId);
|
||||
if (!s) throw new SenderError('Server not found');
|
||||
ctx.db.channel.insert({
|
||||
id: 0n,
|
||||
server_id: serverId,
|
||||
name,
|
||||
kind: isVoice ? { tag: 'Voice' } : { tag: 'Text' }
|
||||
ctx.db.channel.insert({
|
||||
id: 0n,
|
||||
server_id: serverId,
|
||||
name,
|
||||
kind: isVoice ? { tag: 'Voice' } : { tag: 'Text' }
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -354,7 +354,7 @@ export const join_voice = spacetimedb.reducer(
|
||||
}
|
||||
const chan = ctx.db.channel.id.find(channelId);
|
||||
if (!chan || chan.kind.tag !== 'Voice') throw new SenderError('Invalid voice channel');
|
||||
|
||||
|
||||
const existing = ctx.db.voice_state.identity.find(ctx.sender);
|
||||
if (existing) {
|
||||
if (existing.channel_id !== channelId) {
|
||||
@@ -382,7 +382,7 @@ export const start_watching = spacetimedb.reducer(
|
||||
(ctx, { watchee, channelId }) => {
|
||||
// Prevent self-watching or duplicate watching
|
||||
if (ctx.sender.isEqual(watchee)) return;
|
||||
|
||||
|
||||
for (const w of ctx.db.watching.by_watcher.filter(ctx.sender)) {
|
||||
if (w.watchee.isEqual(watchee)) return;
|
||||
}
|
||||
@@ -412,6 +412,31 @@ export const leave_voice = spacetimedb.reducer((ctx) => {
|
||||
export const send_sdp_offer = spacetimedb.reducer(
|
||||
{ receiver: t.identity(), sdp: t.string(), channelId: t.u64() },
|
||||
(ctx, { receiver, sdp, channelId }) => {
|
||||
// Clear any existing offers/answers/candidates between this pair in both directions
|
||||
// to ensure a fresh negotiation state.
|
||||
|
||||
// Outgoing from sender to receiver
|
||||
for (const offer of ctx.db.sdp_offer.by_sender.filter(ctx.sender)) {
|
||||
if (offer.receiver.isEqual(receiver)) ctx.db.sdp_offer.id.delete(offer.id);
|
||||
}
|
||||
for (const answer of ctx.db.sdp_answer.by_sender.filter(ctx.sender)) {
|
||||
if (answer.receiver.isEqual(receiver)) ctx.db.sdp_answer.id.delete(answer.id);
|
||||
}
|
||||
for (const cand of ctx.db.ice_candidate.by_sender.filter(ctx.sender)) {
|
||||
if (cand.receiver.isEqual(receiver)) ctx.db.ice_candidate.id.delete(cand.id);
|
||||
}
|
||||
|
||||
// Incoming to sender from receiver (stale messages from previous negotiations)
|
||||
for (const offer of ctx.db.sdp_offer.by_receiver.filter(ctx.sender)) {
|
||||
if (offer.sender.isEqual(receiver)) ctx.db.sdp_offer.id.delete(offer.id);
|
||||
}
|
||||
for (const answer of ctx.db.sdp_answer.by_receiver.filter(ctx.sender)) {
|
||||
if (answer.sender.isEqual(receiver)) ctx.db.sdp_answer.id.delete(answer.id);
|
||||
}
|
||||
for (const cand of ctx.db.ice_candidate.by_receiver.filter(ctx.sender)) {
|
||||
if (cand.sender.isEqual(receiver)) ctx.db.ice_candidate.id.delete(cand.id);
|
||||
}
|
||||
|
||||
ctx.db.sdp_offer.insert({ id: 0n, sender: ctx.sender, receiver, sdp, channel_id: channelId });
|
||||
}
|
||||
);
|
||||
@@ -419,6 +444,11 @@ export const send_sdp_offer = spacetimedb.reducer(
|
||||
export const send_sdp_answer = spacetimedb.reducer(
|
||||
{ receiver: t.identity(), sdp: t.string(), channelId: t.u64() },
|
||||
(ctx, { receiver, sdp, channelId }) => {
|
||||
for (const answer of ctx.db.sdp_answer.by_sender.filter(ctx.sender)) {
|
||||
if (answer.receiver.isEqual(receiver)) {
|
||||
ctx.db.sdp_answer.id.delete(answer.id);
|
||||
}
|
||||
}
|
||||
ctx.db.sdp_answer.insert({ id: 0n, sender: ctx.sender, receiver, sdp, channel_id: channelId });
|
||||
}
|
||||
);
|
||||
@@ -432,7 +462,7 @@ export const send_ice_candidate = spacetimedb.reducer(
|
||||
|
||||
function clearSignalingForUser(ctx: any, identity: any) {
|
||||
// Clean up stale signaling messages for the user
|
||||
|
||||
|
||||
// Clean up watching status
|
||||
for (const w of ctx.db.watching.by_watcher.filter(identity)) {
|
||||
ctx.db.watching.id.delete(w.id);
|
||||
@@ -473,7 +503,7 @@ export const create_thread = spacetimedb.reducer(
|
||||
}
|
||||
const parentMsg = ctx.db.message.id.find(parentMessageId);
|
||||
if (!parentMsg) throw new SenderError('Parent message not found');
|
||||
|
||||
|
||||
ctx.db.thread.insert({ id: 0n, channel_id: channelId, parent_message_id: parentMessageId, name });
|
||||
}
|
||||
);
|
||||
@@ -482,7 +512,7 @@ export const send_message = spacetimedb.reducer(
|
||||
{ text: t.string(), channelId: t.u64(), threadId: t.u64().optional() },
|
||||
(ctx, { text, channelId, threadId }) => {
|
||||
if (!text || text.trim().length === 0) throw new SenderError('Messages must not be empty');
|
||||
|
||||
|
||||
const user = ctx.db.user.identity.find(ctx.sender);
|
||||
if (!user || (!user.username && !user.subject)) {
|
||||
throw new SenderError('You must be logged in to send messages');
|
||||
@@ -514,7 +544,7 @@ export const init = spacetimedb.init(ctx => {
|
||||
|
||||
export const onConnect = spacetimedb.clientConnected(ctx => {
|
||||
const user = ctx.db.user.identity.find(ctx.sender);
|
||||
|
||||
|
||||
if (ctx.senderAuth.hasJWT && ctx.senderAuth.jwt) {
|
||||
const jwt = ctx.senderAuth.jwt;
|
||||
const issuer = jwt.issuer;
|
||||
@@ -523,8 +553,8 @@ export const onConnect = spacetimedb.clientConnected(ctx => {
|
||||
const name = (payload.name as string) || (payload.nickname as string) || (payload.preferred_username as string) || (payload.email as string);
|
||||
|
||||
if (user) {
|
||||
ctx.db.user.identity.update({
|
||||
...user,
|
||||
ctx.db.user.identity.update({
|
||||
...user,
|
||||
online: true,
|
||||
talking: false,
|
||||
name: user.name || name,
|
||||
|
||||
Reference in New Issue
Block a user