From 01cb685d54ebf0f902e74fef75c836da46bf4ba5 Mon Sep 17 00:00:00 2001
From: Bart De Vries <bart@mogwai.be>
Date: Sat, 25 Jun 2022 15:02:25 +0200
Subject: [PATCH] Add option to mark custom amount of episodes as unplayed when
 adding new feed

FEATURE: 454553
---
 src/qml/Settings/GeneralSettingsPage.qml | 32 ++++++++++++++++++++++++
 src/settingsmanager.kcfg                 | 22 ++++++++++++++++
 src/updatefeedjob.cpp                    | 15 ++++++++++-
 src/updatefeedjob.h                      |  1 +
 4 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/src/qml/Settings/GeneralSettingsPage.qml b/src/qml/Settings/GeneralSettingsPage.qml
index 4237496a..ddef1fc6 100644
--- a/src/qml/Settings/GeneralSettingsPage.qml
+++ b/src/qml/Settings/GeneralSettingsPage.qml
@@ -109,6 +109,38 @@ Kirigami.ScrollablePage {
             onToggled: SettingsManager.resetPositionOnPlayed = checked
         }
 
+        Controls.RadioButton {
+            Kirigami.FormData.label: i18n("When adding new podcasts:")
+            checked: SettingsManager.markUnreadOnNewFeed === 0
+            text: i18n("Mark all episodes as played")
+            onToggled: SettingsManager.markUnreadOnNewFeed = 0
+        }
+
+        RowLayout {
+            Controls.RadioButton {
+                id: markCustomUnreadNumberButton
+                checked: SettingsManager.markUnreadOnNewFeed === 1
+                text: i18n("Mark most recent episodes as unplayed:")
+                onToggled: SettingsManager.markUnreadOnNewFeed = 1
+            }
+
+            Controls.SpinBox {
+                id: markCustomUnreadNumberSpinBox
+                enabled: markCustomUnreadNumberButton.checked
+                value: SettingsManager.markUnreadOnNewFeedCustomAmount
+                from: 0
+                to: 100
+
+                onValueModified: SettingsManager.markUnreadOnNewFeedCustomAmount = value
+            }
+        }
+
+        Controls.RadioButton {
+            checked: SettingsManager.markUnreadOnNewFeed === 2
+            text: i18n("Mark all episodes as unplayed")
+            onToggled: SettingsManager.markUnreadOnNewFeed = 2
+        }
+
         Kirigami.Heading {
             Kirigami.FormData.isSection: true
             text: i18n("Article")
diff --git a/src/settingsmanager.kcfg b/src/settingsmanager.kcfg
index 9fdcece0..91548c59 100644
--- a/src/settingsmanager.kcfg
+++ b/src/settingsmanager.kcfg
@@ -52,6 +52,28 @@
             <label>Reset play position when episode is marked as played</label>
             <default>true</default>
         </entry>
+        <entry name="markUnreadOnNewFeed" type="Enum">
+            <label>How many episodes to mark as unread when adding a new feed</label>
+            <choices>
+                <choice name="None">
+                    <label>None</label>
+                    <value>0</value>
+                </choice>
+                <choice name="Custom">
+                    <label>Custom</label>
+                    <value>1</value>
+                </choice>
+                <choice name="All">
+                    <label>All</label>
+                    <value>2</value>
+                </choice>
+            </choices>
+            <default>None</default>
+        </entry>
+        <entry name="markUnreadOnNewFeedCustomAmount" type="Int">
+            <label>Custom number of episodes to mark as unread/unplayed when adding new feed</label>
+            <default>1</default>
+        </entry>
         <entry name="toggleRemainingTime" type="Bool">
             <label>Whether the player shows remaining track time instead of total track time</label>
             <default>false</default>
diff --git a/src/updatefeedjob.cpp b/src/updatefeedjob.cpp
index e5c666db..2b89254c 100644
--- a/src/updatefeedjob.cpp
+++ b/src/updatefeedjob.cpp
@@ -84,6 +84,8 @@ void UpdateFeedJob::processFeed(Syndication::FeedPtr feed)
     if (m_isNewFeed)
         qCDebug(kastsFetcher) << "New feed" << feed->title();
 
+    m_markUnreadOnNewFeed = !(SettingsManager::self()->markUnreadOnNewFeed() == 2);
+
     // Retrieve "other" fields; this will include the "itunes" tags
     QMultiMap<QString, QDomElement> otherItems = feed->additionalProperties();
 
@@ -277,7 +279,7 @@ bool UpdateFeedJob::processEntry(Syndication::ItemPtr entry)
     entryDetails.updated = static_cast<int>(entry->dateUpdated());
     entryDetails.link = entry->link();
     entryDetails.hasEnclosure = (entry->enclosures().length() > 0);
-    entryDetails.read = m_isNewFeed; // if new feed, then mark all as read
+    entryDetails.read = m_isNewFeed ? m_markUnreadOnNewFeed : false; // if new feed, then check settings
     entryDetails.isNew = !m_isNewFeed; // if new feed, then mark none as new
 
     if (!entry->content().isEmpty())
@@ -592,6 +594,17 @@ void UpdateFeedJob::writeToDatabase()
         Database::execute(writeQuery);
     }
 
+    // set custom amount of episodes to unread/new if required
+    if (m_isNewFeed && (SettingsManager::self()->markUnreadOnNewFeed() == 1) && (SettingsManager::self()->markUnreadOnNewFeedCustomAmount() > 0)) {
+        writeQuery.prepare(QStringLiteral(
+            "UPDATE Entries SET read=:read, new=:new WHERE id in (SELECT id FROM Entries WHERE feed =:feed ORDER BY updated DESC LIMIT :recentUnread);"));
+        writeQuery.bindValue(QStringLiteral(":feed"), m_url);
+        writeQuery.bindValue(QStringLiteral(":read"), false);
+        writeQuery.bindValue(QStringLiteral(":new"), true);
+        writeQuery.bindValue(QStringLiteral(":recentUnread"), SettingsManager::self()->markUnreadOnNewFeedCustomAmount());
+        Database::execute(writeQuery);
+    }
+
     if (Database::commit(m_url)) {
         QStringList newIds, updateIds;
 
diff --git a/src/updatefeedjob.h b/src/updatefeedjob.h
index e7d134dd..640cd8be 100644
--- a/src/updatefeedjob.h
+++ b/src/updatefeedjob.h
@@ -98,6 +98,7 @@ private:
     QByteArray m_data;
 
     bool m_isNewFeed;
+    bool m_markUnreadOnNewFeed;
     QVector<EntryDetails> m_entries, m_newEntries, m_updateEntries;
     QVector<AuthorDetails> m_authors, m_newAuthors, m_updateAuthors;
     QVector<EnclosureDetails> m_enclosures, m_newEnclosures, m_updateEnclosures;