From c6a59abd25edb1a62d9e8799dc2e48669e4ab4e9 Mon Sep 17 00:00:00 2001 From: Alex Emmet <111742636+Alex-Emmet@users.noreply.github.com> Date: Tue, 31 Mar 2026 00:00:45 +0200 Subject: [PATCH] [Fix] Communities should be stored and loaded propperly --- src/omikron/omikron_connection.rs | 36 ++++++++++--- src/util/communities_util.rs | 90 +++++++++++++++++++++++++++++++ src/util/db.rs | 12 +++++ src/util/mod.rs | 1 + 4 files changed, 132 insertions(+), 7 deletions(-) create mode 100644 src/util/communities_util.rs diff --git a/src/omikron/omikron_connection.rs b/src/omikron/omikron_connection.rs index f74540f..4d8edc4 100755 --- a/src/omikron/omikron_connection.rs +++ b/src/omikron/omikron_connection.rs @@ -1,7 +1,7 @@ use crate::users::contact::Contact; -use crate::users::user_community_util::UserCommunityUtil; use crate::util::chat_files::{MessageState, change_message_state}; use crate::util::chats_util::{get_user, mod_user}; +use crate::util::communities_util::CommunitiesUtil; use crate::util::crypto_util::{DataFormat, SecurePayload}; use crate::util::file_util::{get_children, load_file, save_file}; use crate::util::{chat_files, chats_util}; @@ -734,6 +734,10 @@ impl OmikronConnection { container.push((DataTypes::sender_id, DataValue::Number(sender_id))); container.push((DataTypes::message_state, DataValue::Str(message_state))); container.push((DataTypes::height, DataValue::Number(height))); + container.push(( + DataTypes::parse("sent_by_self".to_string()), + DataValue::Bool(sent_by_self), + )); msg_array.push(DataValue::Container(container)); } @@ -801,7 +805,7 @@ impl OmikronConnection { } if cv.is_type(CommunicationType::add_community) { - UserCommunityUtil::add_community( + CommunitiesUtil::add_community( cv.get_sender() as i64, cv.get_data(DataTypes::community_address) .as_str() @@ -824,19 +828,37 @@ impl OmikronConnection { } if cv.is_type(CommunicationType::get_communities) { + let mut comm_array = Vec::new(); + for c in CommunitiesUtil::get_communities(cv.get_sender() as i64) { + let mut container: Vec<(DataTypes, DataValue)> = Vec::new(); + if let Some(address) = c["address"].as_str() { + container.push(( + DataTypes::community_address, + DataValue::Str(address.to_string()), + )); + } + if let Some(title) = c["title"].as_str() { + container.push(( + DataTypes::community_title, + DataValue::Str(title.to_string()), + )); + } + if let Some(position) = c["position"].as_str() { + container.push((DataTypes::position, DataValue::Str(position.to_string()))); + } + comm_array.push(DataValue::Container(container)); + } + let resp = CommunicationValue::new(CommunicationType::get_communities) .with_id(cv.get_id()) .with_receiver(cv.get_sender()) - /*.add_data( - DataTypes::communities, - DataValue::Array(UserCommunityUtil::get_communities(cv.get_sender() as i64)), - ) */; + .add_data(DataTypes::communities, DataValue::Array(comm_array)); self.send_message(&resp).await; return; } if cv.is_type(CommunicationType::remove_community) { - UserCommunityUtil::remove_community( + CommunitiesUtil::remove_community( cv.get_sender() as i64, cv.get_data(DataTypes::community_address) .as_str() diff --git a/src/util/communities_util.rs b/src/util/communities_util.rs new file mode 100644 index 0000000..ed8b7ae --- /dev/null +++ b/src/util/communities_util.rs @@ -0,0 +1,90 @@ +use crate::util::db; +use json::Array; +use rusqlite::params; +use std::sync::{Arc, LazyLock, Mutex}; + +static MESSAGES_DB: LazyLock>> = LazyLock::new(|| { + db::create_general_messages_db().expect("Failed to create or initialize general messages DB") +}); + +pub struct CommunitiesUtil; + +impl CommunitiesUtil { + pub fn add_community(storage_owner: i64, address: String, title: String, position: String) { + if let Err(e) = db::with_conn(&MESSAGES_DB, |conn| { + conn.execute( + r#" + INSERT INTO communities ( + storage_owner, + address, + title, + position + ) VALUES (?1, ?2, ?3, ?4) + ON CONFLICT(storage_owner, address) DO UPDATE SET + title = excluded.title, + position = excluded.position + "#, + params![storage_owner, address, title, position], + )?; + Ok(()) + }) { + eprintln!("Failed to add_community: {}", e); + } + } + + pub fn remove_community(storage_owner: i64, community_address: String) { + if let Err(e) = db::with_conn(&MESSAGES_DB, |conn| { + conn.execute( + "DELETE FROM communities WHERE storage_owner = ?1 AND address = ?2", + params![storage_owner, community_address], + )?; + Ok(()) + }) { + eprintln!("Failed to remove_community: {}", e); + } + } + + pub fn get_communities(storage_owner: i64) -> Array { + let communities_out = Array::new(); + + let res: Result = db::with_conn(&MESSAGES_DB, |conn| { + let mut stmt = conn.prepare( + r#" + SELECT address, title, position + FROM communities + WHERE storage_owner = ?1 + "#, + )?; + + let rows = stmt.query_map(params![storage_owner], |r| { + let address: String = r.get(0)?; + let title: String = r.get(1)?; + let position: String = r.get(2)?; + Ok((address, title, position)) + })?; + + let mut out = Array::new(); + for row in rows { + match row { + Ok((address, title, position)) => { + let mut community = json::JsonValue::new_object(); + community["title"] = json::JsonValue::String(title); + community["address"] = json::JsonValue::String(address); + community["position"] = json::JsonValue::String(position); + out.push(community); + } + Err(e) => eprintln!("Failed to read community row: {}", e), + } + } + Ok(out) + }); + + match res { + Ok(arr) => arr, + Err(e) => { + eprintln!("Failed to query communities in get_communities: {}", e); + communities_out + } + } + } +} diff --git a/src/util/db.rs b/src/util/db.rs index d21ab41..9fb40a0 100644 --- a/src/util/db.rs +++ b/src/util/db.rs @@ -137,6 +137,18 @@ pub fn create_general_messages_db() -> Result>, String> { CREATE INDEX IF NOT EXISTS idx_contacts_owner ON contacts (storage_owner, last_message_at DESC, user_id ASC); + + CREATE TABLE IF NOT EXISTS communities ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + storage_owner INTEGER NOT NULL, + address TEXT NOT NULL, + title TEXT NOT NULL, + position TEXT NOT NULL, + UNIQUE(storage_owner, address) + ); + + CREATE INDEX IF NOT EXISTS idx_communities_owner + ON communities (storage_owner); "#; match create_shared_connection("messages", INIT_SQL) { diff --git a/src/util/mod.rs b/src/util/mod.rs index efd4374..47901f9 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,5 +1,6 @@ pub mod chat_files; pub mod chats_util; +pub mod communities_util; pub mod config_util; pub mod crypto_helper; pub mod crypto_util;