aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fietsboek/locale/de/LC_MESSAGES/messages.mobin14524 -> 14714 bytes
-rw-r--r--fietsboek/locale/de/LC_MESSAGES/messages.po156
-rw-r--r--fietsboek/locale/en/LC_MESSAGES/messages.mobin13551 -> 13738 bytes
-rw-r--r--fietsboek/locale/en/LC_MESSAGES/messages.po156
-rw-r--r--fietsboek/locale/fietslog.pot156
-rw-r--r--fietsboek/templates/browse.jinja211
-rw-r--r--fietsboek/views/browse.py38
7 files changed, 300 insertions, 217 deletions
diff --git a/fietsboek/locale/de/LC_MESSAGES/messages.mo b/fietsboek/locale/de/LC_MESSAGES/messages.mo
index 1a44e6b..e6dd1c6 100644
--- a/fietsboek/locale/de/LC_MESSAGES/messages.mo
+++ b/fietsboek/locale/de/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/fietsboek/locale/de/LC_MESSAGES/messages.po b/fietsboek/locale/de/LC_MESSAGES/messages.po
index be0aca1..b34e849 100644
--- a/fietsboek/locale/de/LC_MESSAGES/messages.po
+++ b/fietsboek/locale/de/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2023-07-22 14:31+0200\n"
+"POT-Creation-Date: 2023-08-17 22:51+0200\n"
"PO-Revision-Date: 2022-07-02 17:35+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: de\n"
@@ -37,35 +37,35 @@ msgstr "Passwörter stimmen nicht überein"
msgid "password_constraint.length"
msgstr "Passwort zu kurz"
-#: fietsboek/models/track.py:589
+#: fietsboek/models/track.py:602
msgid "tooltip.table.length"
msgstr "Länge"
-#: fietsboek/models/track.py:590
+#: fietsboek/models/track.py:603
msgid "tooltip.table.people"
msgstr "# Personen"
-#: fietsboek/models/track.py:591
+#: fietsboek/models/track.py:604
msgid "tooltip.table.uphill"
msgstr "Bergauf"
-#: fietsboek/models/track.py:592
+#: fietsboek/models/track.py:605
msgid "tooltip.table.downhill"
msgstr "Bergab"
-#: fietsboek/models/track.py:593
+#: fietsboek/models/track.py:606
msgid "tooltip.table.moving_time"
msgstr "Fahrzeit"
-#: fietsboek/models/track.py:594
+#: fietsboek/models/track.py:607
msgid "tooltip.table.stopped_time"
msgstr "Haltezeit"
-#: fietsboek/models/track.py:596
+#: fietsboek/models/track.py:609
msgid "tooltip.table.max_speed"
msgstr "Maximalgeschwindigkeit"
-#: fietsboek/models/track.py:600
+#: fietsboek/models/track.py:613
msgid "tooltip.table.avg_speed"
msgstr "Durchschnittsgeschwindigkeit"
@@ -137,109 +137,121 @@ msgstr "Aufnahme (natürlich)"
msgid "page.browse.filter.type.synthetic"
msgstr "Vorlage (synthetisch)"
-#: fietsboek/templates/browse.jinja2:86
+#: fietsboek/templates/browse.jinja2:82
+msgid "page.browse.filter.favourite.all"
+msgstr "Alle Strecken"
+
+#: fietsboek/templates/browse.jinja2:83
+msgid "page.browse.filter.favourite.yes"
+msgstr "Nur Favoriten"
+
+#: fietsboek/templates/browse.jinja2:84
+msgid "page.browse.filter.favourite.no"
+msgstr "Keine Favoriten"
+
+#: fietsboek/templates/browse.jinja2:97
msgid "page.browse.filter.my_tracks.only"
msgstr "Zeige nur eigene Strecken"
-#: fietsboek/templates/browse.jinja2:87
+#: fietsboek/templates/browse.jinja2:98
msgid "page.browse.filter.friends_tracks_only"
msgstr "Zeige nur Strecken von Freunden"
-#: fietsboek/templates/browse.jinja2:88
+#: fietsboek/templates/browse.jinja2:99
msgid "page.browse.filter.me_tagged_only"
msgstr "Zeige nur Strecken, in denen ich markiert bin"
-#: fietsboek/templates/browse.jinja2:98
+#: fietsboek/templates/browse.jinja2:109
msgid "page.browse.filters.apply"
msgstr "Filter anwenden"
-#: fietsboek/templates/browse.jinja2:102
+#: fietsboek/templates/browse.jinja2:113
msgid "page.browse.filters.clear_all"
msgstr "Filter zurücksetzen"
-#: fietsboek/templates/browse.jinja2:105
+#: fietsboek/templates/browse.jinja2:116
msgid "page.browse.filters.expand_advanced"
msgstr "Erweitert"
-#: fietsboek/templates/browse.jinja2:110 fietsboek/templates/browse.jinja2:111
+#: fietsboek/templates/browse.jinja2:121 fietsboek/templates/browse.jinja2:122
msgid "page.browse.sort.date"
msgstr "Nach Datum sortieren"
-#: fietsboek/templates/browse.jinja2:112 fietsboek/templates/browse.jinja2:113
+#: fietsboek/templates/browse.jinja2:123 fietsboek/templates/browse.jinja2:124
msgid "page.browse.sort.length"
msgstr "Nach Länge sortieren"
-#: fietsboek/templates/browse.jinja2:114 fietsboek/templates/browse.jinja2:115
+#: fietsboek/templates/browse.jinja2:125 fietsboek/templates/browse.jinja2:126
msgid "page.browse.sort.duration"
msgstr "Nach Dauer sortieren"
-#: fietsboek/templates/browse.jinja2:132
+#: fietsboek/templates/browse.jinja2:148
msgid "page.browse.organic_tooltip"
msgstr "Dies ist eine Aufnahme einer Strecke"
-#: fietsboek/templates/browse.jinja2:134
+#: fietsboek/templates/browse.jinja2:150
msgid "page.browse.synthetic_tooltip"
msgstr "Dies ist eine geplante Strecke"
-#: fietsboek/templates/browse.jinja2:142 fietsboek/templates/details.jinja2:90
+#: fietsboek/templates/browse.jinja2:158 fietsboek/templates/details.jinja2:103
#: fietsboek/templates/profile.jinja2:15
msgid "page.details.date"
msgstr "Datum"
-#: fietsboek/templates/browse.jinja2:144 fietsboek/templates/details.jinja2:104
+#: fietsboek/templates/browse.jinja2:160 fietsboek/templates/details.jinja2:117
#: fietsboek/templates/profile.jinja2:17
msgid "page.details.length"
msgstr "Länge"
-#: fietsboek/templates/browse.jinja2:149 fietsboek/templates/details.jinja2:95
+#: fietsboek/templates/browse.jinja2:165 fietsboek/templates/details.jinja2:108
#: fietsboek/templates/profile.jinja2:21
msgid "page.details.start_time"
msgstr "Startzeit"
-#: fietsboek/templates/browse.jinja2:151 fietsboek/templates/details.jinja2:99
+#: fietsboek/templates/browse.jinja2:167 fietsboek/templates/details.jinja2:112
#: fietsboek/templates/profile.jinja2:23
msgid "page.details.end_time"
msgstr "Endzeit"
-#: fietsboek/templates/browse.jinja2:156 fietsboek/templates/details.jinja2:108
+#: fietsboek/templates/browse.jinja2:172 fietsboek/templates/details.jinja2:121
#: fietsboek/templates/profile.jinja2:27
msgid "page.details.uphill"
msgstr "Bergauf"
-#: fietsboek/templates/browse.jinja2:158 fietsboek/templates/details.jinja2:112
+#: fietsboek/templates/browse.jinja2:174 fietsboek/templates/details.jinja2:125
#: fietsboek/templates/profile.jinja2:29
msgid "page.details.downhill"
msgstr "Bergab"
-#: fietsboek/templates/browse.jinja2:163 fietsboek/templates/details.jinja2:117
+#: fietsboek/templates/browse.jinja2:179 fietsboek/templates/details.jinja2:130
#: fietsboek/templates/profile.jinja2:33
msgid "page.details.moving_time"
msgstr "Fahrzeit"
-#: fietsboek/templates/browse.jinja2:165 fietsboek/templates/details.jinja2:121
+#: fietsboek/templates/browse.jinja2:181 fietsboek/templates/details.jinja2:134
#: fietsboek/templates/profile.jinja2:35
msgid "page.details.stopped_time"
msgstr "Haltezeit"
-#: fietsboek/templates/browse.jinja2:169 fietsboek/templates/details.jinja2:125
+#: fietsboek/templates/browse.jinja2:185 fietsboek/templates/details.jinja2:138
#: fietsboek/templates/profile.jinja2:39
msgid "page.details.max_speed"
msgstr "maximale Geschwindigkeit"
-#: fietsboek/templates/browse.jinja2:171 fietsboek/templates/details.jinja2:129
+#: fietsboek/templates/browse.jinja2:187 fietsboek/templates/details.jinja2:142
#: fietsboek/templates/profile.jinja2:41
msgid "page.details.avg_speed"
msgstr "durchschnittliche Geschwindigkeit"
-#: fietsboek/templates/browse.jinja2:189
+#: fietsboek/templates/browse.jinja2:205
msgid "page.browse.download_multiple"
msgstr "ausgewählte Herunterladen"
-#: fietsboek/templates/browse.jinja2:191
+#: fietsboek/templates/browse.jinja2:207
msgid "page.browse.no_results"
msgstr "Es wurden keine Strecken gefunden, die den Filtern entsprechen."
-#: fietsboek/templates/browse.jinja2:193
+#: fietsboek/templates/browse.jinja2:209
msgid "page.browse.no_tracks"
msgstr ""
"Es wurden keine Strecken gefunden, auf die Du Zugriff hast. Versuche, "
@@ -285,90 +297,90 @@ msgstr "Passwort wiederholen"
msgid "page.create_account.create"
msgstr "Erstellen"
-#: fietsboek/templates/details.jinja2:6
+#: fietsboek/templates/details.jinja2:7
msgid "page.details.title"
msgstr "Details"
-#: fietsboek/templates/details.jinja2:9
+#: fietsboek/templates/details.jinja2:20
msgid "page.details.edit"
msgstr "Bearbeiten"
-#: fietsboek/templates/details.jinja2:10
+#: fietsboek/templates/details.jinja2:21
msgid "page.details.share"
msgstr "Teilen"
-#: fietsboek/templates/details.jinja2:11
+#: fietsboek/templates/details.jinja2:22
msgid "page.details.delete"
msgstr "Löschen"
-#: fietsboek/templates/details.jinja2:17
+#: fietsboek/templates/details.jinja2:28
msgid "page.details.sharelink.title"
msgstr "Link zum Teilen"
-#: fietsboek/templates/details.jinja2:21
+#: fietsboek/templates/details.jinja2:32
msgid "page.details.sharelink.info"
msgstr "Jeder mit Zugang zu diesem Link kann die Strecke ansehen!"
-#: fietsboek/templates/details.jinja2:28
+#: fietsboek/templates/details.jinja2:39
msgid "page.details.sharelink.invalidate"
msgstr "Link invalidieren"
-#: fietsboek/templates/details.jinja2:30
+#: fietsboek/templates/details.jinja2:41
msgid "page.details.sharelink.close"
msgstr "Schließen"
-#: fietsboek/templates/details.jinja2:40
+#: fietsboek/templates/details.jinja2:51
msgid "page.details.delete.title"
msgstr "Strecke Löschen"
-#: fietsboek/templates/details.jinja2:44
+#: fietsboek/templates/details.jinja2:55
msgid "page.details.delete.info"
msgstr "Das Löschen der Strecke wird alle damit verbundenen Informationen löschen!"
-#: fietsboek/templates/details.jinja2:49
+#: fietsboek/templates/details.jinja2:60
msgid "page.details.delete.delete"
msgstr "Löschen"
-#: fietsboek/templates/details.jinja2:51
+#: fietsboek/templates/details.jinja2:62
msgid "page.details.delete.close"
msgstr "Abbrechen"
-#: fietsboek/templates/details.jinja2:70
+#: fietsboek/templates/details.jinja2:81
msgid "page.details.tags"
msgstr "Schlagwörter"
-#: fietsboek/templates/details.jinja2:80 fietsboek/templates/edit.jinja2:10
+#: fietsboek/templates/details.jinja2:91 fietsboek/templates/edit.jinja2:10
#: fietsboek/templates/finish_upload.jinja2:10
msgid "page.noscript"
msgstr ""
"JavaScript ist deaktiviert, zum Nutzen aller Funktionen bitte JavaScript "
"aktivieren"
-#: fietsboek/templates/details.jinja2:85
+#: fietsboek/templates/details.jinja2:97
msgid "page.details.download"
msgstr "Herunterladen"
-#: fietsboek/templates/details.jinja2:174
+#: fietsboek/templates/details.jinja2:187
msgid "page.details.comments"
msgstr "Kommentare"
-#: fietsboek/templates/details.jinja2:178
+#: fietsboek/templates/details.jinja2:191
msgid "page.details.comments.author"
msgstr "Kommentar von {}"
-#: fietsboek/templates/details.jinja2:195
+#: fietsboek/templates/details.jinja2:208
msgid "page.details.comments.new.title"
msgstr "Kommentar erstellen"
-#: fietsboek/templates/details.jinja2:198
+#: fietsboek/templates/details.jinja2:211
msgid "page.details.comments.new.input_title"
msgstr "Titel"
-#: fietsboek/templates/details.jinja2:199
+#: fietsboek/templates/details.jinja2:212
msgid "page.details.comments.new.input_comment"
msgstr "Kommentar"
-#: fietsboek/templates/details.jinja2:202
+#: fietsboek/templates/details.jinja2:215
msgid "page.details.comments.new.submit"
msgstr "Absenden"
@@ -504,13 +516,13 @@ msgstr ""
"Links, um sie fortzusetzen:"
#: fietsboek/templates/home.jinja2:31 fietsboek/templates/home.jinja2:38
-#: fietsboek/templates/home.jinja2:59
+#: fietsboek/templates/home.jinja2:66
msgid "page.home.summary.track"
msgid_plural "page.home.summary.tracks"
msgstr[0] "%(num)d Strecke"
msgstr[1] "%(num)d Strecken"
-#: fietsboek/templates/home.jinja2:59
+#: fietsboek/templates/home.jinja2:66
msgid "page.home.total"
msgstr "Gesamt"
@@ -824,23 +836,23 @@ msgstr "Konto noch nicht bestätigt"
msgid "flash.logged_in"
msgstr "Du bist nun angemeldet"
-#: fietsboek/views/default.py:142
+#: fietsboek/views/default.py:143
msgid "flash.logged_out"
msgstr "Du bist nun abgemeldet"
-#: fietsboek/views/default.py:172
+#: fietsboek/views/default.py:173
msgid "flash.reset_invalid_email"
msgstr "Ungültige E-Mail-Adresse angegeben"
-#: fietsboek/views/default.py:177
+#: fietsboek/views/default.py:178
msgid "flash.password_token_generated"
msgstr "Ein Link zum Zurücksetzen des Passworts wurde versandt"
-#: fietsboek/views/default.py:182
+#: fietsboek/views/default.py:183
msgid "page.password_reset.email.subject"
msgstr "Fietsboek Passwortzurücksetzung"
-#: fietsboek/views/default.py:185
+#: fietsboek/views/default.py:186
msgid "page.password_reset.email.body"
msgstr ""
"Du kannst Dein Fietsboek-Passwort hier zurücksetzen: {}\n"
@@ -848,27 +860,27 @@ msgstr ""
"Falls Du keine Passwortzurücksetzung beantragt hast, dann ignoriere diese"
" E-Mail."
-#: fietsboek/views/default.py:224
+#: fietsboek/views/default.py:225
msgid "flash.resend_verification_email_fail"
msgstr "Ungültige E-Mail-Adresse angegeben"
-#: fietsboek/views/default.py:229
+#: fietsboek/views/default.py:230
msgid "flash.verification_token_generated"
msgstr "Ein Link zur Bestätigung Deines Kontos wurde versandt"
-#: fietsboek/views/default.py:249
+#: fietsboek/views/default.py:250
msgid "flash.token_expired"
msgstr "Der Link ist nicht mehr gültig"
-#: fietsboek/views/default.py:255
+#: fietsboek/views/default.py:256
msgid "flash.email_verified"
msgstr "E-Mail-Adresse bestätigt"
-#: fietsboek/views/default.py:269
+#: fietsboek/views/default.py:270
msgid "flash.password_updated"
msgstr "Passwort aktualisiert"
-#: fietsboek/views/detail.py:155
+#: fietsboek/views/detail.py:161
msgid "flash.track_deleted"
msgstr "Strecke gelöscht"
@@ -888,23 +900,23 @@ msgstr "Hochladen erfolgreich"
msgid "flash.upload_cancelled"
msgstr "Hochladen abgebrochen"
-#: fietsboek/views/user_data.py:60
+#: fietsboek/views/user_data.py:61
msgid "flash.personal_data_updated"
msgstr "Persönliche Daten wurden gespeichert"
-#: fietsboek/views/user_data.py:78
+#: fietsboek/views/user_data.py:79
msgid "flash.friend_not_found"
msgstr "Das angegebene Konto wurde nicht gefunden"
-#: fietsboek/views/user_data.py:84
+#: fietsboek/views/user_data.py:85
msgid "flash.friend_already_exists"
msgstr "Dieser Freund existiert bereits"
-#: fietsboek/views/user_data.py:92
+#: fietsboek/views/user_data.py:93
msgid "flash.friend_added"
msgstr "Freund hinzugefügt"
-#: fietsboek/views/user_data.py:102
+#: fietsboek/views/user_data.py:103
msgid "flash.friend_request_sent"
msgstr "Freundschaftsanfrage gesendet"
diff --git a/fietsboek/locale/en/LC_MESSAGES/messages.mo b/fietsboek/locale/en/LC_MESSAGES/messages.mo
index 2a6205f..56137c1 100644
--- a/fietsboek/locale/en/LC_MESSAGES/messages.mo
+++ b/fietsboek/locale/en/LC_MESSAGES/messages.mo
Binary files differ
diff --git a/fietsboek/locale/en/LC_MESSAGES/messages.po b/fietsboek/locale/en/LC_MESSAGES/messages.po
index 6c13d78..c1ff29e 100644
--- a/fietsboek/locale/en/LC_MESSAGES/messages.po
+++ b/fietsboek/locale/en/LC_MESSAGES/messages.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2023-07-22 14:31+0200\n"
+"POT-Creation-Date: 2023-08-17 22:51+0200\n"
"PO-Revision-Date: 2023-04-03 20:42+0200\n"
"Last-Translator: \n"
"Language: en\n"
@@ -37,35 +37,35 @@ msgstr "Passwords don't match"
msgid "password_constraint.length"
msgstr "Password not long enough"
-#: fietsboek/models/track.py:589
+#: fietsboek/models/track.py:602
msgid "tooltip.table.length"
msgstr "Length"
-#: fietsboek/models/track.py:590
+#: fietsboek/models/track.py:603
msgid "tooltip.table.people"
msgstr "# People"
-#: fietsboek/models/track.py:591
+#: fietsboek/models/track.py:604
msgid "tooltip.table.uphill"
msgstr "Uphill"
-#: fietsboek/models/track.py:592
+#: fietsboek/models/track.py:605
msgid "tooltip.table.downhill"
msgstr "Downhill"
-#: fietsboek/models/track.py:593
+#: fietsboek/models/track.py:606
msgid "tooltip.table.moving_time"
msgstr "Moving Time"
-#: fietsboek/models/track.py:594
+#: fietsboek/models/track.py:607
msgid "tooltip.table.stopped_time"
msgstr "Stopped Time"
-#: fietsboek/models/track.py:596
+#: fietsboek/models/track.py:609
msgid "tooltip.table.max_speed"
msgstr "Max Speed"
-#: fietsboek/models/track.py:600
+#: fietsboek/models/track.py:613
msgid "tooltip.table.avg_speed"
msgstr "Average Speed"
@@ -137,109 +137,121 @@ msgstr "Recording (organic)"
msgid "page.browse.filter.type.synthetic"
msgstr "Template (synthetic)"
-#: fietsboek/templates/browse.jinja2:86
+#: fietsboek/templates/browse.jinja2:82
+msgid "page.browse.filter.favourite.all"
+msgstr "All Tracks"
+
+#: fietsboek/templates/browse.jinja2:83
+msgid "page.browse.filter.favourite.yes"
+msgstr "Only Favourites"
+
+#: fietsboek/templates/browse.jinja2:84
+msgid "page.browse.filter.favourite.no"
+msgstr "No Favourites"
+
+#: fietsboek/templates/browse.jinja2:97
msgid "page.browse.filter.my_tracks.only"
msgstr "Show only my own tracks"
-#: fietsboek/templates/browse.jinja2:87
+#: fietsboek/templates/browse.jinja2:98
msgid "page.browse.filter.friends_tracks_only"
msgstr "Show only tracks of my friends"
-#: fietsboek/templates/browse.jinja2:88
+#: fietsboek/templates/browse.jinja2:99
msgid "page.browse.filter.me_tagged_only"
msgstr "Show only tracks in which I'm tagged"
-#: fietsboek/templates/browse.jinja2:98
+#: fietsboek/templates/browse.jinja2:109
msgid "page.browse.filters.apply"
msgstr "Apply filters"
-#: fietsboek/templates/browse.jinja2:102
+#: fietsboek/templates/browse.jinja2:113
msgid "page.browse.filters.clear_all"
msgstr "Remove filters"
-#: fietsboek/templates/browse.jinja2:105
+#: fietsboek/templates/browse.jinja2:116
msgid "page.browse.filters.expand_advanced"
msgstr "Advanced"
-#: fietsboek/templates/browse.jinja2:110 fietsboek/templates/browse.jinja2:111
+#: fietsboek/templates/browse.jinja2:121 fietsboek/templates/browse.jinja2:122
msgid "page.browse.sort.date"
msgstr "Sort by date"
-#: fietsboek/templates/browse.jinja2:112 fietsboek/templates/browse.jinja2:113
+#: fietsboek/templates/browse.jinja2:123 fietsboek/templates/browse.jinja2:124
msgid "page.browse.sort.length"
msgstr "Sort by length"
-#: fietsboek/templates/browse.jinja2:114 fietsboek/templates/browse.jinja2:115
+#: fietsboek/templates/browse.jinja2:125 fietsboek/templates/browse.jinja2:126
msgid "page.browse.sort.duration"
msgstr "Sort by duration"
-#: fietsboek/templates/browse.jinja2:132
+#: fietsboek/templates/browse.jinja2:148
msgid "page.browse.organic_tooltip"
msgstr "This is a recording of a track"
-#: fietsboek/templates/browse.jinja2:134
+#: fietsboek/templates/browse.jinja2:150
msgid "page.browse.synthetic_tooltip"
msgstr "This is a pre-planned track"
-#: fietsboek/templates/browse.jinja2:142 fietsboek/templates/details.jinja2:90
+#: fietsboek/templates/browse.jinja2:158 fietsboek/templates/details.jinja2:103
#: fietsboek/templates/profile.jinja2:15
msgid "page.details.date"
msgstr "Date"
-#: fietsboek/templates/browse.jinja2:144 fietsboek/templates/details.jinja2:104
+#: fietsboek/templates/browse.jinja2:160 fietsboek/templates/details.jinja2:117
#: fietsboek/templates/profile.jinja2:17
msgid "page.details.length"
msgstr "Length"
-#: fietsboek/templates/browse.jinja2:149 fietsboek/templates/details.jinja2:95
+#: fietsboek/templates/browse.jinja2:165 fietsboek/templates/details.jinja2:108
#: fietsboek/templates/profile.jinja2:21
msgid "page.details.start_time"
msgstr "Record Start"
-#: fietsboek/templates/browse.jinja2:151 fietsboek/templates/details.jinja2:99
+#: fietsboek/templates/browse.jinja2:167 fietsboek/templates/details.jinja2:112
#: fietsboek/templates/profile.jinja2:23
msgid "page.details.end_time"
msgstr "Record End"
-#: fietsboek/templates/browse.jinja2:156 fietsboek/templates/details.jinja2:108
+#: fietsboek/templates/browse.jinja2:172 fietsboek/templates/details.jinja2:121
#: fietsboek/templates/profile.jinja2:27
msgid "page.details.uphill"
msgstr "Uphill"
-#: fietsboek/templates/browse.jinja2:158 fietsboek/templates/details.jinja2:112
+#: fietsboek/templates/browse.jinja2:174 fietsboek/templates/details.jinja2:125
#: fietsboek/templates/profile.jinja2:29
msgid "page.details.downhill"
msgstr "Downhill"
-#: fietsboek/templates/browse.jinja2:163 fietsboek/templates/details.jinja2:117
+#: fietsboek/templates/browse.jinja2:179 fietsboek/templates/details.jinja2:130
#: fietsboek/templates/profile.jinja2:33
msgid "page.details.moving_time"
msgstr "Moving Time"
-#: fietsboek/templates/browse.jinja2:165 fietsboek/templates/details.jinja2:121
+#: fietsboek/templates/browse.jinja2:181 fietsboek/templates/details.jinja2:134
#: fietsboek/templates/profile.jinja2:35
msgid "page.details.stopped_time"
msgstr "Stopped Time"
-#: fietsboek/templates/browse.jinja2:169 fietsboek/templates/details.jinja2:125
+#: fietsboek/templates/browse.jinja2:185 fietsboek/templates/details.jinja2:138
#: fietsboek/templates/profile.jinja2:39
msgid "page.details.max_speed"
msgstr "Max Speed"
-#: fietsboek/templates/browse.jinja2:171 fietsboek/templates/details.jinja2:129
+#: fietsboek/templates/browse.jinja2:187 fietsboek/templates/details.jinja2:142
#: fietsboek/templates/profile.jinja2:41
msgid "page.details.avg_speed"
msgstr "Average Speed"
-#: fietsboek/templates/browse.jinja2:189
+#: fietsboek/templates/browse.jinja2:205
msgid "page.browse.download_multiple"
msgstr "Download selected"
-#: fietsboek/templates/browse.jinja2:191
+#: fietsboek/templates/browse.jinja2:207
msgid "page.browse.no_results"
msgstr "No results matching the filters were found."
-#: fietsboek/templates/browse.jinja2:193
+#: fietsboek/templates/browse.jinja2:209
msgid "page.browse.no_tracks"
msgstr "You currently do not have access to any tracks. Try logging in."
@@ -283,88 +295,88 @@ msgstr "Repeat password"
msgid "page.create_account.create"
msgstr "Create"
-#: fietsboek/templates/details.jinja2:6
+#: fietsboek/templates/details.jinja2:7
msgid "page.details.title"
msgstr "Track Details"
-#: fietsboek/templates/details.jinja2:9
+#: fietsboek/templates/details.jinja2:20
msgid "page.details.edit"
msgstr "Edit"
-#: fietsboek/templates/details.jinja2:10
+#: fietsboek/templates/details.jinja2:21
msgid "page.details.share"
msgstr "Share"
-#: fietsboek/templates/details.jinja2:11
+#: fietsboek/templates/details.jinja2:22
msgid "page.details.delete"
msgstr "Delete"
-#: fietsboek/templates/details.jinja2:17
+#: fietsboek/templates/details.jinja2:28
msgid "page.details.sharelink.title"
msgstr "Share Link"
-#: fietsboek/templates/details.jinja2:21
+#: fietsboek/templates/details.jinja2:32
msgid "page.details.sharelink.info"
msgstr "Everyone with access to this link can view the track!"
-#: fietsboek/templates/details.jinja2:28
+#: fietsboek/templates/details.jinja2:39
msgid "page.details.sharelink.invalidate"
msgstr "Invalidate link"
-#: fietsboek/templates/details.jinja2:30
+#: fietsboek/templates/details.jinja2:41
msgid "page.details.sharelink.close"
msgstr "Close"
-#: fietsboek/templates/details.jinja2:40
+#: fietsboek/templates/details.jinja2:51
msgid "page.details.delete.title"
msgstr "Delete Track"
-#: fietsboek/templates/details.jinja2:44
+#: fietsboek/templates/details.jinja2:55
msgid "page.details.delete.info"
msgstr "Deleting this track will remove all associated information with it!"
-#: fietsboek/templates/details.jinja2:49
+#: fietsboek/templates/details.jinja2:60
msgid "page.details.delete.delete"
msgstr "Delete"
-#: fietsboek/templates/details.jinja2:51
+#: fietsboek/templates/details.jinja2:62
msgid "page.details.delete.close"
msgstr "Abort"
-#: fietsboek/templates/details.jinja2:70
+#: fietsboek/templates/details.jinja2:81
msgid "page.details.tags"
msgstr "Tagged as"
-#: fietsboek/templates/details.jinja2:80 fietsboek/templates/edit.jinja2:10
+#: fietsboek/templates/details.jinja2:91 fietsboek/templates/edit.jinja2:10
#: fietsboek/templates/finish_upload.jinja2:10
msgid "page.noscript"
msgstr "JavaScript is disabled, please enable JavaScript"
-#: fietsboek/templates/details.jinja2:85
+#: fietsboek/templates/details.jinja2:97
msgid "page.details.download"
msgstr "Download Tour"
-#: fietsboek/templates/details.jinja2:174
+#: fietsboek/templates/details.jinja2:187
msgid "page.details.comments"
msgstr "Comments"
-#: fietsboek/templates/details.jinja2:178
+#: fietsboek/templates/details.jinja2:191
msgid "page.details.comments.author"
msgstr "Comment by {}"
-#: fietsboek/templates/details.jinja2:195
+#: fietsboek/templates/details.jinja2:208
msgid "page.details.comments.new.title"
msgstr "Create a new comment"
-#: fietsboek/templates/details.jinja2:198
+#: fietsboek/templates/details.jinja2:211
msgid "page.details.comments.new.input_title"
msgstr "Title"
-#: fietsboek/templates/details.jinja2:199
+#: fietsboek/templates/details.jinja2:212
msgid "page.details.comments.new.input_comment"
msgstr "Comment"
-#: fietsboek/templates/details.jinja2:202
+#: fietsboek/templates/details.jinja2:215
msgid "page.details.comments.new.submit"
msgstr "Submit"
@@ -498,13 +510,13 @@ msgid "page.home.unfinished_uploads"
msgstr "You have unfinished uploads. Click on the links below to resume them:"
#: fietsboek/templates/home.jinja2:31 fietsboek/templates/home.jinja2:38
-#: fietsboek/templates/home.jinja2:59
+#: fietsboek/templates/home.jinja2:66
msgid "page.home.summary.track"
msgid_plural "page.home.summary.tracks"
msgstr[0] "%(num)d track"
msgstr[1] "%(num)d tracks"
-#: fietsboek/templates/home.jinja2:59
+#: fietsboek/templates/home.jinja2:66
msgid "page.home.total"
msgstr "Total"
@@ -814,50 +826,50 @@ msgstr "Your account is not verified yet"
msgid "flash.logged_in"
msgstr "You are now logged in"
-#: fietsboek/views/default.py:142
+#: fietsboek/views/default.py:143
msgid "flash.logged_out"
msgstr "You have been logged out"
-#: fietsboek/views/default.py:172
+#: fietsboek/views/default.py:173
msgid "flash.reset_invalid_email"
msgstr "Invalid email address provided"
-#: fietsboek/views/default.py:177
+#: fietsboek/views/default.py:178
msgid "flash.password_token_generated"
msgstr "A password reset email has been sent"
-#: fietsboek/views/default.py:182
+#: fietsboek/views/default.py:183
msgid "page.password_reset.email.subject"
msgstr "Fietsboek Password Reset"
-#: fietsboek/views/default.py:185
+#: fietsboek/views/default.py:186
msgid "page.password_reset.email.body"
msgstr ""
"You can reset your Fietsboek password here: {}\n"
"\n"
"If you did not request a password reset, ignore this email."
-#: fietsboek/views/default.py:224
+#: fietsboek/views/default.py:225
msgid "flash.resend_verification_email_fail"
msgstr "Invalid email address provided"
-#: fietsboek/views/default.py:229
+#: fietsboek/views/default.py:230
msgid "flash.verification_token_generated"
msgstr "A verification email has been sent"
-#: fietsboek/views/default.py:249
+#: fietsboek/views/default.py:250
msgid "flash.token_expired"
msgstr "The link has expired"
-#: fietsboek/views/default.py:255
+#: fietsboek/views/default.py:256
msgid "flash.email_verified"
msgstr "Your email address has been verified"
-#: fietsboek/views/default.py:269
+#: fietsboek/views/default.py:270
msgid "flash.password_updated"
msgstr "Password has been updated"
-#: fietsboek/views/detail.py:155
+#: fietsboek/views/detail.py:161
msgid "flash.track_deleted"
msgstr "Track has been deleted"
@@ -877,23 +889,23 @@ msgstr "Upload successful"
msgid "flash.upload_cancelled"
msgstr "Upload cancelled"
-#: fietsboek/views/user_data.py:60
+#: fietsboek/views/user_data.py:61
msgid "flash.personal_data_updated"
msgstr "Personal data has been updated"
-#: fietsboek/views/user_data.py:78
+#: fietsboek/views/user_data.py:79
msgid "flash.friend_not_found"
msgstr "The friend was not found"
-#: fietsboek/views/user_data.py:84
+#: fietsboek/views/user_data.py:85
msgid "flash.friend_already_exists"
msgstr "Friend already exists"
-#: fietsboek/views/user_data.py:92
+#: fietsboek/views/user_data.py:93
msgid "flash.friend_added"
msgstr "Friend has been added"
-#: fietsboek/views/user_data.py:102
+#: fietsboek/views/user_data.py:103
msgid "flash.friend_request_sent"
msgstr "Friend request sent"
diff --git a/fietsboek/locale/fietslog.pot b/fietsboek/locale/fietslog.pot
index f6577af..ed93194 100644
--- a/fietsboek/locale/fietslog.pot
+++ b/fietsboek/locale/fietslog.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2023-07-22 14:31+0200\n"
+"POT-Creation-Date: 2023-08-17 22:51+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -33,35 +33,35 @@ msgstr ""
msgid "password_constraint.length"
msgstr ""
-#: fietsboek/models/track.py:589
+#: fietsboek/models/track.py:602
msgid "tooltip.table.length"
msgstr ""
-#: fietsboek/models/track.py:590
+#: fietsboek/models/track.py:603
msgid "tooltip.table.people"
msgstr ""
-#: fietsboek/models/track.py:591
+#: fietsboek/models/track.py:604
msgid "tooltip.table.uphill"
msgstr ""
-#: fietsboek/models/track.py:592
+#: fietsboek/models/track.py:605
msgid "tooltip.table.downhill"
msgstr ""
-#: fietsboek/models/track.py:593
+#: fietsboek/models/track.py:606
msgid "tooltip.table.moving_time"
msgstr ""
-#: fietsboek/models/track.py:594
+#: fietsboek/models/track.py:607
msgid "tooltip.table.stopped_time"
msgstr ""
-#: fietsboek/models/track.py:596
+#: fietsboek/models/track.py:609
msgid "tooltip.table.max_speed"
msgstr ""
-#: fietsboek/models/track.py:600
+#: fietsboek/models/track.py:613
msgid "tooltip.table.avg_speed"
msgstr ""
@@ -133,109 +133,121 @@ msgstr ""
msgid "page.browse.filter.type.synthetic"
msgstr ""
-#: fietsboek/templates/browse.jinja2:86
+#: fietsboek/templates/browse.jinja2:82
+msgid "page.browse.filter.favourite.all"
+msgstr ""
+
+#: fietsboek/templates/browse.jinja2:83
+msgid "page.browse.filter.favourite.yes"
+msgstr ""
+
+#: fietsboek/templates/browse.jinja2:84
+msgid "page.browse.filter.favourite.no"
+msgstr ""
+
+#: fietsboek/templates/browse.jinja2:97
msgid "page.browse.filter.my_tracks.only"
msgstr ""
-#: fietsboek/templates/browse.jinja2:87
+#: fietsboek/templates/browse.jinja2:98
msgid "page.browse.filter.friends_tracks_only"
msgstr ""
-#: fietsboek/templates/browse.jinja2:88
+#: fietsboek/templates/browse.jinja2:99
msgid "page.browse.filter.me_tagged_only"
msgstr ""
-#: fietsboek/templates/browse.jinja2:98
+#: fietsboek/templates/browse.jinja2:109
msgid "page.browse.filters.apply"
msgstr ""
-#: fietsboek/templates/browse.jinja2:102
+#: fietsboek/templates/browse.jinja2:113
msgid "page.browse.filters.clear_all"
msgstr ""
-#: fietsboek/templates/browse.jinja2:105
+#: fietsboek/templates/browse.jinja2:116
msgid "page.browse.filters.expand_advanced"
msgstr ""
-#: fietsboek/templates/browse.jinja2:110 fietsboek/templates/browse.jinja2:111
+#: fietsboek/templates/browse.jinja2:121 fietsboek/templates/browse.jinja2:122
msgid "page.browse.sort.date"
msgstr ""
-#: fietsboek/templates/browse.jinja2:112 fietsboek/templates/browse.jinja2:113
+#: fietsboek/templates/browse.jinja2:123 fietsboek/templates/browse.jinja2:124
msgid "page.browse.sort.length"
msgstr ""
-#: fietsboek/templates/browse.jinja2:114 fietsboek/templates/browse.jinja2:115
+#: fietsboek/templates/browse.jinja2:125 fietsboek/templates/browse.jinja2:126
msgid "page.browse.sort.duration"
msgstr ""
-#: fietsboek/templates/browse.jinja2:132
+#: fietsboek/templates/browse.jinja2:148
msgid "page.browse.organic_tooltip"
msgstr ""
-#: fietsboek/templates/browse.jinja2:134
+#: fietsboek/templates/browse.jinja2:150
msgid "page.browse.synthetic_tooltip"
msgstr ""
-#: fietsboek/templates/browse.jinja2:142 fietsboek/templates/details.jinja2:90
+#: fietsboek/templates/browse.jinja2:158 fietsboek/templates/details.jinja2:103
#: fietsboek/templates/profile.jinja2:15
msgid "page.details.date"
msgstr ""
-#: fietsboek/templates/browse.jinja2:144 fietsboek/templates/details.jinja2:104
+#: fietsboek/templates/browse.jinja2:160 fietsboek/templates/details.jinja2:117
#: fietsboek/templates/profile.jinja2:17
msgid "page.details.length"
msgstr ""
-#: fietsboek/templates/browse.jinja2:149 fietsboek/templates/details.jinja2:95
+#: fietsboek/templates/browse.jinja2:165 fietsboek/templates/details.jinja2:108
#: fietsboek/templates/profile.jinja2:21
msgid "page.details.start_time"
msgstr ""
-#: fietsboek/templates/browse.jinja2:151 fietsboek/templates/details.jinja2:99
+#: fietsboek/templates/browse.jinja2:167 fietsboek/templates/details.jinja2:112
#: fietsboek/templates/profile.jinja2:23
msgid "page.details.end_time"
msgstr ""
-#: fietsboek/templates/browse.jinja2:156 fietsboek/templates/details.jinja2:108
+#: fietsboek/templates/browse.jinja2:172 fietsboek/templates/details.jinja2:121
#: fietsboek/templates/profile.jinja2:27
msgid "page.details.uphill"
msgstr ""
-#: fietsboek/templates/browse.jinja2:158 fietsboek/templates/details.jinja2:112
+#: fietsboek/templates/browse.jinja2:174 fietsboek/templates/details.jinja2:125
#: fietsboek/templates/profile.jinja2:29
msgid "page.details.downhill"
msgstr ""
-#: fietsboek/templates/browse.jinja2:163 fietsboek/templates/details.jinja2:117
+#: fietsboek/templates/browse.jinja2:179 fietsboek/templates/details.jinja2:130
#: fietsboek/templates/profile.jinja2:33
msgid "page.details.moving_time"
msgstr ""
-#: fietsboek/templates/browse.jinja2:165 fietsboek/templates/details.jinja2:121
+#: fietsboek/templates/browse.jinja2:181 fietsboek/templates/details.jinja2:134
#: fietsboek/templates/profile.jinja2:35
msgid "page.details.stopped_time"
msgstr ""
-#: fietsboek/templates/browse.jinja2:169 fietsboek/templates/details.jinja2:125
+#: fietsboek/templates/browse.jinja2:185 fietsboek/templates/details.jinja2:138
#: fietsboek/templates/profile.jinja2:39
msgid "page.details.max_speed"
msgstr ""
-#: fietsboek/templates/browse.jinja2:171 fietsboek/templates/details.jinja2:129
+#: fietsboek/templates/browse.jinja2:187 fietsboek/templates/details.jinja2:142
#: fietsboek/templates/profile.jinja2:41
msgid "page.details.avg_speed"
msgstr ""
-#: fietsboek/templates/browse.jinja2:189
+#: fietsboek/templates/browse.jinja2:205
msgid "page.browse.download_multiple"
msgstr ""
-#: fietsboek/templates/browse.jinja2:191
+#: fietsboek/templates/browse.jinja2:207
msgid "page.browse.no_results"
msgstr ""
-#: fietsboek/templates/browse.jinja2:193
+#: fietsboek/templates/browse.jinja2:209
msgid "page.browse.no_tracks"
msgstr ""
@@ -279,88 +291,88 @@ msgstr ""
msgid "page.create_account.create"
msgstr ""
-#: fietsboek/templates/details.jinja2:6
+#: fietsboek/templates/details.jinja2:7
msgid "page.details.title"
msgstr ""
-#: fietsboek/templates/details.jinja2:9
+#: fietsboek/templates/details.jinja2:20
msgid "page.details.edit"
msgstr ""
-#: fietsboek/templates/details.jinja2:10
+#: fietsboek/templates/details.jinja2:21
msgid "page.details.share"
msgstr ""
-#: fietsboek/templates/details.jinja2:11
+#: fietsboek/templates/details.jinja2:22
msgid "page.details.delete"
msgstr ""
-#: fietsboek/templates/details.jinja2:17
+#: fietsboek/templates/details.jinja2:28
msgid "page.details.sharelink.title"
msgstr ""
-#: fietsboek/templates/details.jinja2:21
+#: fietsboek/templates/details.jinja2:32
msgid "page.details.sharelink.info"
msgstr ""
-#: fietsboek/templates/details.jinja2:28
+#: fietsboek/templates/details.jinja2:39
msgid "page.details.sharelink.invalidate"
msgstr ""
-#: fietsboek/templates/details.jinja2:30
+#: fietsboek/templates/details.jinja2:41
msgid "page.details.sharelink.close"
msgstr ""
-#: fietsboek/templates/details.jinja2:40
+#: fietsboek/templates/details.jinja2:51
msgid "page.details.delete.title"
msgstr ""
-#: fietsboek/templates/details.jinja2:44
+#: fietsboek/templates/details.jinja2:55
msgid "page.details.delete.info"
msgstr ""
-#: fietsboek/templates/details.jinja2:49
+#: fietsboek/templates/details.jinja2:60
msgid "page.details.delete.delete"
msgstr ""
-#: fietsboek/templates/details.jinja2:51
+#: fietsboek/templates/details.jinja2:62
msgid "page.details.delete.close"
msgstr ""
-#: fietsboek/templates/details.jinja2:70
+#: fietsboek/templates/details.jinja2:81
msgid "page.details.tags"
msgstr ""
-#: fietsboek/templates/details.jinja2:80 fietsboek/templates/edit.jinja2:10
+#: fietsboek/templates/details.jinja2:91 fietsboek/templates/edit.jinja2:10
#: fietsboek/templates/finish_upload.jinja2:10
msgid "page.noscript"
msgstr ""
-#: fietsboek/templates/details.jinja2:85
+#: fietsboek/templates/details.jinja2:97
msgid "page.details.download"
msgstr ""
-#: fietsboek/templates/details.jinja2:174
+#: fietsboek/templates/details.jinja2:187
msgid "page.details.comments"
msgstr ""
-#: fietsboek/templates/details.jinja2:178
+#: fietsboek/templates/details.jinja2:191
msgid "page.details.comments.author"
msgstr ""
-#: fietsboek/templates/details.jinja2:195
+#: fietsboek/templates/details.jinja2:208
msgid "page.details.comments.new.title"
msgstr ""
-#: fietsboek/templates/details.jinja2:198
+#: fietsboek/templates/details.jinja2:211
msgid "page.details.comments.new.input_title"
msgstr ""
-#: fietsboek/templates/details.jinja2:199
+#: fietsboek/templates/details.jinja2:212
msgid "page.details.comments.new.input_comment"
msgstr ""
-#: fietsboek/templates/details.jinja2:202
+#: fietsboek/templates/details.jinja2:215
msgid "page.details.comments.new.submit"
msgstr ""
@@ -492,13 +504,13 @@ msgid "page.home.unfinished_uploads"
msgstr ""
#: fietsboek/templates/home.jinja2:31 fietsboek/templates/home.jinja2:38
-#: fietsboek/templates/home.jinja2:59
+#: fietsboek/templates/home.jinja2:66
msgid "page.home.summary.track"
msgid_plural "page.home.summary.tracks"
msgstr[0] ""
msgstr[1] ""
-#: fietsboek/templates/home.jinja2:59
+#: fietsboek/templates/home.jinja2:66
msgid "page.home.total"
msgstr ""
@@ -806,47 +818,47 @@ msgstr ""
msgid "flash.logged_in"
msgstr ""
-#: fietsboek/views/default.py:142
+#: fietsboek/views/default.py:143
msgid "flash.logged_out"
msgstr ""
-#: fietsboek/views/default.py:172
+#: fietsboek/views/default.py:173
msgid "flash.reset_invalid_email"
msgstr ""
-#: fietsboek/views/default.py:177
+#: fietsboek/views/default.py:178
msgid "flash.password_token_generated"
msgstr ""
-#: fietsboek/views/default.py:182
+#: fietsboek/views/default.py:183
msgid "page.password_reset.email.subject"
msgstr ""
-#: fietsboek/views/default.py:185
+#: fietsboek/views/default.py:186
msgid "page.password_reset.email.body"
msgstr ""
-#: fietsboek/views/default.py:224
+#: fietsboek/views/default.py:225
msgid "flash.resend_verification_email_fail"
msgstr ""
-#: fietsboek/views/default.py:229
+#: fietsboek/views/default.py:230
msgid "flash.verification_token_generated"
msgstr ""
-#: fietsboek/views/default.py:249
+#: fietsboek/views/default.py:250
msgid "flash.token_expired"
msgstr ""
-#: fietsboek/views/default.py:255
+#: fietsboek/views/default.py:256
msgid "flash.email_verified"
msgstr ""
-#: fietsboek/views/default.py:269
+#: fietsboek/views/default.py:270
msgid "flash.password_updated"
msgstr ""
-#: fietsboek/views/detail.py:155
+#: fietsboek/views/detail.py:161
msgid "flash.track_deleted"
msgstr ""
@@ -866,23 +878,23 @@ msgstr ""
msgid "flash.upload_cancelled"
msgstr ""
-#: fietsboek/views/user_data.py:60
+#: fietsboek/views/user_data.py:61
msgid "flash.personal_data_updated"
msgstr ""
-#: fietsboek/views/user_data.py:78
+#: fietsboek/views/user_data.py:79
msgid "flash.friend_not_found"
msgstr ""
-#: fietsboek/views/user_data.py:84
+#: fietsboek/views/user_data.py:85
msgid "flash.friend_already_exists"
msgstr ""
-#: fietsboek/views/user_data.py:92
+#: fietsboek/views/user_data.py:93
msgid "flash.friend_added"
msgstr ""
-#: fietsboek/views/user_data.py:102
+#: fietsboek/views/user_data.py:103
msgid "flash.friend_request_sent"
msgstr ""
diff --git a/fietsboek/templates/browse.jinja2 b/fietsboek/templates/browse.jinja2
index 3995511..1eae88d 100644
--- a/fietsboek/templates/browse.jinja2
+++ b/fietsboek/templates/browse.jinja2
@@ -74,6 +74,17 @@
<option value="SYNTHETIC"{% if "SYNTHETIC" in request.params.getall("type[]") %} selected{% endif %}>{{ _("page.browse.filter.type.synthetic") }}</option>
</select>
</div>
+
+ {% if request.identity %}
+ <div class="input-group mt-2">
+ <button type="button" class="btn btn-outline-secondary button-clear-input"><i class="bi bi-eraser-fill"></i></button>
+ <select class="form-select" name="favourite">
+ <option value="">{{ _("page.browse.filter.favourite.all") }}</option>
+ <option value="true"{% if request.params.get("favourite") == "true" %} selected{% endif %}>{{ _("page.browse.filter.favourite.yes") }}</option>
+ <option value="false"{% if request.params.get("favourite") == "false" %} selected{% endif %}>{{ _("page.browse.filter.favourite.no") }}</option>
+ </select>
+ </div>
+ {% endif %}
</div>
<div class="col-md-6">
{% if request.identity %}
diff --git a/fietsboek/views/browse.py b/fietsboek/views/browse.py
index d4f48b7..f23d3a1 100644
--- a/fietsboek/views/browse.py
+++ b/fietsboek/views/browse.py
@@ -10,7 +10,7 @@ from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPNotFound
from pyramid.request import Request
from pyramid.response import Response
from pyramid.view import view_config
-from sqlalchemy import func, or_, select
+from sqlalchemy import func, not_, or_, select
from sqlalchemy.orm import aliased
from sqlalchemy.sql import Select
@@ -226,6 +226,38 @@ class UserTaggedFilter(Filter):
return track.owner == self.user or self.user in track.tagged_people
+class FavouriteFilter(Filter):
+ """A :class:`Filter` that accepts only favoured or non-favoured tracks."""
+
+ def __init__(self, user: models.User, favourite: bool):
+ """Sets up the filter.
+
+ :param user: The user for which the favourite status should be checked.
+ :param favourite: ``True`` if only favourites should be returned,
+ ``False`` otherwise.
+ """
+ self.user = user
+ self.favourite = favourite
+
+ def compile(self, query: Select, track: AliasedTrack) -> Select:
+ tfa = models.track.track_favourite_assoc
+ if self.favourite:
+ invert = lambda x: x
+ else:
+ invert = not_
+ return query.where(
+ invert(
+ select(tfa)
+ .where(tfa.c.track_id == track.id)
+ .where(tfa.c.user_id == self.user.id)
+ .exists()
+ )
+ )
+
+ def apply(self, track: TrackWithMetadata) -> bool:
+ return (self.user in track.favourees) == self.favourite
+
+
class FilterCollection(Filter):
"""A class that applies multiple :class:`Filter`."""
@@ -345,6 +377,10 @@ class FilterCollection(Filter):
)
)
+ if request.identity and request.params.get("favourite"):
+ favourite = request.params.get("favourite") == "true"
+ filters.append(FavouriteFilter(request.identity, favourite))
+
return cls(filters)