Beta version 3.1.6: Detach FastReply from MarkAsRead.

This commit is contained in:
John Preston 2021-10-06 19:24:30 +04:00
parent 8b7cd4a0c7
commit 5cd0a3719e
8 changed files with 68 additions and 85 deletions

View file

@ -405,7 +405,7 @@ public:
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideReplyButton); Window::Notifications::Manager::DisplayOptions options);
NotificationData(const NotificationData &other) = delete; NotificationData(const NotificationData &other) = delete;
NotificationData &operator=(const NotificationData &other) = delete; NotificationData &operator=(const NotificationData &other) = delete;
@ -453,7 +453,7 @@ bool NotificationData::init(
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideReplyButton) { Window::Notifications::Manager::DisplayOptions options) {
try { try {
_dbusConnection = Gio::DBus::Connection::get_sync( _dbusConnection = Gio::DBus::Connection::get_sync(
Gio::DBus::BusType::BUS_TYPE_SESSION); Gio::DBus::BusType::BUS_TYPE_SESSION);
@ -524,13 +524,13 @@ bool NotificationData::init(
_actions.push_back("default"); _actions.push_back("default");
_actions.push_back({}); _actions.push_back({});
if (!hideReplyButton) { if (!options.hideMarkAsRead) {
_actions.push_back("mail-mark-read"); _actions.push_back("mail-mark-read");
_actions.push_back( _actions.push_back(
tr::lng_context_mark_read(tr::now).toStdString()); tr::lng_context_mark_read(tr::now).toStdString());
} }
if (capabilities.contains("inline-reply") && !hideReplyButton) { if (capabilities.contains("inline-reply") && !options.hideReplyButton) {
_actions.push_back("inline-reply"); _actions.push_back("inline-reply");
_actions.push_back( _actions.push_back(
tr::lng_notification_reply(tr::now).toStdString()); tr::lng_notification_reply(tr::now).toStdString());
@ -826,8 +826,7 @@ public:
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options);
bool hideReplyButton);
void clearAll(); void clearAll();
void clearFromHistory(not_null<History*> history); void clearFromHistory(not_null<History*> history);
void clearFromSession(not_null<Main::Session*> session); void clearFromSession(not_null<Main::Session*> session);
@ -883,8 +882,7 @@ void Manager::Private::showNotification(
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options) {
bool hideReplyButton) {
if (!Supported()) { if (!Supported()) {
return; return;
} }
@ -901,7 +899,7 @@ void Manager::Private::showNotification(
title, title,
subtitle, subtitle,
msg, msg,
hideReplyButton); options);
if (!inited) { if (!inited) {
return; return;
} }
@ -1020,8 +1018,7 @@ void Manager::doShowNativeNotification(
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options) {
bool hideReplyButton) {
_private->showNotification( _private->showNotification(
peer, peer,
userpicView, userpicView,
@ -1029,8 +1026,7 @@ void Manager::doShowNativeNotification(
title, title,
subtitle, subtitle,
msg, msg,
hideNameAndPhoto, options);
hideReplyButton);
} }
void Manager::doClearAllFast() { void Manager::doClearAllFast() {

View file

@ -26,8 +26,7 @@ protected:
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options) override;
bool hideReplyButton) override;
void doClearAllFast() override; void doClearAllFast() override;
void doClearFromHistory(not_null<History*> history) override; void doClearFromHistory(not_null<History*> history) override;
void doClearFromSession(not_null<Main::Session*> session) override; void doClearFromSession(not_null<Main::Session*> session) override;

View file

@ -26,8 +26,7 @@ protected:
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options) override;
bool hideReplyButton) override;
void doClearAllFast() override; void doClearAllFast() override;
void doClearFromHistory(not_null<History*> history) override; void doClearFromHistory(not_null<History*> history) override;
void doClearFromSession(not_null<Main::Session*> session) override; void doClearFromSession(not_null<Main::Session*> session) override;

View file

@ -184,8 +184,7 @@ public:
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options);
bool hideReplyButton);
void clearAll(); void clearAll();
void clearFromHistory(not_null<History*> history); void clearFromHistory(not_null<History*> history);
void clearFromSession(not_null<Main::Session*> session); void clearFromSession(not_null<Main::Session*> session);
@ -250,8 +249,7 @@ void Manager::Private::showNotification(
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options) {
bool hideReplyButton) {
@autoreleasepool { @autoreleasepool {
NSUserNotification *notification = [[[NSUserNotification alloc] init] autorelease]; NSUserNotification *notification = [[[NSUserNotification alloc] init] autorelease];
@ -279,7 +277,8 @@ void Manager::Private::showNotification(
[notification setTitle:Q2NSString(title)]; [notification setTitle:Q2NSString(title)];
[notification setSubtitle:Q2NSString(subtitle)]; [notification setSubtitle:Q2NSString(subtitle)];
[notification setInformativeText:Q2NSString(msg)]; [notification setInformativeText:Q2NSString(msg)];
if (!hideNameAndPhoto && [notification respondsToSelector:@selector(setContentImage:)]) { if (!options.hideNameAndPhoto
&& [notification respondsToSelector:@selector(setContentImage:)]) {
auto userpic = peer->isSelf() auto userpic = peer->isSelf()
? Ui::EmptyUserpic::GenerateSavedMessages(st::notifyMacPhotoSize) ? Ui::EmptyUserpic::GenerateSavedMessages(st::notifyMacPhotoSize)
: peer->isRepliesChat() : peer->isRepliesChat()
@ -289,7 +288,8 @@ void Manager::Private::showNotification(
[notification setContentImage:img]; [notification setContentImage:img];
} }
if (!hideReplyButton && [notification respondsToSelector:@selector(setHasReplyButton:)]) { if (!options.hideReplyButton
&& [notification respondsToSelector:@selector(setHasReplyButton:)]) {
[notification setHasReplyButton:YES]; [notification setHasReplyButton:YES];
} }
@ -419,8 +419,7 @@ void Manager::doShowNativeNotification(
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options) {
bool hideReplyButton) {
_private->showNotification( _private->showNotification(
peer, peer,
userpicView, userpicView,
@ -428,8 +427,7 @@ void Manager::doShowNativeNotification(
title, title,
subtitle, subtitle,
msg, msg,
hideNameAndPhoto, options);
hideReplyButton);
} }
void Manager::doClearAllFast() { void Manager::doClearAllFast() {

View file

@ -51,19 +51,11 @@ namespace Notifications {
#ifndef __MINGW32__ #ifndef __MINGW32__
namespace { namespace {
[[nodiscard]] std::wstring NotificationTemplate(QString id) { [[nodiscard]] std::wstring NotificationTemplate(
QString id,
Window::Notifications::Manager::DisplayOptions options) {
const auto wid = id.replace('&', "&amp;").toStdWString(); const auto wid = id.replace('&', "&amp;").toStdWString();
return LR"( const auto fastReply = LR"(
<toast launch="action=open&amp;)" + wid + LR"(">
<visual>
<binding template="ToastGeneric">
<image placement="appLogoOverride" hint-crop="circle" src=""/>
<text hint-maxLines="1"></text>
<text></text>
<text></text>
</binding>
</visual>
<actions>
<input id="fastReply" type="text" placeHolderContent=""/> <input id="fastReply" type="text" placeHolderContent=""/>
<action <action
content="Send" content="Send"
@ -71,18 +63,15 @@ namespace {
activationType="background" activationType="background"
imageUri="" imageUri=""
hint-inputId="fastReply"/> hint-inputId="fastReply"/>
)";
const auto markAsRead = LR"(
<action <action
content="" content=""
arguments="action=mark&amp;)" + wid + LR"(" arguments="action=mark&amp;)" + wid + LR"("
activationType="background"/> activationType="background"/>
</actions>
<audio silent="true"/>
</toast>
)"; )";
} const auto actions = (options.hideReplyButton ? L"" : fastReply)
+ (options.hideMarkAsRead ? L"" : markAsRead);
[[nodiscard]] std::wstring NotificationTemplateSmall(QString id) {
const auto wid = id.replace('&', "&amp;").toStdWString();
return LR"( return LR"(
<toast launch="action=open&amp;)" + wid + LR"("> <toast launch="action=open&amp;)" + wid + LR"(">
<visual> <visual>
@ -93,6 +82,9 @@ namespace {
<text></text> <text></text>
</binding> </binding>
</visual> </visual>
)" + (actions.empty()
? L""
: (L"<actions>" + actions + L"</actions>")) + LR"(
<audio silent="true"/> <audio silent="true"/>
</toast> </toast>
)"; )";
@ -160,11 +152,13 @@ void SetImageSrc(const XmlDocument &toastXml, const std::wstring &path) {
// Throws. // Throws.
void SetReplyIconSrc(const XmlDocument &toastXml, const std::wstring &path) { void SetReplyIconSrc(const XmlDocument &toastXml, const std::wstring &path) {
const auto nodeList = toastXml.GetElementsByTagName(L"action"); const auto nodeList = toastXml.GetElementsByTagName(L"action");
const auto attributes = nodeList.Item(0).Attributes(); const auto length = int(nodeList.Length());
return SetNodeValueString( for (auto i = 0; i != length; ++i) {
toastXml, const auto attributes = nodeList.Item(i).Attributes();
attributes.GetNamedItem(L"imageUri"), if (const auto uri = attributes.GetNamedItem(L"imageUri")) {
L"file:///" + path); return SetNodeValueString(toastXml, uri, L"file:///" + path);
}
}
} }
// Throws. // Throws.
@ -192,11 +186,16 @@ void SetMarkAsReadText(
const XmlDocument &toastXml, const XmlDocument &toastXml,
const std::wstring &text) { const std::wstring &text) {
const auto nodeList = toastXml.GetElementsByTagName(L"action"); const auto nodeList = toastXml.GetElementsByTagName(L"action");
const auto attributes = nodeList.Item(1).Attributes(); const auto length = int(nodeList.Length());
return SetNodeValueString( for (auto i = 0; i != length; ++i) {
toastXml, const auto attributes = nodeList.Item(i).Attributes();
attributes.GetNamedItem(L"content"), if (!attributes.GetNamedItem(L"imageUri")) {
text); return SetNodeValueString(
toastXml,
attributes.GetNamedItem(L"content"),
text);
}
}
} }
auto Checked = false; auto Checked = false;
@ -416,8 +415,7 @@ public:
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options);
bool hideReplyButton);
void clearAll(); void clearAll();
void clearFromHistory(not_null<History*> history); void clearFromHistory(not_null<History*> history);
void clearFromSession(not_null<Main::Session*> session); void clearFromSession(not_null<Main::Session*> session);
@ -439,8 +437,7 @@ private:
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options);
bool hideReplyButton);
[[nodiscard]] std::wstring ensureSendButtonIcon(); [[nodiscard]] std::wstring ensureSendButtonIcon();
Window::Notifications::CachedUserpics _cachedUserpics; Window::Notifications::CachedUserpics _cachedUserpics;
@ -591,8 +588,7 @@ bool Manager::Private::showNotification(
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options) {
bool hideReplyButton) {
if (!_notifier) { if (!_notifier) {
return false; return false;
} }
@ -605,8 +601,7 @@ bool Manager::Private::showNotification(
title, title,
subtitle, subtitle,
msg, msg,
hideNameAndPhoto, options);
hideReplyButton);
}).value_or(false); }).value_or(false);
} }
@ -626,8 +621,7 @@ bool Manager::Private::showNotificationInTryCatch(
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options) {
bool hideReplyButton) {
const auto withSubtitle = !subtitle.isEmpty(); const auto withSubtitle = !subtitle.isEmpty();
auto toastXml = XmlDocument(); auto toastXml = XmlDocument();
@ -646,9 +640,7 @@ bool Manager::Private::showNotificationInTryCatch(
const auto modern = Platform::IsWindows10OrGreater(); const auto modern = Platform::IsWindows10OrGreater();
if (modern) { if (modern) {
toastXml.LoadXml(hideReplyButton toastXml.LoadXml(NotificationTemplate(idString, options));
? NotificationTemplateSmall(idString)
: NotificationTemplate(idString));
} else { } else {
toastXml = ToastNotificationManager::GetTemplateContent( toastXml = ToastNotificationManager::GetTemplateContent(
(withSubtitle (withSubtitle
@ -658,7 +650,7 @@ bool Manager::Private::showNotificationInTryCatch(
SetAction(toastXml, idString); SetAction(toastXml, idString);
} }
const auto userpicKey = hideNameAndPhoto const auto userpicKey = options.hideNameAndPhoto
? InMemoryKey() ? InMemoryKey()
: peer->userpicUniqueKey(userpicView); : peer->userpicUniqueKey(userpicView);
const auto userpicPath = _cachedUserpics.get( const auto userpicPath = _cachedUserpics.get(
@ -667,11 +659,13 @@ bool Manager::Private::showNotificationInTryCatch(
userpicView); userpicView);
const auto userpicPathWide = QDir::toNativeSeparators( const auto userpicPathWide = QDir::toNativeSeparators(
userpicPath).toStdWString(); userpicPath).toStdWString();
if (modern && !hideReplyButton) { if (modern && !options.hideReplyButton) {
SetReplyIconSrc(toastXml, ensureSendButtonIcon()); SetReplyIconSrc(toastXml, ensureSendButtonIcon());
SetReplyPlaceholder( SetReplyPlaceholder(
toastXml, toastXml,
tr::lng_message_ph(tr::now).toStdWString()); tr::lng_message_ph(tr::now).toStdWString());
}
if (modern && !options.hideMarkAsRead) {
SetMarkAsReadText( SetMarkAsReadText(
toastXml, toastXml,
tr::lng_context_mark_read(tr::now).toStdWString()); tr::lng_context_mark_read(tr::now).toStdWString());
@ -814,8 +808,7 @@ void Manager::doShowNativeNotification(
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options) {
bool hideReplyButton) {
_private->showNotification( _private->showNotification(
peer, peer,
userpicView, userpicView,
@ -823,8 +816,7 @@ void Manager::doShowNativeNotification(
title, title,
subtitle, subtitle,
msg, msg,
hideNameAndPhoto, options);
hideReplyButton);
} }
void Manager::doClearAllFast() { void Manager::doClearAllFast() {

View file

@ -34,8 +34,7 @@ protected:
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options) override;
bool hideReplyButton) override;
void doClearAllFast() override; void doClearAllFast() override;
void doClearFromHistory(not_null<History*> history) override; void doClearFromHistory(not_null<History*> history) override;
void doClearFromSession(not_null<Main::Session*> session) override; void doClearFromSession(not_null<Main::Session*> session) override;

View file

@ -593,11 +593,13 @@ Manager::DisplayOptions Manager::getNotificationOptions(
|| (view > Core::Settings::NotifyView::ShowName); || (view > Core::Settings::NotifyView::ShowName);
result.hideMessageText = hideEverything result.hideMessageText = hideEverything
|| (view > Core::Settings::NotifyView::ShowPreview); || (view > Core::Settings::NotifyView::ShowPreview);
result.hideReplyButton = result.hideMessageText result.hideMarkAsRead = result.hideMessageText
|| !item || !item
|| ((item->out() || item->history()->peer->isSelf()) || ((item->out() || item->history()->peer->isSelf())
&& item->isFromScheduled()) && item->isFromScheduled());
result.hideReplyButton = result.hideMarkAsRead
|| !item->history()->peer->canWrite() || !item->history()->peer->canWrite()
|| item->history()->peer->isBroadcast()
|| (item->history()->peer->slowmodeSecondsLeft() > 0); || (item->history()->peer->slowmodeSecondsLeft() > 0);
return result; return result;
} }
@ -755,8 +757,7 @@ void NativeManager::doShowNotification(
scheduled ? WrapFromScheduled(fullTitle) : fullTitle, scheduled ? WrapFromScheduled(fullTitle) : fullTitle,
subtitle, subtitle,
text, text,
options.hideNameAndPhoto, options);
options.hideReplyButton);
} }
bool NativeManager::forceHideDetails() const { bool NativeManager::forceHideDetails() const {

View file

@ -199,6 +199,7 @@ public:
struct DisplayOptions { struct DisplayOptions {
bool hideNameAndPhoto = false; bool hideNameAndPhoto = false;
bool hideMessageText = false; bool hideMessageText = false;
bool hideMarkAsRead = false;
bool hideReplyButton = false; bool hideReplyButton = false;
}; };
[[nodiscard]] DisplayOptions getNotificationOptions( [[nodiscard]] DisplayOptions getNotificationOptions(
@ -289,8 +290,7 @@ protected:
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options) = 0;
bool hideReplyButton) = 0;
}; };
@ -310,8 +310,7 @@ protected:
const QString &title, const QString &title,
const QString &subtitle, const QString &subtitle,
const QString &msg, const QString &msg,
bool hideNameAndPhoto, DisplayOptions options) override {
bool hideReplyButton) override {
} }
void doClearAllFast() override { void doClearAllFast() override {
} }