From 99280e252de67afb3589cb10648ff9de3b0b6cdb Mon Sep 17 00:00:00 2001 From: penpenpng Date: Thu, 5 Dec 2024 23:20:00 +0900 Subject: [PATCH] feat: jump to the toppest posts when clicking the top of column (#85) * feat: add useScroller * feat: apply useScroller * fix: integrate useScroll and useScroller * fix: dissolve scroller dependency * fix: remove broken ref * refactor: revert old #85 changes * feat: forward column operator * feat: expose onClickHeader callback * feat: jump to the top posts when clicking the column header * fix: remove topMarkerRef * feat: expose onLoad callback * feat: scroll column to top on loading new page * refactor: simplify expression * chore: add code comment --------- Co-authored-by: Shusui MOYATANI --- src/components/column/BasicColumnHeader.tsx | 7 ++++- src/components/column/BookmarkColumn.tsx | 8 ++++-- src/components/column/Column.tsx | 30 ++++++++++++++++++-- src/components/column/FollowingColumn.tsx | 11 +++++-- src/components/column/LoadMore.tsx | 11 ++++--- src/components/column/NotificationColumn.tsx | 15 ++++++++-- src/components/column/PostsColumn.tsx | 15 ++++++++-- src/components/column/ReactionsColumn.tsx | 15 ++++++++-- src/components/column/RelaysColumn.tsx | 11 +++++-- src/components/column/SearchColumn.tsx | 8 +++++- 10 files changed, 105 insertions(+), 26 deletions(-) diff --git a/src/components/column/BasicColumnHeader.tsx b/src/components/column/BasicColumnHeader.tsx index e0c3b9d5..0de9fc69 100644 --- a/src/components/column/BasicColumnHeader.tsx +++ b/src/components/column/BasicColumnHeader.tsx @@ -7,6 +7,7 @@ export type BasicColumnHeaderProps = { icon?: JSX.Element; settings: () => JSX.Element; onClose?: () => void; + onClickHeader?: () => void; }; const BasicColumnHeader: Component = (props) => { @@ -21,7 +22,11 @@ const BasicColumnHeader: Component = (props) => { {(icon) => {icon}} - {props.name} + {props.name}}> + + -
+
diff --git a/src/components/column/FollowingColumn.tsx b/src/components/column/FollowingColumn.tsx index 86bdd8fd..1da9d973 100644 --- a/src/components/column/FollowingColumn.tsx +++ b/src/components/column/FollowingColumn.tsx @@ -1,10 +1,10 @@ -import { Component, createEffect, onCleanup, onMount } from 'solid-js'; +import { Component, createEffect, createSignal, onCleanup, onMount } from 'solid-js'; import Home from 'heroicons/24/outline/home.svg'; import uniq from 'lodash/uniq'; import BasicColumnHeader from '@/components/column/BasicColumnHeader'; -import Column from '@/components/column/Column'; +import Column, { type ColumnOperator } from '@/components/column/Column'; import ColumnSettings from '@/components/column/ColumnSettings'; import LoadMore, { useLoadMore } from '@/components/column/LoadMore'; import Timeline from '@/components/timeline/Timeline'; @@ -27,8 +27,13 @@ const FollowingColumn: Component = (props) => { const { followingPubkeys } = useFollowings(() => ({ pubkey: props.column.pubkey })); + const [columnOperator, setColumnOperator] = createSignal(); + const loadMore = useLoadMore(() => ({ duration: 4 * 60 * 60, + onLoad: () => { + columnOperator()?.scrollToTop(); + }, })); const { events, eose } = useSubscription(() => { @@ -74,11 +79,13 @@ const FollowingColumn: Component = (props) => { icon={} settings={() => } onClose={() => removeColumn(props.column.id)} + onClickHeader={() => columnOperator()?.scrollToTop()} /> } width={props.column.width} columnIndex={props.columnIndex} lastColumn={props.lastColumn} + columnOperatorRef={setColumnOperator} > diff --git a/src/components/column/LoadMore.tsx b/src/components/column/LoadMore.tsx index 2c832b7e..523aa276 100644 --- a/src/components/column/LoadMore.tsx +++ b/src/components/column/LoadMore.tsx @@ -17,6 +17,7 @@ import epoch from '@/utils/epoch'; export type UseLoadMoreProps = { duration: number | null; + onLoad?: () => void; }; export type UseLoadMore = { @@ -26,7 +27,6 @@ export type UseLoadMore = { continuous: Accessor; loadLatest: () => void; loadOld: () => void; - setTopMarkerRef: (el: HTMLElement) => void; }; export type LoadMoreProps = { @@ -46,7 +46,6 @@ export const useLoadMore = (propsProvider: () => UseLoadMoreProps): UseLoadMore const [events, setEvents] = createSignal([]); const [since, setSince] = createSignal(calcSince(epoch())); const [until, setUntil] = createSignal(); - const [topMarkerRef, setTopMarkerRef] = createSignal(); const continuous = () => until() == null; const loadLatest = () => { @@ -54,7 +53,8 @@ export const useLoadMore = (propsProvider: () => UseLoadMoreProps): UseLoadMore setUntil(undefined); setSince(calcSince(epoch())); }); - topMarkerRef()?.scrollIntoView(); + + props().onLoad?.(); }; const loadOld = () => { @@ -64,7 +64,8 @@ export const useLoadMore = (propsProvider: () => UseLoadMoreProps): UseLoadMore setUntil(oldest.created_at); setSince(calcSince(oldest.created_at)); }); - topMarkerRef()?.scrollIntoView(); + + props().onLoad?.(); }; return { @@ -74,7 +75,6 @@ export const useLoadMore = (propsProvider: () => UseLoadMoreProps): UseLoadMore continuous, loadLatest, loadOld, - setTopMarkerRef, }; }; @@ -84,7 +84,6 @@ const LoadMore: Component = (props) => { return ( <> -