Update cache after profile photo deletion instead of dropping it.
GitOrigin-RevId: 0bb120eeececb7706016aec01accd4f6194deef4
This commit is contained in:
parent
1984159963
commit
6b00f2fe6b
@ -9709,9 +9709,12 @@ void ContactsManager::on_update_user_photo(User *u, UserId user_id,
|
|||||||
|
|
||||||
void ContactsManager::do_update_user_photo(User *u, UserId user_id,
|
void ContactsManager::do_update_user_photo(User *u, UserId user_id,
|
||||||
tl_object_ptr<telegram_api::UserProfilePhoto> &&photo, const char *source) {
|
tl_object_ptr<telegram_api::UserProfilePhoto> &&photo, const char *source) {
|
||||||
u->is_photo_inited = true;
|
do_update_user_photo(u, user_id,
|
||||||
ProfilePhoto new_photo = get_profile_photo(td_->file_manager_.get(), user_id, u->access_hash, std::move(photo));
|
get_profile_photo(td_->file_manager_.get(), user_id, u->access_hash, std::move(photo)), source);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactsManager::do_update_user_photo(User *u, UserId user_id, ProfilePhoto new_photo, const char *source) {
|
||||||
|
u->is_photo_inited = true;
|
||||||
if (new_photo != u->photo) {
|
if (new_photo != u->photo) {
|
||||||
LOG_IF(ERROR, u->access_hash == -1 && new_photo.small_file_id.is_valid())
|
LOG_IF(ERROR, u->access_hash == -1 && new_photo.small_file_id.is_valid())
|
||||||
<< "Update profile photo of " << user_id << " without access hash from " << source;
|
<< "Update profile photo of " << user_id << " without access hash from " << source;
|
||||||
@ -10008,15 +10011,84 @@ void ContactsManager::on_change_profile_photo(tl_object_ptr<telegram_api::photos
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ContactsManager::on_delete_profile_photo(int64 profile_photo_id, Promise<Unit> promise) {
|
void ContactsManager::on_delete_profile_photo(int64 profile_photo_id, Promise<Unit> promise) {
|
||||||
UserId my_id = get_my_id();
|
UserId my_user_id = get_my_id();
|
||||||
|
|
||||||
drop_user_photos(my_id, false, true, "on_delete_profile_photo");
|
bool need_reget_user = delete_profile_photo_from_cache(my_user_id, profile_photo_id);
|
||||||
|
if (need_reget_user && !G()->close_flag()) {
|
||||||
if (G()->close_flag()) {
|
return reload_user(my_user_id, std::move(promise));
|
||||||
return promise.set_value(Unit());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reload_user(my_id, std::move(promise));
|
promise.set_value(Unit());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ContactsManager::delete_profile_photo_from_cache(UserId user_id, int64 profile_photo_id) {
|
||||||
|
CHECK(profile_photo_id != 0);
|
||||||
|
|
||||||
|
// we have subsequence of user photos in user_photos_
|
||||||
|
// UserProfilePhoto in User and Photo in UserFull
|
||||||
|
|
||||||
|
User *u = get_user_force(user_id);
|
||||||
|
bool is_main_photo_deleted = u != nullptr && u->photo.id == profile_photo_id;
|
||||||
|
|
||||||
|
// update photo list
|
||||||
|
auto it = user_photos_.find(user_id);
|
||||||
|
if (it != user_photos_.end() && it->second.count > 0) {
|
||||||
|
auto user_photos = &it->second;
|
||||||
|
auto old_size = user_photos->photos.size();
|
||||||
|
if (td::remove_if(user_photos->photos,
|
||||||
|
[profile_photo_id](const auto &photo) { return photo.id.get() == profile_photo_id; })) {
|
||||||
|
auto removed_photos = old_size - user_photos->photos.size();
|
||||||
|
CHECK(removed_photos > 0);
|
||||||
|
LOG_IF(ERROR, removed_photos != 1) << "Had " << removed_photos << " photos with ID " << profile_photo_id;
|
||||||
|
user_photos->count -= narrow_cast<int32>(removed_photos);
|
||||||
|
// offset was not changed
|
||||||
|
CHECK(user_photos->count >= 0);
|
||||||
|
} else {
|
||||||
|
// failed to find photo to remove from cache
|
||||||
|
// don't know how to adjust user_photos->offset, so drop photos cache
|
||||||
|
LOG(INFO) << "Drop photos of " << user_id;
|
||||||
|
user_photos->photos.clear();
|
||||||
|
user_photos->count = -1;
|
||||||
|
user_photos->offset = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update Photo in UserFull
|
||||||
|
auto user_full = get_user_full_force(user_id);
|
||||||
|
if (user_full != nullptr && !user_full->photo.is_empty() &&
|
||||||
|
(is_main_photo_deleted || user_full->photo.id.get() == profile_photo_id)) {
|
||||||
|
if (it != user_photos_.end() && it->second.count != -1 && it->second.offset == 0 && !it->second.photos.empty()) {
|
||||||
|
// found exact new photo
|
||||||
|
if (it->second.photos[0] != user_full->photo) {
|
||||||
|
user_full->photo = it->second.photos[0];
|
||||||
|
user_full->is_changed = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// repair UserFull photo
|
||||||
|
user_full->expires_at = 0.0;
|
||||||
|
user_full->photo = Photo();
|
||||||
|
user_full->is_changed = true;
|
||||||
|
|
||||||
|
get_user_full(user_id, true, Auto());
|
||||||
|
update_user_full(user_full, user_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update Photo in User
|
||||||
|
if (is_main_photo_deleted) {
|
||||||
|
// if main photo is deleted
|
||||||
|
if (it != user_photos_.end() && it->second.count != -1 && it->second.offset == 0 && !it->second.photos.empty()) {
|
||||||
|
// found exact new photo
|
||||||
|
do_update_user_photo(u, user_id, as_profile_photo(it->second.photos[0]), "delete_profile_photo_from_cache");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_update_user_photo(u, user_id, ProfilePhoto(), "delete_profile_photo_from_cache 2");
|
||||||
|
|
||||||
|
return it == user_photos_.end() || it->second.count != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsManager::drop_user_photos(UserId user_id, bool is_empty, bool drop_user_full_photo, const char *source) {
|
void ContactsManager::drop_user_photos(UserId user_id, bool is_empty, bool drop_user_full_photo, const char *source) {
|
||||||
|
@ -1123,6 +1123,7 @@ class ContactsManager : public Actor {
|
|||||||
|
|
||||||
void do_update_user_photo(User *u, UserId user_id, tl_object_ptr<telegram_api::UserProfilePhoto> &&photo,
|
void do_update_user_photo(User *u, UserId user_id, tl_object_ptr<telegram_api::UserProfilePhoto> &&photo,
|
||||||
const char *source);
|
const char *source);
|
||||||
|
void do_update_user_photo(User *u, UserId user_id, ProfilePhoto new_photo, const char *source);
|
||||||
|
|
||||||
void upload_profile_photo(FileId file_id, bool is_animation, double main_frame_timestamp, Promise<Unit> &&promise,
|
void upload_profile_photo(FileId file_id, bool is_animation, double main_frame_timestamp, Promise<Unit> &&promise,
|
||||||
vector<int> bad_parts = {});
|
vector<int> bad_parts = {});
|
||||||
@ -1136,6 +1137,8 @@ class ContactsManager : public Actor {
|
|||||||
void on_update_user_full_common_chat_count(UserFull *user_full, UserId user_id, int32 common_chat_count);
|
void on_update_user_full_common_chat_count(UserFull *user_full, UserId user_id, int32 common_chat_count);
|
||||||
void on_update_user_full_need_phone_number_privacy_exception(UserFull *user_full, UserId user_id,
|
void on_update_user_full_need_phone_number_privacy_exception(UserFull *user_full, UserId user_id,
|
||||||
bool need_phone_number_privacy_exception);
|
bool need_phone_number_privacy_exception);
|
||||||
|
|
||||||
|
bool delete_profile_photo_from_cache(UserId user_id, int64 profile_photo_id);
|
||||||
void drop_user_photos(UserId user_id, bool is_empty, bool drop_user_full_photo, const char *source);
|
void drop_user_photos(UserId user_id, bool is_empty, bool drop_user_full_photo, const char *source);
|
||||||
void drop_user_full(UserId user_id);
|
void drop_user_full(UserId user_id);
|
||||||
|
|
||||||
|
@ -290,6 +290,13 @@ DialogPhoto as_dialog_photo(const Photo &photo) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProfilePhoto as_profile_photo(const Photo &photo) {
|
||||||
|
ProfilePhoto result;
|
||||||
|
static_cast<DialogPhoto &>(result) = as_dialog_photo(photo);
|
||||||
|
result.id = photo.id.get();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool operator==(const DialogPhoto &lhs, const DialogPhoto &rhs) {
|
bool operator==(const DialogPhoto &lhs, const DialogPhoto &rhs) {
|
||||||
return lhs.small_file_id == rhs.small_file_id && lhs.big_file_id == rhs.big_file_id &&
|
return lhs.small_file_id == rhs.small_file_id && lhs.big_file_id == rhs.big_file_id &&
|
||||||
lhs.has_animation == rhs.has_animation;
|
lhs.has_animation == rhs.has_animation;
|
||||||
|
@ -96,6 +96,8 @@ tl_object_ptr<td_api::chatPhotoInfo> get_chat_photo_info_object(FileManager *fil
|
|||||||
|
|
||||||
DialogPhoto as_dialog_photo(const Photo &photo);
|
DialogPhoto as_dialog_photo(const Photo &photo);
|
||||||
|
|
||||||
|
ProfilePhoto as_profile_photo(const Photo &photo);
|
||||||
|
|
||||||
vector<FileId> dialog_photo_get_file_ids(const DialogPhoto &dialog_photo);
|
vector<FileId> dialog_photo_get_file_ids(const DialogPhoto &dialog_photo);
|
||||||
|
|
||||||
bool operator==(const DialogPhoto &lhs, const DialogPhoto &rhs);
|
bool operator==(const DialogPhoto &lhs, const DialogPhoto &rhs);
|
||||||
|
@ -85,13 +85,13 @@ auto transform(V &&v, const Func &f) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class V, class Func>
|
template <class V, class Func>
|
||||||
void remove_if(V &v, const Func &f) {
|
bool remove_if(V &v, const Func &f) {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (i != v.size() && !f(v[i])) {
|
while (i != v.size() && !f(v[i])) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (i == v.size()) {
|
if (i == v.size()) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t j = i;
|
size_t j = i;
|
||||||
@ -101,6 +101,7 @@ void remove_if(V &v, const Func &f) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
v.erase(v.begin() + j, v.end());
|
v.erase(v.begin() + j, v.end());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class V, class T>
|
template <class V, class T>
|
||||||
|
Loading…
Reference in New Issue
Block a user