diff --git a/src/components/FeedSuggestedFollows/index.tsx b/src/components/FeedSuggestedFollows/index.tsx
index 0c8993f8ce..9d36a524be 100644
--- a/src/components/FeedSuggestedFollows/index.tsx
+++ b/src/components/FeedSuggestedFollows/index.tsx
@@ -6,21 +6,69 @@ import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useProfileShadow} from '#/state/cache/profile-shadow'
-import {useModerationOpts} from '#/state/queries/preferences'
+import {useModerationOpts} from '#/state/preferences/moderation-opts'
import {useSuggestedFollowsQuery} from '#/state/queries/suggested-follows'
import {isJustAMute} from 'lib/moderation'
import {sanitizeDisplayName} from 'lib/strings/display-names'
import {sanitizeHandle} from 'lib/strings/handles'
import {PreviewableUserAvatar} from '#/view/com/util/UserAvatar'
import {atoms as a, useTheme} from '#/alf'
-import {Button, ButtonIcon} from '#/components/Button'
+import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {useFollowMethods} from '#/components/hooks/useFollowMethods'
import {useRichText} from '#/components/hooks/useRichText'
+import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as Refresh} from '#/components/icons/ArrowRotateCounterClockwise'
import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
+import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
import {RichText} from '#/components/RichText'
import {Text} from '#/components/Typography'
+export function SuggestedFollowCardSkeleton() {
+ const t = useTheme()
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
export function SuggestedFollowCard({
profile: profileUnshadowed,
}: {
@@ -32,10 +80,9 @@ export function SuggestedFollowCard({
const moderationOpts = useModerationOpts()
const {follow, unfollow} = useFollowMethods({
profile,
- // @ts-ignore TODO
- logContext: 'FeedSuggestedFollowsCard',
+ logContext: 'FeedSuggestedFollowCard',
})
- // @ts-ignore TODO
+ // @ts-ignore TODO why isn't this type correct
const [descriptionRT] = useRichText(profileUnshadowed?.description ?? '')
if (!moderationOpts) return null
@@ -49,7 +96,7 @@ export function SuggestedFollowCard({
a.p_lg,
a.rounded_md,
a.gap_sm,
- t.atoms.bg,
+ t.atoms.bg_contrast_25,
{
width: 300,
},
@@ -57,8 +104,7 @@ export function SuggestedFollowCard({
@@ -94,7 +140,7 @@ export function SuggestedFollowCard({
size="small"
shape="round"
variant="solid"
- color="secondary"
+ color="primary"
onPress={profile.viewer?.following ? unfollow : follow}>
{profile.viewer?.following ? (
@@ -105,16 +151,54 @@ export function SuggestedFollowCard({
-
+
)
}
-export function FeedSuggestedFollows() {
+export function ErrorState({retry}: {retry: () => void}) {
const t = useTheme()
- const {isLoading, data: suggestions, error} = useSuggestedFollowsQuery()
+ return (
+ <>
+
+
+ Whoops, something went wrong :(
+
+
+
+
+
+ >
+ )
+}
+
+export function FeedSuggestedFollowsCards() {
+ const {
+ isLoading,
+ data: suggestions,
+ error,
+ refetch,
+ } = useSuggestedFollowsQuery()
const profiles: AppBskyActorDefs.ProfileViewBasic[] = []
if (suggestions) {
@@ -131,6 +215,28 @@ export function FeedSuggestedFollows() {
}
}
+ return (
+
+
+ {isLoading ? (
+ Array(3)
+ .fill(0)
+ .map((_, i) => )
+ ) : error || !profiles.length ? (
+
+ ) : (
+ profiles.map((profile, i) => (
+
+ ))
+ )}
+
+
+ )
+}
+
+export function FeedSuggestedFollowsInterstitial() {
+ const t = useTheme()
+
return (
@@ -140,17 +246,7 @@ export function FeedSuggestedFollows() {
-
-
- {isLoading
- ? null
- : error || !profiles.length
- ? null
- : profiles.map((profile, i) => (
-
- ))}
-
-
+
)
}
diff --git a/src/screens/Home/EmptyTimeline.tsx b/src/screens/Home/EmptyTimeline.tsx
new file mode 100644
index 0000000000..b4f538c61e
--- /dev/null
+++ b/src/screens/Home/EmptyTimeline.tsx
@@ -0,0 +1,70 @@
+import React from 'react'
+import {View} from 'react-native'
+import {msg, Trans} from '@lingui/macro'
+import {useLingui} from '@lingui/react'
+
+import {CenteredView} from '#/view/com/util/Views'
+import {atoms as a} from '#/alf'
+import {Button, ButtonIcon, ButtonText} from '#/components/Button'
+import {FeedSuggestedFollowsCards} from '#/components/FeedSuggestedFollows'
+import {IconCircle} from '#/components/IconCircle'
+import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as Refresh} from '#/components/icons/ArrowRotateCounterClockwise'
+import {FilterTimeline_Stroke2_Corner0_Rounded as FilterTimeline} from '#/components/icons/FilterTimeline'
+import {Divider} from '#/components/Menu'
+import {Text} from '#/components/Typography'
+
+export function EmptyTimeline() {
+ const {_} = useLingui()
+
+ return (
+
+
+
+
+
+ Welcome to your timeline
+
+
+
+ Your timeline is where you can see posts from people you follow.
+ It's always chronologically sorted, so you'll never miss a post.
+
+
+
+
+ Follow some people to get started!
+
+
+
+
+
+
+
+
+
+
+ When you're done:
+
+
+
+
+
+
+ )
+}