mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Implement context menu actions in stories list.
This commit is contained in:
parent
a733b83642
commit
ac534780cc
5 changed files with 116 additions and 45 deletions
|
@ -915,6 +915,11 @@ void ListWidget::showContextMenu(
|
||||||
auto canForwardAll = [&] {
|
auto canForwardAll = [&] {
|
||||||
return ranges::none_of(_selected, [](auto &&item) {
|
return ranges::none_of(_selected, [](auto &&item) {
|
||||||
return !item.second.canForward;
|
return !item.second.canForward;
|
||||||
|
}) && (!_controller->key().storiesPeer() || _selected.size() == 1);
|
||||||
|
};
|
||||||
|
auto canToggleStoryPinAll = [&] {
|
||||||
|
return ranges::none_of(_selected, [](auto &&item) {
|
||||||
|
return !item.second.canToggleStoryPin;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1016,6 +1021,16 @@ void ListWidget::showContextMenu(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (overSelected == SelectionState::OverSelectedItems) {
|
if (overSelected == SelectionState::OverSelectedItems) {
|
||||||
|
if (canToggleStoryPinAll()) {
|
||||||
|
const auto tab = _controller->key().storiesTab();
|
||||||
|
const auto pin = (tab == Stories::Tab::Archive);
|
||||||
|
_contextMenu->addAction(
|
||||||
|
(pin
|
||||||
|
? tr::lng_mediaview_save_to_profile
|
||||||
|
: tr::lng_archived_add)(tr::now),
|
||||||
|
crl::guard(this, [this] { toggleStoryPinSelected(); }),
|
||||||
|
(pin ? &st::menuIconStoriesSaved : &st::menuIconArchive));
|
||||||
|
}
|
||||||
if (canForwardAll()) {
|
if (canForwardAll()) {
|
||||||
_contextMenu->addAction(
|
_contextMenu->addAction(
|
||||||
tr::lng_context_forward_selected(tr::now),
|
tr::lng_context_forward_selected(tr::now),
|
||||||
|
@ -1045,6 +1060,18 @@ void ListWidget::showContextMenu(
|
||||||
const auto selectionData = _provider->computeSelectionData(
|
const auto selectionData = _provider->computeSelectionData(
|
||||||
item,
|
item,
|
||||||
FullSelection);
|
FullSelection);
|
||||||
|
if (selectionData.canToggleStoryPin) {
|
||||||
|
const auto tab = _controller->key().storiesTab();
|
||||||
|
const auto pin = (tab == Stories::Tab::Archive);
|
||||||
|
_contextMenu->addAction(
|
||||||
|
(pin
|
||||||
|
? tr::lng_mediaview_save_to_profile
|
||||||
|
: tr::lng_mediaview_archive_story)(tr::now),
|
||||||
|
crl::guard(this, [=] {
|
||||||
|
toggleStoryPin({ 1, globalId.itemId });
|
||||||
|
}),
|
||||||
|
(pin ? &st::menuIconStoriesSaved : &st::menuIconArchive));
|
||||||
|
}
|
||||||
if (selectionData.canForward) {
|
if (selectionData.canForward) {
|
||||||
_contextMenu->addAction(
|
_contextMenu->addAction(
|
||||||
tr::lng_context_forward_msg(tr::now),
|
tr::lng_context_forward_msg(tr::now),
|
||||||
|
@ -1066,6 +1093,20 @@ void ListWidget::showContextMenu(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (const auto peer = _controller->key().storiesPeer()) {
|
||||||
|
if (!peer->isSelf() && IsStoryMsgId(globalId.itemId.msg)) {
|
||||||
|
const auto storyId = FullStoryId{
|
||||||
|
globalId.itemId.peer,
|
||||||
|
StoryIdFromMsgId(globalId.itemId.msg),
|
||||||
|
};
|
||||||
|
_contextMenu->addAction(
|
||||||
|
tr::lng_profile_report(tr::now),
|
||||||
|
[=] { ::Media::Stories::ReportRequested(
|
||||||
|
_controller->uiShow(),
|
||||||
|
storyId); },
|
||||||
|
&st::menuIconReport);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!_provider->hasSelectRestriction()) {
|
if (!_provider->hasSelectRestriction()) {
|
||||||
_contextMenu->addAction(
|
_contextMenu->addAction(
|
||||||
tr::lng_context_select_msg(tr::now),
|
tr::lng_context_select_msg(tr::now),
|
||||||
|
@ -1105,16 +1146,7 @@ void ListWidget::contextMenuEvent(QContextMenuEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::forwardSelected() {
|
void ListWidget::forwardSelected() {
|
||||||
if (_controller->storiesPeer()) {
|
if (auto items = collectSelectedIds(); !items.empty()) {
|
||||||
const auto ids = collectSelectedIds();
|
|
||||||
if (ids.size() == 1 && IsStoryMsgId(ids.front().msg)) {
|
|
||||||
const auto id = ids.front();
|
|
||||||
_controller->parentController()->show(
|
|
||||||
::Media::Stories::PrepareShareBox(
|
|
||||||
_controller->parentController()->uiShow(),
|
|
||||||
{ id.peer, StoryIdFromMsgId(id.msg) }));
|
|
||||||
}
|
|
||||||
} else if (auto items = collectSelectedIds(); !items.empty()) {
|
|
||||||
forwardItems(std::move(items));
|
forwardItems(std::move(items));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1129,15 +1161,25 @@ void ListWidget::forwardItem(GlobalMsgId globalId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::forwardItems(MessageIdsList &&items) {
|
void ListWidget::forwardItems(MessageIdsList &&items) {
|
||||||
auto callback = [weak = Ui::MakeWeak(this)] {
|
if (_controller->storiesPeer()) {
|
||||||
if (const auto strong = weak.data()) {
|
if (items.size() == 1 && IsStoryMsgId(items.front().msg)) {
|
||||||
strong->clearSelected();
|
const auto id = items.front();
|
||||||
|
_controller->parentController()->show(
|
||||||
|
::Media::Stories::PrepareShareBox(
|
||||||
|
_controller->parentController()->uiShow(),
|
||||||
|
{ id.peer, StoryIdFromMsgId(id.msg) }));
|
||||||
}
|
}
|
||||||
};
|
} else {
|
||||||
setActionBoxWeak(Window::ShowForwardMessagesBox(
|
auto callback = [weak = Ui::MakeWeak(this)] {
|
||||||
_controller,
|
if (const auto strong = weak.data()) {
|
||||||
std::move(items),
|
strong->clearSelected();
|
||||||
std::move(callback)));
|
}
|
||||||
|
};
|
||||||
|
setActionBoxWeak(Window::ShowForwardMessagesBox(
|
||||||
|
_controller,
|
||||||
|
std::move(items),
|
||||||
|
std::move(callback)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::deleteSelected() {
|
void ListWidget::deleteSelected() {
|
||||||
|
@ -1147,12 +1189,16 @@ void ListWidget::deleteSelected() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::toggleStoryPinSelected() {
|
void ListWidget::toggleStoryPinSelected() {
|
||||||
auto list = std::vector<FullStoryId>();
|
toggleStoryPin(collectSelectedIds(), crl::guard(this, [=] {
|
||||||
const auto confirmed = crl::guard(this, [=] {
|
|
||||||
clearSelected();
|
clearSelected();
|
||||||
});
|
}));
|
||||||
for (const auto &item : collectSelectedItems().list) {
|
}
|
||||||
const auto id = item.globalId.itemId;
|
|
||||||
|
void ListWidget::toggleStoryPin(
|
||||||
|
MessageIdsList &&items,
|
||||||
|
Fn<void()> confirmed) {
|
||||||
|
auto list = std::vector<FullStoryId>();
|
||||||
|
for (const auto &id : items) {
|
||||||
if (IsStoryMsgId(id.msg)) {
|
if (IsStoryMsgId(id.msg)) {
|
||||||
list.push_back({ id.peer, StoryIdFromMsgId(id.msg) });
|
list.push_back({ id.peer, StoryIdFromMsgId(id.msg) });
|
||||||
}
|
}
|
||||||
|
@ -1165,7 +1211,9 @@ void ListWidget::toggleStoryPinSelected() {
|
||||||
controller->showToast(
|
controller->showToast(
|
||||||
::Media::Stories::PrepareTogglePinnedToast(count, pin));
|
::Media::Stories::PrepareTogglePinnedToast(count, pin));
|
||||||
close();
|
close();
|
||||||
confirmed();
|
if (confirmed) {
|
||||||
|
confirmed();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const auto session = &_controller->session();
|
const auto session = &_controller->session();
|
||||||
const auto onePhrase = pin
|
const auto onePhrase = pin
|
||||||
|
|
|
@ -192,6 +192,9 @@ private:
|
||||||
void toggleStoryPinSelected();
|
void toggleStoryPinSelected();
|
||||||
void deleteItem(GlobalMsgId globalId);
|
void deleteItem(GlobalMsgId globalId);
|
||||||
void deleteItems(SelectedItems &&items, Fn<void()> confirmed = nullptr);
|
void deleteItems(SelectedItems &&items, Fn<void()> confirmed = nullptr);
|
||||||
|
void toggleStoryPin(
|
||||||
|
MessageIdsList &&items,
|
||||||
|
Fn<void()> confirmed = nullptr);
|
||||||
void applyItemSelection(
|
void applyItemSelection(
|
||||||
HistoryItem *item,
|
HistoryItem *item,
|
||||||
TextSelection selection);
|
TextSelection selection);
|
||||||
|
|
|
@ -314,7 +314,21 @@ ListItemSelectionData Provider::computeSelectionData(
|
||||||
auto result = ListItemSelectionData(selection);
|
auto result = ListItemSelectionData(selection);
|
||||||
const auto peer = item->history()->peer;
|
const auto peer = item->history()->peer;
|
||||||
result.canDelete = peer->isSelf();
|
result.canDelete = peer->isSelf();
|
||||||
result.canForward = peer->isSelf();
|
result.canForward = [&] {
|
||||||
|
if (!peer->isSelf()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto id = item->id;
|
||||||
|
if (!IsStoryMsgId(id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const auto maybeStory = peer->owner().stories().lookup(
|
||||||
|
{ peer->id, StoryIdFromMsgId(id) });
|
||||||
|
if (!maybeStory) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (*maybeStory)->canShare();
|
||||||
|
}();
|
||||||
result.canToggleStoryPin = peer->isSelf();
|
result.canToggleStoryPin = peer->isSelf();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1278,26 +1278,7 @@ void Controller::deleteRequested() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::reportRequested() {
|
void Controller::reportRequested() {
|
||||||
const auto story = this->story();
|
ReportRequested(uiShow(), _shown, &st::storiesReportBox);
|
||||||
if (!story) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto id = story->fullId();
|
|
||||||
const auto owner = &story->owner();
|
|
||||||
const auto confirmed = [=](Fn<void()> close) {
|
|
||||||
owner->stories().deleteList({ id });
|
|
||||||
close();
|
|
||||||
};
|
|
||||||
const auto show = uiShow();
|
|
||||||
const auto st = &st::storiesReportBox;
|
|
||||||
show->show(Box(Ui::ReportReasonBox, *st, Ui::ReportSource::Story, [=](
|
|
||||||
Ui::ReportReason reason) {
|
|
||||||
const auto done = [=](const QString &text) {
|
|
||||||
owner->stories().report(show, id, reason, text);
|
|
||||||
show->hideLayer();
|
|
||||||
};
|
|
||||||
show->showBox(Box(Ui::ReportDetailsBox, *st, done));
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::togglePinnedRequested(bool pinned) {
|
void Controller::togglePinnedRequested(bool pinned) {
|
||||||
|
@ -1391,4 +1372,20 @@ Ui::Toast::Config PrepareTogglePinnedToast(int count, bool pinned) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ReportRequested(
|
||||||
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
|
FullStoryId id,
|
||||||
|
const style::ReportBox *stOverride) {
|
||||||
|
const auto owner = &show->session().data();
|
||||||
|
const auto st = stOverride ? stOverride : &st::defaultReportBox;
|
||||||
|
show->show(Box(Ui::ReportReasonBox, *st, Ui::ReportSource::Story, [=](
|
||||||
|
Ui::ReportReason reason) {
|
||||||
|
const auto done = [=](const QString &text) {
|
||||||
|
owner->stories().report(show, id, reason, text);
|
||||||
|
show->hideLayer();
|
||||||
|
};
|
||||||
|
show->showBox(Box(Ui::ReportDetailsBox, *st, done));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Media::Stories
|
} // namespace Media::Stories
|
||||||
|
|
|
@ -10,6 +10,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_stories.h"
|
#include "data/data_stories.h"
|
||||||
#include "ui/effects/animations.h"
|
#include "ui/effects/animations.h"
|
||||||
|
|
||||||
|
namespace style {
|
||||||
|
struct ReportBox;
|
||||||
|
} // namespace style
|
||||||
|
|
||||||
namespace base {
|
namespace base {
|
||||||
class PowerSaveBlocker;
|
class PowerSaveBlocker;
|
||||||
} // namespace base
|
} // namespace base
|
||||||
|
@ -40,6 +44,7 @@ struct Config;
|
||||||
|
|
||||||
namespace Main {
|
namespace Main {
|
||||||
class Session;
|
class Session;
|
||||||
|
class SessionShow;
|
||||||
} // namespace Main
|
} // namespace Main
|
||||||
|
|
||||||
namespace Media::Player {
|
namespace Media::Player {
|
||||||
|
@ -260,5 +265,9 @@ private:
|
||||||
[[nodiscard]] Ui::Toast::Config PrepareTogglePinnedToast(
|
[[nodiscard]] Ui::Toast::Config PrepareTogglePinnedToast(
|
||||||
int count,
|
int count,
|
||||||
bool pinned);
|
bool pinned);
|
||||||
|
void ReportRequested(
|
||||||
|
std::shared_ptr<Main::SessionShow> show,
|
||||||
|
FullStoryId id,
|
||||||
|
const style::ReportBox *stOverride = nullptr);
|
||||||
|
|
||||||
} // namespace Media::Stories
|
} // namespace Media::Stories
|
||||||
|
|
Loading…
Add table
Reference in a new issue