fix gmail attachment names encoding + other gmail stuff
This commit is contained in:
parent
abebbf7e56
commit
fb2c439b40
|
@ -6,6 +6,7 @@ Added:
|
|||
* macOS build is now built with macOS 11.
|
||||
* Linux build is now built with Ubuntu 20.04 which is now oldest supported Linux LTS distribution.
|
||||
* Reworked logic of determining which article states (read/unread/starred/unstarred) have changed when synchronizing states to remote feed servers. This concerns all synchronized plugins like Gmail, Greader, Feedly, etc. and show in theory lead to much better performance when you mark many articles as read or unread.
|
||||
* Couple of extra QoL enhancements for Gmail like proper encoding of attachment filenames, turned off displaying of "enclosures" as these are displayed in other way, etc.
|
||||
|
||||
Fixed:
|
||||
* Deadlock when fetching feeds in some corner situations is now resolved. (#910)
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
Enclosure::Enclosure(QString url, QString mime) : m_url(std::move(url)), m_mimeType(std::move(mime)) {}
|
||||
|
||||
QList<Enclosure> Enclosures::decodeEnclosuresFromString(const QString& enclosures_data) {
|
||||
QList<Enclosure> enclosures;
|
||||
auto enc = enclosures_data.split(ENCLOSURES_OUTER_SEPARATOR,
|
||||
#if QT_VERSION >= 0x050F00 // Qt >= 5.15.0
|
||||
Qt::SplitBehaviorFlags::SkipEmptyParts);
|
||||
|
@ -25,17 +24,20 @@ QList<Enclosure> Enclosures::decodeEnclosuresFromString(const QString& enclosure
|
|||
QString::SplitBehavior::SkipEmptyParts);
|
||||
#endif
|
||||
|
||||
QList<Enclosure> enclosures;
|
||||
enclosures.reserve(enc.size());
|
||||
|
||||
for (const QString& single_enclosure : qAsConst(enc)) {
|
||||
Enclosure enclosure;
|
||||
|
||||
if (single_enclosure.contains(ECNLOSURES_INNER_SEPARATOR)) {
|
||||
QStringList mime_url = single_enclosure.split(ECNLOSURES_INNER_SEPARATOR);
|
||||
|
||||
enclosure.m_mimeType = QByteArray::fromBase64(mime_url.at(0).toLocal8Bit());
|
||||
enclosure.m_url = QByteArray::fromBase64(mime_url.at(1).toLocal8Bit());
|
||||
enclosure.m_mimeType = QString::fromUtf8(QByteArray::fromBase64(mime_url.at(0).toLocal8Bit()));
|
||||
enclosure.m_url = QString::fromUtf8(QByteArray::fromBase64(mime_url.at(1).toLocal8Bit()));
|
||||
}
|
||||
else {
|
||||
enclosure.m_url = QByteArray::fromBase64(single_enclosure.toLocal8Bit());
|
||||
enclosure.m_url = QString::fromUtf8(QByteArray::fromBase64(single_enclosure.toLocal8Bit()));
|
||||
}
|
||||
|
||||
enclosures.append(enclosure);
|
||||
|
@ -49,11 +51,11 @@ QString Enclosures::encodeEnclosuresToString(const QList<Enclosure>& enclosures)
|
|||
|
||||
for (const Enclosure& enclosure : enclosures) {
|
||||
if (enclosure.m_mimeType.isEmpty()) {
|
||||
enclosures_str.append(enclosure.m_url.toLocal8Bit().toBase64());
|
||||
enclosures_str.append(enclosure.m_url.toUtf8().toBase64());
|
||||
}
|
||||
else {
|
||||
enclosures_str.append(QString(enclosure.m_mimeType.toLocal8Bit().toBase64()) + ECNLOSURES_INNER_SEPARATOR +
|
||||
enclosure.m_url.toLocal8Bit().toBase64());
|
||||
enclosures_str.append(QString(enclosure.m_mimeType.toUtf8().toBase64()) + ECNLOSURES_INNER_SEPARATOR +
|
||||
enclosure.m_url.toUtf8().toBase64());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<item>
|
||||
<widget class="QTabWidget" name="m_tabFeedsMessages">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>2</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="m_tabFeeds">
|
||||
<attribute name="title">
|
||||
|
@ -300,7 +300,7 @@
|
|||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="m_cbShowEnclosuresDirectly">
|
||||
<property name="text">
|
||||
<string>Display attached pictures directly in article</string>
|
||||
<string>Display attachments directly in article</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -88,6 +88,8 @@ QVariant TextBrowserViewer::loadOneResource(int type, const QUrl& name) {
|
|||
|
||||
PreparedHtml TextBrowserViewer::prepareHtmlForMessage(const QList<Message>& messages, RootItem* selected_item) const {
|
||||
PreparedHtml html;
|
||||
bool acc_displays_enclosures =
|
||||
selected_item == nullptr || selected_item->getParentServiceRoot()->displaysEnclosures();
|
||||
|
||||
for (const Message& message : messages) {
|
||||
bool is_plain = !TextFactory::couldBeHtml(message.m_contents);
|
||||
|
@ -104,14 +106,17 @@ PreparedHtml TextBrowserViewer::prepareHtmlForMessage(const QList<Message>& mess
|
|||
html.m_html += QSL("<div>");
|
||||
|
||||
// Add links to enclosures.
|
||||
for (const Enclosure& enc : message.m_enclosures) {
|
||||
html.m_html += QSL("[%2] <a href=\"%1\">%1</a><br/>").arg(enc.m_url, enc.m_mimeType);
|
||||
if (acc_displays_enclosures) {
|
||||
for (const Enclosure& enc : message.m_enclosures) {
|
||||
html.m_html += QSL("[%2] <a href=\"%1\">%1</a><br/>").arg(enc.m_url, enc.m_mimeType);
|
||||
}
|
||||
}
|
||||
|
||||
// Display enclosures which are pictures if user has it enabled.
|
||||
auto first_enc_break_added = false;
|
||||
|
||||
if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::DisplayEnclosuresInMessage)).toBool()) {
|
||||
if (acc_displays_enclosures &&
|
||||
qApp->settings()->value(GROUP(Messages), SETTING(Messages::DisplayEnclosuresInMessage)).toBool()) {
|
||||
for (const Enclosure& enc : message.m_enclosures) {
|
||||
if (enc.m_mimeType.startsWith(QSL("image/"))) {
|
||||
if (!first_enc_break_added) {
|
||||
|
|
|
@ -230,18 +230,22 @@ PreparedHtml SkinFactory::generateHtmlOfArticles(const QList<Message>& messages,
|
|||
QString enclosure_images;
|
||||
bool is_plain = !TextFactory::couldBeHtml(message.m_contents);
|
||||
|
||||
for (const Enclosure& enclosure : message.m_enclosures) {
|
||||
QString enc_url = QUrl::fromPercentEncoding(enclosure.m_url.toUtf8());
|
||||
if (root == nullptr || root->getParentServiceRoot()->displaysEnclosures()) {
|
||||
for (const Enclosure& enclosure : message.m_enclosures) {
|
||||
QString enc_url = QUrl::fromPercentEncoding(enclosure.m_url.toUtf8());
|
||||
|
||||
enclosures += skin.m_enclosureMarkup.arg(enc_url, QSL("🧷"), enclosure.m_mimeType);
|
||||
enclosures += skin.m_enclosureMarkup.arg(enc_url, QSL("🧷"), enclosure.m_mimeType);
|
||||
|
||||
if (enclosure.m_mimeType.startsWith(QSL("image/")) &&
|
||||
qApp->settings()->value(GROUP(Messages), SETTING(Messages::DisplayEnclosuresInMessage)).toBool()) {
|
||||
// Add thumbnail image.
|
||||
enclosure_images +=
|
||||
skin.m_enclosureImageMarkup.arg(enclosure.m_url,
|
||||
enclosure.m_mimeType,
|
||||
forced_img_size <= 0 ? QString() : QString::number(forced_img_size));
|
||||
if (qApp->settings()->value(GROUP(Messages), SETTING(Messages::DisplayEnclosuresInMessage)).toBool()) {
|
||||
if (enclosure.m_mimeType.startsWith(QSL("image/")) &&
|
||||
qApp->settings()->value(GROUP(Messages), SETTING(Messages::DisplayEnclosuresInMessage)).toBool()) {
|
||||
// Add thumbnail image.
|
||||
enclosure_images +=
|
||||
skin.m_enclosureImageMarkup.arg(enclosure.m_url,
|
||||
enclosure.m_mimeType,
|
||||
forced_img_size <= 0 ? QString() : QString::number(forced_img_size));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -323,6 +323,10 @@ bool ServiceRoot::wantsBaggedIdsOfExistingMessages() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ServiceRoot::displaysEnclosures() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ServiceRoot::aboutToBeginFeedFetching(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QHash<BagOfMessages, QStringList>>& stated_messages,
|
||||
const QHash<QString, QStringList>& tagged_messages) {
|
||||
|
|
|
@ -67,6 +67,7 @@ class ServiceRoot : public RootItem {
|
|||
virtual QVariantHash customDatabaseData() const;
|
||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||
virtual bool wantsBaggedIdsOfExistingMessages() const;
|
||||
virtual bool displaysEnclosures() const;
|
||||
virtual void aboutToBeginFeedFetching(const QList<Feed*>& feeds,
|
||||
const QHash<QString, QHash<ServiceRoot::BagOfMessages, QStringList>>&
|
||||
stated_messages,
|
||||
|
|
|
@ -547,6 +547,10 @@ bool GmailNetworkFactory::fillFullMessage(Message& msg, const QJsonObject& json,
|
|||
|
||||
msg.m_author = sanitizeEmailAuthor(headers[QSL("From")]);
|
||||
msg.m_title = headers[QSL("Subject")];
|
||||
|
||||
// NOTE: Provide link to web-based GUI for the message.
|
||||
msg.m_url = QSL("https://mail.google.com/mail/u/0/#all/%1").arg(msg.m_customId);
|
||||
|
||||
msg.m_createdFromFeed = true;
|
||||
msg.m_created = TextFactory::parseDateTime(headers[QSL("Date")]);
|
||||
|
||||
|
|
|
@ -245,3 +245,7 @@ void GmailServiceRoot::saveAllCachedData(bool ignore_errors) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GmailServiceRoot::displaysEnclosures() const {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
class GmailNetworkFactory;
|
||||
|
||||
class GmailServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit GmailServiceRoot(RootItem* parent = nullptr);
|
||||
|
@ -31,6 +31,7 @@ class GmailServiceRoot : public ServiceRoot, public CacheForServiceRoot {
|
|||
virtual QString code() const;
|
||||
virtual QString additionalTooltip() const;
|
||||
virtual void saveAllCachedData(bool ignore_errors);
|
||||
virtual bool displaysEnclosures() const;
|
||||
virtual QVariantHash customDatabaseData() const;
|
||||
virtual void setCustomDatabaseData(const QVariantHash& data);
|
||||
virtual QList<Message> obtainNewMessages(Feed* feed,
|
||||
|
|
Loading…
Reference in New Issue