Support local voice note message drafts.

This commit is contained in:
levlam 2024-01-30 17:23:08 +03:00
parent 0ed3ed75fa
commit 9d93e9f090
4 changed files with 121 additions and 11 deletions

View File

@ -1527,7 +1527,7 @@ scopeNotificationSettings mute_for:int32 sound_id:int64 show_preview:Bool use_de
//@description Contains information about a message draft
//@reply_to Information about the message to be replied; must be of the type inputMessageReplyToMessage; may be null if none
//@date Point in time (Unix timestamp) when the draft was created
//@input_message_text Content of the message draft; must be of the type inputMessageText, or inputMessageVideoNote
//@input_message_text Content of the message draft; must be of the type inputMessageText, inputMessageVideoNote, or inputMessageVoiceNote
draftMessage reply_to:InputMessageReplyTo date:int32 input_message_text:InputMessageContent = DraftMessage;
@ -3148,7 +3148,7 @@ messageCopyOptions send_copy:Bool replace_caption:Bool new_caption:formattedText
//@description A text message
//@text Formatted text to be sent; 0-getOption("message_text_length_max") characters. Only Bold, Italic, Underline, Strikethrough, Spoiler, CustomEmoji, BlockQuote, Code, Pre, PreCode, TextUrl and MentionName entities are allowed to be specified manually
//@link_preview_options Options to be used for generation of a link preview; pass null to use default link preview options
//@link_preview_options Options to be used for generation of a link preview; may be null if none; pass null to use default link preview options
//@clear_draft True, if a chat message draft must be deleted
inputMessageText text:formattedText link_preview_options:linkPreviewOptions clear_draft:Bool = InputMessageContent;
@ -3213,18 +3213,18 @@ inputMessageVideo video:InputFile thumbnail:inputThumbnail added_sticker_file_id
//@description A video note message
//@video_note Video note to be sent
//@thumbnail Video thumbnail; pass null to skip thumbnail uploading
//@thumbnail Video thumbnail; may be null if empty; pass null to skip thumbnail uploading
//@duration Duration of the video, in seconds
//@length Video width and height; must be positive and not greater than 640
//@self_destruct_type Video note self-destruct type; pass null if none; private chats only
//@self_destruct_type Video note self-destruct type; may be null if none; pass null if none; private chats only
inputMessageVideoNote video_note:InputFile thumbnail:inputThumbnail duration:int32 length:int32 self_destruct_type:MessageSelfDestructType = InputMessageContent;
//@description A voice note message
//@voice_note Voice note to be sent
//@duration Duration of the voice note, in seconds
//@waveform Waveform representation of the voice note in 5-bit format
//@caption Voice note caption; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters
//@self_destruct_type Voice note self-destruct type; pass null if none; private chats only
//@caption Voice note caption; may be null if empty; pass null to use an empty caption; 0-getOption("message_caption_length_max") characters
//@self_destruct_type Voice note self-destruct type; may be null if none; pass null if none; private chats only
inputMessageVoiceNote voice_note:InputFile duration:int32 waveform:bytes caption:formattedText self_destruct_type:MessageSelfDestructType = InputMessageContent;
//@description A message with a location

View File

@ -205,10 +205,10 @@ class DraftMessageContentVideoNote final : public DraftMessageContent {
template <class ParserT>
void parse(ParserT &parser) {
bool has_path = !path_.empty();
bool has_duration = duration_ != 0;
bool has_length = length_ != 0;
bool has_ttl = ttl_.is_valid();
bool has_path;
bool has_duration;
bool has_length;
bool has_ttl;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_path);
PARSE_FLAG(has_duration);
@ -230,6 +230,82 @@ class DraftMessageContentVideoNote final : public DraftMessageContent {
}
};
class DraftMessageContentVoiceNote final : public DraftMessageContent {
public:
string path_;
int32 duration_ = 0;
string waveform_;
MessageSelfDestructType ttl_;
DraftMessageContentVoiceNote() = default;
DraftMessageContentVoiceNote(string &&path, int32 duration, string &&waveform, MessageSelfDestructType ttl)
: path_(std::move(path)), duration_(duration), waveform_(std::move(waveform)), ttl_(ttl) {
}
DraftMessageContentType get_type() const final {
return DraftMessageContentType::VoiceNote;
}
td_api::object_ptr<td_api::InputMessageContent> get_input_message_content_object() const final {
return td_api::make_object<td_api::inputMessageVoiceNote>(td_api::make_object<td_api::inputFileLocal>(path_),
duration_, waveform_, nullptr,
ttl_.get_message_self_desctruct_type_object());
}
template <class StorerT>
void store(StorerT &storer) const {
bool has_path = !path_.empty();
bool has_duration = duration_ != 0;
bool has_waveform = !waveform_.empty();
bool has_ttl = ttl_.is_valid();
BEGIN_STORE_FLAGS();
STORE_FLAG(has_path);
STORE_FLAG(has_duration);
STORE_FLAG(has_waveform);
STORE_FLAG(has_ttl);
END_STORE_FLAGS();
if (has_path) {
td::store(path_, storer);
}
if (has_duration) {
td::store(duration_, storer);
}
if (has_waveform) {
td::store(waveform_, storer);
}
if (has_ttl) {
td::store(ttl_, storer);
}
}
template <class ParserT>
void parse(ParserT &parser) {
bool has_path;
bool has_duration;
bool has_waveform;
bool has_ttl;
BEGIN_PARSE_FLAGS();
PARSE_FLAG(has_path);
PARSE_FLAG(has_duration);
PARSE_FLAG(has_waveform);
PARSE_FLAG(has_ttl);
END_PARSE_FLAGS();
if (has_path) {
td::parse(path_, parser);
}
if (has_duration) {
td::parse(duration_, parser);
}
if (has_waveform) {
td::parse(waveform_, parser);
}
if (has_ttl) {
td::parse(ttl_, parser);
}
}
};
template <class StorerT>
static void store(const DraftMessageContent *content, StorerT &storer) {
CHECK(content != nullptr);
@ -243,6 +319,11 @@ static void store(const DraftMessageContent *content, StorerT &storer) {
video_note->store(storer);
break;
}
case DraftMessageContentType::VoiceNote: {
const auto *voice_note = static_cast<const DraftMessageContentVoiceNote *>(content);
voice_note->store(storer);
break;
}
default:
UNREACHABLE();
}
@ -266,6 +347,12 @@ void parse_draft_message_content(unique_ptr<DraftMessageContent> &content, LogEv
content = std::move(video_note);
break;
}
case DraftMessageContentType::VoiceNote: {
unique_ptr<DraftMessageContentVoiceNote> voice_note;
parse(voice_note, parser);
content = std::move(voice_note);
break;
}
default:
parser.set_error("Wrong draft content type");
}
@ -369,6 +456,18 @@ Result<unique_ptr<DraftMessage>> DraftMessage::get_draft_message(
video_note->duration_, video_note->length_, ttl);
break;
}
case td_api::inputMessageVoiceNote::ID: {
auto voice_note = td_api::move_object_as<td_api::inputMessageVoiceNote>(input_message_content);
if (voice_note->voice_note_ == nullptr || voice_note->voice_note_->get_id() != td_api::inputFileLocal::ID) {
return Status::Error(400, "Invalid voice message file specified");
}
TRY_RESULT(ttl,
MessageSelfDestructType::get_message_self_destruct_type(std::move(voice_note->self_destruct_type_)));
result->local_content_ = td::make_unique<DraftMessageContentVoiceNote>(
std::move(static_cast<td_api::inputFileLocal *>(voice_note->voice_note_.get())->path_),
voice_note->duration_, std::move(voice_note->waveform_), ttl);
break;
}
default:
return Status::Error(400, "Input message content type must be InputMessageText");
}

View File

@ -23,7 +23,7 @@ namespace td {
class Dependencies;
class Td;
enum class DraftMessageContentType : int32 { VideoNote };
enum class DraftMessageContentType : int32 { VideoNote, VoiceNote };
class DraftMessageContent {
public:

View File

@ -4306,6 +4306,17 @@ class CliClient final : public Actor {
nullptr, 0,
td_api::make_object<td_api::inputMessageVideoNote>(as_input_file(video_path), nullptr, 10, 5,
get_message_self_destruct_type()))));
} else if (op == "scdmvoice") {
ChatId chat_id;
string voice_path;
get_args(args, chat_id, voice_path);
send_request(td_api::make_object<td_api::setChatDraftMessage>(
chat_id, message_thread_id_,
td_api::make_object<td_api::draftMessage>(
nullptr, 0,
td_api::make_object<td_api::inputMessageVoiceNote>(as_input_file(voice_path), 0, "abacaba",
as_caption("voice caption"),
get_message_self_destruct_type()))));
} else if (op == "cadm") {
send_request(td_api::make_object<td_api::clearAllDraftMessages>());
} else if (op == "tchpc") {