Allow archive with stories only.
This commit is contained in:
parent
35214d108e
commit
4402cce928
|
@ -3822,8 +3822,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_userpic_builder_emoji_subtitle" = "Choose sticker or emoji";
|
"lng_userpic_builder_emoji_subtitle" = "Choose sticker or emoji";
|
||||||
|
|
||||||
"lng_stories_my_name" = "My Story";
|
"lng_stories_my_name" = "My Story";
|
||||||
"lng_stories_archive" = "Archive";
|
"lng_stories_archive" = "Hide Stories";
|
||||||
"lng_stories_unarchive" = "Unarchive";
|
"lng_stories_unarchive" = "Unhide Stories";
|
||||||
"lng_stories_row_count#one" = "{count} Story";
|
"lng_stories_row_count#one" = "{count} Story";
|
||||||
"lng_stories_row_count#other" = "{count} Stories";
|
"lng_stories_row_count#other" = "{count} Stories";
|
||||||
"lng_stories_views#one" = "{count} view";
|
"lng_stories_views#one" = "{count} view";
|
||||||
|
@ -3838,8 +3838,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_stories_archive_title" = "Stories Archive";
|
"lng_stories_archive_title" = "Stories Archive";
|
||||||
"lng_stories_archive_about" = "Only you can see archived stories unless you choose to save them to your profile.";
|
"lng_stories_archive_about" = "Only you can see archived stories unless you choose to save them to your profile.";
|
||||||
"lng_stories_reply_sent" = "Message Sent";
|
"lng_stories_reply_sent" = "Message Sent";
|
||||||
"lng_stories_hidden_to_contacts" = "Stories of {user} were moved to **Archive**.";
|
"lng_stories_hidden_to_contacts" = "Stories from {user} will now be shown in **Archived Chats**.";
|
||||||
"lng_stories_shown_in_chats" = "Stories of {user} were moved to the **Chats List**.";
|
"lng_stories_shown_in_chats" = "Stories from {user} will now be shown in the **Chats List**.";
|
||||||
"lng_stories_delete_one_sure" = "Are you sure you want to delete this story?";
|
"lng_stories_delete_one_sure" = "Are you sure you want to delete this story?";
|
||||||
"lng_stories_delete_sure#one" = "Are you sure you want to delete {count} story?";
|
"lng_stories_delete_sure#one" = "Are you sure you want to delete {count} story?";
|
||||||
"lng_stories_delete_sure#other" = "Are you sure you want to delete {count} stories?";
|
"lng_stories_delete_sure#other" = "Are you sure you want to delete {count} stories?";
|
||||||
|
|
|
@ -39,6 +39,21 @@ constexpr auto kShowChatNamesCount = 8;
|
||||||
not_null<Folder*> folder) {
|
not_null<Folder*> folder) {
|
||||||
const auto &list = folder->lastHistories();
|
const auto &list = folder->lastHistories();
|
||||||
if (list.empty()) {
|
if (list.empty()) {
|
||||||
|
if (const auto storiesUnread = folder->storiesUnreadCount()) {
|
||||||
|
return {
|
||||||
|
tr::lng_contacts_stories_status_new(
|
||||||
|
tr::now,
|
||||||
|
lt_count,
|
||||||
|
storiesUnread),
|
||||||
|
};
|
||||||
|
} else if (const auto storiesCount = folder->storiesCount()) {
|
||||||
|
return {
|
||||||
|
tr::lng_contacts_stories_status(
|
||||||
|
tr::now,
|
||||||
|
lt_count,
|
||||||
|
storiesCount),
|
||||||
|
};
|
||||||
|
}
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,6 +316,33 @@ void Folder::validateListEntryCache() {
|
||||||
Ui::ItemTextDefaultOptions());
|
Ui::ItemTextDefaultOptions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Folder::updateStoriesCount(int count, int unread) {
|
||||||
|
if (_storiesCount == count && _storiesUnreadCount == unread) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto limit = (1 << 16) - 1;
|
||||||
|
const auto was = (_storiesCount > 0);
|
||||||
|
_storiesCount = std::min(count, limit);
|
||||||
|
_storiesUnreadCount = std::min(unread, limit);
|
||||||
|
const auto now = (_storiesCount > 0);
|
||||||
|
if (was == now) {
|
||||||
|
updateChatListEntryPostponed();
|
||||||
|
} else if (now) {
|
||||||
|
updateChatListSortPosition();
|
||||||
|
} else {
|
||||||
|
updateChatListExistence();
|
||||||
|
}
|
||||||
|
++_chatListViewVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Folder::storiesCount() const {
|
||||||
|
return _storiesCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Folder::storiesUnreadCount() const {
|
||||||
|
return _storiesUnreadCount;
|
||||||
|
}
|
||||||
|
|
||||||
void Folder::requestChatListMessage() {
|
void Folder::requestChatListMessage() {
|
||||||
if (!chatListMessageKnown()) {
|
if (!chatListMessageKnown()) {
|
||||||
owner().histories().requestDialogEntry(this);
|
owner().histories().requestDialogEntry(this);
|
||||||
|
@ -339,7 +381,7 @@ int Folder::fixedOnTopIndex() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Folder::shouldBeInChatList() const {
|
bool Folder::shouldBeInChatList() const {
|
||||||
return !_chatsList.empty();
|
return !_chatsList.empty() || (_storiesCount > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dialogs::UnreadState Folder::chatListUnreadState() const {
|
Dialogs::UnreadState Folder::chatListUnreadState() const {
|
||||||
|
|
|
@ -75,6 +75,10 @@ public:
|
||||||
return _listEntryCache;
|
return _listEntryCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateStoriesCount(int count, int unread);
|
||||||
|
[[nodiscard]] int storiesCount() const;
|
||||||
|
[[nodiscard]] int storiesUnreadCount() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void indexNameParts();
|
void indexNameParts();
|
||||||
|
|
||||||
|
@ -104,6 +108,9 @@ private:
|
||||||
int _chatListViewVersion = 0;
|
int _chatListViewVersion = 0;
|
||||||
//rpl::variable<MessagePosition> _unreadPosition;
|
//rpl::variable<MessagePosition> _unreadPosition;
|
||||||
|
|
||||||
|
uint16_t _storiesCount = 0;
|
||||||
|
uint16_t _storiesUnreadCount = 0;
|
||||||
|
|
||||||
rpl::lifetime _lifetime;
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_folder.h"
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
@ -562,6 +563,31 @@ void Stories::preloadListsMore() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Stories::notifySourcesChanged(StorySourcesList list) {
|
||||||
|
_sourcesChanged[static_cast<int>(list)].fire({});
|
||||||
|
if (list == StorySourcesList::Hidden) {
|
||||||
|
pushHiddenCountsToFolder();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stories::pushHiddenCountsToFolder() {
|
||||||
|
const auto &list = sources(StorySourcesList::Hidden);
|
||||||
|
if (list.empty()) {
|
||||||
|
if (_folderForHidden) {
|
||||||
|
_folderForHidden->updateStoriesCount(0, 0);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!_folderForHidden) {
|
||||||
|
_folderForHidden = _owner->folder(Folder::kId);
|
||||||
|
}
|
||||||
|
const auto count = int(list.size());
|
||||||
|
const auto unread = ranges::count_if(
|
||||||
|
list,
|
||||||
|
[](const StoriesSourceInfo &info) { return info.unreadCount > 0; });
|
||||||
|
_folderForHidden->updateStoriesCount(count, unread);
|
||||||
|
}
|
||||||
|
|
||||||
void Stories::sendResolveRequests() {
|
void Stories::sendResolveRequests() {
|
||||||
if (!_resolveSent.empty()) {
|
if (!_resolveSent.empty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -722,7 +748,7 @@ void Stories::applyRemovedFromActive(FullStoryId id) {
|
||||||
&StoriesSourceInfo::id);
|
&StoriesSourceInfo::id);
|
||||||
if (i != end(sources)) {
|
if (i != end(sources)) {
|
||||||
sources.erase(i);
|
sources.erase(i);
|
||||||
_sourcesChanged[index].fire({});
|
notifySourcesChanged(list);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const auto i = _all.find(id.peer);
|
const auto i = _all.find(id.peer);
|
||||||
|
@ -751,7 +777,7 @@ void Stories::applyDeletedFromSources(PeerId id, StorySourcesList list) {
|
||||||
if (i != end(sources)) {
|
if (i != end(sources)) {
|
||||||
sources.erase(i);
|
sources.erase(i);
|
||||||
}
|
}
|
||||||
_sourcesChanged[static_cast<int>(list)].fire({});
|
notifySourcesChanged(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Stories::removeDependencyStory(not_null<Story*> story) {
|
void Stories::removeDependencyStory(not_null<Story*> story) {
|
||||||
|
@ -780,7 +806,7 @@ void Stories::sort(StorySourcesList list) {
|
||||||
return std::make_pair(key, info.id);
|
return std::make_pair(key, info.id);
|
||||||
};
|
};
|
||||||
ranges::sort(sources, ranges::greater(), proj);
|
ranges::sort(sources, ranges::greater(), proj);
|
||||||
_sourcesChanged[index].fire({});
|
notifySourcesChanged(list);
|
||||||
preloadSourcesChanged(list);
|
preloadSourcesChanged(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1044,7 +1070,7 @@ void Stories::toggleHidden(
|
||||||
const auto i = ranges::find(_sources[main], peerId, proj);
|
const auto i = ranges::find(_sources[main], peerId, proj);
|
||||||
if (i != end(_sources[main])) {
|
if (i != end(_sources[main])) {
|
||||||
_sources[main].erase(i);
|
_sources[main].erase(i);
|
||||||
_sourcesChanged[main].fire({});
|
notifySourcesChanged(StorySourcesList::NotHidden);
|
||||||
preloadSourcesChanged(StorySourcesList::NotHidden);
|
preloadSourcesChanged(StorySourcesList::NotHidden);
|
||||||
}
|
}
|
||||||
const auto j = ranges::find(_sources[other], peerId, proj);
|
const auto j = ranges::find(_sources[other], peerId, proj);
|
||||||
|
@ -1058,7 +1084,7 @@ void Stories::toggleHidden(
|
||||||
const auto i = ranges::find(_sources[other], peerId, proj);
|
const auto i = ranges::find(_sources[other], peerId, proj);
|
||||||
if (i != end(_sources[other])) {
|
if (i != end(_sources[other])) {
|
||||||
_sources[other].erase(i);
|
_sources[other].erase(i);
|
||||||
_sourcesChanged[other].fire({});
|
notifySourcesChanged(StorySourcesList::Hidden);
|
||||||
preloadSourcesChanged(StorySourcesList::Hidden);
|
preloadSourcesChanged(StorySourcesList::Hidden);
|
||||||
}
|
}
|
||||||
const auto j = ranges::find(_sources[main], peerId, proj);
|
const auto j = ranges::find(_sources[main], peerId, proj);
|
||||||
|
|
|
@ -24,6 +24,7 @@ enum class ReportReason;
|
||||||
|
|
||||||
namespace Data {
|
namespace Data {
|
||||||
|
|
||||||
|
class Folder;
|
||||||
class Session;
|
class Session;
|
||||||
struct StoryView;
|
struct StoryView;
|
||||||
struct StoryIdDates;
|
struct StoryIdDates;
|
||||||
|
@ -282,6 +283,9 @@ private:
|
||||||
void preloadFinished(FullStoryId id, bool markAsPreloaded = false);
|
void preloadFinished(FullStoryId id, bool markAsPreloaded = false);
|
||||||
void preloadListsMore();
|
void preloadListsMore();
|
||||||
|
|
||||||
|
void notifySourcesChanged(StorySourcesList list);
|
||||||
|
void pushHiddenCountsToFolder();
|
||||||
|
|
||||||
[[nodiscard]] int pollingInterval(
|
[[nodiscard]] int pollingInterval(
|
||||||
const PollingSettings &settings) const;
|
const PollingSettings &settings) const;
|
||||||
void maybeSchedulePolling(
|
void maybeSchedulePolling(
|
||||||
|
@ -319,6 +323,7 @@ private:
|
||||||
rpl::event_stream<> _sourcesChanged[kStorySourcesListCount];
|
rpl::event_stream<> _sourcesChanged[kStorySourcesListCount];
|
||||||
bool _sourcesLoaded[kStorySourcesListCount] = { false };
|
bool _sourcesLoaded[kStorySourcesListCount] = { false };
|
||||||
QString _sourcesStates[kStorySourcesListCount];
|
QString _sourcesStates[kStorySourcesListCount];
|
||||||
|
Folder *_folderForHidden = nullptr;
|
||||||
|
|
||||||
mtpRequestId _loadMoreRequestId[kStorySourcesListCount] = { 0 };
|
mtpRequestId _loadMoreRequestId[kStorySourcesListCount] = { 0 };
|
||||||
|
|
||||||
|
|
|
@ -257,7 +257,7 @@ dialogsFilter: InputField(defaultInputField) {
|
||||||
placeholderFg: placeholderFg;
|
placeholderFg: placeholderFg;
|
||||||
placeholderFgActive: placeholderFgActive;
|
placeholderFgActive: placeholderFgActive;
|
||||||
placeholderFgError: placeholderFgActive;
|
placeholderFgError: placeholderFgActive;
|
||||||
placeholderMargins: margins(2px, 0px, 2px, 0px);
|
placeholderMargins: margins(5px, 0px, 2px, 0px);
|
||||||
placeholderScale: 0.;
|
placeholderScale: 0.;
|
||||||
placeholderShift: -50px;
|
placeholderShift: -50px;
|
||||||
placeholderFont: normalFont;
|
placeholderFont: normalFont;
|
||||||
|
|
|
@ -233,20 +233,11 @@ void BasicRow::paintRipple(
|
||||||
|
|
||||||
void BasicRow::paintUserpic(
|
void BasicRow::paintUserpic(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
not_null<PeerData*> peer,
|
not_null<Entry*> entry,
|
||||||
|
PeerData *peer,
|
||||||
Ui::VideoUserpic *videoUserpic,
|
Ui::VideoUserpic *videoUserpic,
|
||||||
History *historyForCornerBadge,
|
|
||||||
const Ui::PaintContext &context) const {
|
const Ui::PaintContext &context) const {
|
||||||
PaintUserpic(
|
PaintUserpic(p, entry, peer, videoUserpic, _userpic, context);
|
||||||
p,
|
|
||||||
peer,
|
|
||||||
videoUserpic,
|
|
||||||
_userpic,
|
|
||||||
context.st->padding.left(),
|
|
||||||
context.st->padding.top(),
|
|
||||||
context.width,
|
|
||||||
context.st->photoSize,
|
|
||||||
context.paused);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Row::Row(Key key, int index, int top) : _id(key), _top(top), _index(index) {
|
Row::Row(Key key, int index, int top) : _id(key), _top(top), _index(index) {
|
||||||
|
@ -334,7 +325,8 @@ void Row::ensureCornerBadgeUserpic() const {
|
||||||
void Row::PaintCornerBadgeFrame(
|
void Row::PaintCornerBadgeFrame(
|
||||||
not_null<CornerBadgeUserpic*> data,
|
not_null<CornerBadgeUserpic*> data,
|
||||||
int framePadding,
|
int framePadding,
|
||||||
not_null<PeerData*> peer,
|
not_null<Entry*> entry,
|
||||||
|
PeerData *peer,
|
||||||
Ui::VideoUserpic *videoUserpic,
|
Ui::VideoUserpic *videoUserpic,
|
||||||
Ui::PeerUserpicView &view,
|
Ui::PeerUserpicView &view,
|
||||||
const Ui::PaintContext &context) {
|
const Ui::PaintContext &context) {
|
||||||
|
@ -356,16 +348,15 @@ void Row::PaintCornerBadgeFrame(
|
||||||
q.scale(scale, scale);
|
q.scale(scale, scale);
|
||||||
q.translate(-center, -center);
|
q.translate(-center, -center);
|
||||||
}
|
}
|
||||||
|
q.translate(-context.st->padding.left(), -context.st->padding.top());
|
||||||
PaintUserpic(
|
PaintUserpic(
|
||||||
q,
|
q,
|
||||||
|
entry,
|
||||||
peer,
|
peer,
|
||||||
videoUserpic,
|
videoUserpic,
|
||||||
view,
|
view,
|
||||||
0,
|
context);
|
||||||
0,
|
q.translate(context.st->padding.left(), context.st->padding.top());
|
||||||
data->frame.width() / data->frame.devicePixelRatio(),
|
|
||||||
photoSize,
|
|
||||||
context.paused);
|
|
||||||
if (storiesCount) {
|
if (storiesCount) {
|
||||||
q.restore();
|
q.restore();
|
||||||
|
|
||||||
|
@ -401,7 +392,7 @@ void Row::PaintCornerBadgeFrame(
|
||||||
const auto &manager = data->layersManager;
|
const auto &manager = data->layersManager;
|
||||||
if (const auto p = manager.progressForLayer(kBottomLayer); p > 0.) {
|
if (const auto p = manager.progressForLayer(kBottomLayer); p > 0.) {
|
||||||
const auto size = photoSize;
|
const auto size = photoSize;
|
||||||
if (data->cacheTTL.isNull() && peer->messagesTTL()) {
|
if (data->cacheTTL.isNull() && peer && peer->messagesTTL()) {
|
||||||
data->cacheTTL = CornerBadgeTTL(peer, view, size);
|
data->cacheTTL = CornerBadgeTTL(peer, view, size);
|
||||||
}
|
}
|
||||||
q.setOpacity(p);
|
q.setOpacity(p);
|
||||||
|
@ -419,11 +410,12 @@ void Row::PaintCornerBadgeFrame(
|
||||||
}
|
}
|
||||||
q.setCompositionMode(QPainter::CompositionMode_Source);
|
q.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
|
|
||||||
const auto size = peer->isUser()
|
const auto online = peer && peer->isUser();
|
||||||
|
const auto size = online
|
||||||
? st::dialogsOnlineBadgeSize
|
? st::dialogsOnlineBadgeSize
|
||||||
: st::dialogsCallBadgeSize;
|
: st::dialogsCallBadgeSize;
|
||||||
const auto stroke = st::dialogsOnlineBadgeStroke;
|
const auto stroke = st::dialogsOnlineBadgeStroke;
|
||||||
const auto skip = peer->isUser()
|
const auto skip = online
|
||||||
? st::dialogsOnlineBadgeSkip
|
? st::dialogsOnlineBadgeSkip
|
||||||
: st::dialogsCallBadgeSkip;
|
: st::dialogsCallBadgeSkip;
|
||||||
const auto shrink = (size / 2) * (1. - topLayerProgress);
|
const auto shrink = (size / 2) * (1. - topLayerProgress);
|
||||||
|
@ -444,27 +436,27 @@ void Row::PaintCornerBadgeFrame(
|
||||||
|
|
||||||
void Row::paintUserpic(
|
void Row::paintUserpic(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
not_null<PeerData*> peer,
|
not_null<Entry*> entry,
|
||||||
|
PeerData *peer,
|
||||||
Ui::VideoUserpic *videoUserpic,
|
Ui::VideoUserpic *videoUserpic,
|
||||||
History *historyForCornerBadge,
|
|
||||||
const Ui::PaintContext &context) const {
|
const Ui::PaintContext &context) const {
|
||||||
updateCornerBadgeShown(peer);
|
if (peer) {
|
||||||
|
updateCornerBadgeShown(peer);
|
||||||
|
}
|
||||||
|
|
||||||
const auto cornerBadgeShown = !_cornerBadgeUserpic
|
const auto cornerBadgeShown = !_cornerBadgeUserpic
|
||||||
? _cornerBadgeShown
|
? _cornerBadgeShown
|
||||||
: !_cornerBadgeUserpic->layersManager.isDisplayedNone();
|
: !_cornerBadgeUserpic->layersManager.isDisplayedNone();
|
||||||
const auto storiesUser = historyForCornerBadge
|
const auto storiesUser = peer ? peer->asUser() : nullptr;
|
||||||
? historyForCornerBadge->peer->asUser()
|
const auto storiesFolder = peer ? nullptr : _id.folder();
|
||||||
: nullptr;
|
const auto storiesHas = storiesUser
|
||||||
const auto storiesHas = storiesUser && storiesUser->hasActiveStories();
|
? storiesUser->hasActiveStories()
|
||||||
if (!historyForCornerBadge || (!cornerBadgeShown && !storiesHas)) {
|
: storiesFolder
|
||||||
BasicRow::paintUserpic(
|
? storiesFolder->storiesCount()
|
||||||
p,
|
: false;
|
||||||
peer,
|
if (!cornerBadgeShown && !storiesHas) {
|
||||||
videoUserpic,
|
BasicRow::paintUserpic(p, entry, peer, videoUserpic, context);
|
||||||
historyForCornerBadge,
|
if (!peer || !_cornerBadgeShown) {
|
||||||
context);
|
|
||||||
if (!historyForCornerBadge || !_cornerBadgeShown) {
|
|
||||||
_cornerBadgeUserpic = nullptr;
|
_cornerBadgeUserpic = nullptr;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -478,20 +470,24 @@ void Row::paintUserpic(
|
||||||
const auto frameSide = (2 * framePadding + context.st->photoSize)
|
const auto frameSide = (2 * framePadding + context.st->photoSize)
|
||||||
* ratio;
|
* ratio;
|
||||||
const auto frameSize = QSize(frameSide, frameSide);
|
const auto frameSize = QSize(frameSide, frameSide);
|
||||||
const auto storiesSource = storiesHas
|
const auto storiesSource = (storiesHas && storiesUser)
|
||||||
? storiesUser->owner().stories().source(storiesUser->id)
|
? storiesUser->owner().stories().source(storiesUser->id)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
const auto storiesCountReal = storiesSource
|
const auto storiesCountReal = storiesSource
|
||||||
? int(storiesSource->ids.size())
|
? int(storiesSource->ids.size())
|
||||||
|
: storiesFolder
|
||||||
|
? storiesFolder->storiesCount()
|
||||||
: storiesHas
|
: storiesHas
|
||||||
? 1
|
? 1
|
||||||
: 0;
|
: 0;
|
||||||
const auto storiesUnreadCountReal = storiesSource
|
const auto storiesUnreadCountReal = storiesSource
|
||||||
? storiesSource->unreadCount()
|
? storiesSource->unreadCount()
|
||||||
: (storiesHas && storiesUser->hasUnreadStories())
|
: storiesFolder
|
||||||
|
? storiesFolder->storiesUnreadCount()
|
||||||
|
: (storiesUser && storiesUser->hasUnreadStories())
|
||||||
? 1
|
? 1
|
||||||
: 0;
|
: 0;
|
||||||
const auto limit = (1 << 7) - 1;
|
const auto limit = Ui::kOutlineSegmentsMax;
|
||||||
const auto storiesCount = std::min(storiesCountReal, limit);
|
const auto storiesCount = std::min(storiesCountReal, limit);
|
||||||
const auto storiesUnreadCount = std::min(storiesUnreadCountReal, limit);
|
const auto storiesUnreadCount = std::min(storiesUnreadCountReal, limit);
|
||||||
if (_cornerBadgeUserpic->frame.size() != frameSize) {
|
if (_cornerBadgeUserpic->frame.size() != frameSize) {
|
||||||
|
@ -500,8 +496,8 @@ void Row::paintUserpic(
|
||||||
QImage::Format_ARGB32_Premultiplied);
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
_cornerBadgeUserpic->frame.setDevicePixelRatio(ratio);
|
_cornerBadgeUserpic->frame.setDevicePixelRatio(ratio);
|
||||||
}
|
}
|
||||||
auto key = peer->userpicUniqueKey(userpicView());
|
auto key = peer ? peer->userpicUniqueKey(userpicView()) : InMemoryKey();
|
||||||
key.first += peer->messagesTTL();
|
key.first += peer ? peer->messagesTTL() : 0;
|
||||||
const auto frameIndex = videoUserpic ? videoUserpic->frameIndex() : -1;
|
const auto frameIndex = videoUserpic ? videoUserpic->frameIndex() : -1;
|
||||||
const auto paletteVersionReal = style::PaletteVersion();
|
const auto paletteVersionReal = style::PaletteVersion();
|
||||||
const auto paletteVersion = (paletteVersionReal & ((1 << 17) - 1));
|
const auto paletteVersion = (paletteVersionReal & ((1 << 17) - 1));
|
||||||
|
@ -528,6 +524,7 @@ void Row::paintUserpic(
|
||||||
PaintCornerBadgeFrame(
|
PaintCornerBadgeFrame(
|
||||||
_cornerBadgeUserpic.get(),
|
_cornerBadgeUserpic.get(),
|
||||||
framePadding,
|
framePadding,
|
||||||
|
_id.entry(),
|
||||||
peer,
|
peer,
|
||||||
videoUserpic,
|
videoUserpic,
|
||||||
userpicView(),
|
userpicView(),
|
||||||
|
@ -537,10 +534,11 @@ void Row::paintUserpic(
|
||||||
context.st->padding.left() - framePadding,
|
context.st->padding.left() - framePadding,
|
||||||
context.st->padding.top() - framePadding,
|
context.st->padding.top() - framePadding,
|
||||||
_cornerBadgeUserpic->frame);
|
_cornerBadgeUserpic->frame);
|
||||||
if (historyForCornerBadge->peer->isUser()) {
|
const auto history = _id.history();
|
||||||
|
if (!history || history->peer->isUser()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto actionPainter = historyForCornerBadge->sendActionPainter();
|
const auto actionPainter = history->sendActionPainter();
|
||||||
const auto bg = context.active
|
const auto bg = context.active
|
||||||
? st::dialogsBgActive
|
? st::dialogsBgActive
|
||||||
: st::dialogsBg;
|
: st::dialogsBg;
|
||||||
|
|
|
@ -35,6 +35,7 @@ struct TopicJumpCache;
|
||||||
|
|
||||||
namespace Dialogs {
|
namespace Dialogs {
|
||||||
|
|
||||||
|
class Entry;
|
||||||
enum class SortMode;
|
enum class SortMode;
|
||||||
|
|
||||||
[[nodiscard]] QRect CornerBadgeTTLRect(int photoSize);
|
[[nodiscard]] QRect CornerBadgeTTLRect(int photoSize);
|
||||||
|
@ -46,9 +47,9 @@ public:
|
||||||
|
|
||||||
virtual void paintUserpic(
|
virtual void paintUserpic(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
not_null<PeerData*> peer,
|
not_null<Entry*> entry,
|
||||||
|
PeerData *peer,
|
||||||
Ui::VideoUserpic *videoUserpic,
|
Ui::VideoUserpic *videoUserpic,
|
||||||
History *historyForCornerBadge,
|
|
||||||
const Ui::PaintContext &context) const;
|
const Ui::PaintContext &context) const;
|
||||||
|
|
||||||
void addRipple(QPoint origin, QSize size, Fn<void()> updateCallback);
|
void addRipple(QPoint origin, QSize size, Fn<void()> updateCallback);
|
||||||
|
@ -99,9 +100,9 @@ public:
|
||||||
Fn<void()> updateCallback = nullptr) const;
|
Fn<void()> updateCallback = nullptr) const;
|
||||||
void paintUserpic(
|
void paintUserpic(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
not_null<PeerData*> peer,
|
not_null<Entry*> entry,
|
||||||
|
PeerData *peer,
|
||||||
Ui::VideoUserpic *videoUserpic,
|
Ui::VideoUserpic *videoUserpic,
|
||||||
History *historyForCornerBadge,
|
|
||||||
const Ui::PaintContext &context) const final override;
|
const Ui::PaintContext &context) const final override;
|
||||||
|
|
||||||
[[nodiscard]] bool lookupIsInTopicJump(int x, int y) const;
|
[[nodiscard]] bool lookupIsInTopicJump(int x, int y) const;
|
||||||
|
@ -183,7 +184,8 @@ private:
|
||||||
static void PaintCornerBadgeFrame(
|
static void PaintCornerBadgeFrame(
|
||||||
not_null<CornerBadgeUserpic*> data,
|
not_null<CornerBadgeUserpic*> data,
|
||||||
int framePadding,
|
int framePadding,
|
||||||
not_null<PeerData*> peer,
|
not_null<Entry*> entry,
|
||||||
|
PeerData *peer,
|
||||||
Ui::VideoUserpic *videoUserpic,
|
Ui::VideoUserpic *videoUserpic,
|
||||||
Ui::PeerUserpicView &view,
|
Ui::PeerUserpicView &view,
|
||||||
const Ui::PaintContext &context);
|
const Ui::PaintContext &context);
|
||||||
|
|
|
@ -1419,6 +1419,7 @@ void Widget::updateStoriesVisibility() {
|
||||||
if (_scroll->position().overscroll < 0) {
|
if (_scroll->position().overscroll < 0) {
|
||||||
_scroll->scrollToY(0);
|
_scroll->scrollToY(0);
|
||||||
}
|
}
|
||||||
|
_scroll->update();
|
||||||
} else {
|
} else {
|
||||||
_scroll->setOverscrollDefaults(0, 0);
|
_scroll->setOverscrollDefaults(0, 0);
|
||||||
_scroll->setOverscrollTypes(Type::Virtual, Type::Real);
|
_scroll->setOverscrollTypes(Type::Virtual, Type::Real);
|
||||||
|
|
|
@ -331,22 +331,23 @@ void PaintRow(
|
||||||
context.st->padding.top(),
|
context.st->padding.top(),
|
||||||
context.width,
|
context.width,
|
||||||
context.st->photoSize);
|
context.st->photoSize);
|
||||||
} else if (from) {
|
} else if (!from && hiddenSenderInfo) {
|
||||||
row->paintUserpic(
|
|
||||||
p,
|
|
||||||
from,
|
|
||||||
videoUserpic,
|
|
||||||
(flags & Flag::AllowUserOnline) ? history : nullptr,
|
|
||||||
context);
|
|
||||||
} else if (hiddenSenderInfo) {
|
|
||||||
hiddenSenderInfo->emptyUserpic.paintCircle(
|
hiddenSenderInfo->emptyUserpic.paintCircle(
|
||||||
p,
|
p,
|
||||||
context.st->padding.left(),
|
context.st->padding.left(),
|
||||||
context.st->padding.top(),
|
context.st->padding.top(),
|
||||||
context.width,
|
context.width,
|
||||||
context.st->photoSize);
|
context.st->photoSize);
|
||||||
|
} else if (!(flags & Flag::AllowUserOnline)) {
|
||||||
|
PaintUserpic(
|
||||||
|
p,
|
||||||
|
entry,
|
||||||
|
from,
|
||||||
|
videoUserpic,
|
||||||
|
row->userpicView(),
|
||||||
|
context);
|
||||||
} else {
|
} else {
|
||||||
entry->paintUserpic(p, row->userpicView(), context);
|
row->paintUserpic(p, entry, from, videoUserpic, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto nameleft = context.st->nameLeft;
|
auto nameleft = context.st->nameLeft;
|
||||||
|
@ -785,7 +786,7 @@ void RowPainter::Paint(
|
||||||
? history->peer->migrateTo()
|
? history->peer->migrateTo()
|
||||||
: history->peer.get())
|
: history->peer.get())
|
||||||
: nullptr;
|
: nullptr;
|
||||||
const auto allowUserOnline = !context.narrow || badgesState.empty();
|
const auto allowUserOnline = true;// !context.narrow || badgesState.empty();
|
||||||
const auto flags = (allowUserOnline ? Flag::AllowUserOnline : Flag(0))
|
const auto flags = (allowUserOnline ? Flag::AllowUserOnline : Flag(0))
|
||||||
| (peer && peer->isSelf() ? Flag::SavedMessages : Flag(0))
|
| (peer && peer->isSelf() ? Flag::SavedMessages : Flag(0))
|
||||||
| (peer && peer->isRepliesChat() ? Flag::RepliesMessages : Flag(0))
|
| (peer && peer->isRepliesChat() ? Flag::RepliesMessages : Flag(0))
|
||||||
|
|
|
@ -7,13 +7,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "dialogs/ui/dialogs_video_userpic.h"
|
#include "dialogs/ui/dialogs_video_userpic.h"
|
||||||
|
|
||||||
#include "ui/painter.h"
|
|
||||||
#include "core/file_location.h"
|
#include "core/file_location.h"
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_photo.h"
|
#include "data/data_photo.h"
|
||||||
#include "data/data_photo_media.h"
|
#include "data/data_photo_media.h"
|
||||||
#include "data/data_file_origin.h"
|
#include "data/data_file_origin.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "dialogs/ui/dialogs_layout.h"
|
||||||
|
#include "ui/painter.h"
|
||||||
|
#include "styles/style_dialogs.h"
|
||||||
|
|
||||||
namespace Dialogs::Ui {
|
namespace Dialogs::Ui {
|
||||||
|
|
||||||
|
@ -129,6 +131,29 @@ void VideoUserpic::clipCallback(Media::Clip::Notification notification) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PaintUserpic(
|
||||||
|
Painter &p,
|
||||||
|
not_null<Entry*> entry,
|
||||||
|
PeerData *peer,
|
||||||
|
VideoUserpic *videoUserpic,
|
||||||
|
PeerUserpicView &view,
|
||||||
|
const Ui::PaintContext &context) {
|
||||||
|
if (peer) {
|
||||||
|
PaintUserpic(
|
||||||
|
p,
|
||||||
|
peer,
|
||||||
|
videoUserpic,
|
||||||
|
view,
|
||||||
|
context.st->padding.left(),
|
||||||
|
context.st->padding.top(),
|
||||||
|
context.width,
|
||||||
|
context.st->photoSize,
|
||||||
|
context.paused);
|
||||||
|
} else {
|
||||||
|
entry->paintUserpic(p, view, context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PaintUserpic(
|
void PaintUserpic(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
|
|
|
@ -19,10 +19,16 @@ namespace Ui {
|
||||||
struct PeerUserpicView;
|
struct PeerUserpicView;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Dialogs {
|
||||||
|
class Entry;
|
||||||
|
} // namespace Dialogs
|
||||||
|
|
||||||
namespace Dialogs::Ui {
|
namespace Dialogs::Ui {
|
||||||
|
|
||||||
using namespace ::Ui;
|
using namespace ::Ui;
|
||||||
|
|
||||||
|
struct PaintContext;
|
||||||
|
|
||||||
class VideoUserpic final {
|
class VideoUserpic final {
|
||||||
public:
|
public:
|
||||||
VideoUserpic(not_null<PeerData*> peer, Fn<void()> repaint);
|
VideoUserpic(not_null<PeerData*> peer, Fn<void()> repaint);
|
||||||
|
@ -54,6 +60,14 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void PaintUserpic(
|
||||||
|
Painter &p,
|
||||||
|
not_null<Entry*> entry,
|
||||||
|
PeerData *peer,
|
||||||
|
VideoUserpic *videoUserpic,
|
||||||
|
PeerUserpicView &view,
|
||||||
|
const Ui::PaintContext &context);
|
||||||
|
|
||||||
void PaintUserpic(
|
void PaintUserpic(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
|
|
|
@ -17,7 +17,7 @@ void PaintOutlineSegments(
|
||||||
Expects(!segments.empty());
|
Expects(!segments.empty());
|
||||||
|
|
||||||
p.setBrush(Qt::NoBrush);
|
p.setBrush(Qt::NoBrush);
|
||||||
const auto count = int(segments.size());
|
const auto count = std::min(int(segments.size()), kOutlineSegmentsMax);
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
p.setPen(QPen(segments.front().brush, segments.front().width));
|
p.setPen(QPen(segments.front().brush, segments.front().width));
|
||||||
p.drawEllipse(ellipse);
|
p.drawEllipse(ellipse);
|
||||||
|
|
|
@ -9,6 +9,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
|
inline constexpr auto kOutlineSegmentsMax = 50;
|
||||||
|
|
||||||
struct OutlineSegment {
|
struct OutlineSegment {
|
||||||
QBrush brush;
|
QBrush brush;
|
||||||
float64 width = 0.;
|
float64 width = 0.;
|
||||||
|
|
|
@ -572,7 +572,7 @@ void MainMenu::setupArchive() {
|
||||||
const auto checkArchive = [=] {
|
const auto checkArchive = [=] {
|
||||||
const auto f = folder();
|
const auto f = folder();
|
||||||
return f
|
return f
|
||||||
&& !f->chatsList()->empty()
|
&& (!f->chatsList()->empty() || f->storiesCount() > 0)
|
||||||
&& controller->session().settings().archiveInMainMenu();
|
&& controller->session().settings().archiveInMainMenu();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -650,10 +650,15 @@ void MainMenu::setupArchive() {
|
||||||
return Badge::UnreadBadge{ state.unreadCounter, true };
|
return Badge::UnreadBadge{ state.unreadCounter, true };
|
||||||
}));
|
}));
|
||||||
|
|
||||||
controller->session().data().chatsListChanges(
|
rpl::merge(
|
||||||
) | rpl::filter([](Data::Folder *folder) {
|
controller->session().data().chatsListChanges(
|
||||||
return folder && (folder->id() == Data::Folder::kId);
|
) | rpl::filter([](Data::Folder *folder) {
|
||||||
}) | rpl::start_with_next([=] {
|
return folder && (folder->id() == Data::Folder::kId);
|
||||||
|
}) | rpl::to_empty,
|
||||||
|
controller->session().data().stories().sourcesChanged(
|
||||||
|
Data::StorySourcesList::Hidden
|
||||||
|
)
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
const auto isArchiveVisible = checkArchive();
|
const auto isArchiveVisible = checkArchive();
|
||||||
wrap->toggle(isArchiveVisible, anim::type::normal);
|
wrap->toggle(isArchiveVisible, anim::type::normal);
|
||||||
if (!isArchiveVisible) {
|
if (!isArchiveVisible) {
|
||||||
|
|
|
@ -949,7 +949,8 @@ SessionController::SessionController(
|
||||||
) | rpl::filter([=](Data::Folder *folder) {
|
) | rpl::filter([=](Data::Folder *folder) {
|
||||||
return (folder != nullptr)
|
return (folder != nullptr)
|
||||||
&& (folder == _openedFolder.current())
|
&& (folder == _openedFolder.current())
|
||||||
&& folder->chatsList()->indexed()->empty();
|
&& folder->chatsList()->indexed()->empty()
|
||||||
|
&& !folder->storiesCount();
|
||||||
}) | rpl::start_with_next([=](Data::Folder *folder) {
|
}) | rpl::start_with_next([=](Data::Folder *folder) {
|
||||||
folder->updateChatListSortPosition();
|
folder->updateChatListSortPosition();
|
||||||
closeFolder();
|
closeFolder();
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit c7e0b7af37bce7ec77195ff717d70457e51e1e7a
|
Subproject commit 1c0889f78a74bb29e8cea6986ea8b18e7add7fb0
|
Loading…
Reference in New Issue
Block a user