chore: added publishedDate and ordered posts
1ec34a32
5 file(s) · +38 −7
| 2 | 2 | ||
| 3 | 3 | Endless rambling of things to fix and improve |
|
| 4 | 4 | ||
| 5 | - | - [ ] Add `publishedDate` to `rssPost` |
|
| 6 | - | - [ ] Order posts by newest first |
|
| 5 | + | - [x] Add `publishedDate` to `rssPost` |
|
| 6 | + | - [x] Order posts by newest first |
|
| 7 | 7 | - [x] Instead of "by author" if Author is unavailable, use blog/feed name |
|
| 8 | 8 | - [x] Add auto-find RSS feed when adding a feed |
|
| 9 | 9 | - [ ] When scrolling through one feed and then selecting another, make the content scroll back to the top |
| 89 | 89 | const feedPostsQuery = useQuery(postsByFeedQuery(selectedFeedId || "")); |
|
| 90 | 90 | const feedPosts = selectedFeedId ? feedPostsQuery : allPosts; |
|
| 91 | 91 | ||
| 92 | - | // Filter posts by search query |
|
| 92 | + | // Filter and sort posts by search query and date |
|
| 93 | 93 | const filteredPosts = React.useMemo(() => { |
|
| 94 | - | if (!searchQuery) return feedPosts; |
|
| 95 | - | return feedPosts.filter((post) => |
|
| 96 | - | post.title?.toLowerCase().includes(searchQuery.toLowerCase()), |
|
| 97 | - | ); |
|
| 94 | + | const filtered = searchQuery |
|
| 95 | + | ? feedPosts.filter((post) => |
|
| 96 | + | post.title?.toLowerCase().includes(searchQuery.toLowerCase()), |
|
| 97 | + | ) |
|
| 98 | + | : feedPosts; |
|
| 99 | + | ||
| 100 | + | // Sort by publishedDate (most recent first) |
|
| 101 | + | return [...filtered].sort((a, b) => { |
|
| 102 | + | // Handle null dates - put them at the end |
|
| 103 | + | if (!a.publishedDate) return 1; |
|
| 104 | + | if (!b.publishedDate) return -1; |
|
| 105 | + | // Most recent first (descending order) |
|
| 106 | + | return b.publishedDate.localeCompare(a.publishedDate); |
|
| 107 | + | }); |
|
| 98 | 108 | }, [feedPosts, searchQuery]); |
|
| 99 | 109 | ||
| 100 | 110 | async function addFeed() { |
|
| 195 | 205 | title: feedData.title, |
|
| 196 | 206 | description: feedData.description || feedData.subtitle || "", |
|
| 197 | 207 | category: categoryInput || "Uncategorized", |
|
| 208 | + | dateUpdated: new Date().toISOString(), |
|
| 198 | 209 | }); |
|
| 199 | 210 | ||
| 200 | 211 | // Process posts/entries |
|
| 204 | 215 | author: isAtom |
|
| 205 | 216 | ? post.author?.name || feedData.title |
|
| 206 | 217 | : post.author || feedData.title, |
|
| 218 | + | publishedDate: new Date(post.pubDate || post.updated).toISOString(), |
|
| 207 | 219 | link: isAtom |
|
| 208 | 220 | ? typeof post.link === "string" |
|
| 209 | 221 | ? post.link || post.id |
|
| 148 | 148 | </Button> |
|
| 149 | 149 | )} |
|
| 150 | 150 | </div> |
|
| 151 | + | <span className="text-xs text-muted-foreground"> |
|
| 152 | + | {selectedPost.publishedDate |
|
| 153 | + | ? new Date(selectedPost.publishedDate).toLocaleDateString( |
|
| 154 | + | "en-US", |
|
| 155 | + | { |
|
| 156 | + | year: "numeric", |
|
| 157 | + | month: "long", |
|
| 158 | + | day: "numeric", |
|
| 159 | + | }, |
|
| 160 | + | ) |
|
| 161 | + | : ""} |
|
| 162 | + | </span> |
|
| 151 | 163 | </div> |
|
| 152 | 164 | <Separator /> |
|
| 153 | 165 | {selectedPost.content ? ( |
| 48 | 48 | {} as Record<string, Feed[]>, |
|
| 49 | 49 | ); |
|
| 50 | 50 | ||
| 51 | + | // Sort feeds within each category alphabetically by title |
|
| 52 | + | Object.keys(feedsByCategory).forEach((category) => { |
|
| 53 | + | feedsByCategory[category].sort((a, b) => a.title.localeCompare(b.title)); |
|
| 54 | + | }); |
|
| 55 | + | ||
| 51 | 56 | const categories = Object.keys(feedsByCategory).sort(); |
|
| 52 | 57 | ||
| 53 | 58 | return ( |
| 28 | 28 | title: NonEmptyString200, |
|
| 29 | 29 | description: nullOr(NonEmptyString1000), |
|
| 30 | 30 | category: nullOr(NonEmptyString50), |
|
| 31 | + | dateUpdated: nullOr(NonEmptyString), |
|
| 31 | 32 | }, |
|
| 32 | 33 | rssPost: { |
|
| 33 | 34 | id: RSSPostId, |
|
| 36 | 37 | link: NonEmptyString1000, |
|
| 37 | 38 | content: nullOr(NonEmptyString), |
|
| 38 | 39 | author: nullOr(NonEmptyString200), |
|
| 40 | + | publishedDate: nullOr(NonEmptyString), |
|
| 39 | 41 | }, |
|
| 40 | 42 | readStatus: { |
|
| 41 | 43 | id: id("ReadStatus"), |
|