diff --git a/src/chatlist.rs b/src/chatlist.rs index fb5109578..499256bb1 100644 --- a/src/chatlist.rs +++ b/src/chatlist.rs @@ -15,7 +15,7 @@ use crate::message::{Message, MessageState, MsgId}; use crate::param::{Param, Params}; use crate::stock_str; use crate::summary::Summary; -use crate::tools::IsNoneOrEmpty; +use crate::tools::{IsNoneOrEmpty, Time, time_elapsed}; /// Regex to find out if a query should filter by unread messages. pub static IS_UNREAD_FILTER: LazyLock = @@ -264,7 +264,8 @@ impl Chatlist { ).await? } else { // show normal chatlist - context.sql.query_map_vec( + let start = Time::now(); + let items = context.sql.query_map_vec( "SELECT c.id, m.id FROM chats c LEFT JOIN msgs m @@ -272,17 +273,25 @@ impl Chatlist { AND m.id=( SELECT id FROM msgs - WHERE chat_id=c.id - AND (hidden=0 OR state=?) + WHERE state=19 AND hidden IN (0,1) AND chat_id=c.id + OR state IN (10,13,16,18,20,24,26) + AND hidden=0 + AND chat_id=c.id ORDER BY timestamp DESC, id DESC LIMIT 1) WHERE c.id>9 AND c.id!=? AND (c.blocked=0 OR c.blocked=2) AND NOT c.archived=? GROUP BY c.id ORDER BY c.id=0 DESC, c.archived=? DESC, IFNULL(m.timestamp,c.created_timestamp) DESC, m.id DESC;", - (MessageState::OutDraft, skip_id, ChatVisibility::Archived, ChatVisibility::Pinned), + (skip_id, ChatVisibility::Archived, ChatVisibility::Pinned), process_row, - ).await? + ).await?; + info!( + context, + "chatlist built in {:?}.", + time_elapsed(&start), + ); + items }; if !flag_no_specials && get_archived_cnt(context).await? > 0 { if ids.is_empty() && flag_add_alldone_hint { diff --git a/src/sql/migrations.rs b/src/sql/migrations.rs index 11a2fb48b..ecd04c4f7 100644 --- a/src/sql/migrations.rs +++ b/src/sql/migrations.rs @@ -1567,6 +1567,57 @@ ALTER TABLE contacts ADD COLUMN name_normalized TEXT; .await?; } + // Add UNIQUE bound to token, in order to avoid saving the same token multiple times + inc_and_check(&mut migration_version, 148)?; + if dbversion < migration_version { + sql.execute_migration( + "CREATE TABLE tokens_new ( + id INTEGER PRIMARY KEY, + namespc INTEGER NOT NULL, + foreign_key TEXT DEFAULT '' NOT NULL, + token TEXT NOT NULL UNIQUE, + timestamp INTEGER DEFAULT 0 NOT NULL + ) STRICT; + INSERT OR IGNORE INTO tokens_new + SELECT id, namespc, foreign_key, token, timestamp FROM tokens; + DROP TABLE tokens; + ALTER TABLE tokens_new RENAME TO tokens;", + migration_version, + ) + .await?; + } + + // Add an `is_published` flag to transports. + // Unpublished transports are not advertised to contacts, + // and self-sent messages are not sent there, + // so that we don't cause extra messages to the corresponding inbox, + // but can still receive messages from contacts who don't know our new transport addresses yet. + // The default is true, but when when the user updates the app, + // existing secondary transports are set to unpublished, + // so that an existing transport address doesn't suddenly get spammed with a lot of messages. + inc_and_check(&mut migration_version, 149)?; + if dbversion < migration_version { + sql.execute_migration( + "ALTER TABLE transports ADD COLUMN is_published INTEGER DEFAULT 1 NOT NULL; + UPDATE transports SET is_published=0 WHERE addr!=( + SELECT value FROM config WHERE keyname='configured_addr' + )", + migration_version, + ) + .await?; + } + + inc_and_check(&mut migration_version, 150)?; + if dbversion < migration_version { + sql.execute_migration( + "UPDATE msgs SET state=26 WHERE state=28; + DROP INDEX IF EXISTS msgs_index7; + CREATE INDEX msgs_index7 ON msgs (state, hidden, chat_id, timestamp);", + migration_version, + ) + .await?; + } + let new_version = sql .get_raw_config_int(VERSION_CFG) .await?