From 0e30c532194d61a82fda7a6fe3749bf4b126868a Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Fri, 26 Sep 2025 09:25:43 +0800 Subject: [PATCH] Add Quotes filter to Catch-up --- src/locales/en.po | 172 +++++++++++++++++++++--------------------- src/pages/catchup.jsx | 46 ++++++++--- 2 files changed, 121 insertions(+), 97 deletions(-) diff --git a/src/locales/en.po b/src/locales/en.po index 680fb709..a6b1b1a8 100644 --- a/src/locales/en.po +++ b/src/locales/en.po @@ -227,15 +227,15 @@ msgid "{0, plural, one {Last 1 post in the past year(s)} other {Last {1} posts i msgstr "{0, plural, one {Last 1 post in the past year(s)} other {Last {1} posts in the past year(s)}}" #: src/components/account-info.jsx:974 -#: src/pages/catchup.jsx:69 +#: src/pages/catchup.jsx:70 msgid "Original" msgstr "" #: src/components/account-info.jsx:978 #: src/components/status.jsx:2561 -#: src/pages/catchup.jsx:70 -#: src/pages/catchup.jsx:1446 -#: src/pages/catchup.jsx:2059 +#: src/pages/catchup.jsx:71 +#: src/pages/catchup.jsx:1460 +#: src/pages/catchup.jsx:2077 #: src/pages/status.jsx:1100 #: src/pages/status.jsx:1824 msgid "Replies" @@ -243,13 +243,15 @@ msgstr "" #: src/components/account-info.jsx:983 #: src/components/quotes-modal.jsx:81 +#: src/pages/catchup.jsx:73 +#: src/pages/catchup.jsx:1463 msgid "Quotes" msgstr "Quotes" #: src/components/account-info.jsx:988 -#: src/pages/catchup.jsx:71 -#: src/pages/catchup.jsx:1448 -#: src/pages/catchup.jsx:2071 +#: src/pages/catchup.jsx:72 +#: src/pages/catchup.jsx:1462 +#: src/pages/catchup.jsx:2089 #: src/pages/settings.jsx:1255 msgid "Boosts" msgstr "" @@ -291,7 +293,7 @@ msgstr "View post stats" #: src/components/status.jsx:3261 #: src/components/translated-bio-sheet.jsx:21 #: src/pages/accounts.jsx:45 -#: src/pages/catchup.jsx:1582 +#: src/pages/catchup.jsx:1597 #: src/pages/filters.jsx:225 #: src/pages/list.jsx:302 #: src/pages/notifications.jsx:943 @@ -347,7 +349,7 @@ msgstr "More from <0/>" #: src/components/nav-menu.jsx:181 #: src/components/shortcuts-settings.jsx:139 #: src/components/timeline.jsx:471 -#: src/pages/catchup.jsx:881 +#: src/pages/catchup.jsx:896 #: src/pages/filters.jsx:90 #: src/pages/followed-hashtags.jsx:41 #: src/pages/home.jsx:54 @@ -380,7 +382,7 @@ msgstr "Choice {0}" #: src/components/compose-poll.jsx:64 #: src/components/media-attachment.jsx:317 #: src/components/shortcuts-settings.jsx:726 -#: src/pages/catchup.jsx:1079 +#: src/pages/catchup.jsx:1094 #: src/pages/filters.jsx:413 msgid "Remove" msgstr "" @@ -704,7 +706,7 @@ msgid "No drafts found." msgstr "" #: src/components/drafts.jsx:263 -#: src/pages/catchup.jsx:1930 +#: src/pages/catchup.jsx:1948 msgid "Poll" msgstr "" @@ -866,7 +868,7 @@ msgstr "" #: src/components/keyboard-shortcuts-help.jsx:47 #: src/components/nav-menu.jsx:368 -#: src/pages/catchup.jsx:1620 +#: src/pages/catchup.jsx:1635 msgid "Keyboard shortcuts" msgstr "" @@ -875,12 +877,12 @@ msgid "Keyboard shortcuts help" msgstr "" #: src/components/keyboard-shortcuts-help.jsx:59 -#: src/pages/catchup.jsx:1645 +#: src/pages/catchup.jsx:1660 msgid "Next post" msgstr "" #: src/components/keyboard-shortcuts-help.jsx:63 -#: src/pages/catchup.jsx:1653 +#: src/pages/catchup.jsx:1668 msgid "Previous post" msgstr "" @@ -905,7 +907,7 @@ msgid "Load new posts" msgstr "" #: src/components/keyboard-shortcuts-help.jsx:87 -#: src/pages/catchup.jsx:1677 +#: src/pages/catchup.jsx:1692 msgid "Open post details" msgstr "" @@ -1221,8 +1223,8 @@ msgstr "" #: src/components/status.jsx:3187 #: src/components/status.jsx:3265 #: src/components/timeline.jsx:1005 -#: src/pages/catchup.jsx:74 -#: src/pages/catchup.jsx:1878 +#: src/pages/catchup.jsx:76 +#: src/pages/catchup.jsx:1896 msgid "Filtered" msgstr "" @@ -1275,7 +1277,7 @@ msgid "following.title" msgstr "Following" #: src/components/nav-menu.jsx:197 -#: src/pages/catchup.jsx:876 +#: src/pages/catchup.jsx:891 msgid "Catch-up" msgstr "" @@ -1325,8 +1327,8 @@ msgstr "" #: src/components/nav-menu.jsx:253 #: src/components/shortcuts-settings.jsx:55 #: src/components/shortcuts-settings.jsx:201 -#: src/pages/catchup.jsx:1447 -#: src/pages/catchup.jsx:2065 +#: src/pages/catchup.jsx:1461 +#: src/pages/catchup.jsx:2083 #: src/pages/favourites.jsx:12 #: src/pages/favourites.jsx:26 #: src/pages/settings.jsx:1251 @@ -2713,7 +2715,7 @@ msgstr "" #. placeholder {0}: filterInfo.titlesStr #. placeholder {0}: filterInfo?.titlesStr #: src/components/status.jsx:2460 -#: src/pages/catchup.jsx:1877 +#: src/pages/catchup.jsx:1895 msgid "Filtered: {0}" msgstr "Filtered: {0}" @@ -2768,7 +2770,7 @@ msgstr "<0/> <1/> boosted" #: src/components/thread-badge.jsx:22 #: src/components/thread-badge.jsx:37 #: src/components/thread-badge.jsx:52 -#: src/pages/catchup.jsx:1895 +#: src/pages/catchup.jsx:1913 msgid "Thread" msgstr "" @@ -3015,255 +3017,255 @@ msgstr "No bookmarks yet. Go bookmark something!" msgid "Unable to load bookmarks." msgstr "" -#: src/pages/catchup.jsx:53 +#: src/pages/catchup.jsx:54 msgid "last 1 hour" msgstr "" -#: src/pages/catchup.jsx:54 +#: src/pages/catchup.jsx:55 msgid "last 2 hours" msgstr "" -#: src/pages/catchup.jsx:55 +#: src/pages/catchup.jsx:56 msgid "last 3 hours" msgstr "" -#: src/pages/catchup.jsx:56 +#: src/pages/catchup.jsx:57 msgid "last 4 hours" msgstr "" -#: src/pages/catchup.jsx:57 +#: src/pages/catchup.jsx:58 msgid "last 5 hours" msgstr "" -#: src/pages/catchup.jsx:58 +#: src/pages/catchup.jsx:59 msgid "last 6 hours" msgstr "" -#: src/pages/catchup.jsx:59 +#: src/pages/catchup.jsx:60 msgid "last 7 hours" msgstr "" -#: src/pages/catchup.jsx:60 +#: src/pages/catchup.jsx:61 msgid "last 8 hours" msgstr "" -#: src/pages/catchup.jsx:61 +#: src/pages/catchup.jsx:62 msgid "last 9 hours" msgstr "" -#: src/pages/catchup.jsx:62 +#: src/pages/catchup.jsx:63 msgid "last 10 hours" msgstr "" -#: src/pages/catchup.jsx:63 +#: src/pages/catchup.jsx:64 msgid "last 11 hours" msgstr "" -#: src/pages/catchup.jsx:64 +#: src/pages/catchup.jsx:65 msgid "last 12 hours" msgstr "" -#: src/pages/catchup.jsx:65 +#: src/pages/catchup.jsx:66 msgid "beyond 12 hours" msgstr "" -#: src/pages/catchup.jsx:72 +#: src/pages/catchup.jsx:74 msgid "Followed tags" msgstr "" -#: src/pages/catchup.jsx:73 +#: src/pages/catchup.jsx:75 msgid "Groups" msgstr "" -#: src/pages/catchup.jsx:595 +#: src/pages/catchup.jsx:610 msgid "Showing {selectedFilterCategory, select, all {all posts} original {original posts} replies {replies} boosts {boosts} followedTags {followed tags} groups {groups} filtered {filtered posts}}, {sortBy, select, createdAt {{sortOrder, select, asc {oldest} desc {latest}}} reblogsCount {{sortOrder, select, asc {fewest boosts} desc {most boosts}}} favouritesCount {{sortOrder, select, asc {fewest likes} desc {most likes}}} repliesCount {{sortOrder, select, asc {fewest replies} desc {most replies}}} density {{sortOrder, select, asc {least dense} desc {most dense}}}} first{groupBy, select, account {, grouped by authors} other {}}" msgstr "Showing {selectedFilterCategory, select, all {all posts} original {original posts} replies {replies} boosts {boosts} followedTags {followed tags} groups {groups} filtered {filtered posts}}, {sortBy, select, createdAt {{sortOrder, select, asc {oldest} desc {latest}}} reblogsCount {{sortOrder, select, asc {fewest boosts} desc {most boosts}}} favouritesCount {{sortOrder, select, asc {fewest likes} desc {most likes}}} repliesCount {{sortOrder, select, asc {fewest replies} desc {most replies}}} density {{sortOrder, select, asc {least dense} desc {most dense}}}} first{groupBy, select, account {, grouped by authors} other {}}" -#: src/pages/catchup.jsx:887 -#: src/pages/catchup.jsx:911 +#: src/pages/catchup.jsx:902 +#: src/pages/catchup.jsx:926 msgid "Catch-up <0>beta" msgstr "" -#: src/pages/catchup.jsx:901 -#: src/pages/catchup.jsx:1586 +#: src/pages/catchup.jsx:916 +#: src/pages/catchup.jsx:1601 msgid "Help" msgstr "" -#: src/pages/catchup.jsx:917 +#: src/pages/catchup.jsx:932 msgid "What is this?" msgstr "" -#: src/pages/catchup.jsx:920 +#: src/pages/catchup.jsx:935 msgid "Catch-up is a separate timeline for your followings, offering a high-level view at a glance, with a simple, email-inspired interface to effortlessly sort and filter through posts." msgstr "" -#: src/pages/catchup.jsx:931 +#: src/pages/catchup.jsx:946 msgid "Preview of Catch-up UI" msgstr "Preview of Catch-up UI" -#: src/pages/catchup.jsx:940 +#: src/pages/catchup.jsx:955 msgid "Let's catch up" msgstr "" -#: src/pages/catchup.jsx:945 +#: src/pages/catchup.jsx:960 msgid "Let's catch up on the posts from your followings." msgstr "" -#: src/pages/catchup.jsx:949 +#: src/pages/catchup.jsx:964 msgid "Show me all posts from…" msgstr "" -#: src/pages/catchup.jsx:972 +#: src/pages/catchup.jsx:987 msgid "until the max" msgstr "until the max" -#: src/pages/catchup.jsx:1002 +#: src/pages/catchup.jsx:1017 msgid "Catch up" msgstr "" -#: src/pages/catchup.jsx:1008 +#: src/pages/catchup.jsx:1023 msgid "Overlaps with your last catch-up" msgstr "" #. placeholder {0}: dtf.format(new Date(lastCatchupEndAt)) -#: src/pages/catchup.jsx:1020 +#: src/pages/catchup.jsx:1035 msgid "Until the last catch-up ({0})" msgstr "" -#: src/pages/catchup.jsx:1029 +#: src/pages/catchup.jsx:1044 msgid "Note: your instance might only show a maximum of 800 posts in the Home timeline regardless of the time range. Could be less or more." msgstr "" -#: src/pages/catchup.jsx:1039 +#: src/pages/catchup.jsx:1054 msgid "Previously…" msgstr "" #. placeholder {0}: pc.count -#: src/pages/catchup.jsx:1057 +#: src/pages/catchup.jsx:1072 msgid "{0, plural, one {# post} other {# posts}}" msgstr "" -#: src/pages/catchup.jsx:1067 +#: src/pages/catchup.jsx:1082 msgid "Remove this catch-up?" msgstr "Remove this catch-up?" #. placeholder {0}: pc.id -#: src/pages/catchup.jsx:1070 +#: src/pages/catchup.jsx:1085 msgid "Removing Catch-up {0}" msgstr "Removing Catch-up {0}" #. placeholder {0}: pc.id -#: src/pages/catchup.jsx:1074 +#: src/pages/catchup.jsx:1089 msgid "Catch-up {0} removed" msgstr "Catch-up {0} removed" -#: src/pages/catchup.jsx:1088 +#: src/pages/catchup.jsx:1103 msgid "Note: Only max 3 will be stored. The rest will be automatically removed." msgstr "" -#: src/pages/catchup.jsx:1103 +#: src/pages/catchup.jsx:1118 msgid "Fetching posts…" msgstr "" -#: src/pages/catchup.jsx:1106 +#: src/pages/catchup.jsx:1121 msgid "This might take a while." msgstr "" -#: src/pages/catchup.jsx:1141 +#: src/pages/catchup.jsx:1156 msgid "Reset filters" msgstr "" -#: src/pages/catchup.jsx:1149 -#: src/pages/catchup.jsx:1592 +#: src/pages/catchup.jsx:1164 +#: src/pages/catchup.jsx:1607 msgid "Top links" msgstr "" #. placeholder {0}: sharers.map((s) => { const { avatarStatic, displayName } = s; return ( ); }) -#: src/pages/catchup.jsx:1262 +#: src/pages/catchup.jsx:1277 msgid "Shared by {0}" msgstr "" -#: src/pages/catchup.jsx:1317 +#: src/pages/catchup.jsx:1332 #: src/pages/mentions.jsx:154 #: src/pages/search.jsx:330 msgid "All" msgstr "" #. placeholder {0}: authorCountsList.length -#: src/pages/catchup.jsx:1402 +#: src/pages/catchup.jsx:1417 msgid "{0, plural, one {# author} other {# authors}}" msgstr "" -#: src/pages/catchup.jsx:1414 +#: src/pages/catchup.jsx:1429 msgid "Sort" msgstr "" -#: src/pages/catchup.jsx:1445 +#: src/pages/catchup.jsx:1459 msgid "Date" msgstr "Date" -#: src/pages/catchup.jsx:1449 +#: src/pages/catchup.jsx:1464 msgid "Density" msgstr "Density" #. js-lingui-explicit-id -#: src/pages/catchup.jsx:1472 +#: src/pages/catchup.jsx:1487 msgid "group.filter" msgstr "Group" -#: src/pages/catchup.jsx:1487 +#: src/pages/catchup.jsx:1502 msgid "Authors" msgstr "Authors" -#: src/pages/catchup.jsx:1488 +#: src/pages/catchup.jsx:1503 msgid "None" msgstr "None" -#: src/pages/catchup.jsx:1504 +#: src/pages/catchup.jsx:1519 msgid "Show all authors" msgstr "" -#: src/pages/catchup.jsx:1555 +#: src/pages/catchup.jsx:1570 msgid "You don't have to read everything." msgstr "You don't have to read everything." -#: src/pages/catchup.jsx:1556 +#: src/pages/catchup.jsx:1571 msgid "That's all." msgstr "That's all." -#: src/pages/catchup.jsx:1564 +#: src/pages/catchup.jsx:1579 msgid "Back to top" msgstr "" -#: src/pages/catchup.jsx:1595 +#: src/pages/catchup.jsx:1610 msgid "Links shared by followings, sorted by shared counts, boosts and likes." msgstr "" -#: src/pages/catchup.jsx:1601 +#: src/pages/catchup.jsx:1616 msgid "Sort: Density" msgstr "" -#: src/pages/catchup.jsx:1604 +#: src/pages/catchup.jsx:1619 msgid "Posts are sorted by information density or depth. Shorter posts are \"lighter\" while longer posts are \"heavier\". Posts with photos are \"heavier\" than posts without photos." msgstr "" -#: src/pages/catchup.jsx:1611 +#: src/pages/catchup.jsx:1626 msgid "Group: Authors" msgstr "" -#: src/pages/catchup.jsx:1614 +#: src/pages/catchup.jsx:1629 msgid "Posts are grouped by authors, sorted by posts count per author." msgstr "" -#: src/pages/catchup.jsx:1661 +#: src/pages/catchup.jsx:1676 msgid "Next author" msgstr "" -#: src/pages/catchup.jsx:1669 +#: src/pages/catchup.jsx:1684 msgid "Previous author" msgstr "" -#: src/pages/catchup.jsx:1685 +#: src/pages/catchup.jsx:1700 msgid "Scroll to top" msgstr "" diff --git a/src/pages/catchup.jsx b/src/pages/catchup.jsx index edac6486..99eee3db 100644 --- a/src/pages/catchup.jsx +++ b/src/pages/catchup.jsx @@ -38,6 +38,7 @@ import getDomain from '../utils/get-domain'; import htmlContentLength from '../utils/html-content-length'; import mem from '../utils/mem'; import niceDateTime from '../utils/nice-date-time'; +import { supportsNativeQuote } from '../utils/quote-utils'; import shortenNumber from '../utils/shorten-number'; import showToast from '../utils/show-toast'; import states, { statusKey } from '../utils/states'; @@ -69,6 +70,7 @@ const FILTER_KEYS = { original: msg`Original`, replies: msg`Replies`, boosts: msg`Boosts`, + quotes: msg`Quotes`, followedTags: msg`Followed tags`, groups: msg`Groups`, filtered: msg`Filtered`, @@ -78,6 +80,10 @@ const FILTER_SORTS = [ 'repliesCount', 'favouritesCount', 'reblogsCount', + // TODO: Add this later when there's enough usage + // Sorting by quotes count seems not useful… yet? + // And we're combining it with boosts count, so that's even weirder… + // 'quotesCount', 'density', ]; const FILTER_GROUPS = [null, 'account']; @@ -93,6 +99,10 @@ const DTF = mem( }), ); +function hasQuote(quote) { + return quote?.id || quote?.quotedStatus?.id; +} + function Catchup() { const { i18n, _, t } = useLingui(); const dtf = DTF(i18n.locale); @@ -302,6 +312,7 @@ function Catchup() { let filtered = 0, groups = 0, boosts = 0, + quotes = 0, replies = 0, followedTags = 0, original = 0; @@ -316,6 +327,9 @@ function Catchup() { } else if (post.reblog) { boosts++; post.__FILTER = 'boosts'; + } else if (supportsNativeQuote() && hasQuote(post.quote)) { + quotes++; + post.__FILTER = 'quotes'; } else if (post._followedTags?.length) { followedTags++; post.__FILTER = 'followedTags'; @@ -396,6 +410,7 @@ function Catchup() { filtered, groups, boosts, + quotes, replies, followedTags, original, @@ -1432,11 +1447,10 @@ function Catchup() { checked={sortBy === key} onChange={() => { setSortBy(key); - const order = /(replies|favourites|reblogs)/.test( - key, - ) - ? 'desc' - : 'asc'; + const order = + /(replies|favourites|reblogs|quotes)/.test(key) + ? 'desc' + : 'asc'; setSortOrder(order); }} /> @@ -1446,6 +1460,7 @@ function Catchup() { repliesCount: t`Replies`, favouritesCount: t`Likes`, reblogsCount: t`Boosts`, + quotesCount: t`Quotes`, density: t`Density`, }[key] } @@ -1707,6 +1722,7 @@ const PostLine = memo( account, group, reblog, + quote, inReplyToId, inReplyToAccountId, _followedTags: isFollowedTags, @@ -1732,9 +1748,11 @@ const PostLine = memo( ? 'group' : reblog ? 'reblog' - : isFollowedTags?.length - ? 'followed-tags' - : '' + : supportsNativeQuote() && hasQuote(quote) + ? 'quote' + : isFollowedTags?.length + ? 'followed-tags' + : '' } ${isReplyTo ? 'reply-to' : ''} ${ isFiltered ? 'filtered' : '' } visibility-${visibility}`} @@ -2051,7 +2069,7 @@ function PostPeek({ post, filterInfo }) { function PostStats({ post }) { const { t } = useLingui(); - const { reblogsCount, repliesCount, favouritesCount } = post; + const { reblogsCount, repliesCount, favouritesCount, quotesCount } = post; return ( {repliesCount > 0 && ( @@ -2066,12 +2084,16 @@ function PostStats({ post }) { {shortenNumber(favouritesCount)} )} - {reblogsCount > 0 && ( + {reblogsCount > 0 || quotesCount > 0 ? ( {' '} - {shortenNumber(reblogsCount)} + {reblogsCount > 0 || quotesCount > 0 + ? `${reblogsCount > 0 ? shortenNumber(reblogsCount) : ''}${ + reblogsCount > 0 && quotesCount > 0 ? '+' : '' + }${quotesCount > 0 ? shortenNumber(quotesCount) : ''}` + : shortenNumber(reblogsCount)} - )} + ) : null} ); }