This implements the gpodder API from scratch. It turned out that
libmygpo-qt has several critical bugs, and there's no response to pull
requests upstream. So using that library was not an option.
The implementation into kasts consists of the following:
- Can sync with gpodder.net or with a nextcloud server that has the
nextcloud-gpodder app installed. (This app is mostly API compatible
with gpodder.)
- Passwords are stored using qtkeychain. If the keychain is
unavailable it will fallback to file.
- It syncs podcast subscriptions and episode play positions, including
marking episodes as played. Episodes that have a non-zero play
position will be added to the queue automatically.
- It will check for a metered connection before syncing. This is
coupled to the allowMeteredFeedUpdates setting.
- Full synchronization can be performed either manually (from the
settings page) or through automatic triggers: on startup and/or on
feed refresh.
- There is an additional possibility to trigger quick upload-only syncs
to make sure that the local changes are immediately uploaded to the
server (if the connection allows). This will trigger when
subscriptions are added or removed, when the pause/play button is
toggled or an episode is marked as played.
- This implements a few safeguards to avoid having multiple feed URLS
pointing to the same underlying feed (e.g. http vs https). This
solves part of #17
Solves #13
FolderDialog has issues retrieving the selected folder if that folder
has been selected through xdg-desktop-portal (i.e. flatpaks). Reverting
to FileDialog from QtQuick.Dialogs.
BUG: 443956
The fetch-on-startup would only happen if the metered state was
explicitly set to "No". Hence, when the state is "Unknown" (which will
happen in most cases) no fetching would be done on startup.
The new logic will check for the metered state not being equal to "Yes".
The feed update routine which is now spread over several methods
in Fetcher, is now put into a self-contained KJob. This will allow
to re-use this job later on in e.g. gpodder sync, where it's
required to update feeds before syncing episode statuses.
This also makes the feed update abortable.
Lastly, but most importantly, the feed update procedure has been
optimized to minimize database transactions, resulting in a dramatic
speed-up. This is especially true for importing new feeds, which
will now be at least 5x faster on slow hardware.
gettext complained that there's another string with the same text but
not plural and that is bad, so add a dummy context to make gettext happy
xgettext: warning: msgid 'Remove Podcast' is used without plural and with plural.
./qml/FeedListDelegate.qml:279: Here is the occurrence without plural.
./qml/FeedListPage.qml:249: Here is the occurrence with plural.
Workaround: If the msgid is a sentence, change the wording of the sentence; otherwise, use contexts for disambiguation.
xgettext: warning: msgid 'Delete Download' is used without plural and with plural.
./qml/GenericEntryDelegate.qml:294: Here is the occurrence without plural.
./qml/GenericEntryListView.qml:207: Here is the occurrence with plural.
Workaround: If the msgid is a sentence, change the wording of the sentence; otherwise, use contexts for disambiguation.
This adds "select all", "deselect all" to the page contextual actions
and adds "show podcast info" to the OverlayPage opened by clicking on
the overflow menu button on the cards.
This also adds correct use of plurals for the actions if more than one
item has been selected.
Context properties always takes in a QVariant, which means that
whenever you access the property it is re-evaluated because in
between each access the property may be changed as
setContextProperty() can be used at any moment in time.
The feeds will be sorted by (1) descending number of unread/unplayed
entries and (2) alphabetically by name. The current item and current
selection are maintained after re-sorting when the number of unread
entries has changed.