api!(jsonrpc): chat_type now contains a variant of a string enum/union. Affected places: FullChat.chat_type, BasicChat.chat_type, ChatListItemFetchResult::ChatListItem.chat_type, Event:: SecurejoinInviterProgress.chat_type and MessageSearchResult.chat_type (#7285)

Actually it will be not as breaking if you used the constants, because
this pr also changes the constants.

closes #7029 

Note that I had to change the constants from enum to namespace, this has
the side effect, that you can no longer also use the constants as types,
you need to instead prefix them with `typeof ` now.
This commit is contained in:
Simon Laux
2025-11-06 13:53:48 +01:00
committed by GitHub
parent ee75094bef
commit a3328ea2de
6 changed files with 73 additions and 24 deletions

View File

@@ -6,7 +6,6 @@ use deltachat::chat::{Chat, ChatId};
use deltachat::constants::Chattype;
use deltachat::contact::{Contact, ContactId};
use deltachat::context::Context;
use num_traits::cast::ToPrimitive;
use serde::{Deserialize, Serialize};
use typescript_type_def::TypeDef;
@@ -46,7 +45,7 @@ pub struct FullChat {
archived: bool,
pinned: bool,
// subtitle - will be moved to frontend because it uses translation functions
chat_type: u32,
chat_type: JsonrpcChatType,
is_unpromoted: bool,
is_self_talk: bool,
contacts: Vec<ContactObject>,
@@ -130,7 +129,7 @@ impl FullChat {
profile_image, //BLOBS ?
archived: chat.get_visibility() == chat::ChatVisibility::Archived,
pinned: chat.get_visibility() == chat::ChatVisibility::Pinned,
chat_type: chat.get_type().to_u32().context("unknown chat type id")?,
chat_type: chat.get_type().into(),
is_unpromoted: chat.is_unpromoted(),
is_self_talk: chat.is_self_talk(),
contacts,
@@ -192,7 +191,7 @@ pub struct BasicChat {
profile_image: Option<String>, //BLOBS ?
archived: bool,
pinned: bool,
chat_type: u32,
chat_type: JsonrpcChatType,
is_unpromoted: bool,
is_self_talk: bool,
color: String,
@@ -220,7 +219,7 @@ impl BasicChat {
profile_image, //BLOBS ?
archived: chat.get_visibility() == chat::ChatVisibility::Archived,
pinned: chat.get_visibility() == chat::ChatVisibility::Pinned,
chat_type: chat.get_type().to_u32().context("unknown chat type id")?,
chat_type: chat.get_type().into(),
is_unpromoted: chat.is_unpromoted(),
is_self_talk: chat.is_self_talk(),
color,
@@ -274,3 +273,37 @@ impl JsonrpcChatVisibility {
}
}
}
#[derive(Clone, Serialize, Deserialize, PartialEq, TypeDef, schemars::JsonSchema)]
#[serde(rename = "ChatType")]
pub enum JsonrpcChatType {
Single,
Group,
Mailinglist,
OutBroadcast,
InBroadcast,
}
impl From<Chattype> for JsonrpcChatType {
fn from(chattype: Chattype) -> Self {
match chattype {
Chattype::Single => JsonrpcChatType::Single,
Chattype::Group => JsonrpcChatType::Group,
Chattype::Mailinglist => JsonrpcChatType::Mailinglist,
Chattype::OutBroadcast => JsonrpcChatType::OutBroadcast,
Chattype::InBroadcast => JsonrpcChatType::InBroadcast,
}
}
}
impl From<JsonrpcChatType> for Chattype {
fn from(chattype: JsonrpcChatType) -> Self {
match chattype {
JsonrpcChatType::Single => Chattype::Single,
JsonrpcChatType::Group => Chattype::Group,
JsonrpcChatType::Mailinglist => Chattype::Mailinglist,
JsonrpcChatType::OutBroadcast => Chattype::OutBroadcast,
JsonrpcChatType::InBroadcast => Chattype::InBroadcast,
}
}
}

View File

@@ -11,6 +11,7 @@ use num_traits::cast::ToPrimitive;
use serde::Serialize;
use typescript_type_def::TypeDef;
use super::chat::JsonrpcChatType;
use super::color_int_to_hex_string;
use super::message::MessageViewtype;
@@ -23,7 +24,7 @@ pub enum ChatListItemFetchResult {
name: String,
avatar_path: Option<String>,
color: String,
chat_type: u32,
chat_type: JsonrpcChatType,
last_updated: Option<i64>,
summary_text1: String,
summary_text2: String,
@@ -151,7 +152,7 @@ pub(crate) async fn get_chat_list_item_by_id(
name: chat.get_name().to_owned(),
avatar_path,
color,
chat_type: chat.get_type().to_u32().context("unknown chat type id")?,
chat_type: chat.get_type().into(),
last_updated,
summary_text1,
summary_text2,

View File

@@ -1,8 +1,9 @@
use deltachat::{Event as CoreEvent, EventType as CoreEventType};
use num_traits::ToPrimitive;
use serde::Serialize;
use typescript_type_def::TypeDef;
use super::chat::JsonrpcChatType;
#[derive(Serialize, TypeDef, schemars::JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct Event {
@@ -307,7 +308,7 @@ pub enum EventType {
/// The type of the joined chat.
/// This can take the same values
/// as `BasicChat.chatType` ([`crate::api::types::chat::BasicChat::chat_type`]).
chat_type: u32,
chat_type: JsonrpcChatType,
/// ID of the chat in case of success.
chat_id: u32,
@@ -570,7 +571,7 @@ impl From<CoreEventType> for EventType {
progress,
} => SecurejoinInviterProgress {
contact_id: contact_id.to_u32(),
chat_type: chat_type.to_u32().unwrap_or(0),
chat_type: chat_type.into(),
chat_id: chat_id.to_u32(),
progress,
},

View File

@@ -16,6 +16,7 @@ use num_traits::cast::ToPrimitive;
use serde::{Deserialize, Serialize};
use typescript_type_def::TypeDef;
use super::chat::JsonrpcChatType;
use super::color_int_to_hex_string;
use super::contact::ContactObject;
use super::reactions::JsonrpcReactions;
@@ -531,7 +532,7 @@ pub struct MessageSearchResult {
chat_profile_image: Option<String>,
chat_color: String,
chat_name: String,
chat_type: u32,
chat_type: JsonrpcChatType,
is_chat_contact_request: bool,
is_chat_archived: bool,
message: String,
@@ -569,7 +570,7 @@ impl MessageSearchResult {
chat_id: chat.id.to_u32(),
chat_name: chat.get_name().to_owned(),
chat_color,
chat_type: chat.get_type().to_u32().context("unknown chat type id")?,
chat_type: chat.get_type().into(),
chat_profile_image,
is_chat_contact_request: chat.is_contact_request(),
is_chat_archived: chat.get_visibility() == ChatVisibility::Archived,

View File

@@ -45,15 +45,30 @@ const constants = data
key.startsWith("DC_SOCKET_") ||
key.startsWith("DC_LP_AUTH_") ||
key.startsWith("DC_PUSH_") ||
key.startsWith("DC_TEXT1_")
key.startsWith("DC_TEXT1_") ||
key.startsWith("DC_CHAT_TYPE")
);
})
.map((row) => {
return ` ${row.key}: ${row.value}`;
return ` export const ${row.key} = ${row.value};`;
})
.join(",\n");
.join("\n");
writeFileSync(
resolve(__dirname, "../generated/constants.ts"),
`// Generated!\n\nexport enum C {\n${constants.replace(/:/g, " =")},\n}\n`,
`// Generated!
export namespace C {
${constants}
/** @deprecated 10-8-2025 compare string directly with \`== "Group"\` */
export const DC_CHAT_TYPE_GROUP = "Group";
/** @deprecated 10-8-2025 compare string directly with \`== "InBroadcast"\`*/
export const DC_CHAT_TYPE_IN_BROADCAST = "InBroadcast";
/** @deprecated 10-8-2025 compare string directly with \`== "Mailinglist"\` */
export const DC_CHAT_TYPE_MAILINGLIST = "Mailinglist";
/** @deprecated 10-8-2025 compare string directly with \`== "OutBroadcast"\` */
export const DC_CHAT_TYPE_OUT_BROADCAST = "OutBroadcast";
/** @deprecated 10-8-2025 compare string directly with \`== "Single"\` */
export const DC_CHAT_TYPE_SINGLE = "Single";
}\n`,
);

View File

@@ -91,19 +91,17 @@ class ChatId(IntEnum):
LAST_SPECIAL = 9
class ChatType(IntEnum):
class ChatType(str, Enum):
"""Chat type."""
UNDEFINED = 0
SINGLE = 100
SINGLE = "Single"
"""1:1 chat, i.e. a direct chat with a single contact"""
GROUP = 120
GROUP = "Group"
MAILINGLIST = 140
MAILINGLIST = "Mailinglist"
OUT_BROADCAST = 160
OUT_BROADCAST = "OutBroadcast"
"""Outgoing broadcast channel, called "Channel" in the UI.
The user can send into this channel,
@@ -115,7 +113,7 @@ class ChatType(IntEnum):
which would make it hard to grep for it.
"""
IN_BROADCAST = 165
IN_BROADCAST = "InBroadcast"
"""Incoming broadcast channel, called "Channel" in the UI.
This channel is read-only,