diff --git a/renderer/components/layouts/timelines.tsx b/renderer/components/layouts/timelines.tsx index 0defc026..c2582057 100644 --- a/renderer/components/layouts/timelines.tsx +++ b/renderer/components/layouts/timelines.tsx @@ -4,7 +4,7 @@ import generator, { Entity } from 'megalodon' import { useRouter } from 'next/router' import { useEffect, useState } from 'react' import { useHotkeys } from 'react-hotkeys-hook' -import { FaBell, FaBookmark, FaGlobe, FaHouse, FaList, FaStar, FaUsers } from 'react-icons/fa6' +import { FaBell, FaBookmark, FaGlobe, FaHouse, FaList, FaStar, FaUsers, FaHashtag } from 'react-icons/fa6' import { useIntl } from 'react-intl' import Jump from '../Jump' import { useUnreads } from '@/provider/unreads' @@ -27,6 +27,7 @@ export default function Layout({ children }: LayoutProps) { const [account, setAccount] = useState(null) const [lists, setLists] = useState>([]) + const [followedTags, setFollowedTags] = useState>([]) const [openJump, setOpenJump] = useState(false) useHotkeys('mod+k', () => setOpenJump(current => !current)) @@ -50,6 +51,11 @@ export default function Layout({ children }: LayoutProps) { setLists(res.data) } f() + const g = async () => { + const res = await c.getFollowedTags() + setFollowedTags(res.data) + } + g() }, [account]) const pages: Array = [ @@ -136,6 +142,21 @@ export default function Layout({ children }: LayoutProps) {
{list.title}
))} + + {followedTags.map(tag => ( + router.push({ pathname: `/accounts/${router.query.id}/tag_${tag.name}` })} + className="sidebar-menu-item theme-text-primary overflow-hidden whitespace-nowrap" + title={tag.name} + > + + + +
{tag.name}
+
+ ))} {children} diff --git a/renderer/components/timelines/Timeline.tsx b/renderer/components/timelines/Timeline.tsx index b4e5bb04..bc7c4e83 100644 --- a/renderer/components/timelines/Timeline.tsx +++ b/renderer/components/timelines/Timeline.tsx @@ -27,6 +27,7 @@ export default function Timeline(props: Props) { const [firstItemIndex, setFirstItemIndex] = useState(TIMELINE_MAX_STATUSES) const [composeHeight, setComposeHeight] = useState(120) const [list, setList] = useState(null) + const [tag, setTag] = useState(null) const [filters, setFilters] = useState>([]) const [nextMaxId, setNextMaxId] = useState(null) @@ -58,6 +59,7 @@ export default function Timeline(props: Props) { const res = await loadTimeline(props.timeline, props.client) setStatuses(res) setList(null) + setTag(null) switch (props.timeline) { case 'home': { streaming.current = await props.client.userStreaming() @@ -77,6 +79,13 @@ export default function Timeline(props: Props) { const res = await props.client.getList(match[1]) streaming.current = await props.client.listStreaming(match[1]) setList(res.data) + } else { + const tag_match = props.timeline.match(/tag_(\w+)/) + if (tag_match && tag_match[1] && typeof tag_match[1] === 'string') { + const res = await props.client.getTag(tag_match[1]) + streaming.current = await props.client.tagStreaming(tag_match[1]) + setTag(res.data) + } } break } @@ -169,9 +178,16 @@ export default function Timeline(props: Props) { default: { // Check list const match = tl.match(/list_(\d+)/) - if (match[1] && typeof match[1] === 'string') { + if (match && match[1] && typeof match[1] === 'string') { const res = await client.getListTimeline(match[1], options) return res.data + } else { + // Check tag + const tag_match = tl.match(/tag_(\w+)/) + if (tag_match && tag_match[1] && typeof tag_match[1] === 'string') { + const res = await client.getTagTimeline(tag_match[1], options) + return res.data + } } return [] } @@ -262,7 +278,10 @@ export default function Timeline(props: Props) {
backToTop()}> - {props.timeline.match(/list_(\d+)/) ? <>{list && list.title} : } + { + props.timeline.match(/list_(\d+)/) ? <>{list && list.title} : + (props.timeline.match(/tag_(\w+)/) ? <>{tag && `# ${tag.name}`} : + )}
search(ev)}>