small fixes
This commit is contained in:
+21
-3
@@ -90,14 +90,25 @@ pub fn init(ctx: &ReducerContext) {
|
|||||||
pub fn on_connect(ctx: &ReducerContext) {
|
pub fn on_connect(ctx: &ReducerContext) {
|
||||||
log::info!("on_connect START: identity={}", ctx.sender().to_hex());
|
log::info!("on_connect START: identity={}", ctx.sender().to_hex());
|
||||||
|
|
||||||
// We'll keep this extremely minimal to ensure connection stability
|
// Extract potential name from OIDC if available
|
||||||
|
let mut initial_name = None;
|
||||||
|
if let Some(jwt) = ctx.sender_auth().jwt() {
|
||||||
|
let sub = jwt.subject();
|
||||||
|
// Use first 8 chars of sub if it's a long string/UUID
|
||||||
|
initial_name = Some(if sub.len() > 12 { sub[..8].to_string() } else { sub.to_string() });
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(mut user) = ctx.db.user().identity().find(ctx.sender()) {
|
if let Some(mut user) = ctx.db.user().identity().find(ctx.sender()) {
|
||||||
user.online = true;
|
user.online = true;
|
||||||
|
// Update name from OIDC if current user has no name
|
||||||
|
if user.name.is_none() && initial_name.is_some() {
|
||||||
|
user.name = initial_name;
|
||||||
|
}
|
||||||
ctx.db.user().identity().update(user);
|
ctx.db.user().identity().update(user);
|
||||||
} else {
|
} else {
|
||||||
ctx.db.user().insert(User {
|
ctx.db.user().insert(User {
|
||||||
identity: ctx.sender(),
|
identity: ctx.sender(),
|
||||||
name: None,
|
name: initial_name,
|
||||||
online: true,
|
online: true,
|
||||||
issuer: None,
|
issuer: None,
|
||||||
subject: None,
|
subject: None,
|
||||||
@@ -160,9 +171,16 @@ pub fn update_auth_info(ctx: &ReducerContext) {
|
|||||||
log::info!("update_auth_info: identity={}", ctx.sender().to_hex());
|
log::info!("update_auth_info: identity={}", ctx.sender().to_hex());
|
||||||
if let Some(mut user) = ctx.db.user().identity().find(ctx.sender()) {
|
if let Some(mut user) = ctx.db.user().identity().find(ctx.sender()) {
|
||||||
if let Some(jwt) = ctx.sender_auth().jwt() {
|
if let Some(jwt) = ctx.sender_auth().jwt() {
|
||||||
|
let sub = jwt.subject();
|
||||||
user.issuer = Some(jwt.issuer().to_string());
|
user.issuer = Some(jwt.issuer().to_string());
|
||||||
user.subject = Some(jwt.subject().to_string());
|
user.subject = Some(sub.to_string());
|
||||||
user.anonymous = false;
|
user.anonymous = false;
|
||||||
|
|
||||||
|
// Also update name if they don't have a custom one yet
|
||||||
|
if user.name.is_none() {
|
||||||
|
user.name = Some(if sub.len() > 12 { sub[..8].to_string() } else { sub.to_string() });
|
||||||
|
}
|
||||||
|
|
||||||
ctx.db.user().identity().update(user);
|
ctx.db.user().identity().update(user);
|
||||||
sync_server_member_info(&ctx.db, ctx.sender());
|
sync_server_member_info(&ctx.db, ctx.sender());
|
||||||
log::info!("update_auth_info: updated user with OIDC info");
|
log::info!("update_auth_info: updated user with OIDC info");
|
||||||
|
|||||||
+18
-18
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createSpacetimeDBProvider } from "spacetimedb/svelte";
|
import { createSpacetimeDBProvider } from "spacetimedb/svelte";
|
||||||
import type { ConnectionBuilder } from "spacetimedb";
|
import type { ConnectionBuilder } from "spacetimedb";
|
||||||
|
import { untrack } from "svelte";
|
||||||
import { getStdbHost, getStdbDbName, handleConnect } from "./config";
|
import { getStdbHost, getStdbDbName, handleConnect } from "./config";
|
||||||
|
|
||||||
let { builder, children, onCancel }: { builder: ConnectionBuilder<any>, children: any, onCancel?: () => void } = $props();
|
let { builder, children, onCancel }: { builder: ConnectionBuilder<any>, children: any, onCancel?: () => void } = $props();
|
||||||
@@ -8,28 +9,27 @@
|
|||||||
// Initialize the provider
|
// Initialize the provider
|
||||||
const db = createSpacetimeDBProvider(builder);
|
const db = createSpacetimeDBProvider(builder);
|
||||||
|
|
||||||
// Fallback: Also register direct listener on the connection if possible
|
// Handshake latch to prevent infinite reactive loops
|
||||||
$effect(() => {
|
let hasSyncedForThisConnection = $state(false);
|
||||||
if ($db.connection) {
|
|
||||||
$db.connection.onConnect((conn: any, identity: any, token: string) => {
|
|
||||||
console.log("InnerProvider: connection.onConnect triggered, syncing state...");
|
|
||||||
handleConnect(conn, identity, token);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Watch for successful connection and persist state
|
// Watch for successful connection and persist state
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
console.log("InnerProvider State:", {
|
// Only trigger when the underlying connection actually changes
|
||||||
isActive: $db.isActive,
|
const conn = $db.connection;
|
||||||
hasIdentity: !!$db.identity,
|
const isActive = $db.isActive;
|
||||||
hasToken: !!$db.token,
|
const identity = $db.identity;
|
||||||
hasConn: !!$db.connection
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($db.isActive && $db.identity && $db.connection) {
|
if (isActive && identity && conn) {
|
||||||
console.log("InnerProvider: Connection valid, syncing state...");
|
untrack(() => {
|
||||||
handleConnect($db.connection, $db.identity, $db.token || "");
|
if (!hasSyncedForThisConnection) {
|
||||||
|
console.log("InnerProvider: Initial handshake established, syncing state...");
|
||||||
|
handleConnect(conn, identity, $db.token || "");
|
||||||
|
hasSyncedForThisConnection = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (!isActive) {
|
||||||
|
// Reset latch if connection drops
|
||||||
|
hasSyncedForThisConnection = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,19 @@
|
|||||||
}>();
|
}>();
|
||||||
|
|
||||||
let builder = $state<ConnectionBuilder<any> | null>(null);
|
let builder = $state<ConnectionBuilder<any> | null>(null);
|
||||||
|
let lastUsedToken = $state<string | undefined>(undefined);
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (!auth.isLoading) {
|
if (!auth.isLoading) {
|
||||||
console.log("InnerSpacetimeProvider: Initializing connection...");
|
const currentToken = auth.user?.id_token;
|
||||||
connectionState.status = "connecting";
|
|
||||||
builder = connectionBuilder(auth.user?.id_token);
|
// Only re-initialize if the token actually changed
|
||||||
|
if (currentToken !== lastUsedToken || !builder) {
|
||||||
|
console.log("InnerSpacetimeProvider: Initializing connection...");
|
||||||
|
connectionState.status = "connecting";
|
||||||
|
builder = connectionBuilder(currentToken);
|
||||||
|
lastUsedToken = currentToken;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -53,13 +53,13 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Split combined connection if it changes
|
// Split combined connection if it changes (Only when on login screen)
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (combinedConnection.includes(":")) {
|
if (!userWantsToConnect && combinedConnection.includes(":")) {
|
||||||
const lastColon = combinedConnection.lastIndexOf(":");
|
const lastColon = combinedConnection.lastIndexOf(":");
|
||||||
const host = combinedConnection.substring(0, lastColon);
|
const host = combinedConnection.substring(0, lastColon);
|
||||||
const db = combinedConnection.substring(lastColon + 1);
|
const db = combinedConnection.substring(lastColon + 1);
|
||||||
if (host && db) {
|
if (host && db && (host !== stdbHost || db !== stdbDbName)) {
|
||||||
untrack(() => {
|
untrack(() => {
|
||||||
stdbHost = host;
|
stdbHost = host;
|
||||||
stdbDbName = db;
|
stdbDbName = db;
|
||||||
@@ -71,23 +71,31 @@
|
|||||||
// Update combined connection if individual fields change (e.g. on mount)
|
// Update combined connection if individual fields change (e.g. on mount)
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
const hostPart = stdbHost.replace(/^(https?|wss?):\/\//, "");
|
const hostPart = stdbHost.replace(/^(https?|wss?):\/\//, "");
|
||||||
combinedConnection = `${hostPart}:${stdbDbName}`;
|
const expected = `${hostPart}:${stdbDbName}`;
|
||||||
|
if (combinedConnection !== expected) {
|
||||||
|
combinedConnection = expected;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let hasStoredToken = $state(false);
|
let hasStoredToken = $state(false);
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
// Check for token on mount and when connection params change
|
// Check for token when connection params change
|
||||||
const _ = combinedConnection;
|
if (stdbHost && stdbDbName) {
|
||||||
hasStoredToken = !!TokenStore.get(stdbHost, stdbDbName);
|
hasStoredToken = !!TokenStore.get(stdbHost, stdbDbName);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (stdbHost) localStorage.setItem(HOST_KEY, stdbHost);
|
if (stdbHost && localStorage.getItem(HOST_KEY) !== stdbHost) {
|
||||||
|
localStorage.setItem(HOST_KEY, stdbHost);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
if (stdbDbName) localStorage.setItem(DB_NAME_KEY, stdbDbName);
|
if (stdbDbName && localStorage.getItem(DB_NAME_KEY) !== stdbDbName) {
|
||||||
|
localStorage.setItem(DB_NAME_KEY, stdbDbName);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const isBypassEnabled =
|
const isBypassEnabled =
|
||||||
|
|||||||
@@ -301,7 +301,11 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if chat.userContextMenu}
|
{#if chat.userContextMenu}
|
||||||
<UserContextMenu {...chat.userContextMenu} onClose={() => (chat.userContextMenu = null)} />
|
<UserContextMenu
|
||||||
|
{...chat.userContextMenu}
|
||||||
|
onClose={() => (chat.userContextMenu = null)}
|
||||||
|
onAction={closeSidebars}
|
||||||
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if chat.confirmModal}
|
{#if chat.confirmModal}
|
||||||
|
|||||||
@@ -5,11 +5,12 @@
|
|||||||
import type * as Types from "../../module_bindings/types";
|
import type * as Types from "../../module_bindings/types";
|
||||||
import { portal } from "../../portal";
|
import { portal } from "../../portal";
|
||||||
|
|
||||||
let { x, y, user, onClose }: {
|
let { x, y, user, onClose, onAction }: {
|
||||||
x: number,
|
x: number,
|
||||||
y: number,
|
y: number,
|
||||||
user: Types.User,
|
user: Types.User,
|
||||||
onClose: () => void
|
onClose: () => void,
|
||||||
|
onAction?: () => void
|
||||||
} = $props();
|
} = $props();
|
||||||
|
|
||||||
const chat = getContext<ChatService>("chat");
|
const chat = getContext<ChatService>("chat");
|
||||||
@@ -108,6 +109,7 @@
|
|||||||
{#if !isMe}
|
{#if !isMe}
|
||||||
<button class="menu-item" onclick={() => {
|
<button class="menu-item" onclick={() => {
|
||||||
chat.handleOpenDirectMessage(user.identity);
|
chat.handleOpenDirectMessage(user.identity);
|
||||||
|
onAction?.();
|
||||||
onClose();
|
onClose();
|
||||||
}}>
|
}}>
|
||||||
<span>Message</span>
|
<span>Message</span>
|
||||||
@@ -116,7 +118,10 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if !isMe}
|
{#if !isMe}
|
||||||
<button class="menu-item" onclick={mentionUser}>
|
<button class="menu-item" onclick={() => {
|
||||||
|
mentionUser();
|
||||||
|
onAction?.();
|
||||||
|
}}>
|
||||||
<span>Mention</span>
|
<span>Mention</span>
|
||||||
<i class="fas fa-at"></i>
|
<i class="fas fa-at"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -115,10 +115,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.channel-item-hash {
|
.channel-item-hash {
|
||||||
font-size: 1.2rem;
|
font-size: 1rem;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
text-align: center;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -296,11 +296,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.channel-item-hash {
|
.channel-item-hash {
|
||||||
font-size: 1.2rem;
|
font-size: 1rem;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
width: 20px;
|
width: 20px;
|
||||||
text-align: center;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Voice Member List Styles */
|
/* Voice Member List Styles */
|
||||||
|
|||||||
Reference in New Issue
Block a user