fix: statistics at the top of page

This commit is contained in:
Evan Carroll 2026-01-18 19:31:30 -06:00
parent 44b322371c
commit 15cc1f708f
5 changed files with 147 additions and 96 deletions

View file

@ -30,7 +30,12 @@ pub async fn list_realms_with_owner(
r.owner_id, r.owner_id,
u.username as owner_username, u.username as owner_username,
r.member_count, 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 r.created_at
FROM realm.realms r FROM realm.realms r
JOIN auth.users u ON r.owner_id = u.id JOIN auth.users u ON r.owner_id = u.id
@ -65,7 +70,12 @@ pub async fn search_realms(
r.owner_id, r.owner_id,
u.username as owner_username, u.username as owner_username,
r.member_count, 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 r.created_at
FROM realm.realms r FROM realm.realms r
JOIN auth.users u ON r.owner_id = u.id 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<RealmDetail,
r.max_users, r.max_users,
r.allow_guest_access, r.allow_guest_access,
r.member_count, 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, r.created_at,
r.updated_at r.updated_at
FROM realm.realms r FROM realm.realms r
@ -317,7 +332,12 @@ pub async fn update_realm(
r.max_users, r.max_users,
r.allow_guest_access, r.allow_guest_access,
r.member_count, 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, r.created_at,
r.updated_at r.updated_at
FROM realm.realms r FROM realm.realms r

View file

@ -262,17 +262,22 @@ pub async fn list_all_realms(pool: &PgPool) -> Result<Vec<RealmSummary>, AppErro
let realms = sqlx::query_as::<_, RealmSummary>( let realms = sqlx::query_as::<_, RealmSummary>(
r#" r#"
SELECT SELECT
id, r.id,
name, r.name,
slug, r.slug,
tagline, r.tagline,
privacy, r.privacy,
is_nsfw, r.is_nsfw,
thumbnail_path, r.thumbnail_path,
member_count, r.member_count,
current_user_count COALESCE((
FROM realm.realms SELECT COUNT(*)::INTEGER
ORDER BY name 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) .fetch_all(pool)

View file

@ -77,27 +77,32 @@ pub async fn get_realm_by_slug<'e>(
let realm = sqlx::query_as::<_, Realm>( let realm = sqlx::query_as::<_, Realm>(
r#" r#"
SELECT SELECT
id, r.id,
name, r.name,
slug, r.slug,
description, r.description,
tagline, r.tagline,
owner_id, r.owner_id,
privacy, r.privacy,
is_nsfw, r.is_nsfw,
min_reputation_tier, r.min_reputation_tier,
theme_color, r.theme_color,
banner_image_path, r.banner_image_path,
thumbnail_path, r.thumbnail_path,
max_users, r.max_users,
allow_guest_access, r.allow_guest_access,
default_scene_id, r.default_scene_id,
member_count, r.member_count,
current_user_count, COALESCE((
created_at, SELECT COUNT(*)::INTEGER
updated_at FROM scene.instance_members im
FROM realm.realms JOIN realm.scenes s ON im.instance_id = s.id
WHERE slug = $1 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) .bind(slug)
@ -112,27 +117,32 @@ pub async fn get_realm_by_id(pool: &PgPool, id: Uuid) -> Result<Option<Realm>, A
let realm = sqlx::query_as::<_, Realm>( let realm = sqlx::query_as::<_, Realm>(
r#" r#"
SELECT SELECT
id, r.id,
name, r.name,
slug, r.slug,
description, r.description,
tagline, r.tagline,
owner_id, r.owner_id,
privacy, r.privacy,
is_nsfw, r.is_nsfw,
min_reputation_tier, r.min_reputation_tier,
theme_color, r.theme_color,
banner_image_path, r.banner_image_path,
thumbnail_path, r.thumbnail_path,
max_users, r.max_users,
allow_guest_access, r.allow_guest_access,
default_scene_id, r.default_scene_id,
member_count, r.member_count,
current_user_count, COALESCE((
created_at, SELECT COUNT(*)::INTEGER
updated_at FROM scene.instance_members im
FROM realm.realms JOIN realm.scenes s ON im.instance_id = s.id
WHERE id = $1 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) .bind(id)
@ -153,18 +163,23 @@ pub async fn list_public_realms(
sqlx::query_as::<_, RealmSummary>( sqlx::query_as::<_, RealmSummary>(
r#" r#"
SELECT SELECT
id, r.id,
name, r.name,
slug, r.slug,
tagline, r.tagline,
privacy, r.privacy,
is_nsfw, r.is_nsfw,
thumbnail_path, r.thumbnail_path,
member_count, r.member_count,
current_user_count COALESCE((
FROM realm.realms SELECT COUNT(*)::INTEGER
WHERE privacy = 'public' FROM scene.instance_members im
ORDER BY current_user_count DESC, member_count DESC 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 LIMIT $1 OFFSET $2
"#, "#,
) )
@ -176,18 +191,23 @@ pub async fn list_public_realms(
sqlx::query_as::<_, RealmSummary>( sqlx::query_as::<_, RealmSummary>(
r#" r#"
SELECT SELECT
id, r.id,
name, r.name,
slug, r.slug,
tagline, r.tagline,
privacy, r.privacy,
is_nsfw, r.is_nsfw,
thumbnail_path, r.thumbnail_path,
member_count, r.member_count,
current_user_count COALESCE((
FROM realm.realms SELECT COUNT(*)::INTEGER
WHERE privacy = 'public' AND is_nsfw = false FROM scene.instance_members im
ORDER BY current_user_count DESC, member_count DESC 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 LIMIT $1 OFFSET $2
"#, "#,
) )
@ -205,18 +225,23 @@ pub async fn get_user_realms(pool: &PgPool, user_id: Uuid) -> Result<Vec<RealmSu
let realms = sqlx::query_as::<_, RealmSummary>( let realms = sqlx::query_as::<_, RealmSummary>(
r#" r#"
SELECT SELECT
id, r.id,
name, r.name,
slug, r.slug,
tagline, r.tagline,
privacy, r.privacy,
is_nsfw, r.is_nsfw,
thumbnail_path, r.thumbnail_path,
member_count, r.member_count,
current_user_count COALESCE((
FROM realm.realms SELECT COUNT(*)::INTEGER
WHERE owner_id = $1 FROM scene.instance_members im
ORDER BY created_at DESC 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) .bind(user_id)

View file

@ -42,14 +42,14 @@ pub fn RealmHeader(
realm_description: Option<String>, realm_description: Option<String>,
scene_name: String, scene_name: String,
scene_description: Option<String>, scene_description: Option<String>,
online_count: i32, online_count: Signal<i32>,
total_members: i32, total_members: i32,
max_capacity: i32, max_capacity: i32,
can_admin: bool, can_admin: bool,
on_logout: Callback<()>, on_logout: Callback<()>,
) -> impl IntoView { ) -> impl IntoView {
let stats_tooltip = format!("Members: {} / Max: {}", total_members, max_capacity); 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); let admin_url = format!("/admin/realms/{}", realm_slug);
view! { view! {

View file

@ -686,7 +686,8 @@ pub fn RealmPage() -> impl IntoView {
let realm_name = realm.name.clone(); let realm_name = realm.name.clone();
let realm_slug_val = realm.slug.clone(); let realm_slug_val = realm.slug.clone();
let realm_description = realm.tagline.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 total_members = realm.member_count;
let max_capacity = realm.max_users; let max_capacity = realm.max_users;
let scene_name = scene_info.0; let scene_name = scene_info.0;