diff --git a/src/librssguard/miscellaneous/skinfactory.cpp b/src/librssguard/miscellaneous/skinfactory.cpp index 7850b2f25..4876a111c 100644 --- a/src/librssguard/miscellaneous/skinfactory.cpp +++ b/src/librssguard/miscellaneous/skinfactory.cpp @@ -56,50 +56,51 @@ bool SkinFactory::isStyleGoodForAlternativeStylePalette(const QString& style_nam // NOTE: Taken from "QPlatformThemePrivate" Qt class. // This is here because in Qt 6.5.0, they hardcoded // DARK palette if user has enabled "dark mode" in OS. -QPalette qt_fusionPalette(bool darkAppearance) { - const QColor windowText = darkAppearance ? QColor(240, 240, 240) : Qt::black; - const QColor backGround = darkAppearance ? QColor(50, 50, 50) : QColor(239, 239, 239); - const QColor light = backGround.lighter(150); - const QColor mid = (backGround.darker(130)); - const QColor midLight = mid.lighter(110); - const QColor base = darkAppearance ? backGround.darker(140) : Qt::white; - const QColor disabledBase(backGround); - const QColor dark = backGround.darker(150); - const QColor darkDisabled = QColor(209, 209, 209).darker(110); - const QColor text = darkAppearance ? windowText : Qt::black; +QPalette qt_fusionPalette(bool dark_appearance) { + const QColor window_text = dark_appearance ? QColor(240, 240, 240) : Qt::black; + const QColor background = dark_appearance ? QColor(50, 50, 50) : QColor(239, 239, 239); + const QColor light = background.lighter(150); + const QColor mid = (background.darker(130)); + const QColor midlight = mid.lighter(110); + const QColor base = dark_appearance ? background.darker(140) : Qt::white; + const QColor disabled_base(background); + const QColor dark = background.darker(150); + const QColor disabled_dark = QColor(209, 209, 209).darker(110); + const QColor text = dark_appearance ? window_text : Qt::black; const QColor highlight = QColor(48, 140, 198); - const QColor hightlightedText = darkAppearance ? windowText : Qt::white; - const QColor disabledText = darkAppearance ? QColor(130, 130, 130) : QColor(190, 190, 190); - const QColor button = backGround; + const QColor hightlighted_text = dark_appearance ? window_text : Qt::white; + const QColor disabled_text = dark_appearance ? QColor(130, 130, 130) : QColor(190, 190, 190); + const QColor button = background; const QColor shadow = dark.darker(135); - const QColor disabledShadow = shadow.lighter(150); + const QColor disabled_shadow = shadow.lighter(150); + QColor placeholder = text; placeholder.setAlpha(128); - QPalette fusionPalette(windowText, backGround, light, dark, mid, text, base); - fusionPalette.setBrush(QPalette::Midlight, midLight); - fusionPalette.setBrush(QPalette::Button, button); - fusionPalette.setBrush(QPalette::Shadow, shadow); - fusionPalette.setBrush(QPalette::HighlightedText, hightlightedText); + QPalette fusion_palette(window_text, background, light, dark, mid, text, base); + fusion_palette.setBrush(QPalette::Midlight, midlight); + fusion_palette.setBrush(QPalette::Button, button); + fusion_palette.setBrush(QPalette::Shadow, shadow); + fusion_palette.setBrush(QPalette::HighlightedText, hightlighted_text); - fusionPalette.setBrush(QPalette::Disabled, QPalette::Text, disabledText); - fusionPalette.setBrush(QPalette::Disabled, QPalette::WindowText, disabledText); - fusionPalette.setBrush(QPalette::Disabled, QPalette::ButtonText, disabledText); - fusionPalette.setBrush(QPalette::Disabled, QPalette::Base, disabledBase); - fusionPalette.setBrush(QPalette::Disabled, QPalette::Dark, darkDisabled); - fusionPalette.setBrush(QPalette::Disabled, QPalette::Shadow, disabledShadow); + fusion_palette.setBrush(QPalette::Disabled, QPalette::Text, disabled_text); + fusion_palette.setBrush(QPalette::Disabled, QPalette::WindowText, disabled_text); + fusion_palette.setBrush(QPalette::Disabled, QPalette::ButtonText, disabled_text); + fusion_palette.setBrush(QPalette::Disabled, QPalette::Base, disabled_base); + fusion_palette.setBrush(QPalette::Disabled, QPalette::Dark, disabled_dark); + fusion_palette.setBrush(QPalette::Disabled, QPalette::Shadow, disabled_shadow); - fusionPalette.setBrush(QPalette::Active, QPalette::Highlight, highlight); - fusionPalette.setBrush(QPalette::Inactive, QPalette::Highlight, highlight); - fusionPalette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 145, 145)); + fusion_palette.setBrush(QPalette::Active, QPalette::Highlight, highlight); + fusion_palette.setBrush(QPalette::Inactive, QPalette::Highlight, highlight); + fusion_palette.setBrush(QPalette::Disabled, QPalette::Highlight, QColor(145, 145, 145)); - fusionPalette.setBrush(QPalette::PlaceholderText, placeholder); + fusion_palette.setBrush(QPalette::PlaceholderText, placeholder); - if (darkAppearance) { - fusionPalette.setBrush(QPalette::Link, highlight); + if (dark_appearance) { + fusion_palette.setBrush(QPalette::Link, highlight); } - return fusionPalette; + return fusion_palette; } void SkinFactory::loadSkinFromData(const Skin& skin) { @@ -181,10 +182,13 @@ void SkinFactory::loadSkinFromData(const Skin& skin) { // NOTE: Very hacky way of avoiding automatic "dark mode" // palettes in some styles. Also in light mode, // colors are now derived from system. + // + // NOTE: At this point disabled as it effectively disables automatic "dark + // mode when it is enabled in OS settings. #if QT_VERSION >= 0x060500 // Qt >= 6.5.0 - else /* if (qApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark) */ { - qApp->setPalette(qt_fusionPalette(false)); - } + // else /* if (qApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark) */ { + // qApp->setPalette(qt_fusionPalette(false)); + // } #endif if (!skin.m_rawData.isEmpty()) { diff --git a/src/librssguard/services/gmail/gmailnetworkfactory.cpp b/src/librssguard/services/gmail/gmailnetworkfactory.cpp index ad7ce6b85..b872a76b4 100644 --- a/src/librssguard/services/gmail/gmailnetworkfactory.cpp +++ b/src/librssguard/services/gmail/gmailnetworkfactory.cpp @@ -308,9 +308,10 @@ QList GmailNetworkFactory::messages(const QString& stream_id, return messages; } -QNetworkReply::NetworkError GmailNetworkFactory::markMessagesRead(RootItem::ReadStatus status, - const QStringList& custom_ids, - const QNetworkProxy& custom_proxy) { +QNetworkReply::NetworkError GmailNetworkFactory::batchModify(const QString& label, + const QStringList& custom_ids, + bool assign, + const QNetworkProxy& custom_proxy) { QString bearer = m_oauth2->bearer().toLocal8Bit(); if (bearer.isEmpty()) { @@ -328,13 +329,11 @@ QNetworkReply::NetworkError GmailNetworkFactory::markMessagesRead(RootItem::Read QJsonObject param_obj; QJsonArray param_add, param_remove; - if (status == RootItem::ReadStatus::Read) { - // We remove label UNREAD. - param_remove.append(GMAIL_SYSTEM_LABEL_UNREAD); + if (assign) { + param_add.append(label); } else { - // We add label UNREAD. - param_add.append(GMAIL_SYSTEM_LABEL_UNREAD); + param_remove.append(label); } param_obj[QSL("addLabelIds")] = param_add; @@ -368,64 +367,19 @@ QNetworkReply::NetworkError GmailNetworkFactory::markMessagesRead(RootItem::Read return QNetworkReply::NetworkError::NoError; } +QNetworkReply::NetworkError GmailNetworkFactory::markMessagesRead(RootItem::ReadStatus status, + const QStringList& custom_ids, + const QNetworkProxy& custom_proxy) { + return batchModify(QSL(GMAIL_SYSTEM_LABEL_UNREAD), custom_ids, status != RootItem::ReadStatus::Read, custom_proxy); +} + QNetworkReply::NetworkError GmailNetworkFactory::markMessagesStarred(RootItem::Importance importance, const QStringList& custom_ids, const QNetworkProxy& custom_proxy) { - QString bearer = m_oauth2->bearer().toLocal8Bit(); - - if (bearer.isEmpty()) { - return QNetworkReply::NetworkError::AuthenticationRequiredError; - } - - QList> headers; - - headers.append(QPair(QSL(HTTP_HEADERS_AUTHORIZATION).toLocal8Bit(), - m_oauth2->bearer().toLocal8Bit())); - headers.append(QPair(QSL(HTTP_HEADERS_CONTENT_TYPE).toLocal8Bit(), - QSL(GMAIL_CONTENT_TYPE_JSON).toLocal8Bit())); - - int timeout = qApp->settings()->value(GROUP(Feeds), SETTING(Feeds::UpdateTimeout)).toInt(); - QJsonObject param_obj; - QJsonArray param_add, param_remove; - - if (importance == RootItem::Importance::Important) { - // We add label STARRED. - param_add.append(GMAIL_SYSTEM_LABEL_STARRED); - } - else { - // We remove label STARRED. - param_remove.append(GMAIL_SYSTEM_LABEL_STARRED); - } - - param_obj[QSL("addLabelIds")] = param_add; - param_obj[QSL("removeLabelIds")] = param_remove; - - // We need to operate within allowed batches. - for (int i = 0; i < custom_ids.size(); i += GMAIL_MAX_BATCH_SIZE) { - auto batch = custom_ids.mid(i, GMAIL_MAX_BATCH_SIZE); - - param_obj[QSL("ids")] = QJsonArray::fromStringList(batch); - - QJsonDocument param_doc(param_obj); - QByteArray output; - auto result = NetworkFactory::performNetworkOperation(QSL(GMAIL_API_BATCH_UPD_LABELS), - timeout, - param_doc.toJson(QJsonDocument::JsonFormat::Compact), - output, - QNetworkAccessManager::Operation::PostOperation, - headers, - false, - {}, - {}, - custom_proxy) - .m_networkError; - - if (result != QNetworkReply::NetworkError::NoError) { - return result; - } - } - - return QNetworkReply::NetworkError::NoError; + return batchModify(QSL(GMAIL_SYSTEM_LABEL_STARRED), + custom_ids, + importance == RootItem::Importance::Important, + custom_proxy); } QStringList GmailNetworkFactory::list(const QString& stream_id, diff --git a/src/librssguard/services/gmail/gmailnetworkfactory.h b/src/librssguard/services/gmail/gmailnetworkfactory.h index 9149d4e06..58bd8370c 100644 --- a/src/librssguard/services/gmail/gmailnetworkfactory.h +++ b/src/librssguard/services/gmail/gmailnetworkfactory.h @@ -50,12 +50,10 @@ class GmailNetworkFactory : public QObject { const QHash& stated_messages, Feed::Status& error, const QNetworkProxy& custom_proxy); - QNetworkReply::NetworkError markMessagesRead(RootItem::ReadStatus status, - const QStringList& custom_ids, - const QNetworkProxy& custom_proxy); - QNetworkReply::NetworkError markMessagesStarred(RootItem::Importance importance, - const QStringList& custom_ids, - const QNetworkProxy& custom_proxy); + QNetworkReply::NetworkError batchModify(const QString& label, + const QStringList& custom_ids, + bool assign, + const QNetworkProxy& custom_proxy); QStringList list(const QString& stream_id, const QStringList& label_ids, int max_results, @@ -64,6 +62,14 @@ class GmailNetworkFactory : public QObject { const QNetworkProxy& custom_proxy); QVariantHash getProfile(const QNetworkProxy& custom_proxy); + // Top-level methods. + QNetworkReply::NetworkError markMessagesRead(RootItem::ReadStatus status, + const QStringList& custom_ids, + const QNetworkProxy& custom_proxy); + QNetworkReply::NetworkError markMessagesStarred(RootItem::Importance importance, + const QStringList& custom_ids, + const QNetworkProxy& custom_proxy); + private slots: void onTokensError(const QString& error, const QString& error_description); void onAuthFailed(); diff --git a/src/librssguard/services/gmail/gmailserviceroot.cpp b/src/librssguard/services/gmail/gmailserviceroot.cpp index 1f41e946a..ed298876f 100644 --- a/src/librssguard/services/gmail/gmailserviceroot.cpp +++ b/src/librssguard/services/gmail/gmailserviceroot.cpp @@ -250,6 +250,44 @@ void GmailServiceRoot::saveAllCachedData(bool ignore_errors) { } } } + + QMapIterator k(msg_cache.m_cachedLabelAssignments); + + // Assign label for these messages. + while (k.hasNext()) { + k.next(); + auto label_custom_id = k.key(); + QStringList messages = k.value(); + + if (!messages.isEmpty()) { + auto res = network()->batchModify(label_custom_id, messages, true, networkProxy()); + + if (res != QNetworkReply::NetworkError::NoError) { + qCriticalNN << LOGSEC_FEEDLY << "Failed to synchronize tag assignments with error:" << QUOTE_W_SPACE(res); + + addLabelsAssignmentsToCache(messages, label_custom_id, true); + } + } + } + + QMapIterator l(msg_cache.m_cachedLabelDeassignments); + + // Remove label from these messages. + while (l.hasNext()) { + l.next(); + auto label_custom_id = l.key(); + QStringList messages = l.value(); + + if (!messages.isEmpty()) { + auto res = network()->batchModify(label_custom_id, messages, false, networkProxy()); + + if (res != QNetworkReply::NetworkError::NoError) { + qCriticalNN << LOGSEC_FEEDLY << "Failed to synchronize tag deassignments with error:" << QUOTE_W_SPACE(res); + + addLabelsAssignmentsToCache(messages, label_custom_id, false); + } + } + } } bool GmailServiceRoot::displaysEnclosures() const {