diff --git a/CHANGELOG.md b/CHANGELOG.md index f832e1a9b..ea6287f55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ - jsonrpc: add `BasicChat` object as a leaner alternative to `FullChat` #3590 - jsonrpc: add `last_seen` property to `Contact` #3590 - breaking! jsonrpc: replace `Message.quoted_text` and `Message.quoted_message_id` with `Message.quote` #3590 +- add separate stock strings for actions done by contacts to make them easier to translate #3518 ### Changes - order contact lists by "last seen"; diff --git a/deltachat-ffi/deltachat.h b/deltachat-ffi/deltachat.h index 3d785a71c..28d912cc7 100644 --- a/deltachat-ffi/deltachat.h +++ b/deltachat-ffi/deltachat.h @@ -5966,28 +5966,38 @@ void dc_event_unref(dc_event_t* event); /// Used in status messages for group name changes. /// - %1$s will be replaced by the old group name /// - %2$s will be replaced by the new group name +/// +/// @deprecated 2022-09-10 #define DC_STR_MSGGRPNAME 15 /// "Group image changed." /// /// Used in status messages for group images changes. +/// +/// @deprecated 2022-09-10 #define DC_STR_MSGGRPIMGCHANGED 16 /// "Member %1$s added." /// /// Used in status messages for added members. /// - %1$s will be replaced by the name of the added member +/// +/// @deprecated 2022-09-10 #define DC_STR_MSGADDMEMBER 17 /// "Member %1$s removed." /// /// Used in status messages for removed members. /// - %1$s will be replaced by the name of the removed member +/// +/// @deprecated 2022-09-10 #define DC_STR_MSGDELMEMBER 18 /// "Group left." /// /// Used in status messages. +/// +/// @deprecated 2022-09-10 #define DC_STR_MSGGROUPLEFT 19 /// "GIF" @@ -6034,9 +6044,7 @@ void dc_event_unref(dc_event_t* event); /// - %1$s will be replaced by the subject of the displayed message #define DC_STR_READRCPT_MAILBODY 32 -/// "Group image deleted." -/// -/// Used in status messages for deleted group images. +/// @deprecated Deprecated, this string is no longer needed. #define DC_STR_MSGGRPIMGDELETED 33 /// "End-to-end encryption preferred." @@ -6089,6 +6097,8 @@ void dc_event_unref(dc_event_t* event); /// - %1$s will be replaced by an action /// as #DC_STR_MSGADDMEMBER or #DC_STR_MSGGRPIMGCHANGED (full-stop removed, if any) /// - %2$s will be replaced by the name of the user taking that action +/// +/// @deprecated 2022-09-10 #define DC_STR_MSGACTIONBYUSER 62 /// "%1$s by me" @@ -6096,6 +6106,8 @@ void dc_event_unref(dc_event_t* event); /// Used to concretize actions. /// - %1$s will be replaced by an action /// as #DC_STR_MSGADDMEMBER or #DC_STR_MSGGRPIMGCHANGED (full-stop removed, if any) +/// +/// @deprecated 2022-09-10 #define DC_STR_MSGACTIONBYME 63 /// "Location streaming enabled." @@ -6159,6 +6171,8 @@ void dc_event_unref(dc_event_t* event); /// "Message deletion timer is disabled." /// /// Used in status messages. +/// +/// @deprecated 2022-09-10 #define DC_STR_EPHEMERAL_DISABLED 75 /// "Message deletion timer is set to %1$s s." @@ -6166,26 +6180,36 @@ void dc_event_unref(dc_event_t* event); /// Used in status messages when the other constants /// (#DC_STR_EPHEMERAL_MINUTE, #DC_STR_EPHEMERAL_HOUR and so on) do not match the timer. /// - %1$s will be replaced by the number of seconds the timer is set to +/// +/// @deprecated 2022-09-10 #define DC_STR_EPHEMERAL_SECONDS 76 /// "Message deletion timer is set to 1 minute." /// /// Used in status messages. +/// +/// @deperecated 2022-09-10 #define DC_STR_EPHEMERAL_MINUTE 77 /// "Message deletion timer is set to 1 hour." /// /// Used in status messages. +/// +/// @deprecated 2022-09-10 #define DC_STR_EPHEMERAL_HOUR 78 /// "Message deletion timer is set to 1 day." /// /// Used in status messages. +/// +/// @deprecated 2022-09-10 #define DC_STR_EPHEMERAL_DAY 79 /// "Message deletion timer is set to 1 week." /// /// Used in status messages. +/// +/// @deprecated 2022-09-10 #define DC_STR_EPHEMERAL_WEEK 80 /// @deprecated Deprecated 2021-01-30, DC_STR_EPHEMERAL_WEEKS is used instead. @@ -6226,12 +6250,11 @@ void dc_event_unref(dc_event_t* event); /// "Chat protection enabled." /// -/// Used in status messages. + +/// @deprecated Deprecated, replaced by DC_STR_MSG_YOU_ENABLED_PROTECTION and DC_STR_MSG_PROTECTION_ENABLED_BY. #define DC_STR_PROTECTION_ENABLED 88 -/// "Chat protection disabled." -/// -/// Used in status messages. +/// @deprecated Deprecated, replaced by DC_STR_MSG_YOU_DISABLED_PROTECTION and DC_STR_MSG_PROTECTION_DISABLED_BY. #define DC_STR_PROTECTION_DISABLED 89 /// "Reply" @@ -6253,29 +6276,37 @@ void dc_event_unref(dc_event_t* event); /// "Message deletion timer is set to %1$s minutes." /// /// Used in status messages. -// -/// `%1$s` will be replaced by the number of minutes (alwasy >1) the timer is set to. +/// +/// `%1$s` will be replaced by the number of minutes (always >1) the timer is set to. +/// +/// @deprecated Replaced by DC_STR_MSG_YOU_EPHEMERAL_TIMER_MINUTES and DC_STR_MSG_EPHEMERAL_TIMER_MINUTES_BY. #define DC_STR_EPHEMERAL_MINUTES 93 /// "Message deletion timer is set to %1$s hours." /// /// Used in status messages. -// +/// /// `%1$s` will be replaced by the number of hours (always >1) the timer is set to. +/// +/// @deprecated Replaced by DC_STR_MSG_YOU_EPHEMERAL_TIMER_HOURS and DC_STR_MSG_EPHEMERAL_TIMER_HOURS_BY. #define DC_STR_EPHEMERAL_HOURS 94 /// "Message deletion timer is set to %1$s days." /// /// Used in status messages. -// +/// /// `%1$s` will be replaced by the number of days (always >1) the timer is set to. +/// +/// @deprecated Replaced by DC_STR_MSG_YOU_EPHEMERAL_TIMER_DAYS and DC_STR_MSG_EPHEMERAL_TIMER_DAYS_BY. #define DC_STR_EPHEMERAL_DAYS 95 /// "Message deletion timer is set to %1$s weeks." /// /// Used in status messages. -// +/// /// `%1$s` will be replaced by the number of weeks (always >1) the timer is set to. +/// +/// @deprecated Replaced by DC_STR_MSG_YOU_EPHEMERAL_TIMER_WEEKS and DC_STR_MSG_EPHEMERAL_TIMER_WEEKS_BY. #define DC_STR_EPHEMERAL_WEEKS 96 /// "Forwarded" @@ -6432,7 +6463,7 @@ void dc_event_unref(dc_event_t* event); /// Used as status in the connectivity view. #define DC_STR_NOT_CONNECTED 121 -/// %1$s changed their address from %2$s to %3$s" +/// "%1$s changed their address from %2$s to %3$s" /// /// Used as an info message to chats with contacts that changed their address. #define DC_STR_AEAP_ADDR_CHANGED 122 @@ -6450,6 +6481,246 @@ void dc_event_unref(dc_event_t* event); /// Used in a device message that explains AEAP. #define DC_STR_AEAP_EXPLANATION_AND_LINK 123 +/// "You changed group name from \"%1$s\" to \"%2$s\"." +/// +/// `%1$s` will be replaced by the old group name. +/// `%2$s` will be replaced by the new group name. +#define DC_STR_GROUP_NAME_CHANGED_BY_YOU 124 + +/// "Group name changed from \"%1$s\" to \"%2$s\" by %3$s." +/// +/// `%1$s` will be replaced by the old group name. +/// `%2$s` will be replaced by the new group name. +/// `%3$s` will be replaced by name and address of the contact who did the action. +#define DC_STR_GROUP_NAME_CHANGED_BY_OTHER 125 + +/// "You changed the group image." +#define DC_STR_GROUP_IMAGE_CHANGED_BY_YOU 126 + +/// "Group image changed by %1$s." +/// +/// `%1$s` will be replaced by name and address of the contact who did the action. +#define DC_STR_GROUP_IMAGE_CHANGED_BY_OTHER 127 + +/// "You added member %1$s." +/// +/// Used in status messages. +#define DC_STR_ADD_MEMBER_BY_YOU 128 + +/// "Member %1$s added by %2$s." +/// +/// `%1$s` will be replaced by name and address of the contact added to the group. +/// `%2$s` will be replaced by name and address of the contact who did the action. +/// +/// Used in status messages. +#define DC_STR_ADD_MEMBER_BY_OTHER 129 + +/// "You removed member %1$s." +/// +/// `%1$s` will be replaced by name and address of the contact removed from the group. +/// +/// Used in status messages. +#define DC_STR_REMOVE_MEMBER_BY_YOU 130 + +/// "Member %1$s removed by %2$s." +/// +/// `%1$s` will be replaced by name and address of the contact removed from the group. +/// `%2$s` will be replaced by name and address of the contact who did the action. +/// +/// Used in status messages. +#define DC_STR_REMOVE_MEMBER_BY_OTHER 131 + +/// "You left the group." +/// +/// Used in status messages. +#define DC_STR_GROUP_LEFT_BY_YOU 132 + +/// "Group left by %1$s." +/// +/// `%1$s` will be replaced by name and address of the contact. +/// +/// Used in status messages. +#define DC_STR_GROUP_LEFT_BY_OTHER 133 + +/// "You deleted the group image." +/// +/// Used in status messages. +#define DC_STR_GROUP_IMAGE_DELETED_BY_YOU 134 + +/// "Group image deleted by %1$s." +/// +/// `%1$s` will be replaced by name and address of the contact. +/// +/// Used in status messages. +#define DC_STR_GROUP_IMAGE_DELETED_BY_OTHER 135 + +/// "You enabled location streaming." +/// +/// Used in status messages. +#define DC_STR_LOCATION_ENABLED_BY_YOU 136 + +/// "Location streaming enabled by %1$s." +/// +/// `%1$s` will be replaced by name and address of the contact. +/// +/// Used in status messages. +#define DC_STR_LOCATION_ENABLED_BY_OTHER 137 + +/// "You disabled message deletion timer." +/// +/// Used in status messages. +#define DC_STR_EPHEMERAL_TIMER_DISABLED_BY_YOU 138 + +/// "Message deletion timer is disabled by %1$s." +/// +/// `%1$s` will be replaced by name and address of the contact. +/// +/// Used in status messages. +#define DC_STR_EPHEMERAL_TIMER_DISABLED_BY_OTHER 139 + +/// "You set message deletion timer to %1$s s." +/// +/// `%1$s` will be replaced by the number of seconds (always >1) the timer is set to. +/// +/// Used in status messages. +#define DC_STR_EPHEMERAL_TIMER_SECONDS_BY_YOU 140 + +/// "Message deletion timer is set to %1$s s by %2$s." +/// +/// `%1$s` will be replaced by the number of seconds (always >1) the timer is set to. +/// `%2$s` will be replaced by name and address of the contact. +/// +/// Used in status messages. +#define DC_STR_EPHEMERAL_TIMER_SECONDS_BY_OTHER 141 + +/// "You set message deletion timer to 1 minute." +/// +/// Used in status messages. +#define DC_STR_EPHEMERAL_TIMER_1_MINUTE_BY_YOU 142 + +/// "Message deletion timer is set to 1 minute by %1$s." +/// +/// `%1$s` will be replaced by name and address of the contact. +/// +/// Used in status messages. +#define DC_STR_EPHEMERAL_TIMER_1_MINUTE_BY_OTHER 143 + +/// "You set message deletion timer to 1 hour." +/// +/// Used in status messages. +#define DC_STR_EPHEMERAL_TIMER_1_HOUR_BY_YOU 144 + +/// "Message deletion timer is set to 1 hour by %1$s." +/// +/// `%1$s` will be replaced by name and address of the contact. +/// +/// Used in status messages. +#define DC_STR_EPHEMERAL_TIMER_1_HOUR_BY_OTHER 145 + +/// "You set message deletion timer to 1 day." +/// +/// Used in status messages. +#define DC_STR_EPHEMERAL_TIMER_1_DAY_BY_YOU 146 + +/// "Message deletion timer is set to 1 day by %1$s." +/// +/// `%1$s` will be replaced by name and address of the contact. +/// +/// Used in status messages. +#define DC_STR_EPHEMERAL_TIMER_1_DAY_BY_OTHER 147 + +/// "You set message deletion timer to 1 week." +/// +/// Used in status messages. +#define DC_STR_EPHEMERAL_TIMER_1_WEEK_BY_YOU 148 + +/// "Message deletion timer is set to 1 week by %1$s." +/// +/// `%1$s` will be replaced by name and address of the contact. +/// +/// Used in status messages. +#define DC_STR_EPHEMERAL_TIMER_1_WEEK_BY_OTHER 149 + +/// "You set message deletion timer to %1$s minutes." +/// +/// Used in status messages. +/// +/// `%1$s` will be replaced by the number of minutes (always >1) the timer is set to. +#define DC_STR_EPHEMERAL_TIMER_MINUTES_BY_YOU 150 + +/// "Message deletion timer is set to %1$s minutes by %2$s." +/// +/// Used in status messages. +/// +/// `%1$s` will be replaced by the number of minutes (always >1) the timer is set to. +/// `%2$s` will be replaced by name and address of the contact. +#define DC_STR_EPHEMERAL_TIMER_MINUTES_BY_OTHER 151 + +/// "You set message deletion timer to %1$s hours." +/// +/// Used in status messages. +/// +/// `%1$s` will be replaced by the number of hours (always >1) the timer is set to. +#define DC_STR_EPHEMERAL_TIMER_HOURS_BY_YOU 152 + +/// "Message deletion timer is set to %1$s hours by %2$s." +/// +/// Used in status messages. +/// +/// `%1$s` will be replaced by the number of hours (always >1) the timer is set to. +/// `%2$s` will be replaced by name and address of the contact. +#define DC_STR_EPHEMERAL_TIMER_HOURS_BY_OTHER 153 + +/// "You set message deletion timer to %1$s days." +/// +/// Used in status messages. +/// +/// `%1$s` will be replaced by the number of days (always >1) the timer is set to. +#define DC_STR_EPHEMERAL_TIMER_DAYS_BY_YOU 154 + +/// "Message deletion timer is set to %1$s days by %2$s." +/// +/// Used in status messages. +/// +/// `%1$s` will be replaced by the number of days (always >1) the timer is set to. +/// `%2$s` will be replaced by name and address of the contact. +#define DC_STR_EPHEMERAL_TIMER_DAYS_BY_OTHER 155 + +/// "You set message deletion timer to %1$s weeks." +/// +/// Used in status messages. +/// +/// `%1$s` will be replaced by the number of weeks (always >1) the timer is set to. +#define DC_STR_EPHEMERAL_TIMER_WEEKS_BY_YOU 156 + +/// "Message deletion timer is set to %1$s weeks by %2$s." +/// +/// Used in status messages. +/// +/// `%1$s` will be replaced by the number of weeks (always >1) the timer is set to. +/// `%2$s` will be replaced by name and address of the contact. +#define DC_STR_EPHEMERAL_TIMER_WEEKS_BY_OTHER 157 + +/// "You enabled chat protection." +/// +/// Used in status messages. +#define DC_STR_PROTECTION_ENABLED_BY_YOU 158 + +/// "Chat protection enabled by %1$s." +/// +/// `%1$s` will be replaced by name and address of the contact. +/// +/// Used in status messages. +#define DC_STR_PROTECTION_ENABLED_BY_OTHER 159 + +/// "You disabled chat protection." +#define DC_STR_PROTECTION_DISABLED_BY_YOU 160 + +/// "Chat protection disabled by %1$s." +/// +/// `%1$s` will be replaced by name and address of the contact. +#define DC_STR_PROTECTION_DISABLED_BY_OTHER 161 + /** * @} */ diff --git a/node/constants.js b/node/constants.js index c1bfd1e25..98808168c 100644 --- a/node/constants.js +++ b/node/constants.js @@ -128,6 +128,8 @@ module.exports = { DC_STATE_UNDEFINED: 0, DC_STR_AC_SETUP_MSG_BODY: 43, DC_STR_AC_SETUP_MSG_SUBJECT: 42, + DC_STR_ADD_MEMBER_BY_OTHER: 129, + DC_STR_ADD_MEMBER_BY_YOU: 128, DC_STR_AEAP_ADDR_CHANGED: 122, DC_STR_AEAP_EXPLANATION_AND_LINK: 123, DC_STR_ARCHIVEDCHATS: 40, @@ -160,6 +162,26 @@ module.exports = { DC_STR_EPHEMERAL_MINUTE: 77, DC_STR_EPHEMERAL_MINUTES: 93, DC_STR_EPHEMERAL_SECONDS: 76, + DC_STR_EPHEMERAL_TIMER_1_DAY_BY_OTHER: 147, + DC_STR_EPHEMERAL_TIMER_1_DAY_BY_YOU: 146, + DC_STR_EPHEMERAL_TIMER_1_HOUR_BY_OTHER: 145, + DC_STR_EPHEMERAL_TIMER_1_HOUR_BY_YOU: 144, + DC_STR_EPHEMERAL_TIMER_1_MINUTE_BY_OTHER: 143, + DC_STR_EPHEMERAL_TIMER_1_MINUTE_BY_YOU: 142, + DC_STR_EPHEMERAL_TIMER_1_WEEK_BY_OTHER: 149, + DC_STR_EPHEMERAL_TIMER_1_WEEK_BY_YOU: 148, + DC_STR_EPHEMERAL_TIMER_DAYS_BY_OTHER: 155, + DC_STR_EPHEMERAL_TIMER_DAYS_BY_YOU: 154, + DC_STR_EPHEMERAL_TIMER_DISABLED_BY_OTHER: 139, + DC_STR_EPHEMERAL_TIMER_DISABLED_BY_YOU: 138, + DC_STR_EPHEMERAL_TIMER_HOURS_BY_OTHER: 153, + DC_STR_EPHEMERAL_TIMER_HOURS_BY_YOU: 152, + DC_STR_EPHEMERAL_TIMER_MINUTES_BY_OTHER: 151, + DC_STR_EPHEMERAL_TIMER_MINUTES_BY_YOU: 150, + DC_STR_EPHEMERAL_TIMER_SECONDS_BY_OTHER: 141, + DC_STR_EPHEMERAL_TIMER_SECONDS_BY_YOU: 140, + DC_STR_EPHEMERAL_TIMER_WEEKS_BY_OTHER: 157, + DC_STR_EPHEMERAL_TIMER_WEEKS_BY_YOU: 156, DC_STR_EPHEMERAL_WEEK: 80, DC_STR_EPHEMERAL_WEEKS: 96, DC_STR_ERROR: 112, @@ -169,10 +191,20 @@ module.exports = { DC_STR_FINGERPRINTS: 30, DC_STR_FORWARDED: 97, DC_STR_GIF: 23, + DC_STR_GROUP_IMAGE_CHANGED_BY_OTHER: 127, + DC_STR_GROUP_IMAGE_CHANGED_BY_YOU: 126, + DC_STR_GROUP_IMAGE_DELETED_BY_OTHER: 135, + DC_STR_GROUP_IMAGE_DELETED_BY_YOU: 134, + DC_STR_GROUP_LEFT_BY_OTHER: 133, + DC_STR_GROUP_LEFT_BY_YOU: 132, + DC_STR_GROUP_NAME_CHANGED_BY_OTHER: 125, + DC_STR_GROUP_NAME_CHANGED_BY_YOU: 124, DC_STR_IMAGE: 9, DC_STR_INCOMING_MESSAGES: 103, DC_STR_LAST_MSG_SENT_SUCCESSFULLY: 111, DC_STR_LOCATION: 66, + DC_STR_LOCATION_ENABLED_BY_OTHER: 137, + DC_STR_LOCATION_ENABLED_BY_YOU: 136, DC_STR_MESSAGES: 114, DC_STR_MSGACTIONBYME: 63, DC_STR_MSGACTIONBYUSER: 62, @@ -192,10 +224,16 @@ module.exports = { DC_STR_PARTIAL_DOWNLOAD_MSG_BODY: 99, DC_STR_PART_OF_TOTAL_USED: 116, DC_STR_PROTECTION_DISABLED: 89, + DC_STR_PROTECTION_DISABLED_BY_OTHER: 161, + DC_STR_PROTECTION_DISABLED_BY_YOU: 160, DC_STR_PROTECTION_ENABLED: 88, + DC_STR_PROTECTION_ENABLED_BY_OTHER: 159, + DC_STR_PROTECTION_ENABLED_BY_YOU: 158, DC_STR_QUOTA_EXCEEDING_MSG_BODY: 98, DC_STR_READRCPT: 31, DC_STR_READRCPT_MAILBODY: 32, + DC_STR_REMOVE_MEMBER_BY_OTHER: 131, + DC_STR_REMOVE_MEMBER_BY_YOU: 130, DC_STR_REPLY_NOUN: 90, DC_STR_SAVED_MESSAGES: 69, DC_STR_SECURE_JOIN_GROUP_QR_DESC: 120, diff --git a/node/lib/constants.ts b/node/lib/constants.ts index 80c1a5129..3dbc60048 100644 --- a/node/lib/constants.ts +++ b/node/lib/constants.ts @@ -128,6 +128,8 @@ export enum C { DC_STATE_UNDEFINED = 0, DC_STR_AC_SETUP_MSG_BODY = 43, DC_STR_AC_SETUP_MSG_SUBJECT = 42, + DC_STR_ADD_MEMBER_BY_OTHER = 129, + DC_STR_ADD_MEMBER_BY_YOU = 128, DC_STR_AEAP_ADDR_CHANGED = 122, DC_STR_AEAP_EXPLANATION_AND_LINK = 123, DC_STR_ARCHIVEDCHATS = 40, @@ -160,6 +162,26 @@ export enum C { DC_STR_EPHEMERAL_MINUTE = 77, DC_STR_EPHEMERAL_MINUTES = 93, DC_STR_EPHEMERAL_SECONDS = 76, + DC_STR_EPHEMERAL_TIMER_1_DAY_BY_OTHER = 147, + DC_STR_EPHEMERAL_TIMER_1_DAY_BY_YOU = 146, + DC_STR_EPHEMERAL_TIMER_1_HOUR_BY_OTHER = 145, + DC_STR_EPHEMERAL_TIMER_1_HOUR_BY_YOU = 144, + DC_STR_EPHEMERAL_TIMER_1_MINUTE_BY_OTHER = 143, + DC_STR_EPHEMERAL_TIMER_1_MINUTE_BY_YOU = 142, + DC_STR_EPHEMERAL_TIMER_1_WEEK_BY_OTHER = 149, + DC_STR_EPHEMERAL_TIMER_1_WEEK_BY_YOU = 148, + DC_STR_EPHEMERAL_TIMER_DAYS_BY_OTHER = 155, + DC_STR_EPHEMERAL_TIMER_DAYS_BY_YOU = 154, + DC_STR_EPHEMERAL_TIMER_DISABLED_BY_OTHER = 139, + DC_STR_EPHEMERAL_TIMER_DISABLED_BY_YOU = 138, + DC_STR_EPHEMERAL_TIMER_HOURS_BY_OTHER = 153, + DC_STR_EPHEMERAL_TIMER_HOURS_BY_YOU = 152, + DC_STR_EPHEMERAL_TIMER_MINUTES_BY_OTHER = 151, + DC_STR_EPHEMERAL_TIMER_MINUTES_BY_YOU = 150, + DC_STR_EPHEMERAL_TIMER_SECONDS_BY_OTHER = 141, + DC_STR_EPHEMERAL_TIMER_SECONDS_BY_YOU = 140, + DC_STR_EPHEMERAL_TIMER_WEEKS_BY_OTHER = 157, + DC_STR_EPHEMERAL_TIMER_WEEKS_BY_YOU = 156, DC_STR_EPHEMERAL_WEEK = 80, DC_STR_EPHEMERAL_WEEKS = 96, DC_STR_ERROR = 112, @@ -169,10 +191,20 @@ export enum C { DC_STR_FINGERPRINTS = 30, DC_STR_FORWARDED = 97, DC_STR_GIF = 23, + DC_STR_GROUP_IMAGE_CHANGED_BY_OTHER = 127, + DC_STR_GROUP_IMAGE_CHANGED_BY_YOU = 126, + DC_STR_GROUP_IMAGE_DELETED_BY_OTHER = 135, + DC_STR_GROUP_IMAGE_DELETED_BY_YOU = 134, + DC_STR_GROUP_LEFT_BY_OTHER = 133, + DC_STR_GROUP_LEFT_BY_YOU = 132, + DC_STR_GROUP_NAME_CHANGED_BY_OTHER = 125, + DC_STR_GROUP_NAME_CHANGED_BY_YOU = 124, DC_STR_IMAGE = 9, DC_STR_INCOMING_MESSAGES = 103, DC_STR_LAST_MSG_SENT_SUCCESSFULLY = 111, DC_STR_LOCATION = 66, + DC_STR_LOCATION_ENABLED_BY_OTHER = 137, + DC_STR_LOCATION_ENABLED_BY_YOU = 136, DC_STR_MESSAGES = 114, DC_STR_MSGACTIONBYME = 63, DC_STR_MSGACTIONBYUSER = 62, @@ -192,10 +224,16 @@ export enum C { DC_STR_PARTIAL_DOWNLOAD_MSG_BODY = 99, DC_STR_PART_OF_TOTAL_USED = 116, DC_STR_PROTECTION_DISABLED = 89, + DC_STR_PROTECTION_DISABLED_BY_OTHER = 161, + DC_STR_PROTECTION_DISABLED_BY_YOU = 160, DC_STR_PROTECTION_ENABLED = 88, + DC_STR_PROTECTION_ENABLED_BY_OTHER = 159, + DC_STR_PROTECTION_ENABLED_BY_YOU = 158, DC_STR_QUOTA_EXCEEDING_MSG_BODY = 98, DC_STR_READRCPT = 31, DC_STR_READRCPT_MAILBODY = 32, + DC_STR_REMOVE_MEMBER_BY_OTHER = 131, + DC_STR_REMOVE_MEMBER_BY_YOU = 130, DC_STR_REPLY_NOUN = 90, DC_STR_SAVED_MESSAGES = 69, DC_STR_SECURE_JOIN_GROUP_QR_DESC = 120, diff --git a/python/src/deltachat/message.py b/python/src/deltachat/message.py index a7a9d9b58..9ed5b132f 100644 --- a/python/src/deltachat/message.py +++ b/python/src/deltachat/message.py @@ -507,6 +507,8 @@ def parse_system_add_remove(text): returns a (action, affected, actor) triple""" + # You removed member a@b. + # You added member a@b. # Member Me (x@y) removed by a@b. # Member x@y added by a@b # Member With space (tmp1@x.org) removed by tmp2@x.org. @@ -518,6 +520,10 @@ def parse_system_add_remove(text): if m: affected, action, actor = m.groups() return action, extract_addr(affected), extract_addr(actor) + m = re.match(r"you (removed|added) member (.+)", text) + if m: + action, affected = m.groups() + return action, extract_addr(affected), "me" if text.startswith("group left by "): addr = extract_addr(text[13:]) if addr: diff --git a/python/tests/test_3_offline.py b/python/tests/test_3_offline.py index fa1b95114..eee852f0d 100644 --- a/python/tests/test_3_offline.py +++ b/python/tests/test_3_offline.py @@ -301,7 +301,7 @@ class TestOfflineChat: assert d["draft"] == "" if chat.get_draft() is None else chat.get_draft() def test_group_chat_creation_with_translation(self, ac1): - ac1.set_stock_translation(const.DC_STR_MSGGRPNAME, "abc %1$s xyz %2$s") + ac1.set_stock_translation(const.DC_STR_GROUP_NAME_CHANGED_BY_YOU, "abc %1$s xyz %2$s") ac1._evtracker.consume_events() with pytest.raises(ValueError): ac1.set_stock_translation(const.DC_STR_FILE, "xyz %1$s") @@ -317,7 +317,7 @@ class TestOfflineChat: chat.send_text("Now we have a group for homework") assert chat.is_promoted() chat.set_name("Homework") - assert chat.get_messages()[-1].text == "abc homework xyz Homework by me." + assert chat.get_messages()[-1].text == "abc homework xyz Homework" @pytest.mark.parametrize("verified", [True, False]) def test_group_chat_qr(self, acfactory, ac1, verified): diff --git a/src/ephemeral.rs b/src/ephemeral.rs index ef90e7b3a..6e45fcd68 100644 --- a/src/ephemeral.rs +++ b/src/ephemeral.rs @@ -587,7 +587,7 @@ mod tests { assert_eq!( stock_ephemeral_timer_changed(&context, Timer::Disabled, ContactId::SELF).await, - "Message deletion timer is disabled by me." + "You disabled message deletion timer." ); assert_eq!( @@ -597,7 +597,7 @@ mod tests { ContactId::SELF ) .await, - "Message deletion timer is set to 1 s by me." + "You set message deletion timer to 1 s." ); assert_eq!( stock_ephemeral_timer_changed( @@ -606,7 +606,7 @@ mod tests { ContactId::SELF ) .await, - "Message deletion timer is set to 30 s by me." + "You set message deletion timer to 30 s." ); assert_eq!( stock_ephemeral_timer_changed( @@ -615,7 +615,7 @@ mod tests { ContactId::SELF ) .await, - "Message deletion timer is set to 1 minute by me." + "You set message deletion timer to 1 minute." ); assert_eq!( stock_ephemeral_timer_changed( @@ -624,7 +624,7 @@ mod tests { ContactId::SELF ) .await, - "Message deletion timer is set to 1.5 minutes by me." + "You set message deletion timer to 1.5 minutes." ); assert_eq!( stock_ephemeral_timer_changed( @@ -633,7 +633,7 @@ mod tests { ContactId::SELF ) .await, - "Message deletion timer is set to 30 minutes by me." + "You set message deletion timer to 30 minutes." ); assert_eq!( stock_ephemeral_timer_changed( @@ -642,7 +642,7 @@ mod tests { ContactId::SELF ) .await, - "Message deletion timer is set to 1 hour by me." + "You set message deletion timer to 1 hour." ); assert_eq!( stock_ephemeral_timer_changed( @@ -651,7 +651,7 @@ mod tests { ContactId::SELF ) .await, - "Message deletion timer is set to 1.5 hours by me." + "You set message deletion timer to 1.5 hours." ); assert_eq!( stock_ephemeral_timer_changed( @@ -662,7 +662,7 @@ mod tests { ContactId::SELF ) .await, - "Message deletion timer is set to 2 hours by me." + "You set message deletion timer to 2 hours." ); assert_eq!( stock_ephemeral_timer_changed( @@ -673,7 +673,7 @@ mod tests { ContactId::SELF ) .await, - "Message deletion timer is set to 1 day by me." + "You set message deletion timer to 1 day." ); assert_eq!( stock_ephemeral_timer_changed( @@ -684,7 +684,7 @@ mod tests { ContactId::SELF ) .await, - "Message deletion timer is set to 2 days by me." + "You set message deletion timer to 2 days." ); assert_eq!( stock_ephemeral_timer_changed( @@ -695,7 +695,7 @@ mod tests { ContactId::SELF ) .await, - "Message deletion timer is set to 1 week by me." + "You set message deletion timer to 1 week." ); assert_eq!( stock_ephemeral_timer_changed( @@ -706,7 +706,7 @@ mod tests { ContactId::SELF ) .await, - "Message deletion timer is set to 4 weeks by me." + "You set message deletion timer to 4 weeks." ); } diff --git a/src/stock_str.rs b/src/stock_str.rs index e0014440b..2b9dc8343 100644 --- a/src/stock_str.rs +++ b/src/stock_str.rs @@ -1,8 +1,5 @@ //! Module to work with translatable stock strings. -use std::future::Future; -use std::pin::Pin; - use anyhow::{bail, Error}; use strum::EnumProperty as EnumPropertyTrait; use strum_macros::EnumProperty; @@ -52,21 +49,6 @@ pub enum StockMessage { #[strum(props(fallback = "File"))] File = 12, - #[strum(props(fallback = "Group name changed from \"%1$s\" to \"%2$s\"."))] - MsgGrpName = 15, - - #[strum(props(fallback = "Group image changed."))] - MsgGrpImgChanged = 16, - - #[strum(props(fallback = "Member %1$s added."))] - MsgAddMember = 17, - - #[strum(props(fallback = "Member %1$s removed."))] - MsgDelMember = 18, - - #[strum(props(fallback = "Group left."))] - MsgGroupLeft = 19, - #[strum(props(fallback = "GIF"))] Gif = 23, @@ -91,9 +73,6 @@ pub enum StockMessage { #[strum(props(fallback = "This is a return receipt for the message \"%1$s\"."))] ReadRcptMailBody = 32, - #[strum(props(fallback = "Group image deleted."))] - MsgGrpImgDeleted = 33, - #[strum(props(fallback = "End-to-end encryption preferred"))] E2ePreferred = 34, @@ -122,12 +101,6 @@ pub enum StockMessage { ))] CannotLogin = 60, - #[strum(props(fallback = "%1$s by %2$s."))] - MsgActionByUser = 62, - - #[strum(props(fallback = "%1$s by me."))] - MsgActionByMe = 63, - #[strum(props(fallback = "Location streaming enabled."))] MsgLocationEnabled = 64, @@ -172,26 +145,6 @@ pub enum StockMessage { #[strum(props(fallback = "Failed to send message to %1$s."))] FailedSendingTo = 74, - #[strum(props(fallback = "Message deletion timer is disabled."))] - MsgEphemeralTimerDisabled = 75, - - // A fallback message for unknown timer values. - // "s" stands for "second" SI unit here. - #[strum(props(fallback = "Message deletion timer is set to %1$s s."))] - MsgEphemeralTimerEnabled = 76, - - #[strum(props(fallback = "Message deletion timer is set to 1 minute."))] - MsgEphemeralTimerMinute = 77, - - #[strum(props(fallback = "Message deletion timer is set to 1 hour."))] - MsgEphemeralTimerHour = 78, - - #[strum(props(fallback = "Message deletion timer is set to 1 day."))] - MsgEphemeralTimerDay = 79, - - #[strum(props(fallback = "Message deletion timer is set to 1 week."))] - MsgEphemeralTimerWeek = 80, - #[strum(props(fallback = "Video chat invitation"))] VideochatInvitation = 82, @@ -218,12 +171,6 @@ pub enum StockMessage { ))] ErrorNoNetwork = 87, - #[strum(props(fallback = "Chat protection enabled."))] - ProtectionEnabled = 88, - - #[strum(props(fallback = "Chat protection disabled."))] - ProtectionDisabled = 89, - // used in summaries, a noun, not a verb (not: "to reply") #[strum(props(fallback = "Reply"))] ReplyNoun = 90, @@ -239,18 +186,6 @@ pub enum StockMessage { ))] DeleteServerTurnedOff = 92, - #[strum(props(fallback = "Message deletion timer is set to %1$s minutes."))] - MsgEphemeralTimerMinutes = 93, - - #[strum(props(fallback = "Message deletion timer is set to %1$s hours."))] - MsgEphemeralTimerHours = 94, - - #[strum(props(fallback = "Message deletion timer is set to %1$s days."))] - MsgEphemeralTimerDays = 95, - - #[strum(props(fallback = "Message deletion timer is set to %1$s weeks."))] - MsgEphemeralTimerWeeks = 96, - #[strum(props(fallback = "Forwarded"))] Forwarded = 97, @@ -340,6 +275,122 @@ pub enum StockMessage { fallback = "You changed your email address from %1$s to %2$s.\n\nIf you now send a message to a verified group, contacts there will automatically replace the old with your new address.\n\nIt's highly advised to set up your old email provider to forward all emails to your new email address. Otherwise you might miss messages of contacts who did not get your new address yet." ))] AeapExplanationAndLink = 123, + + #[strum(props(fallback = "You changed group name from \"%1$s\" to \"%2$s\"."))] + MsgYouChangedGrpName = 124, + + #[strum(props(fallback = "Group name changed from \"%1$s\" to \"%2$s\" by %3$s."))] + MsgGrpNameChangedBy = 125, + + #[strum(props(fallback = "You changed the group image."))] + MsgYouChangedGrpImg = 126, + + #[strum(props(fallback = "Group image changed by %1$s."))] + MsgGrpImgChangedBy = 127, + + #[strum(props(fallback = "You added member %1$s."))] + MsgYouAddMember = 128, + + #[strum(props(fallback = "Member %1$s added by %2$s."))] + MsgAddMemberBy = 129, + + #[strum(props(fallback = "You removed member %1$s."))] + MsgYouDelMember = 130, + + #[strum(props(fallback = "Member %1$s removed by %2$s."))] + MsgDelMemberBy = 131, + + #[strum(props(fallback = "You left the group."))] + MsgYouLeftGroup = 132, + + #[strum(props(fallback = "Group left by %1$s."))] + MsgGroupLeftBy = 133, + + #[strum(props(fallback = "You deleted the group image."))] + MsgYouDeletedGrpImg = 134, + + #[strum(props(fallback = "Group image deleted by %1$s."))] + MsgGrpImgDeletedBy = 135, + + #[strum(props(fallback = "You enabled location streaming."))] + MsgYouEnabledLocation = 136, + + #[strum(props(fallback = "Location streaming enabled by %1$s."))] + MsgLocationEnabledBy = 137, + + #[strum(props(fallback = "You disabled message deletion timer."))] + MsgYouDisabledEphemeralTimer = 138, + + #[strum(props(fallback = "Message deletion timer is disabled by %1$s."))] + MsgEphemeralTimerDisabledBy = 139, + + // A fallback message for unknown timer values. + // "s" stands for "second" SI unit here. + #[strum(props(fallback = "You set message deletion timer to %1$s s."))] + MsgYouEnabledEphemeralTimer = 140, + + #[strum(props(fallback = "Message deletion timer is set to %1$s s by %2$s."))] + MsgEphemeralTimerEnabledBy = 141, + + #[strum(props(fallback = "You set message deletion timer to 1 minute."))] + MsgYouEphemeralTimerMinute = 142, + + #[strum(props(fallback = "Message deletion timer is set to 1 minute by %1$s."))] + MsgEphemeralTimerMinuteBy = 143, + + #[strum(props(fallback = "You set message deletion timer to 1 hour."))] + MsgYouEphemeralTimerHour = 144, + + #[strum(props(fallback = "Message deletion timer is set to 1 hour by %1$s."))] + MsgEphemeralTimerHourBy = 145, + + #[strum(props(fallback = "You set message deletion timer to 1 day."))] + MsgYouEphemeralTimerDay = 146, + + #[strum(props(fallback = "Message deletion timer is set to 1 day by %1$s."))] + MsgEphemeralTimerDayBy = 147, + + #[strum(props(fallback = "You set message deletion timer to 1 week."))] + MsgYouEphemeralTimerWeek = 148, + + #[strum(props(fallback = "Message deletion timer is set to 1 week by %1$s."))] + MsgEphemeralTimerWeekBy = 149, + + #[strum(props(fallback = "You set message deletion timer to %1$s minutes."))] + MsgYouEphemeralTimerMinutes = 150, + + #[strum(props(fallback = "Message deletion timer is set to %1$s minutes by %2$s."))] + MsgEphemeralTimerMinutesBy = 151, + + #[strum(props(fallback = "You set message deletion timer to %1$s hours."))] + MsgYouEphemeralTimerHours = 152, + + #[strum(props(fallback = "Message deletion timer is set to %1$s hours by %2$s."))] + MsgEphemeralTimerHoursBy = 153, + + #[strum(props(fallback = "You set message deletion timer to %1$s days."))] + MsgYouEphemeralTimerDays = 154, + + #[strum(props(fallback = "Message deletion timer is set to %1$s days by %2$s."))] + MsgEphemeralTimerDaysBy = 155, + + #[strum(props(fallback = "You set message deletion timer to %1$s weeks."))] + MsgYouEphemeralTimerWeeks = 156, + + #[strum(props(fallback = "Message deletion timer is set to %1$s weeks by %2$s."))] + MsgEphemeralTimerWeeksBy = 157, + + #[strum(props(fallback = "You enabled chat protection."))] + YouEnabledProtection = 158, + + #[strum(props(fallback = "Chat protection enabled by %1$s."))] + ProtectionEnabledBy = 159, + + #[strum(props(fallback = "You disabled chat protection."))] + YouDisabledProtection = 160, + + #[strum(props(fallback = "Chat protection disabled by %1$s."))] + ProtectionDisabledBy = 161, } impl StockMessage { @@ -393,38 +444,15 @@ trait StockStringMods: AsRef + Sized { .replacen("%3$d", replacement.as_ref(), 1) .replacen("%3$@", replacement.as_ref(), 1) } +} - /// Augments the message by saying it was performed by a user. - /// - /// This looks up the display name of `contact` and uses the [`msg_action_by_me`] and - /// [`msg_action_by_user`] stock strings to turn the stock string in one that says the - /// action was performed by this user. - /// - /// E.g. this turns `Group image changed.` into `Group image changed by me.` or `Group - /// image changed by Alice.`. - /// - /// Note that the original message should end in a `.`. - fn action_by_contact<'a>( - self, - context: &'a Context, - contact_id: ContactId, - ) -> Pin + Send + 'a>> - where - Self: Send + 'a, - { - Box::pin(async move { - let message = self.as_ref().trim_end_matches('.'); - match contact_id { - ContactId::SELF => msg_action_by_me(context, message).await, - _ => { - let displayname = Contact::get_by_id(context, contact_id) - .await - .map(|contact| contact.get_name_n_addr()) - .unwrap_or_else(|_| contact_id.to_string()); - msg_action_by_user(context, message, displayname).await - } - } - }) +impl ContactId { + /// Get contact name for stock string. + async fn get_stock_name(self, context: &Context) -> String { + Contact::get_by_id(context, self) + .await + .map(|contact| contact.get_name_n_addr()) + .unwrap_or_else(|_| self.to_string()) } } @@ -477,20 +505,28 @@ pub(crate) async fn msg_grp_name( to_group: impl AsRef, by_contact: ContactId, ) -> String { - translated(context, StockMessage::MsgGrpName) - .await - .replace1(from_group) - .replace2(to_group) - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouChangedGrpName) + .await + .replace1(from_group) + .replace2(to_group) + } else { + translated(context, StockMessage::MsgGrpNameChangedBy) + .await + .replace1(from_group) + .replace2(to_group) + .replace3(by_contact.get_stock_name(context).await) + } } -/// Stock string: `Group image changed.`. pub(crate) async fn msg_grp_img_changed(context: &Context, by_contact: ContactId) -> String { - translated(context, StockMessage::MsgGrpImgChanged) - .await - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouChangedGrpImg).await + } else { + translated(context, StockMessage::MsgGrpImgChangedBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } } /// Stock string: `Member %1$s added.`. @@ -510,11 +546,16 @@ pub(crate) async fn msg_add_member( .unwrap_or_else(|_| addr.to_string()), _ => addr.to_string(), }; - translated(context, StockMessage::MsgAddMember) - .await - .replace1(who) - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouAddMember) + .await + .replace1(who) + } else { + translated(context, StockMessage::MsgAddMemberBy) + .await + .replace1(who) + .replace2(by_contact.get_stock_name(context).await) + } } /// Stock string: `Member %1$s removed.`. @@ -534,19 +575,27 @@ pub(crate) async fn msg_del_member( .unwrap_or_else(|_| addr.to_string()), _ => addr.to_string(), }; - translated(context, StockMessage::MsgDelMember) - .await - .replace1(who) - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouDelMember) + .await + .replace1(who) + } else { + translated(context, StockMessage::MsgDelMemberBy) + .await + .replace1(who) + .replace2(by_contact.get_stock_name(context).await) + } } /// Stock string: `Group left.`. pub(crate) async fn msg_group_left(context: &Context, by_contact: ContactId) -> String { - translated(context, StockMessage::MsgGroupLeft) - .await - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouLeftGroup).await + } else { + translated(context, StockMessage::MsgGroupLeftBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } } /// Stock string: `GIF`. @@ -593,10 +642,13 @@ pub(crate) async fn read_rcpt_mail_body(context: &Context, message: impl AsRef String { - translated(context, StockMessage::MsgGrpImgDeleted) - .await - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouDeletedGrpImg).await + } else { + translated(context, StockMessage::MsgGrpImgDeletedBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } } /// Stock string: `End-to-end encryption preferred.`. @@ -714,25 +766,6 @@ pub(crate) async fn cannot_login(context: &Context, user: impl AsRef) -> St .replace1(user) } -/// Stock string: `%1$s by %2$s.`. -pub(crate) async fn msg_action_by_user( - context: &Context, - action: impl AsRef, - user: impl AsRef, -) -> String { - translated(context, StockMessage::MsgActionByUser) - .await - .replace1(action) - .replace2(user) -} - -/// Stock string: `%1$s by me.`. -pub(crate) async fn msg_action_by_me(context: &Context, action: impl AsRef) -> String { - translated(context, StockMessage::MsgActionByMe) - .await - .replace1(action) -} - /// Stock string: `Location streaming enabled.`. pub(crate) async fn msg_location_enabled(context: &Context) -> String { translated(context, StockMessage::MsgLocationEnabled).await @@ -740,10 +773,13 @@ pub(crate) async fn msg_location_enabled(context: &Context) -> String { /// Stock string: `Location streaming enabled by ...`. pub(crate) async fn msg_location_enabled_by(context: &Context, contact: ContactId) -> String { - translated(context, StockMessage::MsgLocationEnabled) - .await - .action_by_contact(context, contact) - .await + if contact == ContactId::SELF { + translated(context, StockMessage::MsgYouEnabledLocation).await + } else { + translated(context, StockMessage::MsgLocationEnabledBy) + .await + .replace1(contact.get_stock_name(context).await) + } } /// Stock string: `Location streaming disabled.`. @@ -809,10 +845,13 @@ pub(crate) async fn msg_ephemeral_timer_disabled( context: &Context, by_contact: ContactId, ) -> String { - translated(context, StockMessage::MsgEphemeralTimerDisabled) - .await - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouDisabledEphemeralTimer).await + } else { + translated(context, StockMessage::MsgEphemeralTimerDisabledBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } } /// Stock string: `Message deletion timer is set to %1$s s.`. @@ -821,43 +860,60 @@ pub(crate) async fn msg_ephemeral_timer_enabled( timer: impl AsRef, by_contact: ContactId, ) -> String { - translated(context, StockMessage::MsgEphemeralTimerEnabled) - .await - .replace1(timer) - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouEnabledEphemeralTimer) + .await + .replace1(timer) + } else { + translated(context, StockMessage::MsgEphemeralTimerEnabledBy) + .await + .replace1(timer) + .replace2(by_contact.get_stock_name(context).await) + } } /// Stock string: `Message deletion timer is set to 1 minute.`. pub(crate) async fn msg_ephemeral_timer_minute(context: &Context, by_contact: ContactId) -> String { - translated(context, StockMessage::MsgEphemeralTimerMinute) - .await - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouEphemeralTimerMinute).await + } else { + translated(context, StockMessage::MsgEphemeralTimerMinuteBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } } /// Stock string: `Message deletion timer is set to 1 hour.`. pub(crate) async fn msg_ephemeral_timer_hour(context: &Context, by_contact: ContactId) -> String { - translated(context, StockMessage::MsgEphemeralTimerHour) - .await - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouEphemeralTimerHour).await + } else { + translated(context, StockMessage::MsgEphemeralTimerHourBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } } /// Stock string: `Message deletion timer is set to 1 day.`. pub(crate) async fn msg_ephemeral_timer_day(context: &Context, by_contact: ContactId) -> String { - translated(context, StockMessage::MsgEphemeralTimerDay) - .await - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouEphemeralTimerDay).await + } else { + translated(context, StockMessage::MsgEphemeralTimerDayBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } } /// Stock string: `Message deletion timer is set to 1 week.`. pub(crate) async fn msg_ephemeral_timer_week(context: &Context, by_contact: ContactId) -> String { - translated(context, StockMessage::MsgEphemeralTimerWeek) - .await - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouEphemeralTimerWeek).await + } else { + translated(context, StockMessage::MsgEphemeralTimerWeekBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } } /// Stock string: `Video chat invitation`. @@ -899,18 +955,24 @@ pub(crate) async fn error_no_network(context: &Context) -> String { /// Stock string: `Chat protection enabled.`. pub(crate) async fn protection_enabled(context: &Context, by_contact: ContactId) -> String { - translated(context, StockMessage::ProtectionEnabled) - .await - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::YouEnabledProtection).await + } else { + translated(context, StockMessage::ProtectionEnabledBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } } /// Stock string: `Chat protection disabled.`. pub(crate) async fn protection_disabled(context: &Context, by_contact: ContactId) -> String { - translated(context, StockMessage::ProtectionDisabled) - .await - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::YouDisabledProtection).await + } else { + translated(context, StockMessage::ProtectionDisabledBy) + .await + .replace1(by_contact.get_stock_name(context).await) + } } /// Stock string: `Reply`. @@ -934,11 +996,16 @@ pub(crate) async fn msg_ephemeral_timer_minutes( minutes: impl AsRef, by_contact: ContactId, ) -> String { - translated(context, StockMessage::MsgEphemeralTimerMinutes) - .await - .replace1(minutes) - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouEphemeralTimerMinutes) + .await + .replace1(minutes) + } else { + translated(context, StockMessage::MsgEphemeralTimerMinutesBy) + .await + .replace1(minutes) + .replace2(by_contact.get_stock_name(context).await) + } } /// Stock string: `Message deletion timer is set to %1$s hours.`. @@ -947,11 +1014,16 @@ pub(crate) async fn msg_ephemeral_timer_hours( hours: impl AsRef, by_contact: ContactId, ) -> String { - translated(context, StockMessage::MsgEphemeralTimerHours) - .await - .replace1(hours) - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouEphemeralTimerHours) + .await + .replace1(hours) + } else { + translated(context, StockMessage::MsgEphemeralTimerHoursBy) + .await + .replace1(hours) + .replace2(by_contact.get_stock_name(context).await) + } } /// Stock string: `Message deletion timer is set to %1$s days.`. @@ -960,11 +1032,16 @@ pub(crate) async fn msg_ephemeral_timer_days( days: impl AsRef, by_contact: ContactId, ) -> String { - translated(context, StockMessage::MsgEphemeralTimerDays) - .await - .replace1(days) - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouEphemeralTimerDays) + .await + .replace1(days) + } else { + translated(context, StockMessage::MsgEphemeralTimerDaysBy) + .await + .replace1(days) + .replace2(by_contact.get_stock_name(context).await) + } } /// Stock string: `Message deletion timer is set to %1$s weeks.`. @@ -973,11 +1050,16 @@ pub(crate) async fn msg_ephemeral_timer_weeks( weeks: impl AsRef, by_contact: ContactId, ) -> String { - translated(context, StockMessage::MsgEphemeralTimerWeeks) - .await - .replace1(weeks) - .action_by_contact(context, by_contact) - .await + if by_contact == ContactId::SELF { + translated(context, StockMessage::MsgYouEphemeralTimerWeeks) + .await + .replace1(weeks) + } else { + translated(context, StockMessage::MsgEphemeralTimerWeeksBy) + .await + .replace1(weeks) + .replace2(by_contact.get_stock_name(context).await) + } } /// Stock string: `Forwarded`. @@ -1256,12 +1338,6 @@ mod tests { // We have no string using %1$d to test... } - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] - async fn test_stock_string_repl_str2() { - let t = TestContext::new().await; - assert_eq!(msg_action_by_user(&t, "foo", "bar").await, "foo by bar."); - } - #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_stock_system_msg_simple() { let t = TestContext::new().await; @@ -1276,7 +1352,7 @@ mod tests { let t = TestContext::new().await; assert_eq!( msg_add_member(&t, "alice@example.org", ContactId::SELF).await, - "Member alice@example.org added by me." + "You added member alice@example.org." ) } @@ -1288,7 +1364,7 @@ mod tests { .expect("failed to create contact"); assert_eq!( msg_add_member(&t, "alice@example.org", ContactId::SELF).await, - "Member Alice (alice@example.org) added by me." + "You added member Alice (alice@example.org)." ); }