diff --git a/deno.lock b/deno.lock
index fd33c5a..ed2ec3b 100644
--- a/deno.lock
+++ b/deno.lock
@@ -35,6 +35,7 @@
"npm:@vitejs/plugin-react-swc@^4.3.1": "4.3.1_vite@8.1.0__@types+node@26.0.1__jiti@2.7.0_@types+node@26.0.1_jiti@2.7.0",
"npm:eslint-plugin-react-hooks@^7.1.1": "7.1.1_eslint@10.6.0__jiti@2.7.0_jiti@2.7.0",
"npm:eslint-plugin-react-refresh@~0.5.3": "0.5.3_eslint@10.6.0__jiti@2.7.0_jiti@2.7.0",
+ "npm:eslint@*": "10.6.0_jiti@2.7.0",
"npm:eslint@^10.6.0": "10.6.0_jiti@2.7.0",
"npm:frimousse@0.3": "0.3.0_react@19.2.7_typescript@6.0.3",
"npm:globals@^17.7.0": "17.7.0",
diff --git a/src/hooks/useDocumentTitle.ts b/src/hooks/useDocumentTitle.ts
new file mode 100644
index 0000000..3102716
--- /dev/null
+++ b/src/hooks/useDocumentTitle.ts
@@ -0,0 +1,31 @@
+import { useEffect } from "react";
+
+// The server injects the configured site name into both
and this meta
+// tag (see api/lib/static.ts / api/middleware/og.ts). Read it once at startup.
+// In the Vite dev server the placeholder isn't substituted, so fall back.
+function readSiteName(): string {
+ const meta = document.querySelector('meta[name="site-name"]')
+ ?.getAttribute("content")?.trim();
+ if (meta && meta !== "__SITE_NAME__") return meta;
+ return "gerbeur";
+}
+
+export const SITE_NAME = readSiteName();
+
+/**
+ * Keeps document.title in sync with the current page during client-side
+ * navigation. Without this the tab title only ever reflects the server-rendered
+ * from the initial page load and goes stale on every SPA navigation.
+ *
+ * - Pass a non-empty string to show ` · `.
+ * - Pass `null` to show just the site name (home / generic pages).
+ * - Pass `undefined` while the page-specific title is still loading: the title
+ * is left untouched, so a server-rendered OG title survives until data
+ * arrives (avoids a flash to the bare site name on direct loads).
+ */
+export function useDocumentTitle(title: string | null | undefined): void {
+ useEffect(() => {
+ if (title === undefined) return;
+ document.title = title ? `${title} · ${SITE_NAME}` : SITE_NAME;
+ }, [title]);
+}
diff --git a/src/locales/en.js b/src/locales/en.js
index c74de8f..f0fe1f6 100644
--- a/src/locales/en.js
+++ b/src/locales/en.js
@@ -1 +1 @@
-/*eslint-disable*/module.exports={messages:JSON.parse("{\"-K9EZb\":[\"Add email…\"],\"-OxI15\":[\"Followed playlists\"],\"-Ya-b9\":[\"Failed to save\"],\"-siMqD\":[\"Journal\"],\"1CalO6\":[\"Style\"],\"1HfJWf\":[\"Search dumps, users, playlists…\"],\"1cbYY_\":[\"Upvoted (\",[\"0\"],[\"1\"],\")\"],\"1njn7W\":[\"Light\"],\"1utXA6\":[\"Dumps\"],\"26iNma\":[\"Post comment\"],\"2DoBvq\":[\"Feeds\"],\"2Hlmdt\":[\"Write a reply…\"],\"2ygf_L\":[\"← Back\"],\"3KKSM4\":[\"private\"],\"3yfh3D\":[\"<0>\",[\"0\"],\"0> followed your playlist <1>\",[\"1\"],\"1>\"],\"49voTZ\":[[\"label\"],\" (\",[\"count\"],\")\"],\"4B6w_o\":[\"Dumped!\"],\"4GKuCs\":[\"Login failed\"],\"4HH9iB\":[\"Not following anyone yet.\"],\"4RtQ1k\":[\"Unfollow \",[\"targetUsername\"]],\"4c-qBx\":[\"Your password has been changed. You can now log in.\"],\"4yj9xV\":[\"Live updates are temporarily disconnected. Trying to reconnect…\"],\"5TviPn\":[\"Cancel search\"],\"5cC8f2\":[\"Edited \",[\"0\"]],\"5oD9f_\":[\"Earlier\"],\"6Qly-0\":[\"a comment\"],\"6gRgw8\":[\"Retry\"],\"7PHCIN\":[\"Cancel removal\"],\"7PzzBU\":[\"User\"],\"7d1a0d\":[\"Public\"],\"7sNhEz\":[\"Username\"],\"8Ug9jB\":[\"Related\"],\"8ZsakT\":[\"Password\"],\"8pxhI8\":[\"Please select a file.\"],\"9BruTc\":[\"Why?\"],\"9l4qcT\":[\"Drop a replacement here\"],\"9uI_rE\":[\"Undo\"],\"9xDZu_\":[\"Could not load.\"],\"A0y396\":[\"+ Invite someone\"],\"A1taO8\":[\"Search\"],\"AQbgNR\":[\"Follow \",[\"targetUsername\"]],\"ATGYL1\":[\"Email address\"],\"AZctoV\":[[\"0\",\"plural\",{\"one\":[\"#\",\" comment\"],\"other\":[\"#\",\" comments\"]}]],\"Ade-6d\":[\"Live updates unavailable.\"],\"AeXO77\":[\"Account\"],\"CI50ct\":[\"Upvoted\"],\"Cj24wt\":[\"Registering…\"],\"DPfwMq\":[\"Done\"],\"DdeHXH\":[\"Delete this dump? This cannot be undone.\"],\"Dp1JhP\":[\"<0>\",[\"0\"],\"0> upvoted <1>\",[\"1\"],\"1>\"],\"ECiS12\":[\"View dump →\"],\"ExR0Fr\":[\"URL is required.\"],\"F5Js1v\":[\"Unfollow playlist\"],\"FgAxTj\":[\"Log out\"],\"Fxf4jq\":[\"Description (optional)\"],\"GDvlUT\":[\"Role\"],\"GLukaH\":[\"Moderator\"],\"GNSsCc\":[\"Failed to create playlist\"],\"GbqhrN\":[[\"0\"],\"–\",[\"1\"],\" characters: letters, numbers, or underscores\"],\"GptGxg\":[\"Change password\"],\"H4o4sk\":[\"No one yet.\"],\"H8pzW-\":[\"Failed to update avatar\"],\"HTLDA4\":[\"Loading more…\"],\"I-x669\":[\"Invitees\"],\"IZX7TO\":[\"Failed to generate invite\"],\"IagCbF\":[\"URL\"],\"ImOQa9\":[\"Reply\"],\"J2eKUI\":[\"File\"],\"JJ-Bhk\":[\"Your email address\"],\"JRQitQ\":[\"Confirm new password\"],\"JXr41k\":[\"<0>\",[\"0\"],\"0> commented on <1>\",[\"1\"],\"1>\"],\"Jd58Fo\":[\"Hot\"],\"Jf0PuK\":[\"Go to login\"],\"KDGWg5\":[\"Remove from playlist\"],\"K_F6pa\":[\"Saving…\"],\"L-rMC9\":[\"Reset to default\"],\"LLyMkV\":[\"Followed (\",[\"0\"],[\"1\"],\")\"],\"MHrjPM\":[\"Title\"],\"MKEPCY\":[\"Follow\"],\"Oprv1v\":[\"Password (min. \",[\"0\"],\" characters)\"],\"Oz0N9s\":[\"new\"],\"PiH3UR\":[\"Copied!\"],\"Pn2B7_\":[\"Current password\"],\"Pwqkdw\":[\"Loading…\"],\"Q6n4F4\":[\"Refresh metadata\"],\"QGaQRo\":[\"Failed to update role\"],\"QKsaQr\":[\"or <0>browse files0>\"],\"QLtPBd\":[\"No dumps in this playlist yet.\"],\"R9Khdg\":[\"Auto\"],\"RCcPrX\":[\"Delete this playlist? This cannot be undone.\"],\"RTksSy\":[\"<0>\",[\"0\"],\"0> started following you\"],\"RaKjrM\":[\"Failed to save edit\"],\"RcUHRT\":[\"Followed\"],\"Rrp6-J\":[\"Log in to like\"],\"SBTElJ\":[\"Searching…\"],\"Sad2tK\":[\"Sending…\"],\"StovX6\":[\"This page does not exist.\"],\"Sxm8rQ\":[\"Users\"],\"T9bjWt\":[\"<0>\",[\"0\"],\"0> was added to <1>\",[\"1\"],\"1>\"],\"TM1ZbA\":[\"Playlists (\",[\"0\"],[\"1\"],\")\"],\"TN382O\":[\"Invalid link\"],\"Tv9vbB\":[\"Follow playlist\"],\"Tz0i8g\":[\"Settings\"],\"U3pytU\":[\"Admin\"],\"UNMVei\":[\"Forgot password?\"],\"UOZith\":[\"Failed to post\"],\"URAieT\":[\"Log in to vote\"],\"UTiUFs\":[\"Fetching…\"],\"VCoEm-\":[\"Back to login\"],\"V_e7nf\":[\"Set new password\"],\"VnNJbN\":[\"From playlists\"],\"VyTYmS\":[\"Change avatar\"],\"W9FRBT\":[\"Like\"],\"WhimMi\":[\"Reset failed\"],\"WpXcBJ\":[\"Nothing here yet.\"],\"XJy2oN\":[\"Logging in…\"],\"Xan6QP\":[\"New dump\"],\"XgRtUf\":[\"Could not change password\"],\"Xi0Mn4\":[\"← Back to profile\"],\"XnL-Eu\":[\"No users match \\\"\",[\"q\"],\"\\\".\"],\"Xs2Lez\":[\"This reset link is missing or malformed.\"],\"YK1Dhc\":[\"a post\"],\"YcjhhX\":[\"User management\"],\"Ye9RMF\":[\"<0>\",[\"0\"],\"0> liked your comment on <1>\",[\"1\"],\"1>\"],\"YpkCca\":[\"No followed playlists yet.\"],\"ZBdbv9\":[\"Edit title\"],\"ZCpU0u\":[\"No playlists match \\\"\",[\"q\"],\"\\\".\"],\"ZmD2o6\":[\"Create & Add\"],\"_3O5R_\":[\"Request failed\"],\"_DwR-n\":[\"Creating…\"],\"_R_sGB\":[\"Password changed successfully.\"],\"_aept4\":[\"Post reply\"],\"_nT6AE\":[\"New password\"],\"_t4W-i\":[\"From people\"],\"aAIQg2\":[\"Appearance\"],\"aDvLhk\":[\"Add a comment…\"],\"b3Thhd\":[\"Upload failed\"],\"b8XMJ8\":[[\"visibleCount\",\"plural\",{\"one\":[\"#\",\" comment\"],\"other\":[\"#\",\" comments\"]}]],\"bQhwn-\":[\"Loading playlist…\"],\"cILfnJ\":[\"Remove file\"],\"cYP9Sb\":[\"+ Playlist\"],\"cbeBbZ\":[\"At least \",[\"0\"],\" characters\"],\"cnGeoo\":[\"Delete\"],\"d8DZWS\":[\"Open search\"],\"dAs22m\":[\"Replace file\"],\"dEgA5A\":[\"Cancel\"],\"dMizp8\":[\"New playlist\"],\"eFSqvc\":[\"Failed to post reply\"],\"eOfXq3\":[\"Title is required.\"],\"ePK91l\":[\"Edit\"],\"eaUTwS\":[\"Send reset link\"],\"ecUA8p\":[\"Today\"],\"ef9nPf\":[\"Loading dump…\"],\"en9o7K\":[\"Failed to post comment\"],\"etFQQS\":[\"What makes it worth it?\"],\"fC6mXb\":[\"Upvote\"],\"fI-mNw\":[\"Playlists\"],\"f_akpP\":[\"Max 50 MB\"],\"fgLNSM\":[\"Register\"],\"gANddk\":[\"Uploading…\"],\"gGx5tM\":[\"Editing\"],\"gIQQwD\":[\"Failed to load\"],\"gLfZlz\":[\"Add to playlist\"],\"gjJ-sb\":[\"Can't connect to the live updates server. Upvotes and notifications may not sync until it reconnects.\"],\"hBuUKa\":[\"Change password…\"],\"hD7w09\":[\"You've reached the end.\"],\"hJSliC\":[\"<0>\",[\"0\"],\"0> posted <1>\",[\"1\"],\"1>\"],\"hYgDIe\":[\"Create\"],\"he3ygx\":[\"Copy\"],\"i7K_Te\":[\"Who am I?\"],\"iDNBZe\":[\"Notifications\"],\"iWpEwy\":[\"Go home\"],\"ipYn7W\":[\"If that address is registered you'll receive a reset link shortly.\"],\"isRobC\":[\"New\"],\"jbernk\":[\"Loading profile…\"],\"joEmfT\":[\"Server unreachable\"],\"jrZTZl\":[\"No dumps yet. Be the first!\"],\"kLttbL\":[\"Registration failed\"],\"lUDifl\":[\"Created (\",[\"0\"],[\"1\"],\")\"],\"lUanmi\":[\"You'll be notified when someone follows your playlists, upvotes your dumps, or posts new content.\"],\"lY5h1V\":[[\"0\",\"plural\",{\"one\":[\"#\",\" dump\"],\"other\":[\"#\",\" dumps\"]}]],\"lcfvr_\":[\"Delete this comment?\"],\"lpIMne\":[\"Passwords do not match\"],\"mt6O6E\":[\"This is a mirage.\"],\"nbm5sI\":[\"No dumps match \\\"\",[\"q\"],\"\\\".\"],\"nrjqON\":[\"Checking invite…\"],\"nwtY4N\":[\"Something went wrong\"],\"nx4kaN\":[\"Could not save\"],\"ogtYkT\":[\"Password updated\"],\"pCpd9p\":[\"<0>\",[\"0\"],\"0> mentioned you in <1>\",[\"where\"],\"1>\"],\"pSheLH\":[\"No invitees yet.\"],\"pvnfJD\":[\"Dark\"],\"qIMfNQ\":[\"Delete playlist\"],\"qbDAcy\":[\"Dump it\"],\"qgx_78\":[\"Follow some public playlists to see their dumps here.\"],\"qvFa8r\":[\"public\"],\"qvz_Pp\":[\"Dump\"],\"rCbqPX\":[\"This invite link is missing, expired, or already used.\"],\"rg9pXu\":[\"Search failed\"],\"rtpJqV\":[\"Dumps (\",[\"0\"],[\"1\"],\")\"],\"sGeXL3\":[\"Thumbnail\"],\"sQia9P\":[\"Log in\"],\"sTiqbm\":[\"invited by\"],\"sdP5Aa\":[\"[deleted]\"],\"shHs8T\":[\"Enter a query to search.\"],\"smeBfS\":[\"Invalid invite\"],\"tfDRzk\":[\"Save\"],\"tvmuQ0\":[\"Color scheme\"],\"u1lDX2\":[\"Fetching preview…\"],\"uD0qXQ\":[\"Drop a file here\"],\"uMGUnV\":[\"No playlists yet.\"],\"ub1EEL\":[\"edited \",[\"0\"]],\"vJBF1r\":[\"Posting…\"],\"vLhLLO\":[\"Notifications (\",[\"unreadNotificationCount\"],\" unread)\"],\"vQMkHu\":[\"Remove vote\"],\"vuosjb\":[\"User menu\"],\"wbXKOv\":[\"File too large (max 50 MB).\"],\"wckWOP\":[\"Manage\"],\"wixIgH\":[\"Already have an account? <0>Log in0>\"],\"x6tjuK\":[\"Default tab\"],\"xEWkgZ\":[\"← Back to all dumps\"],\"xPHtx0\":[\"Submit search\"],\"xVuNgt\":[\"+ New playlist\"],\"xc9O_u\":[\"Delete dump\"],\"y6sq5j\":[\"Following\"],\"y7oaHj\":[\"Playlist title\"],\"yA_6BX\":[\"View all →\"],\"yBBtRm\":[\"Follow some users to see their dumps here.\"],\"yQ2kGp\":[\"Load more\"],\"y_0uwd\":[\"Yesterday\"],\"yz7wBu\":[\"Close\"],\"z0ROB3\":[\"Remove like\"],\"z1uNN0\":[\"No emoji found.\"],\"zVuxvN\":[\"Refreshing…\"],\"zwBp5t\":[\"Private\"]}")};
\ No newline at end of file
+/*eslint-disable*/module.exports={messages:JSON.parse("{\"-K9EZb\":[\"Add email…\"],\"-OxI15\":[\"Followed playlists\"],\"-Ya-b9\":[\"Failed to save\"],\"-siMqD\":[\"Journal\"],\"1CalO6\":[\"Style\"],\"1HfJWf\":[\"Search dumps, users, playlists…\"],\"1cbYY_\":[\"Upvoted (\",[\"0\"],[\"1\"],\")\"],\"1njn7W\":[\"Light\"],\"1utXA6\":[\"Dumps\"],\"26iNma\":[\"Post comment\"],\"2DoBvq\":[\"Feeds\"],\"2Hlmdt\":[\"Write a reply…\"],\"2ygf_L\":[\"← Back\"],\"3KKSM4\":[\"private\"],\"3yfh3D\":[\"<0>\",[\"0\"],\"0> followed your playlist <1>\",[\"1\"],\"1>\"],\"49voTZ\":[[\"label\"],\" (\",[\"count\"],\")\"],\"4B6w_o\":[\"Dumped!\"],\"4GKuCs\":[\"Login failed\"],\"4HH9iB\":[\"Not following anyone yet.\"],\"4RtQ1k\":[\"Unfollow \",[\"targetUsername\"]],\"4c-qBx\":[\"Your password has been changed. You can now log in.\"],\"4yj9xV\":[\"Live updates are temporarily disconnected. Trying to reconnect…\"],\"5TviPn\":[\"Cancel search\"],\"5cC8f2\":[\"Edited \",[\"0\"]],\"5oD9f_\":[\"Earlier\"],\"6Qly-0\":[\"a comment\"],\"6YE0P6\":[\"Editing \",[\"0\"]],\"6gRgw8\":[\"Retry\"],\"7PHCIN\":[\"Cancel removal\"],\"7PzzBU\":[\"User\"],\"7d1a0d\":[\"Public\"],\"7sNhEz\":[\"Username\"],\"8F1i42\":[\"Page not found\"],\"8Ug9jB\":[\"Related\"],\"8ZsakT\":[\"Password\"],\"8pxhI8\":[\"Please select a file.\"],\"9BruTc\":[\"Why?\"],\"9l4qcT\":[\"Drop a replacement here\"],\"9uI_rE\":[\"Undo\"],\"9xDZu_\":[\"Could not load.\"],\"A0y396\":[\"+ Invite someone\"],\"A1taO8\":[\"Search\"],\"AQbgNR\":[\"Follow \",[\"targetUsername\"]],\"ATGYL1\":[\"Email address\"],\"AZctoV\":[[\"0\",\"plural\",{\"one\":[\"#\",\" comment\"],\"other\":[\"#\",\" comments\"]}]],\"Ade-6d\":[\"Live updates unavailable.\"],\"AeXO77\":[\"Account\"],\"CI50ct\":[\"Upvoted\"],\"Cj24wt\":[\"Registering…\"],\"DPfwMq\":[\"Done\"],\"DdeHXH\":[\"Delete this dump? This cannot be undone.\"],\"Dp1JhP\":[\"<0>\",[\"0\"],\"0> upvoted <1>\",[\"1\"],\"1>\"],\"ECiS12\":[\"View dump →\"],\"ExR0Fr\":[\"URL is required.\"],\"F5Js1v\":[\"Unfollow playlist\"],\"FgAxTj\":[\"Log out\"],\"Fxf4jq\":[\"Description (optional)\"],\"GDvlUT\":[\"Role\"],\"GLukaH\":[\"Moderator\"],\"GNSsCc\":[\"Failed to create playlist\"],\"GbqhrN\":[[\"0\"],\"–\",[\"1\"],\" characters: letters, numbers, or underscores\"],\"GptGxg\":[\"Change password\"],\"H4o4sk\":[\"No one yet.\"],\"H8pzW-\":[\"Failed to update avatar\"],\"HTLDA4\":[\"Loading more…\"],\"I-x669\":[\"Invitees\"],\"IZX7TO\":[\"Failed to generate invite\"],\"IagCbF\":[\"URL\"],\"ImOQa9\":[\"Reply\"],\"J2eKUI\":[\"File\"],\"JJ-Bhk\":[\"Your email address\"],\"JRQitQ\":[\"Confirm new password\"],\"JXr41k\":[\"<0>\",[\"0\"],\"0> commented on <1>\",[\"1\"],\"1>\"],\"Jd58Fo\":[\"Hot\"],\"Jf0PuK\":[\"Go to login\"],\"KDGWg5\":[\"Remove from playlist\"],\"K_F6pa\":[\"Saving…\"],\"L-rMC9\":[\"Reset to default\"],\"LLyMkV\":[\"Followed (\",[\"0\"],[\"1\"],\")\"],\"MHrjPM\":[\"Title\"],\"MKEPCY\":[\"Follow\"],\"Oprv1v\":[\"Password (min. \",[\"0\"],\" characters)\"],\"Oz0N9s\":[\"new\"],\"PiH3UR\":[\"Copied!\"],\"Pn2B7_\":[\"Current password\"],\"Pwqkdw\":[\"Loading…\"],\"Q6n4F4\":[\"Refresh metadata\"],\"QGaQRo\":[\"Failed to update role\"],\"QKsaQr\":[\"or <0>browse files0>\"],\"QLtPBd\":[\"No dumps in this playlist yet.\"],\"R9Khdg\":[\"Auto\"],\"RCcPrX\":[\"Delete this playlist? This cannot be undone.\"],\"RTksSy\":[\"<0>\",[\"0\"],\"0> started following you\"],\"RaKjrM\":[\"Failed to save edit\"],\"RcUHRT\":[\"Followed\"],\"RfwZxd\":[\"Reset password\"],\"Rrp6-J\":[\"Log in to like\"],\"SBTElJ\":[\"Searching…\"],\"Sad2tK\":[\"Sending…\"],\"StovX6\":[\"This page does not exist.\"],\"Sxm8rQ\":[\"Users\"],\"T9bjWt\":[\"<0>\",[\"0\"],\"0> was added to <1>\",[\"1\"],\"1>\"],\"TM1ZbA\":[\"Playlists (\",[\"0\"],[\"1\"],\")\"],\"TN382O\":[\"Invalid link\"],\"Tv9vbB\":[\"Follow playlist\"],\"Tz0i8g\":[\"Settings\"],\"U3pytU\":[\"Admin\"],\"UNMVei\":[\"Forgot password?\"],\"UOZith\":[\"Failed to post\"],\"URAieT\":[\"Log in to vote\"],\"UTiUFs\":[\"Fetching…\"],\"VCoEm-\":[\"Back to login\"],\"V_e7nf\":[\"Set new password\"],\"VnNJbN\":[\"From playlists\"],\"VyTYmS\":[\"Change avatar\"],\"W9FRBT\":[\"Like\"],\"WhimMi\":[\"Reset failed\"],\"WpXcBJ\":[\"Nothing here yet.\"],\"XJy2oN\":[\"Logging in…\"],\"Xan6QP\":[\"New dump\"],\"XgRtUf\":[\"Could not change password\"],\"Xi0Mn4\":[\"← Back to profile\"],\"XnL-Eu\":[\"No users match \\\"\",[\"q\"],\"\\\".\"],\"Xs2Lez\":[\"This reset link is missing or malformed.\"],\"YK1Dhc\":[\"a post\"],\"YcjhhX\":[\"User management\"],\"Ye9RMF\":[\"<0>\",[\"0\"],\"0> liked your comment on <1>\",[\"1\"],\"1>\"],\"YpkCca\":[\"No followed playlists yet.\"],\"ZBdbv9\":[\"Edit title\"],\"ZCpU0u\":[\"No playlists match \\\"\",[\"q\"],\"\\\".\"],\"ZmD2o6\":[\"Create & Add\"],\"_3O5R_\":[\"Request failed\"],\"_DwR-n\":[\"Creating…\"],\"_R_sGB\":[\"Password changed successfully.\"],\"_aept4\":[\"Post reply\"],\"_nT6AE\":[\"New password\"],\"_t4W-i\":[\"From people\"],\"aAIQg2\":[\"Appearance\"],\"aDvLhk\":[\"Add a comment…\"],\"b3Thhd\":[\"Upload failed\"],\"b8XMJ8\":[[\"visibleCount\",\"plural\",{\"one\":[\"#\",\" comment\"],\"other\":[\"#\",\" comments\"]}]],\"bQhwn-\":[\"Loading playlist…\"],\"cILfnJ\":[\"Remove file\"],\"cYP9Sb\":[\"+ Playlist\"],\"cbeBbZ\":[\"At least \",[\"0\"],\" characters\"],\"cnGeoo\":[\"Delete\"],\"d8DZWS\":[\"Open search\"],\"dAs22m\":[\"Replace file\"],\"dEgA5A\":[\"Cancel\"],\"dMizp8\":[\"New playlist\"],\"eFSqvc\":[\"Failed to post reply\"],\"eOfXq3\":[\"Title is required.\"],\"ePK91l\":[\"Edit\"],\"eaUTwS\":[\"Send reset link\"],\"ecUA8p\":[\"Today\"],\"ef9nPf\":[\"Loading dump…\"],\"en9o7K\":[\"Failed to post comment\"],\"etFQQS\":[\"What makes it worth it?\"],\"fC6mXb\":[\"Upvote\"],\"fI-mNw\":[\"Playlists\"],\"f_akpP\":[\"Max 50 MB\"],\"fgLNSM\":[\"Register\"],\"gANddk\":[\"Uploading…\"],\"gGx5tM\":[\"Editing\"],\"gIQQwD\":[\"Failed to load\"],\"gLfZlz\":[\"Add to playlist\"],\"gjJ-sb\":[\"Can't connect to the live updates server. Upvotes and notifications may not sync until it reconnects.\"],\"hBuUKa\":[\"Change password…\"],\"hD7w09\":[\"You've reached the end.\"],\"hJSliC\":[\"<0>\",[\"0\"],\"0> posted <1>\",[\"1\"],\"1>\"],\"hYgDIe\":[\"Create\"],\"he3ygx\":[\"Copy\"],\"i7K_Te\":[\"Who am I?\"],\"iDNBZe\":[\"Notifications\"],\"iWpEwy\":[\"Go home\"],\"ipYn7W\":[\"If that address is registered you'll receive a reset link shortly.\"],\"isRobC\":[\"New\"],\"jbernk\":[\"Loading profile…\"],\"joEmfT\":[\"Server unreachable\"],\"jrZTZl\":[\"No dumps yet. Be the first!\"],\"kLttbL\":[\"Registration failed\"],\"lUDifl\":[\"Created (\",[\"0\"],[\"1\"],\")\"],\"lUanmi\":[\"You'll be notified when someone follows your playlists, upvotes your dumps, or posts new content.\"],\"lY5h1V\":[[\"0\",\"plural\",{\"one\":[\"#\",\" dump\"],\"other\":[\"#\",\" dumps\"]}]],\"lcfvr_\":[\"Delete this comment?\"],\"lpIMne\":[\"Passwords do not match\"],\"mt6O6E\":[\"This is a mirage.\"],\"nbm5sI\":[\"No dumps match \\\"\",[\"q\"],\"\\\".\"],\"nrjqON\":[\"Checking invite…\"],\"nwtY4N\":[\"Something went wrong\"],\"nx4kaN\":[\"Could not save\"],\"ogtYkT\":[\"Password updated\"],\"pCpd9p\":[\"<0>\",[\"0\"],\"0> mentioned you in <1>\",[\"where\"],\"1>\"],\"pSheLH\":[\"No invitees yet.\"],\"pvnfJD\":[\"Dark\"],\"qIMfNQ\":[\"Delete playlist\"],\"qbDAcy\":[\"Dump it\"],\"qgx_78\":[\"Follow some public playlists to see their dumps here.\"],\"qvFa8r\":[\"public\"],\"qvz_Pp\":[\"Dump\"],\"rCbqPX\":[\"This invite link is missing, expired, or already used.\"],\"rg9pXu\":[\"Search failed\"],\"rtpJqV\":[\"Dumps (\",[\"0\"],[\"1\"],\")\"],\"sGeXL3\":[\"Thumbnail\"],\"sQia9P\":[\"Log in\"],\"sTiqbm\":[\"invited by\"],\"sdP5Aa\":[\"[deleted]\"],\"shHs8T\":[\"Enter a query to search.\"],\"smeBfS\":[\"Invalid invite\"],\"tfDRzk\":[\"Save\"],\"tvmuQ0\":[\"Color scheme\"],\"u1lDX2\":[\"Fetching preview…\"],\"uD0qXQ\":[\"Drop a file here\"],\"uMGUnV\":[\"No playlists yet.\"],\"ub1EEL\":[\"edited \",[\"0\"]],\"vJBF1r\":[\"Posting…\"],\"vLhLLO\":[\"Notifications (\",[\"unreadNotificationCount\"],\" unread)\"],\"vQMkHu\":[\"Remove vote\"],\"vuosjb\":[\"User menu\"],\"wbXKOv\":[\"File too large (max 50 MB).\"],\"wckWOP\":[\"Manage\"],\"wixIgH\":[\"Already have an account? <0>Log in0>\"],\"x6tjuK\":[\"Default tab\"],\"xEWkgZ\":[\"← Back to all dumps\"],\"xPHtx0\":[\"Submit search\"],\"xVuNgt\":[\"+ New playlist\"],\"xc9O_u\":[\"Delete dump\"],\"y6sq5j\":[\"Following\"],\"y7oaHj\":[\"Playlist title\"],\"yA_6BX\":[\"View all →\"],\"yBBtRm\":[\"Follow some users to see their dumps here.\"],\"yQ2kGp\":[\"Load more\"],\"y_0uwd\":[\"Yesterday\"],\"yz7wBu\":[\"Close\"],\"z0ROB3\":[\"Remove like\"],\"z1uNN0\":[\"No emoji found.\"],\"zVuxvN\":[\"Refreshing…\"],\"zwBp5t\":[\"Private\"]}")};
\ No newline at end of file
diff --git a/src/locales/en.po b/src/locales/en.po
index f4083f9..1054759 100644
--- a/src/locales/en.po
+++ b/src/locales/en.po
@@ -30,11 +30,11 @@ msgstr "{0, plural, one {# dump} other {# dumps}}"
#. placeholder {0}: VALIDATION.USERNAME_MIN
#. placeholder {1}: VALIDATION.USERNAME_MAX
-#: src/pages/UserRegister.tsx:124
+#: src/pages/UserRegister.tsx:126
msgid "{0}–{1} characters: letters, numbers, or underscores"
msgstr "{0}–{1} characters: letters, numbers, or underscores"
-#: src/pages/Search.tsx:176
+#: src/pages/Search.tsx:178
msgid "{label} ({count})"
msgstr "{label} ({count})"
@@ -42,24 +42,24 @@ msgstr "{label} ({count})"
msgid "{visibleCount, plural, one {# comment} other {# comments}}"
msgstr "{visibleCount, plural, one {# comment} other {# comments}}"
-#: src/pages/PlaylistDetail.tsx:561
-#: src/pages/UserPublicProfile.tsx:732
+#: src/pages/PlaylistDetail.tsx:570
+#: src/pages/UserPublicProfile.tsx:741
msgid "← Back"
msgstr "← Back"
-#: src/pages/Dump.tsx:250
-#: src/pages/Dump.tsx:463
-#: src/pages/DumpEdit.tsx:168
+#: src/pages/Dump.tsx:259
+#: src/pages/Dump.tsx:472
+#: src/pages/DumpEdit.tsx:178
msgid "← Back to all dumps"
msgstr "← Back to all dumps"
-#: src/pages/UserDumps.tsx:63
-#: src/pages/UserPlaylists.tsx:354
-#: src/pages/UserUpvoted.tsx:134
+#: src/pages/UserDumps.tsx:66
+#: src/pages/UserPlaylists.tsx:357
+#: src/pages/UserUpvoted.tsx:137
msgid "← Back to profile"
msgstr "← Back to profile"
-#: src/pages/UserPublicProfile.tsx:113
+#: src/pages/UserPublicProfile.tsx:114
msgid "+ Invite someone"
msgstr "+ Invite someone"
@@ -67,65 +67,65 @@ msgstr "+ Invite someone"
msgid "+ New playlist"
msgstr "+ New playlist"
-#: src/pages/Dump.tsx:318
+#: src/pages/Dump.tsx:327
msgid "+ Playlist"
msgstr "+ Playlist"
#. placeholder {0}: d.commenterUsername
#. placeholder {1}: d.dumpTitle
-#: src/pages/Notifications.tsx:194
+#: src/pages/Notifications.tsx:195
msgid "<0>{0}0> commented on <1>{1}1>"
msgstr "<0>{0}0> commented on <1>{1}1>"
#. placeholder {0}: d.followerUsername
#. placeholder {1}: d.playlistTitle
-#: src/pages/Notifications.tsx:154
+#: src/pages/Notifications.tsx:155
msgid "<0>{0}0> followed your playlist <1>{1}1>"
msgstr "<0>{0}0> followed your playlist <1>{1}1>"
#. placeholder {0}: d.likerUsername
#. placeholder {1}: d.dumpTitle
-#: src/pages/Notifications.tsx:204
+#: src/pages/Notifications.tsx:205
msgid "<0>{0}0> liked your comment on <1>{1}1>"
msgstr "<0>{0}0> liked your comment on <1>{1}1>"
#. placeholder {0}: d.mentionerUsername
-#: src/pages/Notifications.tsx:216
+#: src/pages/Notifications.tsx:217
msgid "<0>{0}0> mentioned you in <1>{where}1>"
msgstr "<0>{0}0> mentioned you in <1>{where}1>"
#. placeholder {0}: d.dumperUsername
#. placeholder {1}: d.dumpTitle
-#: src/pages/Notifications.tsx:164
+#: src/pages/Notifications.tsx:165
msgid "<0>{0}0> posted <1>{1}1>"
msgstr "<0>{0}0> posted <1>{1}1>"
#. placeholder {0}: d.followerUsername
-#: src/pages/Notifications.tsx:145
+#: src/pages/Notifications.tsx:146
msgid "<0>{0}0> started following you"
msgstr "<0>{0}0> started following you"
#. placeholder {0}: d.voterUsername
#. placeholder {1}: d.dumpTitle
-#: src/pages/Notifications.tsx:184
+#: src/pages/Notifications.tsx:185
msgid "<0>{0}0> upvoted <1>{1}1>"
msgstr "<0>{0}0> upvoted <1>{1}1>"
#. placeholder {0}: d.dumpTitle
#. placeholder {1}: d.playlistTitle
-#: src/pages/Notifications.tsx:174
+#: src/pages/Notifications.tsx:175
msgid "<0>{0}0> was added to <1>{1}1>"
msgstr "<0>{0}0> was added to <1>{1}1>"
-#: src/pages/Notifications.tsx:214
+#: src/pages/Notifications.tsx:215
msgid "a comment"
msgstr "a comment"
-#: src/pages/Notifications.tsx:214
+#: src/pages/Notifications.tsx:215
msgid "a post"
msgstr "a post"
-#: src/pages/UserPublicProfile.tsx:1111
+#: src/pages/UserPublicProfile.tsx:1120
msgid "Account"
msgstr "Account"
@@ -133,7 +133,7 @@ msgstr "Account"
msgid "Add a comment…"
msgstr "Add a comment…"
-#: src/pages/UserPublicProfile.tsx:807
+#: src/pages/UserPublicProfile.tsx:816
msgid "Add email…"
msgstr "Add email…"
@@ -142,31 +142,31 @@ msgstr "Add email…"
msgid "Add to playlist"
msgstr "Add to playlist"
-#: src/pages/UserPublicProfile.tsx:1520
+#: src/pages/UserPublicProfile.tsx:1529
msgid "Admin"
msgstr "Admin"
-#: src/pages/UserRegister.tsx:154
+#: src/pages/UserRegister.tsx:156
msgid "Already have an account? <0>Log in0>"
msgstr "Already have an account? <0>Log in0>"
-#: src/pages/UserPublicProfile.tsx:1130
+#: src/pages/UserPublicProfile.tsx:1139
msgid "Appearance"
msgstr "Appearance"
#. placeholder {0}: VALIDATION.PASSWORD_MIN
#: src/components/ChangePasswordModal.tsx:82
-#: src/pages/ResetPassword.tsx:109
-#: src/pages/UserRegister.tsx:143
+#: src/pages/ResetPassword.tsx:111
+#: src/pages/UserRegister.tsx:145
msgid "At least {0} characters"
msgstr "At least {0} characters"
-#: src/pages/UserPublicProfile.tsx:1178
+#: src/pages/UserPublicProfile.tsx:1187
msgid "Auto"
msgstr "Auto"
-#: src/pages/ResetPassword.tsx:59
-#: src/pages/ResetPassword.tsx:132
+#: src/pages/ResetPassword.tsx:61
+#: src/pages/ResetPassword.tsx:134
msgid "Back to login"
msgstr "Back to login"
@@ -178,15 +178,15 @@ msgstr "Can't connect to the live updates server. Upvotes and notifications may
#: src/components/CommentThread.tsx:124
#: src/components/ConfirmModal.tsx:32
#: src/components/form/FormActions.tsx:32
-#: src/pages/Dump.tsx:359
-#: src/pages/DumpEdit.tsx:433
-#: src/pages/PlaylistDetail.tsx:911
-#: src/pages/UserPublicProfile.tsx:1637
-#: src/pages/UserPublicProfile.tsx:1707
+#: src/pages/Dump.tsx:368
+#: src/pages/DumpEdit.tsx:443
+#: src/pages/PlaylistDetail.tsx:920
+#: src/pages/UserPublicProfile.tsx:1646
+#: src/pages/UserPublicProfile.tsx:1716
msgid "Cancel"
msgstr "Cancel"
-#: src/pages/PlaylistDetail.tsx:736
+#: src/pages/PlaylistDetail.tsx:745
msgid "Cancel removal"
msgstr "Cancel removal"
@@ -194,7 +194,7 @@ msgstr "Cancel removal"
msgid "Cancel search"
msgstr "Cancel search"
-#: src/pages/UserPublicProfile.tsx:759
+#: src/pages/UserPublicProfile.tsx:768
msgid "Change avatar"
msgstr "Change avatar"
@@ -203,11 +203,11 @@ msgstr "Change avatar"
msgid "Change password"
msgstr "Change password"
-#: src/pages/UserPublicProfile.tsx:1123
+#: src/pages/UserPublicProfile.tsx:1132
msgid "Change password…"
msgstr "Change password…"
-#: src/pages/UserRegister.tsx:83
+#: src/pages/UserRegister.tsx:85
msgid "Checking invite…"
msgstr "Checking invite…"
@@ -216,20 +216,20 @@ msgstr "Checking invite…"
msgid "Close"
msgstr "Close"
-#: src/pages/UserPublicProfile.tsx:1170
+#: src/pages/UserPublicProfile.tsx:1179
msgid "Color scheme"
msgstr "Color scheme"
#: src/components/ChangePasswordModal.tsx:89
-#: src/pages/ResetPassword.tsx:116
+#: src/pages/ResetPassword.tsx:118
msgid "Confirm new password"
msgstr "Confirm new password"
-#: src/pages/UserPublicProfile.tsx:104
+#: src/pages/UserPublicProfile.tsx:105
msgid "Copied!"
msgstr "Copied!"
-#: src/pages/UserPublicProfile.tsx:104
+#: src/pages/UserPublicProfile.tsx:105
msgid "Copy"
msgstr "Copy"
@@ -241,7 +241,7 @@ msgstr "Could not change password"
msgid "Could not load."
msgstr "Could not load."
-#: src/pages/DumpEdit.tsx:334
+#: src/pages/DumpEdit.tsx:344
msgid "Could not save"
msgstr "Could not save"
@@ -255,7 +255,7 @@ msgstr "Create & Add"
#. placeholder {0}: created.items.length
#. placeholder {1}: created.hasMore ? "+" : ""
-#: src/pages/UserPlaylists.tsx:388
+#: src/pages/UserPlaylists.tsx:391
msgid "Created ({0}{1})"
msgstr "Created ({0}{1})"
@@ -267,29 +267,29 @@ msgstr "Creating…"
msgid "Current password"
msgstr "Current password"
-#: src/pages/UserPublicProfile.tsx:1192
+#: src/pages/UserPublicProfile.tsx:1201
msgid "Dark"
msgstr "Dark"
-#: src/pages/UserPublicProfile.tsx:1205
+#: src/pages/UserPublicProfile.tsx:1214
msgid "Default tab"
msgstr "Default tab"
#: src/components/CommentThread.tsx:376
#: src/components/CommentThread.tsx:382
#: src/components/ConfirmModal.tsx:16
-#: src/pages/PlaylistDetail.tsx:907
+#: src/pages/PlaylistDetail.tsx:916
msgid "Delete"
msgstr "Delete"
-#: src/pages/DumpEdit.tsx:242
-#: src/pages/DumpEdit.tsx:429
+#: src/pages/DumpEdit.tsx:252
+#: src/pages/DumpEdit.tsx:439
msgid "Delete dump"
msgstr "Delete dump"
#: src/components/PlaylistCard.tsx:109
-#: src/pages/PlaylistDetail.tsx:749
-#: src/pages/UserPlaylists.tsx:465
+#: src/pages/PlaylistDetail.tsx:758
+#: src/pages/UserPlaylists.tsx:468
msgid "Delete playlist"
msgstr "Delete playlist"
@@ -297,17 +297,17 @@ msgstr "Delete playlist"
msgid "Delete this comment?"
msgstr "Delete this comment?"
-#: src/pages/DumpEdit.tsx:241
+#: src/pages/DumpEdit.tsx:251
msgid "Delete this dump? This cannot be undone."
msgstr "Delete this dump? This cannot be undone."
-#: src/pages/PlaylistDetail.tsx:748
-#: src/pages/UserPlaylists.tsx:464
+#: src/pages/PlaylistDetail.tsx:757
+#: src/pages/UserPlaylists.tsx:467
msgid "Delete this playlist? This cannot be undone."
msgstr "Delete this playlist? This cannot be undone."
#: src/components/PlaylistCreateForm.tsx:78
-#: src/pages/PlaylistDetail.tsx:868
+#: src/pages/PlaylistDetail.tsx:877
msgid "Description (optional)"
msgstr "Description (optional)"
@@ -319,7 +319,7 @@ msgstr "Done"
msgid "Drop a file here"
msgstr "Drop a file here"
-#: src/pages/DumpEdit.tsx:404
+#: src/pages/DumpEdit.tsx:414
msgid "Drop a replacement here"
msgstr "Drop a replacement here"
@@ -335,25 +335,25 @@ msgstr "Dump it"
msgid "Dumped!"
msgstr "Dumped!"
-#: src/pages/Search.tsx:172
-#: src/pages/UserDumps.tsx:77
-#: src/pages/UserPublicProfile.tsx:880
+#: src/pages/Search.tsx:174
+#: src/pages/UserDumps.tsx:80
+#: src/pages/UserPublicProfile.tsx:889
msgid "Dumps"
msgstr "Dumps"
#. placeholder {0}: dumps.items.length
#. placeholder {1}: dumps.hasMore ? "+" : ""
-#: src/pages/UserPublicProfile.tsx:900
+#: src/pages/UserPublicProfile.tsx:909
msgid "Dumps ({0}{1})"
msgstr "Dumps ({0}{1})"
-#: src/pages/Notifications.tsx:393
+#: src/pages/Notifications.tsx:395
msgid "Earlier"
msgstr "Earlier"
#: src/components/CommentThread.tsx:367
-#: src/pages/Dump.tsx:459
-#: src/pages/PlaylistDetail.tsx:616
+#: src/pages/Dump.tsx:468
+#: src/pages/PlaylistDetail.tsx:625
msgid "Edit"
msgstr "Edit"
@@ -365,8 +365,8 @@ msgstr "Edit title"
#. placeholder {0}: relativeTime(dump.updatedAt)
#. placeholder {0}: relativeTime(playlist.updatedAt)
#: src/components/CommentThread.tsx:317
-#: src/pages/Dump.tsx:412
-#: src/pages/PlaylistDetail.tsx:655
+#: src/pages/Dump.tsx:421
+#: src/pages/PlaylistDetail.tsx:664
msgid "edited {0}"
msgstr "edited {0}"
@@ -374,20 +374,25 @@ msgstr "edited {0}"
#. placeholder {0}: dump.updatedAt.toLocaleString()
#. placeholder {0}: playlist.updatedAt.toLocaleString()
#: src/components/CommentThread.tsx:315
-#: src/pages/Dump.tsx:410
-#: src/pages/PlaylistDetail.tsx:652
+#: src/pages/Dump.tsx:419
+#: src/pages/PlaylistDetail.tsx:661
msgid "Edited {0}"
msgstr "Edited {0}"
-#: src/pages/DumpEdit.tsx:193
+#: src/pages/DumpEdit.tsx:203
msgid "Editing"
msgstr "Editing"
-#: src/pages/UserRegister.tsx:131
+#. placeholder {0}: state.dump.title
+#: src/pages/DumpEdit.tsx:48
+msgid "Editing {0}"
+msgstr "Editing {0}"
+
+#: src/pages/UserRegister.tsx:133
msgid "Email address"
msgstr "Email address"
-#: src/pages/Search.tsx:205
+#: src/pages/Search.tsx:207
msgid "Enter a query to search."
msgstr "Enter a query to search."
@@ -395,9 +400,9 @@ msgstr "Enter a query to search."
msgid "Failed to create playlist"
msgstr "Failed to create playlist"
-#: src/pages/UserPublicProfile.tsx:85
-#: src/pages/UserPublicProfile.tsx:88
-#: src/pages/UserPublicProfile.tsx:116
+#: src/pages/UserPublicProfile.tsx:86
+#: src/pages/UserPublicProfile.tsx:89
+#: src/pages/UserPublicProfile.tsx:117
msgid "Failed to generate invite"
msgstr "Failed to generate invite"
@@ -405,10 +410,10 @@ msgstr "Failed to generate invite"
#: src/pages/index/HotFeed.tsx:36
#: src/pages/index/JournalFeed.tsx:33
#: src/pages/index/NewFeed.tsx:36
-#: src/pages/Notifications.tsx:367
-#: src/pages/UserPublicProfile.tsx:1002
-#: src/pages/UserPublicProfile.tsx:1044
-#: src/pages/UserPublicProfile.tsx:1089
+#: src/pages/Notifications.tsx:369
+#: src/pages/UserPublicProfile.tsx:1011
+#: src/pages/UserPublicProfile.tsx:1053
+#: src/pages/UserPublicProfile.tsx:1098
msgid "Failed to load"
msgstr "Failed to load"
@@ -424,9 +429,9 @@ msgstr "Failed to post comment"
msgid "Failed to post reply"
msgstr "Failed to post reply"
-#: src/pages/PlaylistDetail.tsx:899
-#: src/pages/UserPublicProfile.tsx:1640
-#: src/pages/UserPublicProfile.tsx:1709
+#: src/pages/PlaylistDetail.tsx:908
+#: src/pages/UserPublicProfile.tsx:1649
+#: src/pages/UserPublicProfile.tsx:1718
msgid "Failed to save"
msgstr "Failed to save"
@@ -434,15 +439,15 @@ msgstr "Failed to save"
msgid "Failed to save edit"
msgstr "Failed to save edit"
-#: src/pages/UserPublicProfile.tsx:816
+#: src/pages/UserPublicProfile.tsx:825
msgid "Failed to update avatar"
msgstr "Failed to update avatar"
-#: src/pages/UserPublicProfile.tsx:1578
+#: src/pages/UserPublicProfile.tsx:1587
msgid "Failed to update role"
msgstr "Failed to update role"
-#: src/pages/UserPublicProfile.tsx:1200
+#: src/pages/UserPublicProfile.tsx:1209
msgid "Feeds"
msgstr "Feeds"
@@ -485,28 +490,28 @@ msgid "Follow some users to see their dumps here."
msgstr "Follow some users to see their dumps here."
#: src/components/FeedTabBar.tsx:21
-#: src/pages/UserPublicProfile.tsx:882
-#: src/pages/UserPublicProfile.tsx:1234
+#: src/pages/UserPublicProfile.tsx:891
+#: src/pages/UserPublicProfile.tsx:1243
msgid "Followed"
msgstr "Followed"
#. placeholder {0}: followed.items.length
#. placeholder {1}: followed.hasMore ? "+" : ""
-#: src/pages/UserPlaylists.tsx:430
+#: src/pages/UserPlaylists.tsx:433
msgid "Followed ({0}{1})"
msgstr "Followed ({0}{1})"
-#: src/pages/UserPublicProfile.tsx:1033
+#: src/pages/UserPublicProfile.tsx:1042
msgid "Followed playlists"
msgstr "Followed playlists"
#: src/components/FollowButton.tsx:37
#: src/components/FollowButton.tsx:64
-#: src/pages/UserPublicProfile.tsx:991
+#: src/pages/UserPublicProfile.tsx:1000
msgid "Following"
msgstr "Following"
-#: src/pages/UserLogin.tsx:87
+#: src/pages/UserLogin.tsx:89
msgid "Forgot password?"
msgstr "Forgot password?"
@@ -518,46 +523,46 @@ msgstr "From people"
msgid "From playlists"
msgstr "From playlists"
-#: src/pages/NotFound.tsx:13
+#: src/pages/NotFound.tsx:16
msgid "Go home"
msgstr "Go home"
-#: src/pages/ResetPassword.tsx:81
+#: src/pages/ResetPassword.tsx:83
msgid "Go to login"
msgstr "Go to login"
#: src/components/FeedTabBar.tsx:17
-#: src/pages/UserPublicProfile.tsx:1213
+#: src/pages/UserPublicProfile.tsx:1222
msgid "Hot"
msgstr "Hot"
-#: src/pages/UserLogin.tsx:118
+#: src/pages/UserLogin.tsx:120
msgid "If that address is registered you'll receive a reset link shortly."
msgstr "If that address is registered you'll receive a reset link shortly."
-#: src/pages/UserRegister.tsx:94
+#: src/pages/UserRegister.tsx:96
msgid "Invalid invite"
msgstr "Invalid invite"
-#: src/pages/ResetPassword.tsx:49
+#: src/pages/ResetPassword.tsx:51
msgid "Invalid link"
msgstr "Invalid link"
-#: src/pages/UserPublicProfile.tsx:778
+#: src/pages/UserPublicProfile.tsx:787
msgid "invited by"
msgstr "invited by"
-#: src/pages/UserPublicProfile.tsx:883
-#: src/pages/UserPublicProfile.tsx:1078
+#: src/pages/UserPublicProfile.tsx:892
+#: src/pages/UserPublicProfile.tsx:1087
msgid "Invitees"
msgstr "Invitees"
#: src/components/FeedTabBar.tsx:19
-#: src/pages/UserPublicProfile.tsx:1227
+#: src/pages/UserPublicProfile.tsx:1236
msgid "Journal"
msgstr "Journal"
-#: src/pages/UserPublicProfile.tsx:1185
+#: src/pages/UserPublicProfile.tsx:1194
msgid "Light"
msgstr "Light"
@@ -574,12 +579,12 @@ msgid "Live updates unavailable."
msgstr "Live updates unavailable."
#: src/components/UserListPopover.tsx:231
-#: src/pages/Notifications.tsx:440
+#: src/pages/Notifications.tsx:442
msgid "Load more"
msgstr "Load more"
-#: src/pages/Dump.tsx:226
-#: src/pages/DumpEdit.tsx:144
+#: src/pages/Dump.tsx:235
+#: src/pages/DumpEdit.tsx:154
msgid "Loading dump…"
msgstr "Loading dump…"
@@ -587,19 +592,19 @@ msgstr "Loading dump…"
#: src/pages/index/HotFeed.tsx:64
#: src/pages/index/JournalFeed.tsx:62
#: src/pages/index/NewFeed.tsx:64
-#: src/pages/Search.tsx:242
-#: src/pages/UserDumps.tsx:118
-#: src/pages/UserPlaylists.tsx:417
-#: src/pages/UserPlaylists.tsx:452
-#: src/pages/UserUpvoted.tsx:187
+#: src/pages/Search.tsx:244
+#: src/pages/UserDumps.tsx:121
+#: src/pages/UserPlaylists.tsx:420
+#: src/pages/UserPlaylists.tsx:455
+#: src/pages/UserUpvoted.tsx:190
msgid "Loading more…"
msgstr "Loading more…"
-#: src/pages/PlaylistDetail.tsx:545
+#: src/pages/PlaylistDetail.tsx:554
msgid "Loading playlist…"
msgstr "Loading playlist…"
-#: src/pages/UserPublicProfile.tsx:715
+#: src/pages/UserPublicProfile.tsx:724
msgid "Loading profile…"
msgstr "Loading profile…"
@@ -611,20 +616,21 @@ msgstr "Loading profile…"
#: src/pages/index/HotFeed.tsx:32
#: src/pages/index/JournalFeed.tsx:29
#: src/pages/index/NewFeed.tsx:32
-#: src/pages/Notifications.tsx:363
-#: src/pages/Notifications.tsx:439
-#: src/pages/UserDumps.tsx:51
-#: src/pages/UserPlaylists.tsx:342
-#: src/pages/UserPublicProfile.tsx:996
-#: src/pages/UserPublicProfile.tsx:1038
-#: src/pages/UserPublicProfile.tsx:1083
-#: src/pages/UserUpvoted.tsx:122
+#: src/pages/Notifications.tsx:365
+#: src/pages/Notifications.tsx:441
+#: src/pages/UserDumps.tsx:54
+#: src/pages/UserPlaylists.tsx:345
+#: src/pages/UserPublicProfile.tsx:1005
+#: src/pages/UserPublicProfile.tsx:1047
+#: src/pages/UserPublicProfile.tsx:1092
+#: src/pages/UserUpvoted.tsx:125
msgid "Loading…"
msgstr "Loading…"
#: src/components/AppHeader.tsx:111
-#: src/pages/UserLogin.tsx:57
-#: src/pages/UserLogin.tsx:76
+#: src/pages/UserLogin.tsx:34
+#: src/pages/UserLogin.tsx:59
+#: src/pages/UserLogin.tsx:78
msgid "Log in"
msgstr "Log in"
@@ -636,20 +642,20 @@ msgstr "Log in to like"
msgid "Log in to vote"
msgstr "Log in to vote"
-#: src/pages/UserPublicProfile.tsx:736
-#: src/pages/UserPublicProfile.tsx:830
+#: src/pages/UserPublicProfile.tsx:745
+#: src/pages/UserPublicProfile.tsx:839
msgid "Log out"
msgstr "Log out"
-#: src/pages/UserLogin.tsx:75
+#: src/pages/UserLogin.tsx:77
msgid "Logging in…"
msgstr "Logging in…"
-#: src/pages/UserLogin.tsx:62
+#: src/pages/UserLogin.tsx:64
msgid "Login failed"
msgstr "Login failed"
-#: src/pages/UserPublicProfile.tsx:888
+#: src/pages/UserPublicProfile.tsx:897
msgid "Manage"
msgstr "Manage"
@@ -657,29 +663,29 @@ msgstr "Manage"
msgid "Max 50 MB"
msgstr "Max 50 MB"
-#: src/pages/UserPublicProfile.tsx:1519
+#: src/pages/UserPublicProfile.tsx:1528
msgid "Moderator"
msgstr "Moderator"
-#: src/pages/Notifications.tsx:356
+#: src/pages/Notifications.tsx:358
msgid "new"
msgstr "new"
#: src/components/FeedTabBar.tsx:18
-#: src/pages/UserPublicProfile.tsx:1220
+#: src/pages/UserPublicProfile.tsx:1229
msgid "New"
msgstr "New"
#: src/components/DumpCreateModal.tsx:292
#: src/components/DumpFab.tsx:65
#: src/components/DumpFab.tsx:66
-#: src/pages/UserDumps.tsx:85
-#: src/pages/UserPublicProfile.tsx:1298
+#: src/pages/UserDumps.tsx:88
+#: src/pages/UserPublicProfile.tsx:1307
msgid "New dump"
msgstr "New dump"
#: src/components/ChangePasswordModal.tsx:75
-#: src/pages/ResetPassword.tsx:101
+#: src/pages/ResetPassword.tsx:103
msgid "New password"
msgstr "New password"
@@ -688,11 +694,11 @@ msgstr "New password"
msgid "New playlist"
msgstr "New playlist"
-#: src/pages/PlaylistDetail.tsx:671
+#: src/pages/PlaylistDetail.tsx:680
msgid "No dumps in this playlist yet."
msgstr "No dumps in this playlist yet."
-#: src/pages/Search.tsx:222
+#: src/pages/Search.tsx:224
msgid "No dumps match \"{q}\"."
msgstr "No dumps match \"{q}\"."
@@ -706,12 +712,12 @@ msgstr "No dumps yet. Be the first!"
msgid "No emoji found."
msgstr "No emoji found."
-#: src/pages/UserPlaylists.tsx:439
-#: src/pages/UserPublicProfile.tsx:1051
+#: src/pages/UserPlaylists.tsx:442
+#: src/pages/UserPublicProfile.tsx:1060
msgid "No followed playlists yet."
msgstr "No followed playlists yet."
-#: src/pages/UserPublicProfile.tsx:1096
+#: src/pages/UserPublicProfile.tsx:1105
msgid "No invitees yet."
msgstr "No invitees yet."
@@ -719,34 +725,35 @@ msgstr "No invitees yet."
msgid "No one yet."
msgstr "No one yet."
-#: src/pages/Search.tsx:281
+#: src/pages/Search.tsx:283
msgid "No playlists match \"{q}\"."
msgstr "No playlists match \"{q}\"."
#: src/components/PlaylistMembershipPanel.tsx:34
-#: src/pages/UserPlaylists.tsx:397
-#: src/pages/UserPublicProfile.tsx:962
+#: src/pages/UserPlaylists.tsx:400
+#: src/pages/UserPublicProfile.tsx:971
msgid "No playlists yet."
msgstr "No playlists yet."
-#: src/pages/Search.tsx:255
+#: src/pages/Search.tsx:257
msgid "No users match \"{q}\"."
msgstr "No users match \"{q}\"."
-#: src/pages/UserPublicProfile.tsx:1009
+#: src/pages/UserPublicProfile.tsx:1018
msgid "Not following anyone yet."
msgstr "Not following anyone yet."
-#: src/pages/Notifications.tsx:374
-#: src/pages/UserDumps.tsx:96
-#: src/pages/UserPublicProfile.tsx:1309
-#: src/pages/UserPublicProfile.tsx:1431
-#: src/pages/UserUpvoted.tsx:156
+#: src/pages/Notifications.tsx:376
+#: src/pages/UserDumps.tsx:99
+#: src/pages/UserPublicProfile.tsx:1318
+#: src/pages/UserPublicProfile.tsx:1440
+#: src/pages/UserUpvoted.tsx:159
msgid "Nothing here yet."
msgstr "Nothing here yet."
#: src/components/NotificationBell.tsx:42
-#: src/pages/Notifications.tsx:352
+#: src/pages/Notifications.tsx:260
+#: src/pages/Notifications.tsx:354
msgid "Notifications"
msgstr "Notifications"
@@ -762,13 +769,17 @@ msgstr "Open search"
msgid "or <0>browse files0>"
msgstr "or <0>browse files0>"
-#: src/pages/UserLogin.tsx:72
-#: src/pages/UserPublicProfile.tsx:1116
+#: src/pages/NotFound.tsx:8
+msgid "Page not found"
+msgstr "Page not found"
+
+#: src/pages/UserLogin.tsx:74
+#: src/pages/UserPublicProfile.tsx:1125
msgid "Password"
msgstr "Password"
#. placeholder {0}: VALIDATION.PASSWORD_MIN
-#: src/pages/UserRegister.tsx:137
+#: src/pages/UserRegister.tsx:139
msgid "Password (min. {0} characters)"
msgstr "Password (min. {0} characters)"
@@ -776,30 +787,30 @@ msgstr "Password (min. {0} characters)"
msgid "Password changed successfully."
msgstr "Password changed successfully."
-#: src/pages/ResetPassword.tsx:71
+#: src/pages/ResetPassword.tsx:73
msgid "Password updated"
msgstr "Password updated"
#: src/components/ChangePasswordModal.tsx:95
-#: src/pages/ResetPassword.tsx:121
+#: src/pages/ResetPassword.tsx:123
msgid "Passwords do not match"
msgstr "Passwords do not match"
-#: src/pages/PlaylistDetail.tsx:854
+#: src/pages/PlaylistDetail.tsx:863
msgid "Playlist title"
msgstr "Playlist title"
#: src/components/AppHeader.tsx:85
#: src/components/UserMenu.tsx:62
-#: src/pages/Search.tsx:175
-#: src/pages/UserPlaylists.tsx:368
-#: src/pages/UserPublicProfile.tsx:881
+#: src/pages/Search.tsx:177
+#: src/pages/UserPlaylists.tsx:371
+#: src/pages/UserPublicProfile.tsx:890
msgid "Playlists"
msgstr "Playlists"
#. placeholder {0}: playlists.items.length
#. placeholder {1}: playlists.hasMore ? "+" : ""
-#: src/pages/UserPublicProfile.tsx:931
+#: src/pages/UserPublicProfile.tsx:940
msgid "Playlists ({0}{1})"
msgstr "Playlists ({0}{1})"
@@ -824,48 +835,49 @@ msgstr "Posting…"
#: src/components/JournalCard.tsx:119
#: src/components/PlaylistCard.tsx:73
#: src/components/PlaylistMembershipPanel.tsx:55
-#: src/pages/Dump.tsx:418
-#: src/pages/PlaylistDetail.tsx:635
+#: src/pages/Dump.tsx:427
+#: src/pages/PlaylistDetail.tsx:644
msgid "private"
msgstr "private"
#: src/components/form/SegmentedField.tsx:78
-#: src/pages/PlaylistDetail.tsx:893
+#: src/pages/PlaylistDetail.tsx:902
msgid "Private"
msgstr "Private"
#: src/components/PlaylistCard.tsx:72
-#: src/pages/PlaylistDetail.tsx:634
+#: src/pages/PlaylistDetail.tsx:643
msgid "public"
msgstr "public"
#: src/components/form/SegmentedField.tsx:77
-#: src/pages/PlaylistDetail.tsx:886
+#: src/pages/PlaylistDetail.tsx:895
msgid "Public"
msgstr "Public"
-#: src/pages/DumpEdit.tsx:222
+#: src/pages/DumpEdit.tsx:232
msgid "Refresh metadata"
msgstr "Refresh metadata"
-#: src/pages/DumpEdit.tsx:221
+#: src/pages/DumpEdit.tsx:231
msgid "Refreshing…"
msgstr "Refreshing…"
-#: src/pages/UserRegister.tsx:106
-#: src/pages/UserRegister.tsx:148
+#: src/pages/UserRegister.tsx:37
+#: src/pages/UserRegister.tsx:108
+#: src/pages/UserRegister.tsx:150
msgid "Register"
msgstr "Register"
-#: src/pages/UserRegister.tsx:147
+#: src/pages/UserRegister.tsx:149
msgid "Registering…"
msgstr "Registering…"
-#: src/pages/UserRegister.tsx:111
+#: src/pages/UserRegister.tsx:113
msgid "Registration failed"
msgstr "Registration failed"
-#: src/pages/Dump.tsx:471
+#: src/pages/Dump.tsx:480
msgid "Related"
msgstr "Related"
@@ -873,7 +885,7 @@ msgstr "Related"
msgid "Remove file"
msgstr "Remove file"
-#: src/pages/PlaylistDetail.tsx:726
+#: src/pages/PlaylistDetail.tsx:735
msgid "Remove from playlist"
msgstr "Remove from playlist"
@@ -885,7 +897,7 @@ msgstr "Remove like"
msgid "Remove vote"
msgstr "Remove vote"
-#: src/pages/DumpEdit.tsx:403
+#: src/pages/DumpEdit.tsx:413
msgid "Replace file"
msgstr "Replace file"
@@ -893,49 +905,54 @@ msgstr "Replace file"
msgid "Reply"
msgstr "Reply"
-#: src/pages/UserLogin.tsx:130
+#: src/pages/UserLogin.tsx:132
msgid "Request failed"
msgstr "Request failed"
-#: src/pages/ResetPassword.tsx:97
+#: src/pages/ResetPassword.tsx:99
msgid "Reset failed"
msgstr "Reset failed"
-#: src/pages/DumpEdit.tsx:354
-#: src/pages/DumpEdit.tsx:372
+#: src/pages/ResetPassword.tsx:24
+msgid "Reset password"
+msgstr "Reset password"
+
+#: src/pages/DumpEdit.tsx:364
+#: src/pages/DumpEdit.tsx:382
msgid "Reset to default"
msgstr "Reset to default"
-#: src/pages/Dump.tsx:243
-#: src/pages/DumpEdit.tsx:161
+#: src/pages/Dump.tsx:252
+#: src/pages/DumpEdit.tsx:171
msgid "Retry"
msgstr "Retry"
-#: src/pages/UserPublicProfile.tsx:1562
+#: src/pages/UserPublicProfile.tsx:1571
msgid "Role"
msgstr "Role"
#: src/components/CommentThread.tsx:328
-#: src/pages/Dump.tsx:351
-#: src/pages/DumpEdit.tsx:436
-#: src/pages/PlaylistDetail.tsx:918
-#: src/pages/UserPublicProfile.tsx:1629
-#: src/pages/UserPublicProfile.tsx:1699
+#: src/pages/Dump.tsx:360
+#: src/pages/DumpEdit.tsx:446
+#: src/pages/PlaylistDetail.tsx:927
+#: src/pages/UserPublicProfile.tsx:1638
+#: src/pages/UserPublicProfile.tsx:1708
msgid "Save"
msgstr "Save"
#: src/components/ChangePasswordModal.tsx:100
#: src/components/CommentThread.tsx:329
-#: src/pages/Dump.tsx:350
-#: src/pages/PlaylistDetail.tsx:914
-#: src/pages/ResetPassword.tsx:124
-#: src/pages/UserPublicProfile.tsx:1626
-#: src/pages/UserPublicProfile.tsx:1696
+#: src/pages/Dump.tsx:359
+#: src/pages/PlaylistDetail.tsx:923
+#: src/pages/ResetPassword.tsx:126
+#: src/pages/UserPublicProfile.tsx:1635
+#: src/pages/UserPublicProfile.tsx:1705
msgid "Saving…"
msgstr "Saving…"
#: src/components/AppHeader.tsx:65
#: src/components/SearchBar.tsx:78
+#: src/pages/Search.tsx:50
msgid "Search"
msgstr "Search"
@@ -943,19 +960,19 @@ msgstr "Search"
msgid "Search dumps, users, playlists…"
msgstr "Search dumps, users, playlists…"
-#: src/pages/Search.tsx:216
+#: src/pages/Search.tsx:218
msgid "Search failed"
msgstr "Search failed"
-#: src/pages/Search.tsx:211
+#: src/pages/Search.tsx:213
msgid "Searching…"
msgstr "Searching…"
-#: src/pages/UserLogin.tsx:139
+#: src/pages/UserLogin.tsx:141
msgid "Send reset link"
msgstr "Send reset link"
-#: src/pages/UserLogin.tsx:138
+#: src/pages/UserLogin.tsx:140
msgid "Sending…"
msgstr "Sending…"
@@ -963,12 +980,12 @@ msgstr "Sending…"
msgid "Server unreachable"
msgstr "Server unreachable"
-#: src/pages/ResetPassword.tsx:92
-#: src/pages/ResetPassword.tsx:125
+#: src/pages/ResetPassword.tsx:94
+#: src/pages/ResetPassword.tsx:127
msgid "Set new password"
msgstr "Set new password"
-#: src/pages/UserPublicProfile.tsx:885
+#: src/pages/UserPublicProfile.tsx:894
msgid "Settings"
msgstr "Settings"
@@ -977,7 +994,7 @@ msgstr "Settings"
msgid "Something went wrong"
msgstr "Something went wrong"
-#: src/pages/UserPublicProfile.tsx:1135
+#: src/pages/UserPublicProfile.tsx:1144
msgid "Style"
msgstr "Style"
@@ -985,29 +1002,29 @@ msgstr "Style"
msgid "Submit search"
msgstr "Submit search"
-#: src/pages/UserRegister.tsx:95
+#: src/pages/UserRegister.tsx:97
msgid "This invite link is missing, expired, or already used."
msgstr "This invite link is missing, expired, or already used."
-#: src/pages/UserLogin.tsx:94
+#: src/pages/UserLogin.tsx:96
msgid "This is a mirage."
msgstr "This is a mirage."
-#: src/pages/NotFound.tsx:10
+#: src/pages/NotFound.tsx:13
msgid "This page does not exist."
msgstr "This page does not exist."
-#: src/pages/ResetPassword.tsx:52
+#: src/pages/ResetPassword.tsx:54
msgid "This reset link is missing or malformed."
msgstr "This reset link is missing or malformed."
-#: src/pages/DumpEdit.tsx:338
+#: src/pages/DumpEdit.tsx:348
msgid "Thumbnail"
msgstr "Thumbnail"
#: src/components/DumpCreateModal.tsx:386
#: src/components/PlaylistCreateForm.tsx:70
-#: src/pages/DumpEdit.tsx:362
+#: src/pages/DumpEdit.tsx:372
msgid "Title"
msgstr "Title"
@@ -1015,11 +1032,11 @@ msgstr "Title"
msgid "Title is required."
msgstr "Title is required."
-#: src/pages/Notifications.tsx:390
+#: src/pages/Notifications.tsx:392
msgid "Today"
msgstr "Today"
-#: src/pages/PlaylistDetail.tsx:738
+#: src/pages/PlaylistDetail.tsx:747
msgid "Undo"
msgstr "Undo"
@@ -1031,7 +1048,7 @@ msgstr "Unfollow {targetUsername}"
msgid "Unfollow playlist"
msgstr "Unfollow playlist"
-#: src/pages/UserPublicProfile.tsx:680
+#: src/pages/UserPublicProfile.tsx:689
msgid "Upload failed"
msgstr "Upload failed"
@@ -1043,18 +1060,18 @@ msgstr "Uploading…"
msgid "Upvote"
msgstr "Upvote"
-#: src/pages/UserUpvoted.tsx:151
+#: src/pages/UserUpvoted.tsx:154
msgid "Upvoted"
msgstr "Upvoted"
#. placeholder {0}: votes.items.length
#. placeholder {1}: votes.hasMore ? "+" : ""
-#: src/pages/UserPublicProfile.tsx:911
+#: src/pages/UserPublicProfile.tsx:920
msgid "Upvoted ({0}{1})"
msgstr "Upvoted ({0}{1})"
#: src/components/DumpCreateModal.tsx:335
-#: src/pages/DumpEdit.tsx:385
+#: src/pages/DumpEdit.tsx:395
msgid "URL"
msgstr "URL"
@@ -1062,11 +1079,11 @@ msgstr "URL"
msgid "URL is required."
msgstr "URL is required."
-#: src/pages/UserPublicProfile.tsx:1518
+#: src/pages/UserPublicProfile.tsx:1527
msgid "User"
msgstr "User"
-#: src/pages/UserPublicProfile.tsx:1246
+#: src/pages/UserPublicProfile.tsx:1255
msgid "User management"
msgstr "User management"
@@ -1074,20 +1091,20 @@ msgstr "User management"
msgid "User menu"
msgstr "User menu"
-#: src/pages/UserLogin.tsx:65
-#: src/pages/UserRegister.tsx:114
+#: src/pages/UserLogin.tsx:67
+#: src/pages/UserRegister.tsx:116
msgid "Username"
msgstr "Username"
-#: src/pages/Search.tsx:174
+#: src/pages/Search.tsx:176
msgid "Users"
msgstr "Users"
-#: src/pages/UserPublicProfile.tsx:981
-#: src/pages/UserPublicProfile.tsx:1024
-#: src/pages/UserPublicProfile.tsx:1066
-#: src/pages/UserPublicProfile.tsx:1330
-#: src/pages/UserPublicProfile.tsx:1461
+#: src/pages/UserPublicProfile.tsx:990
+#: src/pages/UserPublicProfile.tsx:1033
+#: src/pages/UserPublicProfile.tsx:1075
+#: src/pages/UserPublicProfile.tsx:1339
+#: src/pages/UserPublicProfile.tsx:1470
msgid "View all →"
msgstr "View all →"
@@ -1096,17 +1113,17 @@ msgid "View dump →"
msgstr "View dump →"
#: src/components/DumpCreateModal.tsx:431
-#: src/pages/DumpEdit.tsx:415
+#: src/pages/DumpEdit.tsx:425
msgid "What makes it worth it?"
msgstr "What makes it worth it?"
-#: src/pages/UserPublicProfile.tsx:865
-#: src/pages/UserPublicProfile.tsx:1688
+#: src/pages/UserPublicProfile.tsx:874
+#: src/pages/UserPublicProfile.tsx:1697
msgid "Who am I?"
msgstr "Who am I?"
#: src/components/DumpCreateModal.tsx:430
-#: src/pages/DumpEdit.tsx:414
+#: src/pages/DumpEdit.tsx:424
msgid "Why?"
msgstr "Why?"
@@ -1114,11 +1131,11 @@ msgstr "Why?"
msgid "Write a reply…"
msgstr "Write a reply…"
-#: src/pages/Notifications.tsx:392
+#: src/pages/Notifications.tsx:394
msgid "Yesterday"
msgstr "Yesterday"
-#: src/pages/Notifications.tsx:377
+#: src/pages/Notifications.tsx:379
msgid "You'll be notified when someone follows your playlists, upvotes your dumps, or posts new content."
msgstr "You'll be notified when someone follows your playlists, upvotes your dumps, or posts new content."
@@ -1126,18 +1143,18 @@ msgstr "You'll be notified when someone follows your playlists, upvotes your dum
#: src/pages/index/HotFeed.tsx:69
#: src/pages/index/JournalFeed.tsx:67
#: src/pages/index/NewFeed.tsx:69
-#: src/pages/Search.tsx:247
-#: src/pages/UserDumps.tsx:123
-#: src/pages/UserPlaylists.tsx:422
-#: src/pages/UserPlaylists.tsx:457
-#: src/pages/UserUpvoted.tsx:192
+#: src/pages/Search.tsx:249
+#: src/pages/UserDumps.tsx:126
+#: src/pages/UserPlaylists.tsx:425
+#: src/pages/UserPlaylists.tsx:460
+#: src/pages/UserUpvoted.tsx:195
msgid "You've reached the end."
msgstr "You've reached the end."
-#: src/pages/UserLogin.tsx:134
+#: src/pages/UserLogin.tsx:136
msgid "Your email address"
msgstr "Your email address"
-#: src/pages/ResetPassword.tsx:74
+#: src/pages/ResetPassword.tsx:76
msgid "Your password has been changed. You can now log in."
msgstr "Your password has been changed. You can now log in."
diff --git a/src/locales/fr.js b/src/locales/fr.js
index 6059fc1..4f94bc5 100644
--- a/src/locales/fr.js
+++ b/src/locales/fr.js
@@ -1 +1 @@
-/*eslint-disable*/module.exports={messages:JSON.parse("{\"-K9EZb\":[\"Ajouter un e-mail…\"],\"-OxI15\":[\"Collections suivies\"],\"-Ya-b9\":[\"Enregistrement échoué\"],\"-siMqD\":[\"Journal\"],\"1CalO6\":[\"Style\"],\"1HfJWf\":[\"Rechercher des recos, utilisateurs, collections…\"],\"1cbYY_\":[\"Votés (\",[\"0\"],[\"1\"],\")\"],\"1njn7W\":[\"Clair\"],\"1utXA6\":[\"Recos\"],\"26iNma\":[\"Publier le commentaire\"],\"2DoBvq\":[\"Flux\"],\"2Hlmdt\":[\"Écrire une réponse…\"],\"2ygf_L\":[\"← Retour\"],\"3KKSM4\":[\"privé\"],\"3yfh3D\":[\"<0>\",[\"0\"],\"0> a suivi votre collection <1>\",[\"1\"],\"1>\"],\"49voTZ\":[[\"label\"],\" (\",[\"count\"],\")\"],\"4B6w_o\":[\"Recommandé !\"],\"4GKuCs\":[\"Connexion échouée\"],\"4HH9iB\":[\"Aucun abonnement pour le moment.\"],\"4RtQ1k\":[\"Ne plus suivre \",[\"targetUsername\"]],\"4c-qBx\":[\"Votre mot de passe a été modifié. Vous pouvez maintenant vous connecter.\"],\"4yj9xV\":[\"Les mises à jour en direct sont temporairement interrompues. Tentative de reconnexion…\"],\"5TviPn\":[\"Annuler la recherche\"],\"5cC8f2\":[\"Modifié le \",[\"0\"]],\"5oD9f_\":[\"Plus tôt\"],\"6Qly-0\":[\"un commentaire\"],\"6gRgw8\":[\"Réessayer\"],\"7PHCIN\":[\"Annuler la suppression\"],\"7PzzBU\":[\"Utilisateur\"],\"7d1a0d\":[\"Public\"],\"7sNhEz\":[\"Nom d'utilisateur\"],\"8Ug9jB\":[\"Connexe\"],\"8ZsakT\":[\"Mot de passe\"],\"8pxhI8\":[\"Veuillez sélectionner un fichier.\"],\"9BruTc\":[\"Pourquoi ?\"],\"9l4qcT\":[\"Déposez un fichier de remplacement ici\"],\"9uI_rE\":[\"Annuler\"],\"9xDZu_\":[\"Impossible de charger.\"],\"A0y396\":[\"+ Inviter quelqu'un\"],\"A1taO8\":[\"Rechercher\"],\"AQbgNR\":[\"Suivre \",[\"targetUsername\"]],\"ATGYL1\":[\"Adresse e-mail\"],\"AZctoV\":[[\"0\",\"plural\",{\"one\":[\"#\",\" commentaire\"],\"other\":[\"#\",\" commentaires\"]}]],\"Ade-6d\":[\"Mises à jour en direct indisponibles.\"],\"AeXO77\":[\"Compte\"],\"CI50ct\":[\"Voté\"],\"Cj24wt\":[\"Inscription…\"],\"DPfwMq\":[\"Terminé\"],\"DdeHXH\":[\"Supprimer cette reco ? Cette action est irréversible.\"],\"Dp1JhP\":[\"<0>\",[\"0\"],\"0> a voté pour <1>\",[\"1\"],\"1>\"],\"ECiS12\":[\"Voir la reco →\"],\"ExR0Fr\":[\"L'URL est obligatoire.\"],\"F5Js1v\":[\"Ne plus suivre la collection\"],\"FgAxTj\":[\"Se déconnecter\"],\"Fxf4jq\":[\"Description (facultatif)\"],\"GDvlUT\":[\"Rôle\"],\"GLukaH\":[\"Modérateur\"],\"GNSsCc\":[\"Impossible de créer la collection\"],\"GbqhrN\":[[\"0\"],\"–\",[\"1\"],\" caractères : lettres, chiffres ou tirets bas\"],\"GptGxg\":[\"Changer le mot de passe\"],\"H4o4sk\":[\"Personne pour le moment.\"],\"H8pzW-\":[\"Impossible de mettre à jour l'avatar\"],\"HTLDA4\":[\"Chargement…\"],\"I-x669\":[\"Invités\"],\"IZX7TO\":[\"Impossible de générer une invitation\"],\"IagCbF\":[\"URL\"],\"ImOQa9\":[\"Répondre\"],\"J2eKUI\":[\"Fichier\"],\"JJ-Bhk\":[\"Votre adresse e-mail\"],\"JRQitQ\":[\"Confirmer le nouveau mot de passe\"],\"JXr41k\":[\"<0>\",[\"0\"],\"0> a commenté sur <1>\",[\"1\"],\"1>\"],\"Jd58Fo\":[\"Tendances\"],\"Jf0PuK\":[\"Aller à la connexion\"],\"KDGWg5\":[\"Retirer de la collection\"],\"K_F6pa\":[\"Enregistrement…\"],\"L-rMC9\":[\"Réinitialiser par défaut\"],\"LLyMkV\":[\"Suivies (\",[\"0\"],[\"1\"],\")\"],\"MHrjPM\":[\"Titre\"],\"MKEPCY\":[\"Suivre\"],\"Oprv1v\":[\"Mot de passe (min. \",[\"0\"],\" caractères)\"],\"Oz0N9s\":[\"nouveau\"],\"PiH3UR\":[\"Copié !\"],\"Pn2B7_\":[\"Mot de passe actuel\"],\"Pwqkdw\":[\"Chargement…\"],\"Q6n4F4\":[\"Actualiser les métadonnées\"],\"QGaQRo\":[\"Erreur lors de la mise à jour du rôle\"],\"QKsaQr\":[\"ou <0>parcourir les fichiers0>\"],\"QLtPBd\":[\"Aucune reco dans cette collection pour l'instant.\"],\"R9Khdg\":[\"Auto\"],\"RCcPrX\":[\"Supprimer cette collection ? Cette action est irréversible.\"],\"RTksSy\":[\"<0>\",[\"0\"],\"0> a commencé à vous suivre\"],\"RaKjrM\":[\"Impossible d'enregistrer la modification\"],\"RcUHRT\":[\"Suivi\"],\"Rrp6-J\":[\"Se connecter pour aimer\"],\"SBTElJ\":[\"Recherche…\"],\"Sad2tK\":[\"Envoi…\"],\"StovX6\":[\"Rien à voir, circulez.\"],\"Sxm8rQ\":[\"Utilisateurs\"],\"T9bjWt\":[\"<0>\",[\"0\"],\"0> a été ajouté à <1>\",[\"1\"],\"1>\"],\"TM1ZbA\":[\"Collections (\",[\"0\"],[\"1\"],\")\"],\"TN382O\":[\"Lien invalide\"],\"Tv9vbB\":[\"Suivre la collection\"],\"Tz0i8g\":[\"Paramètres\"],\"U3pytU\":[\"Administrateur\"],\"UNMVei\":[\"Mot de passe oublié ?\"],\"UOZith\":[\"Publication échouée\"],\"URAieT\":[\"Se connecter pour voter\"],\"UTiUFs\":[\"Récupération…\"],\"VCoEm-\":[\"Retour à la connexion\"],\"V_e7nf\":[\"Définir un nouveau mot de passe\"],\"VnNJbN\":[\"De collections\"],\"VyTYmS\":[\"Changer l'avatar\"],\"W9FRBT\":[\"Aimer\"],\"WhimMi\":[\"Échec de la réinitialisation\"],\"WpXcBJ\":[\"Rien ici pour l'instant.\"],\"XJy2oN\":[\"Connexion…\"],\"Xan6QP\":[\"Nouvelle reco\"],\"XgRtUf\":[\"Impossible de changer le mot de passe\"],\"Xi0Mn4\":[\"← Retour au profil\"],\"XnL-Eu\":[\"Aucun utilisateur ne correspond à « \",[\"q\"],\" ».\"],\"Xs2Lez\":[\"Ce lien de réinitialisation est absent ou malformé.\"],\"YK1Dhc\":[\"une publication\"],\"YcjhhX\":[\"Gestion utilisateur\"],\"Ye9RMF\":[\"<0>\",[\"0\"],\"0> a aimé votre commentaire sur <1>\",[\"1\"],\"1>\"],\"YpkCca\":[\"Pas encore de collections suivies.\"],\"ZBdbv9\":[\"Modifier le titre\"],\"ZCpU0u\":[\"Aucune collection ne correspond à « \",[\"q\"],\" ».\"],\"ZmD2o6\":[\"Créer et ajouter\"],\"_3O5R_\":[\"Échec de la demande\"],\"_DwR-n\":[\"Création…\"],\"_R_sGB\":[\"Mot de passe modifié avec succès.\"],\"_aept4\":[\"Publier la réponse\"],\"_nT6AE\":[\"Nouveau mot de passe\"],\"_t4W-i\":[\"De personnes\"],\"aAIQg2\":[\"Apparence\"],\"aDvLhk\":[\"Ajouter un commentaire…\"],\"b3Thhd\":[\"Envoi échoué\"],\"b8XMJ8\":[[\"visibleCount\",\"plural\",{\"one\":[\"#\",\" commentaire\"],\"other\":[\"#\",\" commentaires\"]}]],\"bQhwn-\":[\"Chargement de la collection…\"],\"cILfnJ\":[\"Supprimer le fichier\"],\"cYP9Sb\":[\"+ Collection\"],\"cbeBbZ\":[\"Au moins \",[\"0\"],\" caractères\"],\"cnGeoo\":[\"Supprimer\"],\"d8DZWS\":[\"Ouvrir la recherche\"],\"dAs22m\":[\"Remplacer le fichier\"],\"dEgA5A\":[\"Annuler\"],\"dMizp8\":[\"Nouvelle collection\"],\"eFSqvc\":[\"Impossible de publier la réponse\"],\"eOfXq3\":[\"Un titre est requis.\"],\"ePK91l\":[\"Modifier\"],\"eaUTwS\":[\"Envoyer le lien de réinitialisation\"],\"ecUA8p\":[\"Aujourd'hui\"],\"ef9nPf\":[\"Chargement de la reco…\"],\"en9o7K\":[\"Impossible de publier le commentaire\"],\"etFQQS\":[\"Pourquoi on en voudrait ?\"],\"fC6mXb\":[\"Voter\"],\"fI-mNw\":[\"Collections\"],\"f_akpP\":[\"Max 50 Mo\"],\"fgLNSM\":[\"S'inscrire\"],\"gANddk\":[\"Envoi…\"],\"gGx5tM\":[\"Modification\"],\"gIQQwD\":[\"Chargement échoué\"],\"gLfZlz\":[\"Ajouter à la collection\"],\"gjJ-sb\":[\"Impossible de se connecter au serveur de mises à jour en direct. Les votes et les notifications pourraient ne pas se synchroniser avant la reconnexion.\"],\"hBuUKa\":[\"Changer le mot de passe…\"],\"hD7w09\":[\"Vous avez tout lu, tout vu, tout bu.\"],\"hJSliC\":[\"<0>\",[\"0\"],\"0> a publié <1>\",[\"1\"],\"1>\"],\"hYgDIe\":[\"Créer\"],\"he3ygx\":[\"Copier\"],\"i7K_Te\":[\"Qui suis-je ?\"],\"iDNBZe\":[\"Notifications\"],\"iWpEwy\":[\"Accueil\"],\"ipYn7W\":[\"Si cette adresse est enregistrée, vous recevrez un lien de réinitialisation sous peu.\"],\"isRobC\":[\"Nouveau\"],\"jbernk\":[\"Chargement du profil…\"],\"joEmfT\":[\"Serveur inaccessible\"],\"jrZTZl\":[\"Pas encore de recos. Soyez le premier !\"],\"kLttbL\":[\"Inscription échouée\"],\"lUDifl\":[\"Créées (\",[\"0\"],[\"1\"],\")\"],\"lUanmi\":[\"Vous serez notifié lorsque quelqu'un suit vos collections, vote pour vos recos ou publie du nouveau contenu.\"],\"lY5h1V\":[[\"0\",\"plural\",{\"one\":[\"#\",\" reco\"],\"other\":[\"#\",\" recos\"]}]],\"lcfvr_\":[\"Supprimer ce commentaire ?\"],\"lpIMne\":[\"Les mots de passe ne correspondent pas\"],\"mt6O6E\":[\"C'est un mirage.\"],\"nbm5sI\":[\"Aucune reco ne correspond à « \",[\"q\"],\" ».\"],\"nrjqON\":[\"Vérification de l'invitation…\"],\"nwtY4N\":[\"Une erreur est survenue\"],\"nx4kaN\":[\"Sauvegarde impossible\"],\"ogtYkT\":[\"Mot de passe mis à jour\"],\"pCpd9p\":[\"<0>\",[\"0\"],\"0> vous a mentionné dans <1>\",[\"where\"],\"1>\"],\"pSheLH\":[\"Aucun invité pour le moment.\"],\"pvnfJD\":[\"Sombre\"],\"qIMfNQ\":[\"Supprimer la collection\"],\"qbDAcy\":[\"Recommander\"],\"qgx_78\":[\"Suivez des collections publiques pour voir leurs recos ici.\"],\"qvFa8r\":[\"public\"],\"qvz_Pp\":[\"Reco\"],\"rCbqPX\":[\"Ce lien d'invitation est manquant, expiré ou déjà utilisé.\"],\"rg9pXu\":[\"Recherche échouée\"],\"rtpJqV\":[\"Recos (\",[\"0\"],[\"1\"],\")\"],\"sGeXL3\":[\"Miniature\"],\"sQia9P\":[\"Se connecter\"],\"sTiqbm\":[\"invité par\"],\"sdP5Aa\":[\"[supprimé]\"],\"shHs8T\":[\"Saisissez une recherche.\"],\"smeBfS\":[\"Invitation invalide\"],\"tfDRzk\":[\"Enregistrer\"],\"tvmuQ0\":[\"Thème de couleur\"],\"u1lDX2\":[\"Récupération de l'aperçu…\"],\"uD0qXQ\":[\"Déposez un fichier ici\"],\"uMGUnV\":[\"Pas encore de collections.\"],\"ub1EEL\":[\"modifié \",[\"0\"]],\"vJBF1r\":[\"Publication…\"],\"vLhLLO\":[\"Notifications (\",[\"unreadNotificationCount\"],\" non lues)\"],\"vQMkHu\":[\"Retirer le vote\"],\"vuosjb\":[\"Menu utilisateur\"],\"wbXKOv\":[\"Fichier trop volumineux (max 50 Mo).\"],\"wckWOP\":[\"Administration\"],\"wixIgH\":[\"Vous avez déjà un compte ? <0>Se connecter0>\"],\"x6tjuK\":[\"Onglet par défaut\"],\"xEWkgZ\":[\"← Retour à toutes les recos\"],\"xPHtx0\":[\"Lancer la recherche\"],\"xVuNgt\":[\"+ Nouvelle collection\"],\"xc9O_u\":[\"Supprimer la reco\"],\"y6sq5j\":[\"Abonné\"],\"y7oaHj\":[\"Titre de la collection\"],\"yA_6BX\":[\"Tout voir →\"],\"yBBtRm\":[\"Suivez des utilisateurs pour voir leurs recos ici.\"],\"yQ2kGp\":[\"Charger plus\"],\"y_0uwd\":[\"Hier\"],\"yz7wBu\":[\"Fermer\"],\"z0ROB3\":[\"Retirer le j'aime\"],\"z1uNN0\":[\"Aucun emoji trouvé.\"],\"zVuxvN\":[\"Actualisation…\"],\"zwBp5t\":[\"Privé\"]}")};
\ No newline at end of file
+/*eslint-disable*/module.exports={messages:JSON.parse("{\"-K9EZb\":[\"Ajouter un e-mail…\"],\"-OxI15\":[\"Collections suivies\"],\"-Ya-b9\":[\"Enregistrement échoué\"],\"-siMqD\":[\"Journal\"],\"1CalO6\":[\"Style\"],\"1HfJWf\":[\"Rechercher des recos, utilisateurs, collections…\"],\"1cbYY_\":[\"Votés (\",[\"0\"],[\"1\"],\")\"],\"1njn7W\":[\"Clair\"],\"1utXA6\":[\"Recos\"],\"26iNma\":[\"Publier le commentaire\"],\"2DoBvq\":[\"Flux\"],\"2Hlmdt\":[\"Écrire une réponse…\"],\"2ygf_L\":[\"← Retour\"],\"3KKSM4\":[\"privé\"],\"3yfh3D\":[\"<0>\",[\"0\"],\"0> a suivi votre collection <1>\",[\"1\"],\"1>\"],\"49voTZ\":[[\"label\"],\" (\",[\"count\"],\")\"],\"4B6w_o\":[\"Recommandé !\"],\"4GKuCs\":[\"Connexion échouée\"],\"4HH9iB\":[\"Aucun abonnement pour le moment.\"],\"4RtQ1k\":[\"Ne plus suivre \",[\"targetUsername\"]],\"4c-qBx\":[\"Votre mot de passe a été modifié. Vous pouvez maintenant vous connecter.\"],\"4yj9xV\":[\"Les mises à jour en direct sont temporairement interrompues. Tentative de reconnexion…\"],\"5TviPn\":[\"Annuler la recherche\"],\"5cC8f2\":[\"Modifié le \",[\"0\"]],\"5oD9f_\":[\"Plus tôt\"],\"6Qly-0\":[\"un commentaire\"],\"6YE0P6\":[\"Édition de \",[\"0\"]],\"6gRgw8\":[\"Réessayer\"],\"7PHCIN\":[\"Annuler la suppression\"],\"7PzzBU\":[\"Utilisateur\"],\"7d1a0d\":[\"Public\"],\"7sNhEz\":[\"Nom d'utilisateur\"],\"8F1i42\":[\"Page introuvable\"],\"8Ug9jB\":[\"Connexe\"],\"8ZsakT\":[\"Mot de passe\"],\"8pxhI8\":[\"Veuillez sélectionner un fichier.\"],\"9BruTc\":[\"Pourquoi ?\"],\"9l4qcT\":[\"Déposez un fichier de remplacement ici\"],\"9uI_rE\":[\"Annuler\"],\"9xDZu_\":[\"Impossible de charger.\"],\"A0y396\":[\"+ Inviter quelqu'un\"],\"A1taO8\":[\"Rechercher\"],\"AQbgNR\":[\"Suivre \",[\"targetUsername\"]],\"ATGYL1\":[\"Adresse e-mail\"],\"AZctoV\":[[\"0\",\"plural\",{\"one\":[\"#\",\" commentaire\"],\"other\":[\"#\",\" commentaires\"]}]],\"Ade-6d\":[\"Mises à jour en direct indisponibles.\"],\"AeXO77\":[\"Compte\"],\"CI50ct\":[\"Voté\"],\"Cj24wt\":[\"Inscription…\"],\"DPfwMq\":[\"Terminé\"],\"DdeHXH\":[\"Supprimer cette reco ? Cette action est irréversible.\"],\"Dp1JhP\":[\"<0>\",[\"0\"],\"0> a voté pour <1>\",[\"1\"],\"1>\"],\"ECiS12\":[\"Voir la reco →\"],\"ExR0Fr\":[\"L'URL est obligatoire.\"],\"F5Js1v\":[\"Ne plus suivre la collection\"],\"FgAxTj\":[\"Se déconnecter\"],\"Fxf4jq\":[\"Description (facultatif)\"],\"GDvlUT\":[\"Rôle\"],\"GLukaH\":[\"Modérateur\"],\"GNSsCc\":[\"Impossible de créer la collection\"],\"GbqhrN\":[[\"0\"],\"–\",[\"1\"],\" caractères : lettres, chiffres ou tirets bas\"],\"GptGxg\":[\"Changer le mot de passe\"],\"H4o4sk\":[\"Personne pour le moment.\"],\"H8pzW-\":[\"Impossible de mettre à jour l'avatar\"],\"HTLDA4\":[\"Chargement…\"],\"I-x669\":[\"Invités\"],\"IZX7TO\":[\"Impossible de générer une invitation\"],\"IagCbF\":[\"URL\"],\"ImOQa9\":[\"Répondre\"],\"J2eKUI\":[\"Fichier\"],\"JJ-Bhk\":[\"Votre adresse e-mail\"],\"JRQitQ\":[\"Confirmer le nouveau mot de passe\"],\"JXr41k\":[\"<0>\",[\"0\"],\"0> a commenté sur <1>\",[\"1\"],\"1>\"],\"Jd58Fo\":[\"Tendances\"],\"Jf0PuK\":[\"Aller à la connexion\"],\"KDGWg5\":[\"Retirer de la collection\"],\"K_F6pa\":[\"Enregistrement…\"],\"L-rMC9\":[\"Réinitialiser par défaut\"],\"LLyMkV\":[\"Suivies (\",[\"0\"],[\"1\"],\")\"],\"MHrjPM\":[\"Titre\"],\"MKEPCY\":[\"Suivre\"],\"Oprv1v\":[\"Mot de passe (min. \",[\"0\"],\" caractères)\"],\"Oz0N9s\":[\"nouveau\"],\"PiH3UR\":[\"Copié !\"],\"Pn2B7_\":[\"Mot de passe actuel\"],\"Pwqkdw\":[\"Chargement…\"],\"Q6n4F4\":[\"Actualiser les métadonnées\"],\"QGaQRo\":[\"Erreur lors de la mise à jour du rôle\"],\"QKsaQr\":[\"ou <0>parcourir les fichiers0>\"],\"QLtPBd\":[\"Aucune reco dans cette collection pour l'instant.\"],\"R9Khdg\":[\"Auto\"],\"RCcPrX\":[\"Supprimer cette collection ? Cette action est irréversible.\"],\"RTksSy\":[\"<0>\",[\"0\"],\"0> a commencé à vous suivre\"],\"RaKjrM\":[\"Impossible d'enregistrer la modification\"],\"RcUHRT\":[\"Suivi\"],\"RfwZxd\":[\"Réinitialiser le mot de passe\"],\"Rrp6-J\":[\"Se connecter pour aimer\"],\"SBTElJ\":[\"Recherche…\"],\"Sad2tK\":[\"Envoi…\"],\"StovX6\":[\"Rien à voir, circulez.\"],\"Sxm8rQ\":[\"Utilisateurs\"],\"T9bjWt\":[\"<0>\",[\"0\"],\"0> a été ajouté à <1>\",[\"1\"],\"1>\"],\"TM1ZbA\":[\"Collections (\",[\"0\"],[\"1\"],\")\"],\"TN382O\":[\"Lien invalide\"],\"Tv9vbB\":[\"Suivre la collection\"],\"Tz0i8g\":[\"Paramètres\"],\"U3pytU\":[\"Administrateur\"],\"UNMVei\":[\"Mot de passe oublié ?\"],\"UOZith\":[\"Publication échouée\"],\"URAieT\":[\"Se connecter pour voter\"],\"UTiUFs\":[\"Récupération…\"],\"VCoEm-\":[\"Retour à la connexion\"],\"V_e7nf\":[\"Définir un nouveau mot de passe\"],\"VnNJbN\":[\"De collections\"],\"VyTYmS\":[\"Changer l'avatar\"],\"W9FRBT\":[\"Aimer\"],\"WhimMi\":[\"Échec de la réinitialisation\"],\"WpXcBJ\":[\"Rien ici pour l'instant.\"],\"XJy2oN\":[\"Connexion…\"],\"Xan6QP\":[\"Nouvelle reco\"],\"XgRtUf\":[\"Impossible de changer le mot de passe\"],\"Xi0Mn4\":[\"← Retour au profil\"],\"XnL-Eu\":[\"Aucun utilisateur ne correspond à « \",[\"q\"],\" ».\"],\"Xs2Lez\":[\"Ce lien de réinitialisation est absent ou malformé.\"],\"YK1Dhc\":[\"une publication\"],\"YcjhhX\":[\"Gestion utilisateur\"],\"Ye9RMF\":[\"<0>\",[\"0\"],\"0> a aimé votre commentaire sur <1>\",[\"1\"],\"1>\"],\"YpkCca\":[\"Pas encore de collections suivies.\"],\"ZBdbv9\":[\"Modifier le titre\"],\"ZCpU0u\":[\"Aucune collection ne correspond à « \",[\"q\"],\" ».\"],\"ZmD2o6\":[\"Créer et ajouter\"],\"_3O5R_\":[\"Échec de la demande\"],\"_DwR-n\":[\"Création…\"],\"_R_sGB\":[\"Mot de passe modifié avec succès.\"],\"_aept4\":[\"Publier la réponse\"],\"_nT6AE\":[\"Nouveau mot de passe\"],\"_t4W-i\":[\"De personnes\"],\"aAIQg2\":[\"Apparence\"],\"aDvLhk\":[\"Ajouter un commentaire…\"],\"b3Thhd\":[\"Envoi échoué\"],\"b8XMJ8\":[[\"visibleCount\",\"plural\",{\"one\":[\"#\",\" commentaire\"],\"other\":[\"#\",\" commentaires\"]}]],\"bQhwn-\":[\"Chargement de la collection…\"],\"cILfnJ\":[\"Supprimer le fichier\"],\"cYP9Sb\":[\"+ Collection\"],\"cbeBbZ\":[\"Au moins \",[\"0\"],\" caractères\"],\"cnGeoo\":[\"Supprimer\"],\"d8DZWS\":[\"Ouvrir la recherche\"],\"dAs22m\":[\"Remplacer le fichier\"],\"dEgA5A\":[\"Annuler\"],\"dMizp8\":[\"Nouvelle collection\"],\"eFSqvc\":[\"Impossible de publier la réponse\"],\"eOfXq3\":[\"Un titre est requis.\"],\"ePK91l\":[\"Modifier\"],\"eaUTwS\":[\"Envoyer le lien de réinitialisation\"],\"ecUA8p\":[\"Aujourd'hui\"],\"ef9nPf\":[\"Chargement de la reco…\"],\"en9o7K\":[\"Impossible de publier le commentaire\"],\"etFQQS\":[\"Pourquoi on en voudrait ?\"],\"fC6mXb\":[\"Voter\"],\"fI-mNw\":[\"Collections\"],\"f_akpP\":[\"Max 50 Mo\"],\"fgLNSM\":[\"S'inscrire\"],\"gANddk\":[\"Envoi…\"],\"gGx5tM\":[\"Modification\"],\"gIQQwD\":[\"Chargement échoué\"],\"gLfZlz\":[\"Ajouter à la collection\"],\"gjJ-sb\":[\"Impossible de se connecter au serveur de mises à jour en direct. Les votes et les notifications pourraient ne pas se synchroniser avant la reconnexion.\"],\"hBuUKa\":[\"Changer le mot de passe…\"],\"hD7w09\":[\"Vous avez tout lu, tout vu, tout bu.\"],\"hJSliC\":[\"<0>\",[\"0\"],\"0> a publié <1>\",[\"1\"],\"1>\"],\"hYgDIe\":[\"Créer\"],\"he3ygx\":[\"Copier\"],\"i7K_Te\":[\"Qui suis-je ?\"],\"iDNBZe\":[\"Notifications\"],\"iWpEwy\":[\"Accueil\"],\"ipYn7W\":[\"Si cette adresse est enregistrée, vous recevrez un lien de réinitialisation sous peu.\"],\"isRobC\":[\"Nouveau\"],\"jbernk\":[\"Chargement du profil…\"],\"joEmfT\":[\"Serveur inaccessible\"],\"jrZTZl\":[\"Pas encore de recos. Soyez le premier !\"],\"kLttbL\":[\"Inscription échouée\"],\"lUDifl\":[\"Créées (\",[\"0\"],[\"1\"],\")\"],\"lUanmi\":[\"Vous serez notifié lorsque quelqu'un suit vos collections, vote pour vos recos ou publie du nouveau contenu.\"],\"lY5h1V\":[[\"0\",\"plural\",{\"one\":[\"#\",\" reco\"],\"other\":[\"#\",\" recos\"]}]],\"lcfvr_\":[\"Supprimer ce commentaire ?\"],\"lpIMne\":[\"Les mots de passe ne correspondent pas\"],\"mt6O6E\":[\"C'est un mirage.\"],\"nbm5sI\":[\"Aucune reco ne correspond à « \",[\"q\"],\" ».\"],\"nrjqON\":[\"Vérification de l'invitation…\"],\"nwtY4N\":[\"Une erreur est survenue\"],\"nx4kaN\":[\"Sauvegarde impossible\"],\"ogtYkT\":[\"Mot de passe mis à jour\"],\"pCpd9p\":[\"<0>\",[\"0\"],\"0> vous a mentionné dans <1>\",[\"where\"],\"1>\"],\"pSheLH\":[\"Aucun invité pour le moment.\"],\"pvnfJD\":[\"Sombre\"],\"qIMfNQ\":[\"Supprimer la collection\"],\"qbDAcy\":[\"Recommander\"],\"qgx_78\":[\"Suivez des collections publiques pour voir leurs recos ici.\"],\"qvFa8r\":[\"public\"],\"qvz_Pp\":[\"Reco\"],\"rCbqPX\":[\"Ce lien d'invitation est manquant, expiré ou déjà utilisé.\"],\"rg9pXu\":[\"Recherche échouée\"],\"rtpJqV\":[\"Recos (\",[\"0\"],[\"1\"],\")\"],\"sGeXL3\":[\"Miniature\"],\"sQia9P\":[\"Se connecter\"],\"sTiqbm\":[\"invité par\"],\"sdP5Aa\":[\"[supprimé]\"],\"shHs8T\":[\"Saisissez une recherche.\"],\"smeBfS\":[\"Invitation invalide\"],\"tfDRzk\":[\"Enregistrer\"],\"tvmuQ0\":[\"Thème de couleur\"],\"u1lDX2\":[\"Récupération de l'aperçu…\"],\"uD0qXQ\":[\"Déposez un fichier ici\"],\"uMGUnV\":[\"Pas encore de collections.\"],\"ub1EEL\":[\"modifié \",[\"0\"]],\"vJBF1r\":[\"Publication…\"],\"vLhLLO\":[\"Notifications (\",[\"unreadNotificationCount\"],\" non lues)\"],\"vQMkHu\":[\"Retirer le vote\"],\"vuosjb\":[\"Menu utilisateur\"],\"wbXKOv\":[\"Fichier trop volumineux (max 50 Mo).\"],\"wckWOP\":[\"Administration\"],\"wixIgH\":[\"Vous avez déjà un compte ? <0>Se connecter0>\"],\"x6tjuK\":[\"Onglet par défaut\"],\"xEWkgZ\":[\"← Retour à toutes les recos\"],\"xPHtx0\":[\"Lancer la recherche\"],\"xVuNgt\":[\"+ Nouvelle collection\"],\"xc9O_u\":[\"Supprimer la reco\"],\"y6sq5j\":[\"Abonné\"],\"y7oaHj\":[\"Titre de la collection\"],\"yA_6BX\":[\"Tout voir →\"],\"yBBtRm\":[\"Suivez des utilisateurs pour voir leurs recos ici.\"],\"yQ2kGp\":[\"Charger plus\"],\"y_0uwd\":[\"Hier\"],\"yz7wBu\":[\"Fermer\"],\"z0ROB3\":[\"Retirer le j'aime\"],\"z1uNN0\":[\"Aucun emoji trouvé.\"],\"zVuxvN\":[\"Actualisation…\"],\"zwBp5t\":[\"Privé\"]}")};
\ No newline at end of file
diff --git a/src/locales/fr.po b/src/locales/fr.po
index c324bbf..d067e87 100644
--- a/src/locales/fr.po
+++ b/src/locales/fr.po
@@ -30,11 +30,11 @@ msgstr "{0, plural, one {# reco} other {# recos}}"
#. placeholder {0}: VALIDATION.USERNAME_MIN
#. placeholder {1}: VALIDATION.USERNAME_MAX
-#: src/pages/UserRegister.tsx:124
+#: src/pages/UserRegister.tsx:126
msgid "{0}–{1} characters: letters, numbers, or underscores"
msgstr "{0}–{1} caractères : lettres, chiffres ou tirets bas"
-#: src/pages/Search.tsx:176
+#: src/pages/Search.tsx:178
msgid "{label} ({count})"
msgstr "{label} ({count})"
@@ -42,24 +42,24 @@ msgstr "{label} ({count})"
msgid "{visibleCount, plural, one {# comment} other {# comments}}"
msgstr "{visibleCount, plural, one {# commentaire} other {# commentaires}}"
-#: src/pages/PlaylistDetail.tsx:561
-#: src/pages/UserPublicProfile.tsx:732
+#: src/pages/PlaylistDetail.tsx:570
+#: src/pages/UserPublicProfile.tsx:741
msgid "← Back"
msgstr "← Retour"
-#: src/pages/Dump.tsx:250
-#: src/pages/Dump.tsx:463
-#: src/pages/DumpEdit.tsx:168
+#: src/pages/Dump.tsx:259
+#: src/pages/Dump.tsx:472
+#: src/pages/DumpEdit.tsx:178
msgid "← Back to all dumps"
msgstr "← Retour à toutes les recos"
-#: src/pages/UserDumps.tsx:63
-#: src/pages/UserPlaylists.tsx:354
-#: src/pages/UserUpvoted.tsx:134
+#: src/pages/UserDumps.tsx:66
+#: src/pages/UserPlaylists.tsx:357
+#: src/pages/UserUpvoted.tsx:137
msgid "← Back to profile"
msgstr "← Retour au profil"
-#: src/pages/UserPublicProfile.tsx:113
+#: src/pages/UserPublicProfile.tsx:114
msgid "+ Invite someone"
msgstr "+ Inviter quelqu'un"
@@ -67,65 +67,65 @@ msgstr "+ Inviter quelqu'un"
msgid "+ New playlist"
msgstr "+ Nouvelle collection"
-#: src/pages/Dump.tsx:318
+#: src/pages/Dump.tsx:327
msgid "+ Playlist"
msgstr "+ Collection"
#. placeholder {0}: d.commenterUsername
#. placeholder {1}: d.dumpTitle
-#: src/pages/Notifications.tsx:194
+#: src/pages/Notifications.tsx:195
msgid "<0>{0}0> commented on <1>{1}1>"
msgstr "<0>{0}0> a commenté sur <1>{1}1>"
#. placeholder {0}: d.followerUsername
#. placeholder {1}: d.playlistTitle
-#: src/pages/Notifications.tsx:154
+#: src/pages/Notifications.tsx:155
msgid "<0>{0}0> followed your playlist <1>{1}1>"
msgstr "<0>{0}0> a suivi votre collection <1>{1}1>"
#. placeholder {0}: d.likerUsername
#. placeholder {1}: d.dumpTitle
-#: src/pages/Notifications.tsx:204
+#: src/pages/Notifications.tsx:205
msgid "<0>{0}0> liked your comment on <1>{1}1>"
msgstr "<0>{0}0> a aimé votre commentaire sur <1>{1}1>"
#. placeholder {0}: d.mentionerUsername
-#: src/pages/Notifications.tsx:216
+#: src/pages/Notifications.tsx:217
msgid "<0>{0}0> mentioned you in <1>{where}1>"
msgstr "<0>{0}0> vous a mentionné dans <1>{where}1>"
#. placeholder {0}: d.dumperUsername
#. placeholder {1}: d.dumpTitle
-#: src/pages/Notifications.tsx:164
+#: src/pages/Notifications.tsx:165
msgid "<0>{0}0> posted <1>{1}1>"
msgstr "<0>{0}0> a publié <1>{1}1>"
#. placeholder {0}: d.followerUsername
-#: src/pages/Notifications.tsx:145
+#: src/pages/Notifications.tsx:146
msgid "<0>{0}0> started following you"
msgstr "<0>{0}0> a commencé à vous suivre"
#. placeholder {0}: d.voterUsername
#. placeholder {1}: d.dumpTitle
-#: src/pages/Notifications.tsx:184
+#: src/pages/Notifications.tsx:185
msgid "<0>{0}0> upvoted <1>{1}1>"
msgstr "<0>{0}0> a voté pour <1>{1}1>"
#. placeholder {0}: d.dumpTitle
#. placeholder {1}: d.playlistTitle
-#: src/pages/Notifications.tsx:174
+#: src/pages/Notifications.tsx:175
msgid "<0>{0}0> was added to <1>{1}1>"
msgstr "<0>{0}0> a été ajouté à <1>{1}1>"
-#: src/pages/Notifications.tsx:214
+#: src/pages/Notifications.tsx:215
msgid "a comment"
msgstr "un commentaire"
-#: src/pages/Notifications.tsx:214
+#: src/pages/Notifications.tsx:215
msgid "a post"
msgstr "une publication"
-#: src/pages/UserPublicProfile.tsx:1111
+#: src/pages/UserPublicProfile.tsx:1120
msgid "Account"
msgstr "Compte"
@@ -133,7 +133,7 @@ msgstr "Compte"
msgid "Add a comment…"
msgstr "Ajouter un commentaire…"
-#: src/pages/UserPublicProfile.tsx:807
+#: src/pages/UserPublicProfile.tsx:816
msgid "Add email…"
msgstr "Ajouter un e-mail…"
@@ -142,31 +142,31 @@ msgstr "Ajouter un e-mail…"
msgid "Add to playlist"
msgstr "Ajouter à la collection"
-#: src/pages/UserPublicProfile.tsx:1520
+#: src/pages/UserPublicProfile.tsx:1529
msgid "Admin"
msgstr "Administrateur"
-#: src/pages/UserRegister.tsx:154
+#: src/pages/UserRegister.tsx:156
msgid "Already have an account? <0>Log in0>"
msgstr "Vous avez déjà un compte ? <0>Se connecter0>"
-#: src/pages/UserPublicProfile.tsx:1130
+#: src/pages/UserPublicProfile.tsx:1139
msgid "Appearance"
msgstr "Apparence"
#. placeholder {0}: VALIDATION.PASSWORD_MIN
#: src/components/ChangePasswordModal.tsx:82
-#: src/pages/ResetPassword.tsx:109
-#: src/pages/UserRegister.tsx:143
+#: src/pages/ResetPassword.tsx:111
+#: src/pages/UserRegister.tsx:145
msgid "At least {0} characters"
msgstr "Au moins {0} caractères"
-#: src/pages/UserPublicProfile.tsx:1178
+#: src/pages/UserPublicProfile.tsx:1187
msgid "Auto"
msgstr "Auto"
-#: src/pages/ResetPassword.tsx:59
-#: src/pages/ResetPassword.tsx:132
+#: src/pages/ResetPassword.tsx:61
+#: src/pages/ResetPassword.tsx:134
msgid "Back to login"
msgstr "Retour à la connexion"
@@ -178,15 +178,15 @@ msgstr "Impossible de se connecter au serveur de mises à jour en direct. Les vo
#: src/components/CommentThread.tsx:124
#: src/components/ConfirmModal.tsx:32
#: src/components/form/FormActions.tsx:32
-#: src/pages/Dump.tsx:359
-#: src/pages/DumpEdit.tsx:433
-#: src/pages/PlaylistDetail.tsx:911
-#: src/pages/UserPublicProfile.tsx:1637
-#: src/pages/UserPublicProfile.tsx:1707
+#: src/pages/Dump.tsx:368
+#: src/pages/DumpEdit.tsx:443
+#: src/pages/PlaylistDetail.tsx:920
+#: src/pages/UserPublicProfile.tsx:1646
+#: src/pages/UserPublicProfile.tsx:1716
msgid "Cancel"
msgstr "Annuler"
-#: src/pages/PlaylistDetail.tsx:736
+#: src/pages/PlaylistDetail.tsx:745
msgid "Cancel removal"
msgstr "Annuler la suppression"
@@ -194,7 +194,7 @@ msgstr "Annuler la suppression"
msgid "Cancel search"
msgstr "Annuler la recherche"
-#: src/pages/UserPublicProfile.tsx:759
+#: src/pages/UserPublicProfile.tsx:768
msgid "Change avatar"
msgstr "Changer l'avatar"
@@ -203,11 +203,11 @@ msgstr "Changer l'avatar"
msgid "Change password"
msgstr "Changer le mot de passe"
-#: src/pages/UserPublicProfile.tsx:1123
+#: src/pages/UserPublicProfile.tsx:1132
msgid "Change password…"
msgstr "Changer le mot de passe…"
-#: src/pages/UserRegister.tsx:83
+#: src/pages/UserRegister.tsx:85
msgid "Checking invite…"
msgstr "Vérification de l'invitation…"
@@ -216,20 +216,20 @@ msgstr "Vérification de l'invitation…"
msgid "Close"
msgstr "Fermer"
-#: src/pages/UserPublicProfile.tsx:1170
+#: src/pages/UserPublicProfile.tsx:1179
msgid "Color scheme"
msgstr "Thème de couleur"
#: src/components/ChangePasswordModal.tsx:89
-#: src/pages/ResetPassword.tsx:116
+#: src/pages/ResetPassword.tsx:118
msgid "Confirm new password"
msgstr "Confirmer le nouveau mot de passe"
-#: src/pages/UserPublicProfile.tsx:104
+#: src/pages/UserPublicProfile.tsx:105
msgid "Copied!"
msgstr "Copié !"
-#: src/pages/UserPublicProfile.tsx:104
+#: src/pages/UserPublicProfile.tsx:105
msgid "Copy"
msgstr "Copier"
@@ -241,7 +241,7 @@ msgstr "Impossible de changer le mot de passe"
msgid "Could not load."
msgstr "Impossible de charger."
-#: src/pages/DumpEdit.tsx:334
+#: src/pages/DumpEdit.tsx:344
msgid "Could not save"
msgstr "Sauvegarde impossible"
@@ -255,7 +255,7 @@ msgstr "Créer et ajouter"
#. placeholder {0}: created.items.length
#. placeholder {1}: created.hasMore ? "+" : ""
-#: src/pages/UserPlaylists.tsx:388
+#: src/pages/UserPlaylists.tsx:391
msgid "Created ({0}{1})"
msgstr "Créées ({0}{1})"
@@ -267,29 +267,29 @@ msgstr "Création…"
msgid "Current password"
msgstr "Mot de passe actuel"
-#: src/pages/UserPublicProfile.tsx:1192
+#: src/pages/UserPublicProfile.tsx:1201
msgid "Dark"
msgstr "Sombre"
-#: src/pages/UserPublicProfile.tsx:1205
+#: src/pages/UserPublicProfile.tsx:1214
msgid "Default tab"
msgstr "Onglet par défaut"
#: src/components/CommentThread.tsx:376
#: src/components/CommentThread.tsx:382
#: src/components/ConfirmModal.tsx:16
-#: src/pages/PlaylistDetail.tsx:907
+#: src/pages/PlaylistDetail.tsx:916
msgid "Delete"
msgstr "Supprimer"
-#: src/pages/DumpEdit.tsx:242
-#: src/pages/DumpEdit.tsx:429
+#: src/pages/DumpEdit.tsx:252
+#: src/pages/DumpEdit.tsx:439
msgid "Delete dump"
msgstr "Supprimer la reco"
#: src/components/PlaylistCard.tsx:109
-#: src/pages/PlaylistDetail.tsx:749
-#: src/pages/UserPlaylists.tsx:465
+#: src/pages/PlaylistDetail.tsx:758
+#: src/pages/UserPlaylists.tsx:468
msgid "Delete playlist"
msgstr "Supprimer la collection"
@@ -297,17 +297,17 @@ msgstr "Supprimer la collection"
msgid "Delete this comment?"
msgstr "Supprimer ce commentaire ?"
-#: src/pages/DumpEdit.tsx:241
+#: src/pages/DumpEdit.tsx:251
msgid "Delete this dump? This cannot be undone."
msgstr "Supprimer cette reco ? Cette action est irréversible."
-#: src/pages/PlaylistDetail.tsx:748
-#: src/pages/UserPlaylists.tsx:464
+#: src/pages/PlaylistDetail.tsx:757
+#: src/pages/UserPlaylists.tsx:467
msgid "Delete this playlist? This cannot be undone."
msgstr "Supprimer cette collection ? Cette action est irréversible."
#: src/components/PlaylistCreateForm.tsx:78
-#: src/pages/PlaylistDetail.tsx:868
+#: src/pages/PlaylistDetail.tsx:877
msgid "Description (optional)"
msgstr "Description (facultatif)"
@@ -319,7 +319,7 @@ msgstr "Terminé"
msgid "Drop a file here"
msgstr "Déposez un fichier ici"
-#: src/pages/DumpEdit.tsx:404
+#: src/pages/DumpEdit.tsx:414
msgid "Drop a replacement here"
msgstr "Déposez un fichier de remplacement ici"
@@ -335,25 +335,25 @@ msgstr "Recommander"
msgid "Dumped!"
msgstr "Recommandé !"
-#: src/pages/Search.tsx:172
-#: src/pages/UserDumps.tsx:77
-#: src/pages/UserPublicProfile.tsx:880
+#: src/pages/Search.tsx:174
+#: src/pages/UserDumps.tsx:80
+#: src/pages/UserPublicProfile.tsx:889
msgid "Dumps"
msgstr "Recos"
#. placeholder {0}: dumps.items.length
#. placeholder {1}: dumps.hasMore ? "+" : ""
-#: src/pages/UserPublicProfile.tsx:900
+#: src/pages/UserPublicProfile.tsx:909
msgid "Dumps ({0}{1})"
msgstr "Recos ({0}{1})"
-#: src/pages/Notifications.tsx:393
+#: src/pages/Notifications.tsx:395
msgid "Earlier"
msgstr "Plus tôt"
#: src/components/CommentThread.tsx:367
-#: src/pages/Dump.tsx:459
-#: src/pages/PlaylistDetail.tsx:616
+#: src/pages/Dump.tsx:468
+#: src/pages/PlaylistDetail.tsx:625
msgid "Edit"
msgstr "Modifier"
@@ -365,8 +365,8 @@ msgstr "Modifier le titre"
#. placeholder {0}: relativeTime(dump.updatedAt)
#. placeholder {0}: relativeTime(playlist.updatedAt)
#: src/components/CommentThread.tsx:317
-#: src/pages/Dump.tsx:412
-#: src/pages/PlaylistDetail.tsx:655
+#: src/pages/Dump.tsx:421
+#: src/pages/PlaylistDetail.tsx:664
msgid "edited {0}"
msgstr "modifié {0}"
@@ -374,20 +374,25 @@ msgstr "modifié {0}"
#. placeholder {0}: dump.updatedAt.toLocaleString()
#. placeholder {0}: playlist.updatedAt.toLocaleString()
#: src/components/CommentThread.tsx:315
-#: src/pages/Dump.tsx:410
-#: src/pages/PlaylistDetail.tsx:652
+#: src/pages/Dump.tsx:419
+#: src/pages/PlaylistDetail.tsx:661
msgid "Edited {0}"
msgstr "Modifié le {0}"
-#: src/pages/DumpEdit.tsx:193
+#: src/pages/DumpEdit.tsx:203
msgid "Editing"
msgstr "Modification"
-#: src/pages/UserRegister.tsx:131
+#. placeholder {0}: state.dump.title
+#: src/pages/DumpEdit.tsx:48
+msgid "Editing {0}"
+msgstr "Édition de {0}"
+
+#: src/pages/UserRegister.tsx:133
msgid "Email address"
msgstr "Adresse e-mail"
-#: src/pages/Search.tsx:205
+#: src/pages/Search.tsx:207
msgid "Enter a query to search."
msgstr "Saisissez une recherche."
@@ -395,9 +400,9 @@ msgstr "Saisissez une recherche."
msgid "Failed to create playlist"
msgstr "Impossible de créer la collection"
-#: src/pages/UserPublicProfile.tsx:85
-#: src/pages/UserPublicProfile.tsx:88
-#: src/pages/UserPublicProfile.tsx:116
+#: src/pages/UserPublicProfile.tsx:86
+#: src/pages/UserPublicProfile.tsx:89
+#: src/pages/UserPublicProfile.tsx:117
msgid "Failed to generate invite"
msgstr "Impossible de générer une invitation"
@@ -405,10 +410,10 @@ msgstr "Impossible de générer une invitation"
#: src/pages/index/HotFeed.tsx:36
#: src/pages/index/JournalFeed.tsx:33
#: src/pages/index/NewFeed.tsx:36
-#: src/pages/Notifications.tsx:367
-#: src/pages/UserPublicProfile.tsx:1002
-#: src/pages/UserPublicProfile.tsx:1044
-#: src/pages/UserPublicProfile.tsx:1089
+#: src/pages/Notifications.tsx:369
+#: src/pages/UserPublicProfile.tsx:1011
+#: src/pages/UserPublicProfile.tsx:1053
+#: src/pages/UserPublicProfile.tsx:1098
msgid "Failed to load"
msgstr "Chargement échoué"
@@ -424,9 +429,9 @@ msgstr "Impossible de publier le commentaire"
msgid "Failed to post reply"
msgstr "Impossible de publier la réponse"
-#: src/pages/PlaylistDetail.tsx:899
-#: src/pages/UserPublicProfile.tsx:1640
-#: src/pages/UserPublicProfile.tsx:1709
+#: src/pages/PlaylistDetail.tsx:908
+#: src/pages/UserPublicProfile.tsx:1649
+#: src/pages/UserPublicProfile.tsx:1718
msgid "Failed to save"
msgstr "Enregistrement échoué"
@@ -434,15 +439,15 @@ msgstr "Enregistrement échoué"
msgid "Failed to save edit"
msgstr "Impossible d'enregistrer la modification"
-#: src/pages/UserPublicProfile.tsx:816
+#: src/pages/UserPublicProfile.tsx:825
msgid "Failed to update avatar"
msgstr "Impossible de mettre à jour l'avatar"
-#: src/pages/UserPublicProfile.tsx:1578
+#: src/pages/UserPublicProfile.tsx:1587
msgid "Failed to update role"
msgstr "Erreur lors de la mise à jour du rôle"
-#: src/pages/UserPublicProfile.tsx:1200
+#: src/pages/UserPublicProfile.tsx:1209
msgid "Feeds"
msgstr "Flux"
@@ -485,28 +490,28 @@ msgid "Follow some users to see their dumps here."
msgstr "Suivez des utilisateurs pour voir leurs recos ici."
#: src/components/FeedTabBar.tsx:21
-#: src/pages/UserPublicProfile.tsx:882
-#: src/pages/UserPublicProfile.tsx:1234
+#: src/pages/UserPublicProfile.tsx:891
+#: src/pages/UserPublicProfile.tsx:1243
msgid "Followed"
msgstr "Suivi"
#. placeholder {0}: followed.items.length
#. placeholder {1}: followed.hasMore ? "+" : ""
-#: src/pages/UserPlaylists.tsx:430
+#: src/pages/UserPlaylists.tsx:433
msgid "Followed ({0}{1})"
msgstr "Suivies ({0}{1})"
-#: src/pages/UserPublicProfile.tsx:1033
+#: src/pages/UserPublicProfile.tsx:1042
msgid "Followed playlists"
msgstr "Collections suivies"
#: src/components/FollowButton.tsx:37
#: src/components/FollowButton.tsx:64
-#: src/pages/UserPublicProfile.tsx:991
+#: src/pages/UserPublicProfile.tsx:1000
msgid "Following"
msgstr "Abonné"
-#: src/pages/UserLogin.tsx:87
+#: src/pages/UserLogin.tsx:89
msgid "Forgot password?"
msgstr "Mot de passe oublié ?"
@@ -518,46 +523,46 @@ msgstr "De personnes"
msgid "From playlists"
msgstr "De collections"
-#: src/pages/NotFound.tsx:13
+#: src/pages/NotFound.tsx:16
msgid "Go home"
msgstr "Accueil"
-#: src/pages/ResetPassword.tsx:81
+#: src/pages/ResetPassword.tsx:83
msgid "Go to login"
msgstr "Aller à la connexion"
#: src/components/FeedTabBar.tsx:17
-#: src/pages/UserPublicProfile.tsx:1213
+#: src/pages/UserPublicProfile.tsx:1222
msgid "Hot"
msgstr "Tendances"
-#: src/pages/UserLogin.tsx:118
+#: src/pages/UserLogin.tsx:120
msgid "If that address is registered you'll receive a reset link shortly."
msgstr "Si cette adresse est enregistrée, vous recevrez un lien de réinitialisation sous peu."
-#: src/pages/UserRegister.tsx:94
+#: src/pages/UserRegister.tsx:96
msgid "Invalid invite"
msgstr "Invitation invalide"
-#: src/pages/ResetPassword.tsx:49
+#: src/pages/ResetPassword.tsx:51
msgid "Invalid link"
msgstr "Lien invalide"
-#: src/pages/UserPublicProfile.tsx:778
+#: src/pages/UserPublicProfile.tsx:787
msgid "invited by"
msgstr "invité par"
-#: src/pages/UserPublicProfile.tsx:883
-#: src/pages/UserPublicProfile.tsx:1078
+#: src/pages/UserPublicProfile.tsx:892
+#: src/pages/UserPublicProfile.tsx:1087
msgid "Invitees"
msgstr "Invités"
#: src/components/FeedTabBar.tsx:19
-#: src/pages/UserPublicProfile.tsx:1227
+#: src/pages/UserPublicProfile.tsx:1236
msgid "Journal"
msgstr "Journal"
-#: src/pages/UserPublicProfile.tsx:1185
+#: src/pages/UserPublicProfile.tsx:1194
msgid "Light"
msgstr "Clair"
@@ -574,12 +579,12 @@ msgid "Live updates unavailable."
msgstr "Mises à jour en direct indisponibles."
#: src/components/UserListPopover.tsx:231
-#: src/pages/Notifications.tsx:440
+#: src/pages/Notifications.tsx:442
msgid "Load more"
msgstr "Charger plus"
-#: src/pages/Dump.tsx:226
-#: src/pages/DumpEdit.tsx:144
+#: src/pages/Dump.tsx:235
+#: src/pages/DumpEdit.tsx:154
msgid "Loading dump…"
msgstr "Chargement de la reco…"
@@ -587,19 +592,19 @@ msgstr "Chargement de la reco…"
#: src/pages/index/HotFeed.tsx:64
#: src/pages/index/JournalFeed.tsx:62
#: src/pages/index/NewFeed.tsx:64
-#: src/pages/Search.tsx:242
-#: src/pages/UserDumps.tsx:118
-#: src/pages/UserPlaylists.tsx:417
-#: src/pages/UserPlaylists.tsx:452
-#: src/pages/UserUpvoted.tsx:187
+#: src/pages/Search.tsx:244
+#: src/pages/UserDumps.tsx:121
+#: src/pages/UserPlaylists.tsx:420
+#: src/pages/UserPlaylists.tsx:455
+#: src/pages/UserUpvoted.tsx:190
msgid "Loading more…"
msgstr "Chargement…"
-#: src/pages/PlaylistDetail.tsx:545
+#: src/pages/PlaylistDetail.tsx:554
msgid "Loading playlist…"
msgstr "Chargement de la collection…"
-#: src/pages/UserPublicProfile.tsx:715
+#: src/pages/UserPublicProfile.tsx:724
msgid "Loading profile…"
msgstr "Chargement du profil…"
@@ -611,20 +616,21 @@ msgstr "Chargement du profil…"
#: src/pages/index/HotFeed.tsx:32
#: src/pages/index/JournalFeed.tsx:29
#: src/pages/index/NewFeed.tsx:32
-#: src/pages/Notifications.tsx:363
-#: src/pages/Notifications.tsx:439
-#: src/pages/UserDumps.tsx:51
-#: src/pages/UserPlaylists.tsx:342
-#: src/pages/UserPublicProfile.tsx:996
-#: src/pages/UserPublicProfile.tsx:1038
-#: src/pages/UserPublicProfile.tsx:1083
-#: src/pages/UserUpvoted.tsx:122
+#: src/pages/Notifications.tsx:365
+#: src/pages/Notifications.tsx:441
+#: src/pages/UserDumps.tsx:54
+#: src/pages/UserPlaylists.tsx:345
+#: src/pages/UserPublicProfile.tsx:1005
+#: src/pages/UserPublicProfile.tsx:1047
+#: src/pages/UserPublicProfile.tsx:1092
+#: src/pages/UserUpvoted.tsx:125
msgid "Loading…"
msgstr "Chargement…"
#: src/components/AppHeader.tsx:111
-#: src/pages/UserLogin.tsx:57
-#: src/pages/UserLogin.tsx:76
+#: src/pages/UserLogin.tsx:34
+#: src/pages/UserLogin.tsx:59
+#: src/pages/UserLogin.tsx:78
msgid "Log in"
msgstr "Se connecter"
@@ -636,20 +642,20 @@ msgstr "Se connecter pour aimer"
msgid "Log in to vote"
msgstr "Se connecter pour voter"
-#: src/pages/UserPublicProfile.tsx:736
-#: src/pages/UserPublicProfile.tsx:830
+#: src/pages/UserPublicProfile.tsx:745
+#: src/pages/UserPublicProfile.tsx:839
msgid "Log out"
msgstr "Se déconnecter"
-#: src/pages/UserLogin.tsx:75
+#: src/pages/UserLogin.tsx:77
msgid "Logging in…"
msgstr "Connexion…"
-#: src/pages/UserLogin.tsx:62
+#: src/pages/UserLogin.tsx:64
msgid "Login failed"
msgstr "Connexion échouée"
-#: src/pages/UserPublicProfile.tsx:888
+#: src/pages/UserPublicProfile.tsx:897
msgid "Manage"
msgstr "Administration"
@@ -657,29 +663,29 @@ msgstr "Administration"
msgid "Max 50 MB"
msgstr "Max 50 Mo"
-#: src/pages/UserPublicProfile.tsx:1519
+#: src/pages/UserPublicProfile.tsx:1528
msgid "Moderator"
msgstr "Modérateur"
-#: src/pages/Notifications.tsx:356
+#: src/pages/Notifications.tsx:358
msgid "new"
msgstr "nouveau"
#: src/components/FeedTabBar.tsx:18
-#: src/pages/UserPublicProfile.tsx:1220
+#: src/pages/UserPublicProfile.tsx:1229
msgid "New"
msgstr "Nouveau"
#: src/components/DumpCreateModal.tsx:292
#: src/components/DumpFab.tsx:65
#: src/components/DumpFab.tsx:66
-#: src/pages/UserDumps.tsx:85
-#: src/pages/UserPublicProfile.tsx:1298
+#: src/pages/UserDumps.tsx:88
+#: src/pages/UserPublicProfile.tsx:1307
msgid "New dump"
msgstr "Nouvelle reco"
#: src/components/ChangePasswordModal.tsx:75
-#: src/pages/ResetPassword.tsx:101
+#: src/pages/ResetPassword.tsx:103
msgid "New password"
msgstr "Nouveau mot de passe"
@@ -688,11 +694,11 @@ msgstr "Nouveau mot de passe"
msgid "New playlist"
msgstr "Nouvelle collection"
-#: src/pages/PlaylistDetail.tsx:671
+#: src/pages/PlaylistDetail.tsx:680
msgid "No dumps in this playlist yet."
msgstr "Aucune reco dans cette collection pour l'instant."
-#: src/pages/Search.tsx:222
+#: src/pages/Search.tsx:224
msgid "No dumps match \"{q}\"."
msgstr "Aucune reco ne correspond à « {q} »."
@@ -706,12 +712,12 @@ msgstr "Pas encore de recos. Soyez le premier !"
msgid "No emoji found."
msgstr "Aucun emoji trouvé."
-#: src/pages/UserPlaylists.tsx:439
-#: src/pages/UserPublicProfile.tsx:1051
+#: src/pages/UserPlaylists.tsx:442
+#: src/pages/UserPublicProfile.tsx:1060
msgid "No followed playlists yet."
msgstr "Pas encore de collections suivies."
-#: src/pages/UserPublicProfile.tsx:1096
+#: src/pages/UserPublicProfile.tsx:1105
msgid "No invitees yet."
msgstr "Aucun invité pour le moment."
@@ -719,34 +725,35 @@ msgstr "Aucun invité pour le moment."
msgid "No one yet."
msgstr "Personne pour le moment."
-#: src/pages/Search.tsx:281
+#: src/pages/Search.tsx:283
msgid "No playlists match \"{q}\"."
msgstr "Aucune collection ne correspond à « {q} »."
#: src/components/PlaylistMembershipPanel.tsx:34
-#: src/pages/UserPlaylists.tsx:397
-#: src/pages/UserPublicProfile.tsx:962
+#: src/pages/UserPlaylists.tsx:400
+#: src/pages/UserPublicProfile.tsx:971
msgid "No playlists yet."
msgstr "Pas encore de collections."
-#: src/pages/Search.tsx:255
+#: src/pages/Search.tsx:257
msgid "No users match \"{q}\"."
msgstr "Aucun utilisateur ne correspond à « {q} »."
-#: src/pages/UserPublicProfile.tsx:1009
+#: src/pages/UserPublicProfile.tsx:1018
msgid "Not following anyone yet."
msgstr "Aucun abonnement pour le moment."
-#: src/pages/Notifications.tsx:374
-#: src/pages/UserDumps.tsx:96
-#: src/pages/UserPublicProfile.tsx:1309
-#: src/pages/UserPublicProfile.tsx:1431
-#: src/pages/UserUpvoted.tsx:156
+#: src/pages/Notifications.tsx:376
+#: src/pages/UserDumps.tsx:99
+#: src/pages/UserPublicProfile.tsx:1318
+#: src/pages/UserPublicProfile.tsx:1440
+#: src/pages/UserUpvoted.tsx:159
msgid "Nothing here yet."
msgstr "Rien ici pour l'instant."
#: src/components/NotificationBell.tsx:42
-#: src/pages/Notifications.tsx:352
+#: src/pages/Notifications.tsx:260
+#: src/pages/Notifications.tsx:354
msgid "Notifications"
msgstr "Notifications"
@@ -762,13 +769,17 @@ msgstr "Ouvrir la recherche"
msgid "or <0>browse files0>"
msgstr "ou <0>parcourir les fichiers0>"
-#: src/pages/UserLogin.tsx:72
-#: src/pages/UserPublicProfile.tsx:1116
+#: src/pages/NotFound.tsx:8
+msgid "Page not found"
+msgstr "Page introuvable"
+
+#: src/pages/UserLogin.tsx:74
+#: src/pages/UserPublicProfile.tsx:1125
msgid "Password"
msgstr "Mot de passe"
#. placeholder {0}: VALIDATION.PASSWORD_MIN
-#: src/pages/UserRegister.tsx:137
+#: src/pages/UserRegister.tsx:139
msgid "Password (min. {0} characters)"
msgstr "Mot de passe (min. {0} caractères)"
@@ -776,30 +787,30 @@ msgstr "Mot de passe (min. {0} caractères)"
msgid "Password changed successfully."
msgstr "Mot de passe modifié avec succès."
-#: src/pages/ResetPassword.tsx:71
+#: src/pages/ResetPassword.tsx:73
msgid "Password updated"
msgstr "Mot de passe mis à jour"
#: src/components/ChangePasswordModal.tsx:95
-#: src/pages/ResetPassword.tsx:121
+#: src/pages/ResetPassword.tsx:123
msgid "Passwords do not match"
msgstr "Les mots de passe ne correspondent pas"
-#: src/pages/PlaylistDetail.tsx:854
+#: src/pages/PlaylistDetail.tsx:863
msgid "Playlist title"
msgstr "Titre de la collection"
#: src/components/AppHeader.tsx:85
#: src/components/UserMenu.tsx:62
-#: src/pages/Search.tsx:175
-#: src/pages/UserPlaylists.tsx:368
-#: src/pages/UserPublicProfile.tsx:881
+#: src/pages/Search.tsx:177
+#: src/pages/UserPlaylists.tsx:371
+#: src/pages/UserPublicProfile.tsx:890
msgid "Playlists"
msgstr "Collections"
#. placeholder {0}: playlists.items.length
#. placeholder {1}: playlists.hasMore ? "+" : ""
-#: src/pages/UserPublicProfile.tsx:931
+#: src/pages/UserPublicProfile.tsx:940
msgid "Playlists ({0}{1})"
msgstr "Collections ({0}{1})"
@@ -824,48 +835,49 @@ msgstr "Publication…"
#: src/components/JournalCard.tsx:119
#: src/components/PlaylistCard.tsx:73
#: src/components/PlaylistMembershipPanel.tsx:55
-#: src/pages/Dump.tsx:418
-#: src/pages/PlaylistDetail.tsx:635
+#: src/pages/Dump.tsx:427
+#: src/pages/PlaylistDetail.tsx:644
msgid "private"
msgstr "privé"
#: src/components/form/SegmentedField.tsx:78
-#: src/pages/PlaylistDetail.tsx:893
+#: src/pages/PlaylistDetail.tsx:902
msgid "Private"
msgstr "Privé"
#: src/components/PlaylistCard.tsx:72
-#: src/pages/PlaylistDetail.tsx:634
+#: src/pages/PlaylistDetail.tsx:643
msgid "public"
msgstr "public"
#: src/components/form/SegmentedField.tsx:77
-#: src/pages/PlaylistDetail.tsx:886
+#: src/pages/PlaylistDetail.tsx:895
msgid "Public"
msgstr "Public"
-#: src/pages/DumpEdit.tsx:222
+#: src/pages/DumpEdit.tsx:232
msgid "Refresh metadata"
msgstr "Actualiser les métadonnées"
-#: src/pages/DumpEdit.tsx:221
+#: src/pages/DumpEdit.tsx:231
msgid "Refreshing…"
msgstr "Actualisation…"
-#: src/pages/UserRegister.tsx:106
-#: src/pages/UserRegister.tsx:148
+#: src/pages/UserRegister.tsx:37
+#: src/pages/UserRegister.tsx:108
+#: src/pages/UserRegister.tsx:150
msgid "Register"
msgstr "S'inscrire"
-#: src/pages/UserRegister.tsx:147
+#: src/pages/UserRegister.tsx:149
msgid "Registering…"
msgstr "Inscription…"
-#: src/pages/UserRegister.tsx:111
+#: src/pages/UserRegister.tsx:113
msgid "Registration failed"
msgstr "Inscription échouée"
-#: src/pages/Dump.tsx:471
+#: src/pages/Dump.tsx:480
msgid "Related"
msgstr "Connexe"
@@ -873,7 +885,7 @@ msgstr "Connexe"
msgid "Remove file"
msgstr "Supprimer le fichier"
-#: src/pages/PlaylistDetail.tsx:726
+#: src/pages/PlaylistDetail.tsx:735
msgid "Remove from playlist"
msgstr "Retirer de la collection"
@@ -885,7 +897,7 @@ msgstr "Retirer le j'aime"
msgid "Remove vote"
msgstr "Retirer le vote"
-#: src/pages/DumpEdit.tsx:403
+#: src/pages/DumpEdit.tsx:413
msgid "Replace file"
msgstr "Remplacer le fichier"
@@ -893,49 +905,54 @@ msgstr "Remplacer le fichier"
msgid "Reply"
msgstr "Répondre"
-#: src/pages/UserLogin.tsx:130
+#: src/pages/UserLogin.tsx:132
msgid "Request failed"
msgstr "Échec de la demande"
-#: src/pages/ResetPassword.tsx:97
+#: src/pages/ResetPassword.tsx:99
msgid "Reset failed"
msgstr "Échec de la réinitialisation"
-#: src/pages/DumpEdit.tsx:354
-#: src/pages/DumpEdit.tsx:372
+#: src/pages/ResetPassword.tsx:24
+msgid "Reset password"
+msgstr "Réinitialiser le mot de passe"
+
+#: src/pages/DumpEdit.tsx:364
+#: src/pages/DumpEdit.tsx:382
msgid "Reset to default"
msgstr "Réinitialiser par défaut"
-#: src/pages/Dump.tsx:243
-#: src/pages/DumpEdit.tsx:161
+#: src/pages/Dump.tsx:252
+#: src/pages/DumpEdit.tsx:171
msgid "Retry"
msgstr "Réessayer"
-#: src/pages/UserPublicProfile.tsx:1562
+#: src/pages/UserPublicProfile.tsx:1571
msgid "Role"
msgstr "Rôle"
#: src/components/CommentThread.tsx:328
-#: src/pages/Dump.tsx:351
-#: src/pages/DumpEdit.tsx:436
-#: src/pages/PlaylistDetail.tsx:918
-#: src/pages/UserPublicProfile.tsx:1629
-#: src/pages/UserPublicProfile.tsx:1699
+#: src/pages/Dump.tsx:360
+#: src/pages/DumpEdit.tsx:446
+#: src/pages/PlaylistDetail.tsx:927
+#: src/pages/UserPublicProfile.tsx:1638
+#: src/pages/UserPublicProfile.tsx:1708
msgid "Save"
msgstr "Enregistrer"
#: src/components/ChangePasswordModal.tsx:100
#: src/components/CommentThread.tsx:329
-#: src/pages/Dump.tsx:350
-#: src/pages/PlaylistDetail.tsx:914
-#: src/pages/ResetPassword.tsx:124
-#: src/pages/UserPublicProfile.tsx:1626
-#: src/pages/UserPublicProfile.tsx:1696
+#: src/pages/Dump.tsx:359
+#: src/pages/PlaylistDetail.tsx:923
+#: src/pages/ResetPassword.tsx:126
+#: src/pages/UserPublicProfile.tsx:1635
+#: src/pages/UserPublicProfile.tsx:1705
msgid "Saving…"
msgstr "Enregistrement…"
#: src/components/AppHeader.tsx:65
#: src/components/SearchBar.tsx:78
+#: src/pages/Search.tsx:50
msgid "Search"
msgstr "Rechercher"
@@ -943,19 +960,19 @@ msgstr "Rechercher"
msgid "Search dumps, users, playlists…"
msgstr "Rechercher des recos, utilisateurs, collections…"
-#: src/pages/Search.tsx:216
+#: src/pages/Search.tsx:218
msgid "Search failed"
msgstr "Recherche échouée"
-#: src/pages/Search.tsx:211
+#: src/pages/Search.tsx:213
msgid "Searching…"
msgstr "Recherche…"
-#: src/pages/UserLogin.tsx:139
+#: src/pages/UserLogin.tsx:141
msgid "Send reset link"
msgstr "Envoyer le lien de réinitialisation"
-#: src/pages/UserLogin.tsx:138
+#: src/pages/UserLogin.tsx:140
msgid "Sending…"
msgstr "Envoi…"
@@ -963,12 +980,12 @@ msgstr "Envoi…"
msgid "Server unreachable"
msgstr "Serveur inaccessible"
-#: src/pages/ResetPassword.tsx:92
-#: src/pages/ResetPassword.tsx:125
+#: src/pages/ResetPassword.tsx:94
+#: src/pages/ResetPassword.tsx:127
msgid "Set new password"
msgstr "Définir un nouveau mot de passe"
-#: src/pages/UserPublicProfile.tsx:885
+#: src/pages/UserPublicProfile.tsx:894
msgid "Settings"
msgstr "Paramètres"
@@ -977,7 +994,7 @@ msgstr "Paramètres"
msgid "Something went wrong"
msgstr "Une erreur est survenue"
-#: src/pages/UserPublicProfile.tsx:1135
+#: src/pages/UserPublicProfile.tsx:1144
msgid "Style"
msgstr "Style"
@@ -985,29 +1002,29 @@ msgstr "Style"
msgid "Submit search"
msgstr "Lancer la recherche"
-#: src/pages/UserRegister.tsx:95
+#: src/pages/UserRegister.tsx:97
msgid "This invite link is missing, expired, or already used."
msgstr "Ce lien d'invitation est manquant, expiré ou déjà utilisé."
-#: src/pages/UserLogin.tsx:94
+#: src/pages/UserLogin.tsx:96
msgid "This is a mirage."
msgstr "C'est un mirage."
-#: src/pages/NotFound.tsx:10
+#: src/pages/NotFound.tsx:13
msgid "This page does not exist."
msgstr "Rien à voir, circulez."
-#: src/pages/ResetPassword.tsx:52
+#: src/pages/ResetPassword.tsx:54
msgid "This reset link is missing or malformed."
msgstr "Ce lien de réinitialisation est absent ou malformé."
-#: src/pages/DumpEdit.tsx:338
+#: src/pages/DumpEdit.tsx:348
msgid "Thumbnail"
msgstr "Miniature"
#: src/components/DumpCreateModal.tsx:386
#: src/components/PlaylistCreateForm.tsx:70
-#: src/pages/DumpEdit.tsx:362
+#: src/pages/DumpEdit.tsx:372
msgid "Title"
msgstr "Titre"
@@ -1015,11 +1032,11 @@ msgstr "Titre"
msgid "Title is required."
msgstr "Un titre est requis."
-#: src/pages/Notifications.tsx:390
+#: src/pages/Notifications.tsx:392
msgid "Today"
msgstr "Aujourd'hui"
-#: src/pages/PlaylistDetail.tsx:738
+#: src/pages/PlaylistDetail.tsx:747
msgid "Undo"
msgstr "Annuler"
@@ -1031,7 +1048,7 @@ msgstr "Ne plus suivre {targetUsername}"
msgid "Unfollow playlist"
msgstr "Ne plus suivre la collection"
-#: src/pages/UserPublicProfile.tsx:680
+#: src/pages/UserPublicProfile.tsx:689
msgid "Upload failed"
msgstr "Envoi échoué"
@@ -1043,18 +1060,18 @@ msgstr "Envoi…"
msgid "Upvote"
msgstr "Voter"
-#: src/pages/UserUpvoted.tsx:151
+#: src/pages/UserUpvoted.tsx:154
msgid "Upvoted"
msgstr "Voté"
#. placeholder {0}: votes.items.length
#. placeholder {1}: votes.hasMore ? "+" : ""
-#: src/pages/UserPublicProfile.tsx:911
+#: src/pages/UserPublicProfile.tsx:920
msgid "Upvoted ({0}{1})"
msgstr "Votés ({0}{1})"
#: src/components/DumpCreateModal.tsx:335
-#: src/pages/DumpEdit.tsx:385
+#: src/pages/DumpEdit.tsx:395
msgid "URL"
msgstr "URL"
@@ -1062,11 +1079,11 @@ msgstr "URL"
msgid "URL is required."
msgstr "L'URL est obligatoire."
-#: src/pages/UserPublicProfile.tsx:1518
+#: src/pages/UserPublicProfile.tsx:1527
msgid "User"
msgstr "Utilisateur"
-#: src/pages/UserPublicProfile.tsx:1246
+#: src/pages/UserPublicProfile.tsx:1255
msgid "User management"
msgstr "Gestion utilisateur"
@@ -1074,20 +1091,20 @@ msgstr "Gestion utilisateur"
msgid "User menu"
msgstr "Menu utilisateur"
-#: src/pages/UserLogin.tsx:65
-#: src/pages/UserRegister.tsx:114
+#: src/pages/UserLogin.tsx:67
+#: src/pages/UserRegister.tsx:116
msgid "Username"
msgstr "Nom d'utilisateur"
-#: src/pages/Search.tsx:174
+#: src/pages/Search.tsx:176
msgid "Users"
msgstr "Utilisateurs"
-#: src/pages/UserPublicProfile.tsx:981
-#: src/pages/UserPublicProfile.tsx:1024
-#: src/pages/UserPublicProfile.tsx:1066
-#: src/pages/UserPublicProfile.tsx:1330
-#: src/pages/UserPublicProfile.tsx:1461
+#: src/pages/UserPublicProfile.tsx:990
+#: src/pages/UserPublicProfile.tsx:1033
+#: src/pages/UserPublicProfile.tsx:1075
+#: src/pages/UserPublicProfile.tsx:1339
+#: src/pages/UserPublicProfile.tsx:1470
msgid "View all →"
msgstr "Tout voir →"
@@ -1096,17 +1113,17 @@ msgid "View dump →"
msgstr "Voir la reco →"
#: src/components/DumpCreateModal.tsx:431
-#: src/pages/DumpEdit.tsx:415
+#: src/pages/DumpEdit.tsx:425
msgid "What makes it worth it?"
msgstr "Pourquoi on en voudrait ?"
-#: src/pages/UserPublicProfile.tsx:865
-#: src/pages/UserPublicProfile.tsx:1688
+#: src/pages/UserPublicProfile.tsx:874
+#: src/pages/UserPublicProfile.tsx:1697
msgid "Who am I?"
msgstr "Qui suis-je ?"
#: src/components/DumpCreateModal.tsx:430
-#: src/pages/DumpEdit.tsx:414
+#: src/pages/DumpEdit.tsx:424
msgid "Why?"
msgstr "Pourquoi ?"
@@ -1114,11 +1131,11 @@ msgstr "Pourquoi ?"
msgid "Write a reply…"
msgstr "Écrire une réponse…"
-#: src/pages/Notifications.tsx:392
+#: src/pages/Notifications.tsx:394
msgid "Yesterday"
msgstr "Hier"
-#: src/pages/Notifications.tsx:377
+#: src/pages/Notifications.tsx:379
msgid "You'll be notified when someone follows your playlists, upvotes your dumps, or posts new content."
msgstr "Vous serez notifié lorsque quelqu'un suit vos collections, vote pour vos recos ou publie du nouveau contenu."
@@ -1126,18 +1143,18 @@ msgstr "Vous serez notifié lorsque quelqu'un suit vos collections, vote pour vo
#: src/pages/index/HotFeed.tsx:69
#: src/pages/index/JournalFeed.tsx:67
#: src/pages/index/NewFeed.tsx:69
-#: src/pages/Search.tsx:247
-#: src/pages/UserDumps.tsx:123
-#: src/pages/UserPlaylists.tsx:422
-#: src/pages/UserPlaylists.tsx:457
-#: src/pages/UserUpvoted.tsx:192
+#: src/pages/Search.tsx:249
+#: src/pages/UserDumps.tsx:126
+#: src/pages/UserPlaylists.tsx:425
+#: src/pages/UserPlaylists.tsx:460
+#: src/pages/UserUpvoted.tsx:195
msgid "You've reached the end."
msgstr "Vous avez tout lu, tout vu, tout bu."
-#: src/pages/UserLogin.tsx:134
+#: src/pages/UserLogin.tsx:136
msgid "Your email address"
msgstr "Votre adresse e-mail"
-#: src/pages/ResetPassword.tsx:74
+#: src/pages/ResetPassword.tsx:76
msgid "Your password has been changed. You can now log in."
msgstr "Votre mot de passe a été modifié. Vous pouvez maintenant vous connecter."
diff --git a/src/pages/Dump.tsx b/src/pages/Dump.tsx
index 40a6a7e..23167ae 100644
--- a/src/pages/Dump.tsx
+++ b/src/pages/Dump.tsx
@@ -24,6 +24,7 @@ import {
} from "../model.ts";
import { useAuth } from "../hooks/useAuth.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { relativeTime } from "../utils/relativeTime.ts";
import { useWS } from "../hooks/useWS.ts";
import { Avatar } from "../components/Avatar.tsx";
@@ -55,6 +56,14 @@ export function Dump() {
const [op, setOp] = useState(null);
const [playlistModalOpen, setPlaylistModalOpen] = useState(false);
+ useDocumentTitle(
+ dumpState.status === "loaded"
+ ? dumpState.dump.title
+ : dumpState.status === "error"
+ ? null
+ : undefined,
+ );
+
const [comments, setComments] = useState([]);
const [relatedDumps, setRelatedDumps] = useState([]);
diff --git a/src/pages/DumpEdit.tsx b/src/pages/DumpEdit.tsx
index 168947d..611029e 100644
--- a/src/pages/DumpEdit.tsx
+++ b/src/pages/DumpEdit.tsx
@@ -7,6 +7,7 @@ import { API_URL, VALIDATION } from "../config/api.ts";
import type { Dump, RawDump, UpdateDumpRequest } from "../model.ts";
import { deserializeDump, parseAPIResponse } from "../model.ts";
import { useRequiredAuth } from "../hooks/useAuth.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { formatBytes } from "../utils/format.ts";
import { dumpFileUrl, dumpThumbnailUrl, dumpUrl } from "../utils/urls.ts";
import { PageShell } from "../components/PageShell.tsx";
@@ -41,6 +42,15 @@ export function DumpEdit() {
const { authFetch, token } = useRequiredAuth();
const [state, setState] = useState({ status: "loading" });
+
+ useDocumentTitle(
+ state.status === "loaded"
+ ? t`Editing ${state.dump.title}`
+ : state.status === "error"
+ ? null
+ : undefined,
+ );
+
const [confirmDelete, setConfirmDelete] = useState(false);
const [refreshing, setRefreshing] = useState(false);
const [thumbUploading, setThumbUploading] = useState(false);
diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx
index 10d9d6b..ee621b9 100644
--- a/src/pages/Index.tsx
+++ b/src/pages/Index.tsx
@@ -28,6 +28,7 @@ import {
import { friendlyFetchError } from "../utils/apiError.ts";
import { useFeedCache } from "../hooks/useFeedCache.ts";
import { useScrollSave } from "../hooks/useScrollSave.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { useAuth } from "../hooks/useAuth.ts";
import { useWS } from "../hooks/useWS.ts";
import { useDumpListSync } from "../hooks/useDumpListSync.ts";
@@ -55,6 +56,8 @@ export function Index() {
const justDeletedId = (location.state as { deletedDumpId?: string } | null)
?.deletedDumpId;
+ useDocumentTitle(null);
+
const { user, token } = useAuth();
const {
voteCounts,
diff --git a/src/pages/NotFound.tsx b/src/pages/NotFound.tsx
index f171754..91f3a03 100644
--- a/src/pages/NotFound.tsx
+++ b/src/pages/NotFound.tsx
@@ -1,8 +1,11 @@
import { Link } from "react-router";
+import { t } from "@lingui/core/macro";
import { Trans } from "@lingui/react/macro";
import { PageShell } from "../components/PageShell.tsx";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
export function NotFound() {
+ useDocumentTitle(t`Page not found`);
return (
404
diff --git a/src/pages/Notifications.tsx b/src/pages/Notifications.tsx
index 291aeff..ab4124c 100644
--- a/src/pages/Notifications.tsx
+++ b/src/pages/Notifications.tsx
@@ -6,6 +6,7 @@ import { relativeTime } from "../utils/relativeTime.ts";
import { API_URL, NOTIFICATIONS_PAGE_SIZE } from "../config/api.ts";
import { useAuth } from "../hooks/useAuth.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { ErrorCard } from "../components/ErrorCard.tsx";
import { Tooltip } from "../components/Tooltip.tsx";
import { useWS } from "../hooks/useWS.ts";
@@ -256,6 +257,7 @@ function groupByDate(
}
export function Notifications() {
+ useDocumentTitle(t`Notifications`);
const { authFetch } = useAuth();
const { clearUnreadNotifications, lastNotification } = useWS();
const [state, setState] = useState({ status: "loading" });
diff --git a/src/pages/PlaylistDetail.tsx b/src/pages/PlaylistDetail.tsx
index 4e9e6f5..4de64de 100644
--- a/src/pages/PlaylistDetail.tsx
+++ b/src/pages/PlaylistDetail.tsx
@@ -27,6 +27,7 @@ import {
import { playlistUrl } from "../utils/urls.ts";
import { can } from "../utils/permissions.ts";
import { useAuth } from "../hooks/useAuth.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { useWS } from "../hooks/useWS.ts";
import { relativeTime } from "../utils/relativeTime.ts";
import { DumpCard } from "../components/DumpCard.tsx";
@@ -71,6 +72,14 @@ export function PlaylistDetail() {
// Stable UUID for WS comparisons — avoids re-running effects on every state change
const playlistUUID = state.status === "loaded" ? state.playlist.id : null;
+ useDocumentTitle(
+ state.status === "loaded"
+ ? state.playlist.title
+ : state.status === "error"
+ ? null
+ : undefined,
+ );
+
// activeDumpIds: which dumps are currently in the playlist (the canonical set)
const [activeDumpIds, setActiveDumpIds] = useState>(new Set());
diff --git a/src/pages/ResetPassword.tsx b/src/pages/ResetPassword.tsx
index 4037191..1b3b44f 100644
--- a/src/pages/ResetPassword.tsx
+++ b/src/pages/ResetPassword.tsx
@@ -4,6 +4,7 @@ import { t } from "@lingui/core/macro";
import { Trans } from "@lingui/react/macro";
import { API_URL, VALIDATION } from "../config/api.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { PageShell } from "../components/PageShell.tsx";
import {
expectOk,
@@ -20,6 +21,7 @@ interface Values {
}
export function ResetPassword() {
+ useDocumentTitle(t`Reset password`);
const [params] = useSearchParams();
const navigate = useNavigate();
const token = params.get("token") ?? "";
diff --git a/src/pages/Search.tsx b/src/pages/Search.tsx
index 195cabb..1c84524 100644
--- a/src/pages/Search.tsx
+++ b/src/pages/Search.tsx
@@ -8,6 +8,7 @@ import { DumpCard } from "../components/DumpCard.tsx";
import { PlaylistCard } from "../components/PlaylistCard.tsx";
import { ErrorCard } from "../components/ErrorCard.tsx";
import { useAuth } from "../hooks/useAuth.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { useWS } from "../hooks/useWS.ts";
import { useInfiniteScroll } from "../hooks/useInfiniteScroll.ts";
import { useTabParam } from "../hooks/useTabParam.ts";
@@ -46,6 +47,7 @@ type SearchState =
};
export function Search() {
+ useDocumentTitle(t`Search`);
const [searchParams] = useSearchParams();
const q = searchParams.get("q") ?? "";
const [tab, setTab] = useTabParam(SEARCH_TABS, "dumps");
diff --git a/src/pages/UserDumps.tsx b/src/pages/UserDumps.tsx
index 141b8bb..37dd011 100644
--- a/src/pages/UserDumps.tsx
+++ b/src/pages/UserDumps.tsx
@@ -4,6 +4,7 @@ import { Trans } from "@lingui/react/macro";
import { Link, useParams } from "react-router";
import { useAuth } from "../hooks/useAuth.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { useWS } from "../hooks/useWS.ts";
import { useDumpListSync } from "../hooks/useDumpListSync.ts";
import { usePositionAwareSync } from "../hooks/usePositionAwareSync.ts";
@@ -19,6 +20,8 @@ export function UserDumps() {
const { user: me } = useAuth();
const { voteCounts, myVotes, lastDumpEvent, castVote, removeVote } = useWS();
+ useDocumentTitle(username ?? null);
+
const { state, setItems, sentinelRef } = useUserDumpFeed(
username,
"dumps",
diff --git a/src/pages/UserLogin.tsx b/src/pages/UserLogin.tsx
index cc9cf58..dfc8ff0 100644
--- a/src/pages/UserLogin.tsx
+++ b/src/pages/UserLogin.tsx
@@ -10,6 +10,7 @@ import {
type RawAuthResponse,
} from "../model.ts";
import { useAuth } from "../hooks/useAuth.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { PageShell } from "../components/PageShell.tsx";
import {
expectOk,
@@ -30,6 +31,7 @@ interface ResetValues {
}
export function UserLogin() {
+ useDocumentTitle(t`Log in`);
const navigate = useNavigate();
const { login } = useAuth();
const [showReset, setShowReset] = useState(false);
diff --git a/src/pages/UserPlaylists.tsx b/src/pages/UserPlaylists.tsx
index 59d38b0..c8a7c2f 100644
--- a/src/pages/UserPlaylists.tsx
+++ b/src/pages/UserPlaylists.tsx
@@ -23,6 +23,7 @@ import {
hydratePlaylist,
} from "../model.ts";
import { useAuth } from "../hooks/useAuth.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { useWS } from "../hooks/useWS.ts";
import { usePlaylistListSync } from "../hooks/usePlaylistListSync.ts";
import { usePositionAwareSync } from "../hooks/usePositionAwareSync.ts";
@@ -60,6 +61,8 @@ function initialFeed(items: Playlist[], hasMore: boolean): PlaylistFeed {
export function UserPlaylists() {
const { username } = useParams();
const { user: me, authFetch, token } = useAuth();
+
+ useDocumentTitle(username ?? null);
const { lastPlaylistEvent } = useWS();
const { cached: cachedCreated, saveState: saveCreated } = useFeedCache<
diff --git a/src/pages/UserPublicProfile.tsx b/src/pages/UserPublicProfile.tsx
index 144b72c..9f70540 100644
--- a/src/pages/UserPublicProfile.tsx
+++ b/src/pages/UserPublicProfile.tsx
@@ -38,6 +38,7 @@ import { NewPlaylistForm } from "../components/NewPlaylistForm.tsx";
import { PageShell } from "../components/PageShell.tsx";
import { PageError } from "../components/PageError.tsx";
import { useAuth } from "../hooks/useAuth.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { useTheme } from "../hooks/useTheme.ts";
import { useDefaultFeedTab } from "../hooks/useDefaultFeedTab.ts";
import { useWS } from "../hooks/useWS.ts";
@@ -211,6 +212,14 @@ export function UserPublicProfile() {
const [state, setState] = useState({ status: "loading" });
+ useDocumentTitle(
+ state.status === "loaded"
+ ? state.user.username
+ : state.status === "error"
+ ? null
+ : undefined,
+ );
+
const profileUserId = state.status === "loaded" ? state.user.id : null;
const isOwnProfile = me?.id === profileUserId;
diff --git a/src/pages/UserRegister.tsx b/src/pages/UserRegister.tsx
index a5ed614..289fe11 100644
--- a/src/pages/UserRegister.tsx
+++ b/src/pages/UserRegister.tsx
@@ -10,6 +10,7 @@ import {
type RegisterRequest,
} from "../model.ts";
import { useAuth } from "../hooks/useAuth.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { PageShell } from "../components/PageShell.tsx";
import { ErrorCard } from "../components/ErrorCard.tsx";
import {
@@ -33,6 +34,7 @@ interface Values {
}
export function UserRegister() {
+ useDocumentTitle(t`Register`);
const navigate = useNavigate();
const { login } = useAuth();
const [searchParams] = useSearchParams();
diff --git a/src/pages/UserUpvoted.tsx b/src/pages/UserUpvoted.tsx
index 9426204..a724962 100644
--- a/src/pages/UserUpvoted.tsx
+++ b/src/pages/UserUpvoted.tsx
@@ -7,6 +7,7 @@ import { API_URL } from "../config/api.ts";
import type { Dump } from "../model.ts";
import { deserializeDump } from "../model.ts";
import { useAuth } from "../hooks/useAuth.ts";
+import { useDocumentTitle } from "../hooks/useDocumentTitle.ts";
import { useWS } from "../hooks/useWS.ts";
import { useDumpListSync } from "../hooks/useDumpListSync.ts";
import { useFading } from "../hooks/useFading.ts";
@@ -21,6 +22,8 @@ export function UserUpvoted() {
const { user: me } = useAuth();
const { voteCounts, myVotes, lastVoteEvent, castVote, removeVote } = useWS();
+ useDocumentTitle(username ?? null);
+
const [votedIds, setVotedIds] = useState>(new Set());
const { fading, startFading, cancelFading, cancelAll } = useFading();
const prevMyVotesRef = useRef | null>(null);