[Fix] Communities should be stored and loaded propperly

This commit is contained in:
Alex Emmet 2026-03-31 00:00:45 +02:00
commit c6a59abd25
4 changed files with 132 additions and 7 deletions

View file

@ -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()

View file

@ -0,0 +1,90 @@
use crate::util::db;
use json::Array;
use rusqlite::params;
use std::sync::{Arc, LazyLock, Mutex};
static MESSAGES_DB: LazyLock<Arc<Mutex<rusqlite::Connection>>> = 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<Array, String> = 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
}
}
}
}

View file

@ -137,6 +137,18 @@ pub fn create_general_messages_db() -> Result<Arc<Mutex<Connection>>, 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) {

View file

@ -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;