Add separate class for StoryContent.
This commit is contained in:
parent
0fb5916ea2
commit
17fc0c3a88
@ -468,6 +468,8 @@ set(TDLIB_SOURCE
|
||||
td/telegram/StickersManager.cpp
|
||||
td/telegram/StickerType.cpp
|
||||
td/telegram/StorageManager.cpp
|
||||
td/telegram/StoryContent.cpp
|
||||
td/telegram/StoryContentType.cpp
|
||||
td/telegram/StoryManager.cpp
|
||||
td/telegram/SuggestedAction.cpp
|
||||
td/telegram/Support.cpp
|
||||
@ -758,6 +760,8 @@ set(TDLIB_SOURCE
|
||||
td/telegram/StickersManager.h
|
||||
td/telegram/StickerType.h
|
||||
td/telegram/StorageManager.h
|
||||
td/telegram/StoryContent.h
|
||||
td/telegram/StoryContentType.h
|
||||
td/telegram/StoryId.h
|
||||
td/telegram/StoryManager.h
|
||||
td/telegram/SuggestedAction.h
|
||||
|
167
td/telegram/StoryContent.cpp
Normal file
167
td/telegram/StoryContent.cpp
Normal file
@ -0,0 +1,167 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#include "td/telegram/StoryContent.h"
|
||||
|
||||
#include "td/telegram/DocumentsManager.h"
|
||||
#include "td/telegram/files/FileId.h"
|
||||
#include "td/telegram/Photo.h"
|
||||
#include "td/telegram/Td.h"
|
||||
#include "td/telegram/VideosManager.h"
|
||||
|
||||
#include "td/utils/common.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
class StoryContentPhoto final : public StoryContent {
|
||||
public:
|
||||
Photo photo_;
|
||||
|
||||
StoryContentPhoto() = default;
|
||||
explicit StoryContentPhoto(Photo &&photo) : photo_(std::move(photo)) {
|
||||
}
|
||||
|
||||
StoryContentType get_type() const final {
|
||||
return StoryContentType::Photo;
|
||||
}
|
||||
};
|
||||
|
||||
class StoryContentVideo final : public StoryContent {
|
||||
public:
|
||||
FileId file_id_;
|
||||
FileId alt_file_id_;
|
||||
|
||||
StoryContentVideo() = default;
|
||||
StoryContentVideo(FileId file_id, FileId alt_file_id) : file_id_(file_id), alt_file_id_(alt_file_id) {
|
||||
}
|
||||
|
||||
StoryContentType get_type() const final {
|
||||
return StoryContentType::Video;
|
||||
}
|
||||
};
|
||||
|
||||
class StoryContentUnsupported final : public StoryContent {
|
||||
public:
|
||||
static constexpr int32 CURRENT_VERSION = 1;
|
||||
int32 version_ = CURRENT_VERSION;
|
||||
|
||||
StoryContentUnsupported() = default;
|
||||
explicit StoryContentUnsupported(int32 version) : version_(version) {
|
||||
}
|
||||
|
||||
StoryContentType get_type() const final {
|
||||
return StoryContentType::Unsupported;
|
||||
}
|
||||
};
|
||||
|
||||
unique_ptr<StoryContent> get_story_content(Td *td, tl_object_ptr<telegram_api::MessageMedia> &&media_ptr,
|
||||
DialogId owner_dialog_id) {
|
||||
CHECK(media_ptr != nullptr);
|
||||
int32 constructor_id = media_ptr->get_id();
|
||||
switch (constructor_id) {
|
||||
case telegram_api::messageMediaPhoto::ID: {
|
||||
auto media = move_tl_object_as<telegram_api::messageMediaPhoto>(media_ptr);
|
||||
if (media->photo_ == nullptr || (media->flags_ & telegram_api::messageMediaPhoto::TTL_SECONDS_MASK) != 0 ||
|
||||
media->spoiler_) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto photo = get_photo(td, std::move(media->photo_), owner_dialog_id);
|
||||
if (photo.is_empty()) {
|
||||
break;
|
||||
}
|
||||
return make_unique<StoryContentPhoto>(std::move(photo));
|
||||
}
|
||||
case telegram_api::messageMediaDocument::ID: {
|
||||
auto media = move_tl_object_as<telegram_api::messageMediaDocument>(media_ptr);
|
||||
if (media->document_ == nullptr || (media->flags_ & telegram_api::messageMediaDocument::TTL_SECONDS_MASK) != 0 ||
|
||||
media->spoiler_) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto document_ptr = std::move(media->document_);
|
||||
int32 document_id = document_ptr->get_id();
|
||||
if (document_id == telegram_api::documentEmpty::ID) {
|
||||
break;
|
||||
}
|
||||
CHECK(document_id == telegram_api::document::ID);
|
||||
auto parsed_document = td->documents_manager_->on_get_document(
|
||||
move_tl_object_as<telegram_api::document>(document_ptr), owner_dialog_id, nullptr);
|
||||
if (parsed_document.empty() || parsed_document.type != Document::Type::Video) {
|
||||
break;
|
||||
}
|
||||
CHECK(parsed_document.file_id.is_valid());
|
||||
|
||||
FileId alt_file_id;
|
||||
if (media->alt_document_ != nullptr) {
|
||||
auto alt_document_ptr = std::move(media->alt_document_);
|
||||
int32 alt_document_id = alt_document_ptr->get_id();
|
||||
if (alt_document_id == telegram_api::documentEmpty::ID) {
|
||||
LOG(ERROR) << "Receive alternative " << to_string(alt_document_ptr);
|
||||
} else {
|
||||
CHECK(alt_document_id == telegram_api::document::ID);
|
||||
auto parsed_alt_document = td->documents_manager_->on_get_document(
|
||||
move_tl_object_as<telegram_api::document>(alt_document_ptr), owner_dialog_id, nullptr);
|
||||
if (parsed_alt_document.empty() || parsed_alt_document.type != Document::Type::Video) {
|
||||
LOG(ERROR) << "Receive alternative " << to_string(alt_document_ptr);
|
||||
} else {
|
||||
alt_file_id = parsed_alt_document.file_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return make_unique<StoryContentVideo>(parsed_document.file_id, alt_file_id);
|
||||
}
|
||||
case telegram_api::messageMediaUnsupported::ID:
|
||||
return make_unique<StoryContentUnsupported>();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
LOG(ERROR) << "Receive a story with content " << to_string(media_ptr);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void merge_story_contents(Td *td, const StoryContent *old_content, StoryContent *new_content, DialogId dialog_id,
|
||||
bool need_merge_files, bool &is_content_changed, bool &need_update) {
|
||||
StoryContentType content_type = new_content->get_type();
|
||||
CHECK(old_content->get_type() == content_type);
|
||||
|
||||
switch (content_type) {
|
||||
case StoryContentType::Photo: {
|
||||
const auto *old_ = static_cast<const StoryContentPhoto *>(old_content);
|
||||
auto *new_ = static_cast<StoryContentPhoto *>(new_content);
|
||||
merge_photos(td, &old_->photo_, &new_->photo_, dialog_id, need_merge_files, is_content_changed, need_update);
|
||||
break;
|
||||
}
|
||||
case StoryContentType::Video: {
|
||||
const auto *old_ = static_cast<const StoryContentVideo *>(old_content);
|
||||
const auto *new_ = static_cast<const StoryContentVideo *>(new_content);
|
||||
if (old_->file_id_ != new_->file_id_) {
|
||||
if (need_merge_files) {
|
||||
td->videos_manager_->merge_videos(new_->file_id_, old_->file_id_);
|
||||
}
|
||||
need_update = true;
|
||||
}
|
||||
if (old_->alt_file_id_ != new_->alt_file_id_) {
|
||||
need_update = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case StoryContentType::Unsupported: {
|
||||
const auto *old_ = static_cast<const StoryContentUnsupported *>(old_content);
|
||||
const auto *new_ = static_cast<const StoryContentUnsupported *>(new_content);
|
||||
if (old_->version_ != new_->version_) {
|
||||
is_content_changed = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace td
|
35
td/telegram/StoryContent.h
Normal file
35
td/telegram/StoryContent.h
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/telegram/DialogId.h"
|
||||
#include "td/telegram/StoryContentType.h"
|
||||
#include "td/telegram/telegram_api.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
class Td;
|
||||
|
||||
class StoryContent {
|
||||
public:
|
||||
StoryContent() = default;
|
||||
StoryContent(const StoryContent &) = default;
|
||||
StoryContent &operator=(const StoryContent &) = default;
|
||||
StoryContent(StoryContent &&) = default;
|
||||
StoryContent &operator=(StoryContent &&) = default;
|
||||
|
||||
virtual StoryContentType get_type() const = 0;
|
||||
virtual ~StoryContent() = default;
|
||||
};
|
||||
|
||||
unique_ptr<StoryContent> get_story_content(Td *td, telegram_api::object_ptr<telegram_api::MessageMedia> &&media_ptr,
|
||||
DialogId owner_dialog_id);
|
||||
|
||||
void merge_story_contents(Td *td, const StoryContent *old_content, StoryContent *new_content, DialogId dialog_id,
|
||||
bool need_merge_files, bool &is_content_changed, bool &need_update);
|
||||
|
||||
} // namespace td
|
25
td/telegram/StoryContentType.cpp
Normal file
25
td/telegram/StoryContentType.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#include "td/telegram/StoryContentType.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
StringBuilder &operator<<(StringBuilder &string_builder, StoryContentType content_type) {
|
||||
switch (content_type) {
|
||||
case StoryContentType::Photo:
|
||||
return string_builder << "Photo";
|
||||
case StoryContentType::Video:
|
||||
return string_builder << "Video";
|
||||
case StoryContentType::Unsupported:
|
||||
return string_builder << "Unsupported";
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return string_builder;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace td
|
26
td/telegram/StoryContentType.h
Normal file
26
td/telegram/StoryContentType.h
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "td/utils/common.h"
|
||||
#include "td/utils/HashTableUtils.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
||||
namespace td {
|
||||
|
||||
// increase StoryContentUnsupported::CURRENT_VERSION each time a new Story content type is added
|
||||
enum class StoryContentType : int32 { Photo, Video, Unsupported };
|
||||
|
||||
StringBuilder &operator<<(StringBuilder &string_builder, StoryContentType content_type);
|
||||
|
||||
struct StoryContentTypeHash {
|
||||
uint32 operator()(StoryContentType content_type) const {
|
||||
return Hash<int32>()(static_cast<int32>(content_type));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace td
|
@ -8,9 +8,9 @@
|
||||
|
||||
#include "td/telegram/AuthManager.h"
|
||||
#include "td/telegram/ContactsManager.h"
|
||||
#include "td/telegram/MessageContent.h"
|
||||
#include "td/telegram/MessageContentType.h"
|
||||
#include "td/telegram/MessageEntity.h"
|
||||
#include "td/telegram/StoryContent.h"
|
||||
#include "td/telegram/StoryContentType.h"
|
||||
#include "td/telegram/Td.h"
|
||||
|
||||
namespace td {
|
||||
@ -18,6 +18,8 @@ namespace td {
|
||||
StoryManager::StoryManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) {
|
||||
}
|
||||
|
||||
StoryManager::~StoryManager() = default;
|
||||
|
||||
void StoryManager::tear_down() {
|
||||
parent_.reset();
|
||||
}
|
||||
@ -53,18 +55,14 @@ StoryId StoryManager::on_get_story(DialogId owner_dialog_id,
|
||||
CHECK(story != nullptr);
|
||||
|
||||
bool is_bot = td_->auth_manager_->is_bot();
|
||||
auto message_text =
|
||||
auto caption =
|
||||
get_message_text(td_->contacts_manager_.get(), std::move(story_item->caption_), std::move(story_item->entities_),
|
||||
true, is_bot, story_item->date_, false, "on_get_story");
|
||||
int32 ttl = 0;
|
||||
auto content = get_message_content(td_, std::move(message_text), std::move(story_item->media_), owner_dialog_id,
|
||||
false, UserId(), &ttl, nullptr, "on_get_story");
|
||||
auto content_type = content->get_type();
|
||||
if (content_type != MessageContentType::Photo && content_type != MessageContentType::Video &&
|
||||
content_type != MessageContentType::Unsupported) {
|
||||
LOG(ERROR) << "Receive " << story_id << " of type " << content_type;
|
||||
auto content = get_story_content(td_, std::move(story_item->media_), owner_dialog_id);
|
||||
if (content == nullptr) {
|
||||
return StoryId();
|
||||
}
|
||||
auto content_type = content->get_type();
|
||||
|
||||
auto privacy_rules = UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(story_item->privacy_));
|
||||
|
||||
@ -85,7 +83,8 @@ StoryId StoryManager::on_get_story(DialogId owner_dialog_id,
|
||||
if (story->is_pinned_ != story_item->pinned_ || story->is_public_ != story_item->public_ ||
|
||||
story->is_for_close_friends_ != story_item->close_friends_ || story->date_ != story_item->date_ ||
|
||||
story->expire_date_ != story_item->expire_date_ || !(story->privacy_rules_ == privacy_rules) ||
|
||||
story->recent_viewer_user_ids_ != recent_viewer_user_ids || story->view_count_ != view_count) {
|
||||
story->recent_viewer_user_ids_ != recent_viewer_user_ids || story->view_count_ != view_count ||
|
||||
story->caption_ != caption) {
|
||||
story->is_pinned_ = story_item->pinned_;
|
||||
story->is_public_ = story_item->public_;
|
||||
story->is_for_close_friends_ = story_item->close_friends_;
|
||||
@ -94,14 +93,15 @@ StoryId StoryManager::on_get_story(DialogId owner_dialog_id,
|
||||
story->privacy_rules_ = std::move(privacy_rules);
|
||||
story->recent_viewer_user_ids_ = std::move(recent_viewer_user_ids);
|
||||
story->view_count_ = view_count;
|
||||
story->caption_ = std::move(caption);
|
||||
is_changed = true;
|
||||
}
|
||||
if (story->content_ == nullptr || story->content_->get_type() != content_type) {
|
||||
story->content_ = std::move(content);
|
||||
is_changed = true;
|
||||
} else {
|
||||
merge_message_contents(td_, story->content_.get(), content.get(), false, owner_dialog_id, false,
|
||||
need_save_to_database, is_changed);
|
||||
merge_story_contents(td_, story->content_.get(), content.get(), owner_dialog_id, false, need_save_to_database,
|
||||
is_changed);
|
||||
}
|
||||
|
||||
if (is_changed || need_save_to_database) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "td/telegram/DialogId.h"
|
||||
#include "td/telegram/MessageEntity.h"
|
||||
#include "td/telegram/StoryId.h"
|
||||
#include "td/telegram/UserId.h"
|
||||
#include "td/telegram/UserPrivacySettingRule.h"
|
||||
@ -18,12 +19,17 @@
|
||||
|
||||
namespace td {
|
||||
|
||||
class MessageContent;
|
||||
class StoryContent;
|
||||
class Td;
|
||||
|
||||
class StoryManager final : public Actor {
|
||||
public:
|
||||
StoryManager(Td *td, ActorShared<> parent);
|
||||
StoryManager(const StoryManager &) = delete;
|
||||
StoryManager &operator=(const StoryManager &) = delete;
|
||||
StoryManager(StoryManager &&) = delete;
|
||||
StoryManager &operator=(StoryManager &&) = delete;
|
||||
~StoryManager() final;
|
||||
|
||||
StoryId on_get_story(DialogId owner_dialog_id, telegram_api::object_ptr<telegram_api::storyItem> &&story_item);
|
||||
|
||||
@ -37,7 +43,8 @@ class StoryManager final : public Actor {
|
||||
vector<UserId> recent_viewer_user_ids_;
|
||||
int32 view_count_ = 0;
|
||||
UserPrivacySettingRules privacy_rules_;
|
||||
unique_ptr<MessageContent> content_;
|
||||
unique_ptr<StoryContent> content_;
|
||||
FormattedText caption_;
|
||||
};
|
||||
|
||||
void tear_down() final;
|
||||
|
Loading…
Reference in New Issue
Block a user