From 15cc1f708f7f5667d03e41fe5ae0c0f28bfedeac9759f08b7be3119e6bdade29 Mon Sep 17 00:00:00 2001 From: Evan Carroll Date: Sun, 18 Jan 2026 19:31:30 -0600 Subject: [PATCH] fix: statistics at the top of page --- .../chattyness-db/src/queries/owner/realms.rs | 28 ++- .../chattyness-db/src/queries/owner/users.rs | 27 +-- crates/chattyness-db/src/queries/realms.rs | 181 ++++++++++-------- .../src/components/layout.rs | 4 +- crates/chattyness-user-ui/src/pages/realm.rs | 3 +- 5 files changed, 147 insertions(+), 96 deletions(-) diff --git a/crates/chattyness-db/src/queries/owner/realms.rs b/crates/chattyness-db/src/queries/owner/realms.rs index e1e2d95..156d6f0 100644 --- a/crates/chattyness-db/src/queries/owner/realms.rs +++ b/crates/chattyness-db/src/queries/owner/realms.rs @@ -30,7 +30,12 @@ pub async fn list_realms_with_owner( r.owner_id, u.username as owner_username, r.member_count, - r.current_user_count, + COALESCE(( + SELECT COUNT(*)::INTEGER + FROM scene.instance_members im + JOIN realm.scenes s ON im.instance_id = s.id + WHERE s.realm_id = r.id + ), 0) AS current_user_count, r.created_at FROM realm.realms r JOIN auth.users u ON r.owner_id = u.id @@ -65,7 +70,12 @@ pub async fn search_realms( r.owner_id, u.username as owner_username, r.member_count, - r.current_user_count, + COALESCE(( + SELECT COUNT(*)::INTEGER + FROM scene.instance_members im + JOIN realm.scenes s ON im.instance_id = s.id + WHERE s.realm_id = r.id + ), 0) AS current_user_count, r.created_at FROM realm.realms r JOIN auth.users u ON r.owner_id = u.id @@ -245,7 +255,12 @@ pub async fn get_realm_by_slug(pool: &PgPool, slug: &str) -> Result Result, AppErro let realms = sqlx::query_as::<_, RealmSummary>( r#" SELECT - id, - name, - slug, - tagline, - privacy, - is_nsfw, - thumbnail_path, - member_count, - current_user_count - FROM realm.realms - ORDER BY name + r.id, + r.name, + r.slug, + r.tagline, + r.privacy, + r.is_nsfw, + r.thumbnail_path, + r.member_count, + COALESCE(( + SELECT COUNT(*)::INTEGER + FROM scene.instance_members im + JOIN realm.scenes s ON im.instance_id = s.id + WHERE s.realm_id = r.id + ), 0) AS current_user_count + FROM realm.realms r + ORDER BY r.name "#, ) .fetch_all(pool) diff --git a/crates/chattyness-db/src/queries/realms.rs b/crates/chattyness-db/src/queries/realms.rs index 2bc7482..61541d4 100644 --- a/crates/chattyness-db/src/queries/realms.rs +++ b/crates/chattyness-db/src/queries/realms.rs @@ -77,27 +77,32 @@ pub async fn get_realm_by_slug<'e>( let realm = sqlx::query_as::<_, Realm>( r#" SELECT - id, - name, - slug, - description, - tagline, - owner_id, - privacy, - is_nsfw, - min_reputation_tier, - theme_color, - banner_image_path, - thumbnail_path, - max_users, - allow_guest_access, - default_scene_id, - member_count, - current_user_count, - created_at, - updated_at - FROM realm.realms - WHERE slug = $1 + r.id, + r.name, + r.slug, + r.description, + r.tagline, + r.owner_id, + r.privacy, + r.is_nsfw, + r.min_reputation_tier, + r.theme_color, + r.banner_image_path, + r.thumbnail_path, + r.max_users, + r.allow_guest_access, + r.default_scene_id, + r.member_count, + COALESCE(( + SELECT COUNT(*)::INTEGER + FROM scene.instance_members im + JOIN realm.scenes s ON im.instance_id = s.id + WHERE s.realm_id = r.id + ), 0) AS current_user_count, + r.created_at, + r.updated_at + FROM realm.realms r + WHERE r.slug = $1 "#, ) .bind(slug) @@ -112,27 +117,32 @@ pub async fn get_realm_by_id(pool: &PgPool, id: Uuid) -> Result, A let realm = sqlx::query_as::<_, Realm>( r#" SELECT - id, - name, - slug, - description, - tagline, - owner_id, - privacy, - is_nsfw, - min_reputation_tier, - theme_color, - banner_image_path, - thumbnail_path, - max_users, - allow_guest_access, - default_scene_id, - member_count, - current_user_count, - created_at, - updated_at - FROM realm.realms - WHERE id = $1 + r.id, + r.name, + r.slug, + r.description, + r.tagline, + r.owner_id, + r.privacy, + r.is_nsfw, + r.min_reputation_tier, + r.theme_color, + r.banner_image_path, + r.thumbnail_path, + r.max_users, + r.allow_guest_access, + r.default_scene_id, + r.member_count, + COALESCE(( + SELECT COUNT(*)::INTEGER + FROM scene.instance_members im + JOIN realm.scenes s ON im.instance_id = s.id + WHERE s.realm_id = r.id + ), 0) AS current_user_count, + r.created_at, + r.updated_at + FROM realm.realms r + WHERE r.id = $1 "#, ) .bind(id) @@ -153,18 +163,23 @@ pub async fn list_public_realms( sqlx::query_as::<_, RealmSummary>( r#" SELECT - id, - name, - slug, - tagline, - privacy, - is_nsfw, - thumbnail_path, - member_count, - current_user_count - FROM realm.realms - WHERE privacy = 'public' - ORDER BY current_user_count DESC, member_count DESC + r.id, + r.name, + r.slug, + r.tagline, + r.privacy, + r.is_nsfw, + r.thumbnail_path, + r.member_count, + COALESCE(( + SELECT COUNT(*)::INTEGER + FROM scene.instance_members im + JOIN realm.scenes s ON im.instance_id = s.id + WHERE s.realm_id = r.id + ), 0) AS current_user_count + FROM realm.realms r + WHERE r.privacy = 'public' + ORDER BY current_user_count DESC, r.member_count DESC LIMIT $1 OFFSET $2 "#, ) @@ -176,18 +191,23 @@ pub async fn list_public_realms( sqlx::query_as::<_, RealmSummary>( r#" SELECT - id, - name, - slug, - tagline, - privacy, - is_nsfw, - thumbnail_path, - member_count, - current_user_count - FROM realm.realms - WHERE privacy = 'public' AND is_nsfw = false - ORDER BY current_user_count DESC, member_count DESC + r.id, + r.name, + r.slug, + r.tagline, + r.privacy, + r.is_nsfw, + r.thumbnail_path, + r.member_count, + COALESCE(( + SELECT COUNT(*)::INTEGER + FROM scene.instance_members im + JOIN realm.scenes s ON im.instance_id = s.id + WHERE s.realm_id = r.id + ), 0) AS current_user_count + FROM realm.realms r + WHERE r.privacy = 'public' AND r.is_nsfw = false + ORDER BY current_user_count DESC, r.member_count DESC LIMIT $1 OFFSET $2 "#, ) @@ -205,18 +225,23 @@ pub async fn get_user_realms(pool: &PgPool, user_id: Uuid) -> Result( r#" SELECT - id, - name, - slug, - tagline, - privacy, - is_nsfw, - thumbnail_path, - member_count, - current_user_count - FROM realm.realms - WHERE owner_id = $1 - ORDER BY created_at DESC + r.id, + r.name, + r.slug, + r.tagline, + r.privacy, + r.is_nsfw, + r.thumbnail_path, + r.member_count, + COALESCE(( + SELECT COUNT(*)::INTEGER + FROM scene.instance_members im + JOIN realm.scenes s ON im.instance_id = s.id + WHERE s.realm_id = r.id + ), 0) AS current_user_count + FROM realm.realms r + WHERE r.owner_id = $1 + ORDER BY r.created_at DESC "#, ) .bind(user_id) diff --git a/crates/chattyness-user-ui/src/components/layout.rs b/crates/chattyness-user-ui/src/components/layout.rs index 9f12aac..6892f82 100644 --- a/crates/chattyness-user-ui/src/components/layout.rs +++ b/crates/chattyness-user-ui/src/components/layout.rs @@ -42,14 +42,14 @@ pub fn RealmHeader( realm_description: Option, scene_name: String, scene_description: Option, - online_count: i32, + online_count: Signal, total_members: i32, max_capacity: i32, can_admin: bool, on_logout: Callback<()>, ) -> impl IntoView { let stats_tooltip = format!("Members: {} / Max: {}", total_members, max_capacity); - let online_text = format!("{} ONLINE", online_count); + let online_text = move || format!("{} ONLINE", online_count.get()); let admin_url = format!("/admin/realms/{}", realm_slug); view! { diff --git a/crates/chattyness-user-ui/src/pages/realm.rs b/crates/chattyness-user-ui/src/pages/realm.rs index 38f9609..78cd484 100644 --- a/crates/chattyness-user-ui/src/pages/realm.rs +++ b/crates/chattyness-user-ui/src/pages/realm.rs @@ -686,7 +686,8 @@ pub fn RealmPage() -> impl IntoView { let realm_name = realm.name.clone(); let realm_slug_val = realm.slug.clone(); let realm_description = realm.tagline.clone(); - let online_count = realm.current_user_count; + // Derive online count reactively from members signal + let online_count = Signal::derive(move || members.get().len() as i32); let total_members = realm.member_count; let max_capacity = realm.max_users; let scene_name = scene_info.0;