From 78be563bdc6505a40389be144ca9e7d5939e12be Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Sat, 1 Jun 2024 12:15:19 -0500 Subject: [PATCH] Condense feeds on mobile --- src/features/bookmarks/index.tsx | 6 ++++-- src/features/community-timeline/index.tsx | 6 ++++-- src/features/hashtag-timeline/index.tsx | 6 ++++-- src/features/home-timeline/index.tsx | 6 ++++-- src/features/landing-timeline/index.tsx | 6 ++++-- src/features/list-timeline/index.tsx | 6 ++++-- src/features/public-timeline/index.tsx | 6 ++++-- src/features/quotes/index.tsx | 6 ++++-- src/features/remote-timeline/index.tsx | 6 ++++-- src/features/test-timeline/index.tsx | 6 ++++-- src/features/ui/components/navbar.tsx | 11 ++++++++++- src/hooks/useIsMobile.ts | 6 ++++++ src/hooks/useScreenWidth.ts | 19 +++++++++++++++++++ src/pages/home-page.tsx | 7 +++++-- 14 files changed, 80 insertions(+), 23 deletions(-) create mode 100644 src/hooks/useIsMobile.ts create mode 100644 src/hooks/useScreenWidth.ts diff --git a/src/features/bookmarks/index.tsx b/src/features/bookmarks/index.tsx index 3522ede0a..f637a7a68 100644 --- a/src/features/bookmarks/index.tsx +++ b/src/features/bookmarks/index.tsx @@ -12,6 +12,7 @@ import PullToRefresh from 'soapbox/components/pull-to-refresh'; import StatusList from 'soapbox/components/status-list'; import { Column } from 'soapbox/components/ui'; import { useAppSelector, useAppDispatch, useTheme } from 'soapbox/hooks'; +import { useIsMobile } from 'soapbox/hooks/useIsMobile'; import toast from 'soapbox/toast'; const messages = defineMessages({ @@ -40,6 +41,7 @@ const Bookmarks: React.FC = ({ params }) => { const intl = useIntl(); const history = useHistory(); const theme = useTheme(); + const isMobile = useIsMobile(); const folderId = params?.id; @@ -106,7 +108,7 @@ const Bookmarks: React.FC = ({ params }) => { action={ } - transparent + transparent={!isMobile} > = ({ params }) => { isLoading={typeof isLoading === 'boolean' ? isLoading : true} onLoadMore={() => handleLoadMore(dispatch, folderId)} emptyMessage={emptyMessage} - divideType={theme === 'black' ? 'border' : 'space'} + divideType={(theme === 'black' || isMobile) ? 'border' : 'space'} /> diff --git a/src/features/community-timeline/index.tsx b/src/features/community-timeline/index.tsx index 9e7fca257..48ebcd049 100644 --- a/src/features/community-timeline/index.tsx +++ b/src/features/community-timeline/index.tsx @@ -6,6 +6,7 @@ import { useCommunityStream } from 'soapbox/api/hooks'; import PullToRefresh from 'soapbox/components/pull-to-refresh'; import { Column } from 'soapbox/components/ui'; import { useAppSelector, useAppDispatch, useSettings, useTheme } from 'soapbox/hooks'; +import { useIsMobile } from 'soapbox/hooks/useIsMobile'; import Timeline from '../ui/components/timeline'; @@ -23,6 +24,7 @@ const CommunityTimeline = () => { const next = useAppSelector(state => state.timelines.get('community')?.next); const timelineId = 'community'; + const isMobile = useIsMobile(); const handleLoadMore = (maxId: string) => { dispatch(expandCommunityTimeline({ url: next, maxId, onlyMedia })); @@ -39,7 +41,7 @@ const CommunityTimeline = () => { }, [onlyMedia]); return ( - + { prefix='home' onLoadMore={handleLoadMore} emptyMessage={} - divideType={theme === 'black' ? 'border' : 'space'} + divideType={(theme === 'black' || isMobile) ? 'border' : 'space'} /> diff --git a/src/features/hashtag-timeline/index.tsx b/src/features/hashtag-timeline/index.tsx index b00a27c14..0a39bdfeb 100644 --- a/src/features/hashtag-timeline/index.tsx +++ b/src/features/hashtag-timeline/index.tsx @@ -8,6 +8,7 @@ import List, { ListItem } from 'soapbox/components/list'; import { Column, Toggle } from 'soapbox/components/ui'; import Timeline from 'soapbox/features/ui/components/timeline'; import { useAppDispatch, useAppSelector, useFeatures, useLoggedIn, useTheme } from 'soapbox/hooks'; +import { useIsMobile } from 'soapbox/hooks/useIsMobile'; interface IHashtagTimeline { params?: { @@ -24,6 +25,7 @@ export const HashtagTimeline: React.FC = ({ params }) => { const next = useAppSelector(state => state.timelines.get(`hashtag:${id}`)?.next); const { isLoggedIn } = useLoggedIn(); const theme = useTheme(); + const isMobile = useIsMobile(); const handleLoadMore = (maxId: string) => { dispatch(expandHashtagTimeline(id, { url: next, maxId })); @@ -50,7 +52,7 @@ export const HashtagTimeline: React.FC = ({ params }) => { }, [id]); return ( - + {features.followHashtags && isLoggedIn && ( = ({ params }) => { timelineId={`hashtag:${id}`} onLoadMore={handleLoadMore} emptyMessage={} - divideType={theme === 'black' ? 'border' : 'space'} + divideType={(theme === 'black' || isMobile) ? 'border' : 'space'} /> ); diff --git a/src/features/home-timeline/index.tsx b/src/features/home-timeline/index.tsx index dd6bdd75d..2bf388d03 100644 --- a/src/features/home-timeline/index.tsx +++ b/src/features/home-timeline/index.tsx @@ -7,6 +7,7 @@ import PullToRefresh from 'soapbox/components/pull-to-refresh'; import { Column, Stack, Text } from 'soapbox/components/ui'; import Timeline from 'soapbox/features/ui/components/timeline'; import { useAppSelector, useAppDispatch, useFeatures, useInstance, useTheme } from 'soapbox/hooks'; +import { useIsMobile } from 'soapbox/hooks/useIsMobile'; const messages = defineMessages({ title: { id: 'column.home', defaultMessage: 'Home' }, @@ -20,6 +21,7 @@ const HomeTimeline: React.FC = () => { const theme = useTheme(); const polling = useRef(null); + const isMobile = useIsMobile(); const isPartial = useAppSelector(state => state.timelines.get('home')?.isPartial === true); const next = useAppSelector(state => state.timelines.get('home')?.next); @@ -60,14 +62,14 @@ const HomeTimeline: React.FC = () => { }, [isPartial]); return ( - + diff --git a/src/features/landing-timeline/index.tsx b/src/features/landing-timeline/index.tsx index aa08a5783..5b6ce33e3 100644 --- a/src/features/landing-timeline/index.tsx +++ b/src/features/landing-timeline/index.tsx @@ -6,6 +6,7 @@ import { useCommunityStream } from 'soapbox/api/hooks'; import PullToRefresh from 'soapbox/components/pull-to-refresh'; import { Column } from 'soapbox/components/ui'; import { useAppSelector, useAppDispatch, useInstance, useTheme } from 'soapbox/hooks'; +import { useIsMobile } from 'soapbox/hooks/useIsMobile'; import AboutPage from '../about'; import Timeline from '../ui/components/timeline'; @@ -16,6 +17,7 @@ const LandingTimeline = () => { const dispatch = useAppDispatch(); const instance = useInstance(); const theme = useTheme(); + const isMobile = useIsMobile(); const timelineEnabled = !instance.pleroma.metadata.restrict_unauthenticated.timelines.local; const next = useAppSelector(state => state.timelines.get('community')?.next); @@ -43,7 +45,7 @@ const LandingTimeline = () => { }, []); return ( - +
@@ -57,7 +59,7 @@ const LandingTimeline = () => { prefix='home' onLoadMore={handleLoadMore} emptyMessage={} - divideType={theme === 'black' ? 'border' : 'space'} + divideType={(theme === 'black' || isMobile) ? 'border' : 'space'} />
) : ( diff --git a/src/features/list-timeline/index.tsx b/src/features/list-timeline/index.tsx index ec1e412dd..19974e6ad 100644 --- a/src/features/list-timeline/index.tsx +++ b/src/features/list-timeline/index.tsx @@ -9,6 +9,7 @@ import { useListStream } from 'soapbox/api/hooks'; import MissingIndicator from 'soapbox/components/missing-indicator'; import { Column, Button, Spinner } from 'soapbox/components/ui'; import { useAppDispatch, useAppSelector, useTheme } from 'soapbox/hooks'; +import { useIsMobile } from 'soapbox/hooks/useIsMobile'; import Timeline from '../ui/components/timeline'; @@ -16,6 +17,7 @@ const ListTimeline: React.FC = () => { const dispatch = useAppDispatch(); const { id } = useParams<{ id: string }>(); const theme = useTheme(); + const isMobile = useIsMobile(); const list = useAppSelector((state) => state.lists.get(id)); const next = useAppSelector(state => state.timelines.get(`list:${id}`)?.next); @@ -60,14 +62,14 @@ const ListTimeline: React.FC = () => { ); return ( - + ); diff --git a/src/features/public-timeline/index.tsx b/src/features/public-timeline/index.tsx index a73ac7289..37010ae5f 100644 --- a/src/features/public-timeline/index.tsx +++ b/src/features/public-timeline/index.tsx @@ -8,6 +8,7 @@ import { usePublicStream } from 'soapbox/api/hooks'; import PullToRefresh from 'soapbox/components/pull-to-refresh'; import { Accordion, Column } from 'soapbox/components/ui'; import { useAppSelector, useAppDispatch, useInstance, useSettings, useTheme, useFeatures } from 'soapbox/hooks'; +import { useIsMobile } from 'soapbox/hooks/useIsMobile'; import PinnedHostsPicker from '../remote-timeline/components/pinned-hosts-picker'; import Timeline from '../ui/components/timeline'; @@ -29,6 +30,7 @@ const PublicTimeline = () => { const next = useAppSelector(state => state.timelines.get('public')?.next); const timelineId = 'public'; + const isMobile = useIsMobile(); const explanationBoxExpanded = settings.explanationBox; const showExplanationBox = settings.showExplanationBox && !features.nostr; @@ -56,7 +58,7 @@ const PublicTimeline = () => { }, [onlyMedia]); return ( - + {showExplanationBox && ( @@ -96,7 +98,7 @@ const PublicTimeline = () => { prefix='home' onLoadMore={handleLoadMore} emptyMessage={} - divideType={theme === 'black' ? 'border' : 'space'} + divideType={(theme === 'black' || isMobile) ? 'border' : 'space'} /> diff --git a/src/features/quotes/index.tsx b/src/features/quotes/index.tsx index 60ea8a550..42745bdbb 100644 --- a/src/features/quotes/index.tsx +++ b/src/features/quotes/index.tsx @@ -8,6 +8,7 @@ import { expandStatusQuotes, fetchStatusQuotes } from 'soapbox/actions/status-qu import StatusList from 'soapbox/components/status-list'; import { Column } from 'soapbox/components/ui'; import { useAppDispatch, useAppSelector, useTheme } from 'soapbox/hooks'; +import { useIsMobile } from 'soapbox/hooks/useIsMobile'; const messages = defineMessages({ heading: { id: 'column.quotes', defaultMessage: 'Post quotes' }, @@ -21,6 +22,7 @@ const Quotes: React.FC = () => { const intl = useIntl(); const { statusId } = useParams<{ statusId: string }>(); const theme = useTheme(); + const isMobile = useIsMobile(); const statusIds = useAppSelector((state) => state.status_lists.getIn([`quotes:${statusId}`, 'items'], ImmutableOrderedSet())); const isLoading = useAppSelector((state) => state.status_lists.getIn([`quotes:${statusId}`, 'isLoading'], true)); @@ -37,7 +39,7 @@ const Quotes: React.FC = () => { const emptyMessage = ; return ( - + } @@ -47,7 +49,7 @@ const Quotes: React.FC = () => { onLoadMore={() => handleLoadMore(statusId, dispatch)} onRefresh={handleRefresh} emptyMessage={emptyMessage} - divideType={theme === 'black' ? 'border' : 'space'} + divideType={(theme === 'black' || isMobile) ? 'border' : 'space'} /> ); diff --git a/src/features/remote-timeline/index.tsx b/src/features/remote-timeline/index.tsx index ca996bb13..630fe80fd 100644 --- a/src/features/remote-timeline/index.tsx +++ b/src/features/remote-timeline/index.tsx @@ -7,6 +7,7 @@ import { useRemoteStream } from 'soapbox/api/hooks'; import IconButton from 'soapbox/components/icon-button'; import { Column, HStack, Text } from 'soapbox/components/ui'; import { useAppSelector, useAppDispatch, useSettings, useTheme } from 'soapbox/hooks'; +import { useIsMobile } from 'soapbox/hooks/useIsMobile'; import Timeline from '../ui/components/timeline'; @@ -32,6 +33,7 @@ const RemoteTimeline: React.FC = ({ params }) => { const next = useAppSelector(state => state.timelines.get('remote')?.next); const pinned = settings.remote_timeline.pinnedHosts.includes(instance); + const isMobile = useIsMobile(); const handleCloseClick: React.MouseEventHandler = () => { history.push('/timeline/fediverse'); @@ -48,7 +50,7 @@ const RemoteTimeline: React.FC = ({ params }) => { }, [onlyMedia]); return ( - + {instance && } {!pinned && ( @@ -76,7 +78,7 @@ const RemoteTimeline: React.FC = ({ params }) => { values={{ instance }} /> } - divideType={theme === 'black' ? 'border' : 'space'} + divideType={(theme === 'black' || isMobile) ? 'border' : 'space'} /> ); diff --git a/src/features/test-timeline/index.tsx b/src/features/test-timeline/index.tsx index 623ef9d33..4b99b550b 100644 --- a/src/features/test-timeline/index.tsx +++ b/src/features/test-timeline/index.tsx @@ -4,6 +4,7 @@ import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import { importFetchedStatuses } from 'soapbox/actions/importer'; import { expandTimelineSuccess } from 'soapbox/actions/timelines'; import { useAppDispatch, useTheme } from 'soapbox/hooks'; +import { useIsMobile } from 'soapbox/hooks/useIsMobile'; import { Column } from '../../components/ui'; import Timeline from '../ui/components/timeline'; @@ -32,6 +33,7 @@ const TestTimeline: React.FC = () => { const intl = useIntl(); const dispatch = useAppDispatch(); const theme = useTheme(); + const isMobile = useIsMobile(); React.useEffect(() => { dispatch(importFetchedStatuses(MOCK_STATUSES)); @@ -39,12 +41,12 @@ const TestTimeline: React.FC = () => { }, []); return ( - + } - divideType={theme === 'black' ? 'border' : 'space'} + divideType={(theme === 'black' || isMobile) ? 'border' : 'space'} /> ); diff --git a/src/features/ui/components/navbar.tsx b/src/features/ui/components/navbar.tsx index d21a0d9f9..e7721d5fc 100644 --- a/src/features/ui/components/navbar.tsx +++ b/src/features/ui/components/navbar.tsx @@ -11,6 +11,7 @@ import SiteLogo from 'soapbox/components/site-logo'; import { Avatar, Button, Form, HStack, IconButton, Input, Tooltip } from 'soapbox/components/ui'; import Search from 'soapbox/features/compose/components/search'; import { useAppDispatch, useAppSelector, useFeatures, useOwnAccount, useRegistrationStatus } from 'soapbox/hooks'; +import { useIsMobile } from 'soapbox/hooks/useIsMobile'; import { isStandalone } from 'soapbox/utils/state'; import ProfileDropdown from './profile-dropdown'; @@ -33,6 +34,7 @@ const Navbar = () => { const { isOpen } = useRegistrationStatus(); const { account } = useOwnAccount(); const node = useRef(null); + const isMobile = useIsMobile(); const [isLoading, setLoading] = useState(false); const [username, setUsername] = useState(''); @@ -72,7 +74,14 @@ const Navbar = () => { if (mfaToken) return ; return ( -