mirror of
https://github.com/chatmail/core.git
synced 2026-05-22 16:26:31 +03:00
"archive" consistency and improvements (#3918)
* move 'archived link' betweeen pinned and normal cahts or above normal chats * add icon for 'archived chats' link * let get_fresh_msg_cnt() work for DC_CHAT_ID_ARCHIVED_LINK * move 'archived link' topmost * use less noticeable archived-icon * slightly smaller archived icon * update CHANGELOG
This commit is contained in:
@@ -10,6 +10,8 @@
|
|||||||
- Add fuzzing tests #3853
|
- Add fuzzing tests #3853
|
||||||
- Add mappings for some file types to Viewtype / MIME type #3881
|
- Add mappings for some file types to Viewtype / MIME type #3881
|
||||||
- Buffer IMAP client writes #3888
|
- Buffer IMAP client writes #3888
|
||||||
|
- move `DC_CHAT_ID_ARCHIVED_LINK` to the top of chat lists
|
||||||
|
and make `dc_get_fresh_msg_cnt()` work for `DC_CHAT_ID_ARCHIVED_LINK` #3918
|
||||||
|
|
||||||
### API-Changes
|
### API-Changes
|
||||||
- jsonrpc: add python API for webxdc updates #3872
|
- jsonrpc: add python API for webxdc updates #3872
|
||||||
|
|||||||
BIN
assets/icon-archive.png
Normal file
BIN
assets/icon-archive.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
60
assets/icon-archive.svg
Normal file
60
assets/icon-archive.svg
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
width="60"
|
||||||
|
height="60"
|
||||||
|
viewBox="0 0 60 60"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="feather feather-archive"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
sodipodi:docname="icon-archive.svg"
|
||||||
|
inkscape:version="1.2.2 (b0a84865, 2022-12-01)"
|
||||||
|
inkscape:export-filename="icon-archive.png"
|
||||||
|
inkscape:export-xdpi="409.60001"
|
||||||
|
inkscape:export-ydpi="409.60001"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs12" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview10"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="6.4597151"
|
||||||
|
inkscape:cx="24.459283"
|
||||||
|
inkscape:cy="32.509174"
|
||||||
|
inkscape:window-width="1457"
|
||||||
|
inkscape:window-height="860"
|
||||||
|
inkscape:window-x="55"
|
||||||
|
inkscape:window-y="38"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg8" />
|
||||||
|
<g
|
||||||
|
id="g846"
|
||||||
|
transform="translate(0.558605,0.464417)">
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:1.78186;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 38.749006,25.398867 V 38.843194 H 20.133784 V 25.398867"
|
||||||
|
id="path847" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-opacity:1;stroke:#808080;stroke-width:1.78186;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 18.065427,20.227972 h 22.751936 v 5.170894 H 18.065427 Z"
|
||||||
|
id="path845" />
|
||||||
|
<path
|
||||||
|
style="fill:#ff0000;fill-opacity:1;stroke:#808080;stroke-width:1.78186;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="m 27.373036,29.535581 h 4.136718"
|
||||||
|
id="line6" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -1227,7 +1227,11 @@ int dc_get_msg_cnt (dc_context_t* context, uint32_t ch
|
|||||||
* Get the number of _fresh_ messages in a chat.
|
* Get the number of _fresh_ messages in a chat.
|
||||||
* Typically used to implement a badge with a number in the chatlist.
|
* Typically used to implement a badge with a number in the chatlist.
|
||||||
*
|
*
|
||||||
* If the specified chat is muted,
|
* As muted archived chats are not unarchived automatically,
|
||||||
|
* a similar information is needed for the @ref dc_get_chatlist() "archive link" as well:
|
||||||
|
* here, the number of archived chats containing fresh messages is returned.
|
||||||
|
*
|
||||||
|
* If the specified chat is muted or the @ref dc_get_chatlist() "archive link",
|
||||||
* the UI should show the badge counter "less obtrusive",
|
* the UI should show the badge counter "less obtrusive",
|
||||||
* e.g. using "gray" instead of "red" color.
|
* e.g. using "gray" instead of "red" color.
|
||||||
*
|
*
|
||||||
|
|||||||
51
src/chat.rs
51
src/chat.rs
@@ -782,17 +782,35 @@ impl ChatId {
|
|||||||
// the times are average, no matter if there are fresh messages or not -
|
// the times are average, no matter if there are fresh messages or not -
|
||||||
// and have to be multiplied by the number of items shown at once on the chatlist,
|
// and have to be multiplied by the number of items shown at once on the chatlist,
|
||||||
// so savings up to 2 seconds are possible on older devices - newer ones will feel "snappier" :)
|
// so savings up to 2 seconds are possible on older devices - newer ones will feel "snappier" :)
|
||||||
let count = context
|
let count = if self.is_archived_link() {
|
||||||
.sql
|
context
|
||||||
.count(
|
.sql
|
||||||
"SELECT COUNT(*)
|
.count(
|
||||||
|
"SELECT COUNT(DISTINCT(m.chat_id))
|
||||||
|
FROM msgs m
|
||||||
|
LEFT JOIN chats c ON m.chat_id=c.id
|
||||||
|
WHERE m.state=10
|
||||||
|
and m.hidden=0
|
||||||
|
AND m.chat_id>9
|
||||||
|
AND c.blocked=0
|
||||||
|
AND c.archived=1
|
||||||
|
",
|
||||||
|
paramsv![],
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
} else {
|
||||||
|
context
|
||||||
|
.sql
|
||||||
|
.count(
|
||||||
|
"SELECT COUNT(*)
|
||||||
FROM msgs
|
FROM msgs
|
||||||
WHERE state=?
|
WHERE state=?
|
||||||
AND hidden=0
|
AND hidden=0
|
||||||
AND chat_id=?;",
|
AND chat_id=?;",
|
||||||
paramsv![MessageState::InFresh, self],
|
paramsv![MessageState::InFresh, self],
|
||||||
)
|
)
|
||||||
.await?;
|
.await?
|
||||||
|
};
|
||||||
Ok(count)
|
Ok(count)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1216,6 +1234,10 @@ impl Chat {
|
|||||||
if !image_rel.is_empty() {
|
if !image_rel.is_empty() {
|
||||||
return Ok(Some(get_abs_path(context, image_rel)));
|
return Ok(Some(get_abs_path(context, image_rel)));
|
||||||
}
|
}
|
||||||
|
} else if self.id.is_archived_link() {
|
||||||
|
if let Ok(image_rel) = get_archive_icon(context).await {
|
||||||
|
return Ok(Some(get_abs_path(context, image_rel)));
|
||||||
|
}
|
||||||
} else if self.typ == Chattype::Single {
|
} else if self.typ == Chattype::Single {
|
||||||
let contacts = get_chat_contacts(context, self.id).await?;
|
let contacts = get_chat_contacts(context, self.id).await?;
|
||||||
if let Some(contact_id) = contacts.first() {
|
if let Some(contact_id) = contacts.first() {
|
||||||
@@ -1708,6 +1730,21 @@ pub(crate) async fn get_broadcast_icon(context: &Context) -> Result<String> {
|
|||||||
Ok(icon)
|
Ok(icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn get_archive_icon(context: &Context) -> Result<String> {
|
||||||
|
if let Some(icon) = context.sql.get_raw_config("icon-archive").await? {
|
||||||
|
return Ok(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
let icon = include_bytes!("../assets/icon-archive.png");
|
||||||
|
let blob = BlobObject::create(context, "icon-archive.png", icon).await?;
|
||||||
|
let icon = blob.as_name().to_string();
|
||||||
|
context
|
||||||
|
.sql
|
||||||
|
.set_raw_config("icon-archive", Some(&icon))
|
||||||
|
.await?;
|
||||||
|
Ok(icon)
|
||||||
|
}
|
||||||
|
|
||||||
async fn update_special_chat_name(
|
async fn update_special_chat_name(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
contact_id: ContactId,
|
contact_id: ContactId,
|
||||||
|
|||||||
@@ -92,8 +92,6 @@ impl Chatlist {
|
|||||||
let flag_no_specials = 0 != listflags & DC_GCL_NO_SPECIALS;
|
let flag_no_specials = 0 != listflags & DC_GCL_NO_SPECIALS;
|
||||||
let flag_add_alldone_hint = 0 != listflags & DC_GCL_ADD_ALLDONE_HINT;
|
let flag_add_alldone_hint = 0 != listflags & DC_GCL_ADD_ALLDONE_HINT;
|
||||||
|
|
||||||
let mut add_archived_link_item = false;
|
|
||||||
|
|
||||||
let process_row = |row: &rusqlite::Row| {
|
let process_row = |row: &rusqlite::Row| {
|
||||||
let chat_id: ChatId = row.get(0)?;
|
let chat_id: ChatId = row.get(0)?;
|
||||||
let msg_id: Option<MsgId> = row.get(1)?;
|
let msg_id: Option<MsgId> = row.get(1)?;
|
||||||
@@ -123,7 +121,7 @@ impl Chatlist {
|
|||||||
//
|
//
|
||||||
// The query shows messages from blocked contacts in
|
// The query shows messages from blocked contacts in
|
||||||
// groups. Otherwise it would be hard to follow conversations.
|
// groups. Otherwise it would be hard to follow conversations.
|
||||||
let mut ids = if let Some(query_contact_id) = query_contact_id {
|
let ids = if let Some(query_contact_id) = query_contact_id {
|
||||||
// show chats shared with a given contact
|
// show chats shared with a given contact
|
||||||
context.sql.query_map(
|
context.sql.query_map(
|
||||||
"SELECT c.id, m.id
|
"SELECT c.id, m.id
|
||||||
@@ -216,7 +214,7 @@ impl Chatlist {
|
|||||||
} else {
|
} else {
|
||||||
ChatId::new(0)
|
ChatId::new(0)
|
||||||
};
|
};
|
||||||
let ids = context.sql.query_map(
|
let mut ids = context.sql.query_map(
|
||||||
"SELECT c.id, m.id
|
"SELECT c.id, m.id
|
||||||
FROM chats c
|
FROM chats c
|
||||||
LEFT JOIN msgs m
|
LEFT JOIN msgs m
|
||||||
@@ -236,19 +234,15 @@ impl Chatlist {
|
|||||||
process_row,
|
process_row,
|
||||||
process_rows,
|
process_rows,
|
||||||
).await?;
|
).await?;
|
||||||
if !flag_no_specials {
|
if !flag_no_specials && get_archived_cnt(context).await? > 0 {
|
||||||
add_archived_link_item = true;
|
if ids.is_empty() && flag_add_alldone_hint {
|
||||||
|
ids.push((DC_CHAT_ID_ALLDONE_HINT, None));
|
||||||
|
}
|
||||||
|
ids.insert(0, (DC_CHAT_ID_ARCHIVED_LINK, None));
|
||||||
}
|
}
|
||||||
ids
|
ids
|
||||||
};
|
};
|
||||||
|
|
||||||
if add_archived_link_item && get_archived_cnt(context).await? > 0 {
|
|
||||||
if ids.is_empty() && flag_add_alldone_hint {
|
|
||||||
ids.push((DC_CHAT_ID_ALLDONE_HINT, None));
|
|
||||||
}
|
|
||||||
ids.push((DC_CHAT_ID_ARCHIVED_LINK, None));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Chatlist { ids })
|
Ok(Chatlist { ids })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user