mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Show hidden stories above contacts list.
This commit is contained in:
parent
f40391b4f0
commit
e7c0385aea
9 changed files with 130 additions and 22 deletions
|
@ -3789,6 +3789,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_userpic_builder_color_subtitle" = "Choose background";
|
"lng_userpic_builder_color_subtitle" = "Choose background";
|
||||||
"lng_userpic_builder_emoji_subtitle" = "Choose sticker or emoji";
|
"lng_userpic_builder_emoji_subtitle" = "Choose sticker or emoji";
|
||||||
|
|
||||||
|
"lng_stories_hide_to_contacts" = "Archive";
|
||||||
|
"lng_stories_show_in_chats" = "Unarchive";
|
||||||
"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_row_unread_and_one" = "{accumulated}, {user}";
|
"lng_stories_row_unread_and_one" = "{accumulated}, {user}";
|
||||||
|
|
|
@ -37,6 +37,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/style_profile.h"
|
#include "styles/style_profile.h"
|
||||||
#include "styles/style_dialogs.h"
|
#include "styles/style_dialogs.h"
|
||||||
|
|
||||||
|
#include "data/data_stories.h"
|
||||||
|
#include "dialogs/ui/dialogs_stories_content.h"
|
||||||
|
#include "dialogs/ui/dialogs_stories_list.h"
|
||||||
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kSortByOnlineThrottle = 3 * crl::time(1000);
|
constexpr auto kSortByOnlineThrottle = 3 * crl::time(1000);
|
||||||
|
@ -51,10 +56,14 @@ object_ptr<Ui::BoxContent> PrepareContactsBox(
|
||||||
&sessionController->session());
|
&sessionController->session());
|
||||||
const auto raw = controller.get();
|
const auto raw = controller.get();
|
||||||
auto init = [=](not_null<PeerListBox*> box) {
|
auto init = [=](not_null<PeerListBox*> box) {
|
||||||
|
using namespace Dialogs;
|
||||||
|
|
||||||
struct State {
|
struct State {
|
||||||
QPointer<Ui::IconButton> toggleSort;
|
Stories::List *stories = nullptr;
|
||||||
|
QPointer<::Ui::IconButton> toggleSort;
|
||||||
Mode mode = ContactsBoxController::SortMode::Online;
|
Mode mode = ContactsBoxController::SortMode::Online;
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto state = box->lifetime().make_state<State>();
|
const auto state = box->lifetime().make_state<State>();
|
||||||
box->addButton(tr::lng_close(), [=] { box->closeBox(); });
|
box->addButton(tr::lng_close(), [=] { box->closeBox(); });
|
||||||
box->addLeftButton(
|
box->addLeftButton(
|
||||||
|
@ -69,6 +78,43 @@ object_ptr<Ui::BoxContent> PrepareContactsBox(
|
||||||
online ? &st::contactsSortOnlineIconOver : nullptr);
|
online ? &st::contactsSortOnlineIconOver : nullptr);
|
||||||
});
|
});
|
||||||
raw->setSortMode(Mode::Online);
|
raw->setSortMode(Mode::Online);
|
||||||
|
|
||||||
|
auto stories = object_ptr<Stories::List>(
|
||||||
|
box,
|
||||||
|
Stories::ContentForSession(
|
||||||
|
&sessionController->session(),
|
||||||
|
Data::StorySourcesList::All),
|
||||||
|
[=] { return state->stories->height() - box->scrollTop(); });
|
||||||
|
const auto raw = state->stories = stories.data();
|
||||||
|
box->peerListSetAboveWidget(std::move(stories));
|
||||||
|
|
||||||
|
raw->entered(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
//clearSelection();
|
||||||
|
}, raw->lifetime());
|
||||||
|
|
||||||
|
raw->clicks(
|
||||||
|
) | rpl::start_with_next([=](uint64 id) {
|
||||||
|
sessionController->openPeerStories(PeerId(int64(id)), {});
|
||||||
|
}, raw->lifetime());
|
||||||
|
|
||||||
|
raw->showProfileRequests(
|
||||||
|
) | rpl::start_with_next([=](uint64 id) {
|
||||||
|
sessionController->showPeerInfo(PeerId(int64(id)));
|
||||||
|
}, raw->lifetime());
|
||||||
|
|
||||||
|
raw->toggleShown(
|
||||||
|
) | rpl::start_with_next([=](Stories::ToggleShownRequest request) {
|
||||||
|
sessionController->session().data().stories().toggleHidden(
|
||||||
|
PeerId(int64(request.id)),
|
||||||
|
!request.shown);
|
||||||
|
}, raw->lifetime());
|
||||||
|
|
||||||
|
raw->loadMoreRequests(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
sessionController->session().data().stories().loadMore(
|
||||||
|
Data::StorySourcesList::All);
|
||||||
|
}, raw->lifetime());
|
||||||
};
|
};
|
||||||
return Box<PeerListBox>(std::move(controller), std::move(init));
|
return Box<PeerListBox>(std::move(controller), std::move(init));
|
||||||
}
|
}
|
||||||
|
|
|
@ -350,9 +350,11 @@ void Stories::parseAndApply(const MTPUserStories &stories) {
|
||||||
const auto peerId = peerFromUser(data.vuser_id());
|
const auto peerId = peerFromUser(data.vuser_id());
|
||||||
const auto readTill = data.vmax_read_id().value_or_empty();
|
const auto readTill = data.vmax_read_id().value_or_empty();
|
||||||
const auto count = int(data.vstories().v.size());
|
const auto count = int(data.vstories().v.size());
|
||||||
|
const auto user = _owner->peer(peerId)->asUser();
|
||||||
auto result = StoriesSource{
|
auto result = StoriesSource{
|
||||||
.user = _owner->peer(peerId)->asUser(),
|
.user = user,
|
||||||
.readTill = readTill,
|
.readTill = readTill,
|
||||||
|
.hidden = user->hasStoriesHidden(),
|
||||||
};
|
};
|
||||||
const auto &list = data.vstories().v;
|
const auto &list = data.vstories().v;
|
||||||
result.ids.reserve(list.size());
|
result.ids.reserve(list.size());
|
||||||
|
@ -806,6 +808,58 @@ void Stories::markAsRead(FullStoryId id, bool viewed) {
|
||||||
_markReadTimer.callOnce(kMarkAsReadDelay);
|
_markReadTimer.callOnce(kMarkAsReadDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Stories::toggleHidden(PeerId peerId, bool hidden) {
|
||||||
|
const auto user = _owner->peer(peerId)->asUser();
|
||||||
|
Assert(user != nullptr);
|
||||||
|
if (user->hasStoriesHidden() != hidden) {
|
||||||
|
user->setFlags(hidden
|
||||||
|
? (user->flags() | UserDataFlag::StoriesHidden)
|
||||||
|
: (user->flags() & ~UserDataFlag::StoriesHidden));
|
||||||
|
session().api().request(MTPcontacts_ToggleStoriesHidden(
|
||||||
|
user->inputUser,
|
||||||
|
MTP_bool(hidden)
|
||||||
|
)).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto i = _all.find(peerId);
|
||||||
|
if (i == end(_all)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i->second.hidden = hidden;
|
||||||
|
const auto main = static_cast<int>(StorySourcesList::NotHidden);
|
||||||
|
const auto all = static_cast<int>(StorySourcesList::All);
|
||||||
|
if (hidden) {
|
||||||
|
const auto i = ranges::find(
|
||||||
|
_sources[main],
|
||||||
|
peerId,
|
||||||
|
&StoriesSourceInfo::id);
|
||||||
|
if (i != end(_sources[main])) {
|
||||||
|
_sources[main].erase(i);
|
||||||
|
_sourcesChanged[main].fire({});
|
||||||
|
}
|
||||||
|
const auto j = ranges::find(_sources[all], peerId, &StoriesSourceInfo::id);
|
||||||
|
if (j != end(_sources[all])) {
|
||||||
|
j->hidden = hidden;
|
||||||
|
_sourcesChanged[all].fire({});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const auto i = ranges::find(
|
||||||
|
_sources[all],
|
||||||
|
peerId,
|
||||||
|
&StoriesSourceInfo::id);
|
||||||
|
if (i != end(_sources[all])) {
|
||||||
|
i->hidden = hidden;
|
||||||
|
_sourcesChanged[all].fire({});
|
||||||
|
|
||||||
|
auto &sources = _sources[main];
|
||||||
|
if (!ranges::contains(sources, peerId, &StoriesSourceInfo::id)) {
|
||||||
|
sources.push_back(*i);
|
||||||
|
sort(StorySourcesList::NotHidden);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Stories::sendMarkAsReadRequest(
|
void Stories::sendMarkAsReadRequest(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
StoryId tillId) {
|
StoryId tillId) {
|
||||||
|
|
|
@ -176,6 +176,8 @@ public:
|
||||||
[[nodiscard]] bool isQuitPrevent();
|
[[nodiscard]] bool isQuitPrevent();
|
||||||
void markAsRead(FullStoryId id, bool viewed);
|
void markAsRead(FullStoryId id, bool viewed);
|
||||||
|
|
||||||
|
void toggleHidden(PeerId peerId, bool hidden);
|
||||||
|
|
||||||
static constexpr auto kViewsPerPage = 50;
|
static constexpr auto kViewsPerPage = 50;
|
||||||
void loadViewsSlice(
|
void loadViewsSlice(
|
||||||
StoryId id,
|
StoryId id,
|
||||||
|
|
|
@ -351,18 +351,9 @@ InnerWidget::InnerWidget(
|
||||||
|
|
||||||
_stories->toggleShown(
|
_stories->toggleShown(
|
||||||
) | rpl::start_with_next([=](Stories::ToggleShownRequest request) {
|
) | rpl::start_with_next([=](Stories::ToggleShownRequest request) {
|
||||||
const auto peerId = PeerId(int64(request.id));
|
session().data().stories().toggleHidden(
|
||||||
const auto user = session().data().peer(peerId)->asUser();
|
PeerId(int64(request.id)),
|
||||||
Assert(user != nullptr);
|
!request.shown);
|
||||||
if (user->hasStoriesHidden() == request.shown) {
|
|
||||||
user->setFlags(request.shown
|
|
||||||
? (user->flags() & ~UserDataFlag::StoriesHidden)
|
|
||||||
: (user->flags() | UserDataFlag::StoriesHidden));
|
|
||||||
session().api().request(MTPcontacts_ToggleStoriesHidden(
|
|
||||||
user->inputUser,
|
|
||||||
MTP_bool(!request.shown)
|
|
||||||
)).send();
|
|
||||||
}
|
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
_stories->loadMoreRequests(
|
_stories->loadMoreRequests(
|
||||||
|
|
|
@ -149,6 +149,7 @@ Content State::next() {
|
||||||
.name = user->shortName(),
|
.name = user->shortName(),
|
||||||
.userpic = std::move(userpic),
|
.userpic = std::move(userpic),
|
||||||
.unread = info.unread,
|
.unread = info.unread,
|
||||||
|
.hidden = info.hidden,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -99,6 +99,7 @@ void List::showContent(Content &&content) {
|
||||||
item.nameCache = QImage();
|
item.nameCache = QImage();
|
||||||
}
|
}
|
||||||
item.user.unread = user.unread;
|
item.user.unread = user.unread;
|
||||||
|
item.user.hidden = user.hidden;
|
||||||
} else {
|
} else {
|
||||||
_data.items.emplace_back(Item{ .user = user });
|
_data.items.emplace_back(Item{ .user = user });
|
||||||
}
|
}
|
||||||
|
@ -429,8 +430,8 @@ void List::paintEvent(QPaintEvent *e) {
|
||||||
});
|
});
|
||||||
p.setBrush(gradient);
|
p.setBrush(gradient);
|
||||||
p.drawEllipse(outer);
|
p.drawEllipse(outer);
|
||||||
p.setOpacity(1.);
|
|
||||||
}
|
}
|
||||||
|
p.setOpacity(1.);
|
||||||
}, [&](Single single) {
|
}, [&](Single single) {
|
||||||
Expects(single.itemSmall || single.itemFull);
|
Expects(single.itemSmall || single.itemFull);
|
||||||
|
|
||||||
|
@ -710,19 +711,24 @@ void List::contextMenuEvent(QContextMenuEvent *e) {
|
||||||
|
|
||||||
const auto id = item.user.id;
|
const auto id = item.user.id;
|
||||||
const auto hidden = item.user.hidden;
|
const auto hidden = item.user.hidden;
|
||||||
_menu->addAction(u"View Profile"_q, [=] {
|
_menu->addAction(tr::lng_context_view_profile(tr::now), [=] {
|
||||||
_showProfileRequests.fire_copy(id);
|
_showProfileRequests.fire_copy(id);
|
||||||
});
|
});
|
||||||
_menu->addAction(hidden ? u"Show in Chats"_q : u"Hide"_q, [=] {
|
_menu->addAction(hidden
|
||||||
_toggleShown.fire({ .id = id, .shown = hidden });
|
? tr::lng_stories_show_in_chats(tr::now)
|
||||||
});
|
: tr::lng_stories_hide_to_contacts(tr::now),
|
||||||
QObject::connect(_menu.get(), &QObject::destroyed, [=] {
|
[=] { _toggleShown.fire({ .id = id, .shown = hidden }); });
|
||||||
|
const auto updateAfterMenuDestroyed = [=] {
|
||||||
const auto globalPosition = QCursor::pos();
|
const auto globalPosition = QCursor::pos();
|
||||||
if (rect().contains(mapFromGlobal(globalPosition))) {
|
if (rect().contains(mapFromGlobal(globalPosition))) {
|
||||||
_lastMousePosition = globalPosition;
|
_lastMousePosition = globalPosition;
|
||||||
updateSelected();
|
updateSelected();
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
QObject::connect(
|
||||||
|
_menu.get(),
|
||||||
|
&QObject::destroyed,
|
||||||
|
crl::guard(&_menuGuard, updateAfterMenuDestroyed));
|
||||||
if (_menu->empty()) {
|
if (_menu->empty()) {
|
||||||
_menu = nullptr;
|
_menu = nullptr;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "base/qt/qt_compare.h"
|
#include "base/qt/qt_compare.h"
|
||||||
|
#include "base/weak_ptr.h"
|
||||||
#include "ui/rp_widget.h"
|
#include "ui/rp_widget.h"
|
||||||
|
|
||||||
class QPainter;
|
class QPainter;
|
||||||
|
@ -160,6 +161,7 @@ private:
|
||||||
int _pressed = -1;
|
int _pressed = -1;
|
||||||
|
|
||||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||||
|
base::has_weak_ptr _menuGuard;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3061,7 +3061,11 @@ void OverlayWidget::show(OpenRequest request) {
|
||||||
setSession(&photo->session());
|
setSession(&photo->session());
|
||||||
|
|
||||||
if (story) {
|
if (story) {
|
||||||
setContext(StoriesContext{ story->peer(), story->id() });
|
setContext(StoriesContext{
|
||||||
|
story->peer(),
|
||||||
|
story->id(),
|
||||||
|
request.storiesList(),
|
||||||
|
});
|
||||||
} else if (contextPeer) {
|
} else if (contextPeer) {
|
||||||
setContext(contextPeer);
|
setContext(contextPeer);
|
||||||
} else if (contextItem) {
|
} else if (contextItem) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue