about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/build-flags.ts1
-rw-r--r--src/lib/moderation.ts21
-rw-r--r--src/locale/locales/cs/messages.po84
-rw-r--r--src/locale/locales/en/messages.po84
-rw-r--r--src/locale/locales/es/messages.po84
-rw-r--r--src/locale/locales/fr/messages.po84
-rw-r--r--src/locale/locales/hi/messages.po84
-rw-r--r--src/view/com/composer/Composer.tsx2
-rw-r--r--src/view/com/composer/text-input/TextInput.web.tsx10
-rw-r--r--src/view/com/feeds/FeedPage.tsx2
-rw-r--r--src/view/com/pager/Pager.tsx2
-rw-r--r--src/view/com/pager/PagerWithHeader.tsx15
-rw-r--r--src/view/com/post-thread/PostThreadItem.tsx31
-rw-r--r--src/view/com/post/Post.tsx8
-rw-r--r--src/view/com/posts/Feed.tsx37
-rw-r--r--src/view/com/posts/FeedErrorMessage.tsx11
-rw-r--r--src/view/com/posts/FeedItem.tsx8
-rw-r--r--src/view/com/posts/FollowingEndOfFeed.tsx9
-rw-r--r--src/view/com/profile/ProfileCard.tsx3
-rw-r--r--src/view/com/profile/ProfileHeader.tsx32
-rw-r--r--src/view/com/profile/ProfileHeaderSuggestedFollows.tsx8
-rw-r--r--src/view/com/util/LoadingPlaceholder.tsx55
-rw-r--r--src/view/com/util/moderation/ContentHider.tsx43
-rw-r--r--src/view/com/util/moderation/PostHider.tsx126
-rw-r--r--src/view/com/util/moderation/ProfileHeaderAlerts.tsx16
-rw-r--r--src/view/com/util/post-embeds/index.tsx15
-rw-r--r--src/view/screens/Home.tsx9
-rw-r--r--src/view/screens/Profile.tsx19
-rw-r--r--src/view/screens/ProfileFeed.tsx7
-rw-r--r--src/view/screens/ProfileList.tsx55
-rw-r--r--src/view/shell/createNativeStackNavigatorWithAuth.tsx3
31 files changed, 617 insertions, 351 deletions
diff --git a/src/lib/build-flags.ts b/src/lib/build-flags.ts
index 28b650b6f..faefdd6ab 100644
--- a/src/lib/build-flags.ts
+++ b/src/lib/build-flags.ts
@@ -1 +1,2 @@
 export const LOGIN_INCLUDE_DEV_SERVERS = true
+export const PWI_ENABLED = false
diff --git a/src/lib/moderation.ts b/src/lib/moderation.ts
index 6c08606ee..8ba99128b 100644
--- a/src/lib/moderation.ts
+++ b/src/lib/moderation.ts
@@ -1,4 +1,4 @@
-import {ModerationCause, ProfileModeration} from '@atproto/api'
+import {ModerationCause, ProfileModeration, PostModeration} from '@atproto/api'
 
 export interface ModerationCauseDescription {
   name: string
@@ -92,6 +92,25 @@ export function getProfileModerationCauses(
   }) as ModerationCause[]
 }
 
+export function isPostMediaBlurred(
+  decisions: PostModeration['decisions'],
+): boolean {
+  return decisions.post.blurMedia
+}
+
+export function isQuoteBlurred(
+  decisions: PostModeration['decisions'],
+): boolean {
+  return (
+    decisions.quote?.blur ||
+    decisions.quote?.blurMedia ||
+    decisions.quote?.filter ||
+    decisions.quotedAccount?.blur ||
+    decisions.quotedAccount?.filter ||
+    false
+  )
+}
+
 export function isCauseALabelOnUri(
   cause: ModerationCause | undefined,
   uri: string,
diff --git a/src/locale/locales/cs/messages.po b/src/locale/locales/cs/messages.po
index 6cd60a889..c84625c25 100644
--- a/src/locale/locales/cs/messages.po
+++ b/src/locale/locales/cs/messages.po
@@ -83,7 +83,7 @@ msgstr ""
 
 #: src/view/com/modals/ListAddRemoveUsers.tsx:264
 #: src/view/com/modals/UserAddRemoveLists.tsx:187
-#: src/view/screens/ProfileList.tsx:675
+#: src/view/screens/ProfileList.tsx:684
 msgid "Add"
 msgstr ""
 
@@ -91,7 +91,7 @@ msgstr ""
 msgid "Add a content warning"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:665
+#: src/view/screens/ProfileList.tsx:674
 msgid "Add a user to this list"
 msgstr ""
 
@@ -199,7 +199,7 @@ msgstr ""
 msgid "Are you sure you'd like to discard this draft?"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:345
+#: src/view/screens/ProfileList.tsx:352
 msgid "Are you sure?"
 msgstr ""
 
@@ -242,11 +242,11 @@ msgstr ""
 msgid "Block Account"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:446
+#: src/view/screens/ProfileList.tsx:453
 msgid "Block accounts"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:302
+#: src/view/screens/ProfileList.tsx:309
 msgid "Block these accounts?"
 msgstr ""
 
@@ -270,7 +270,7 @@ msgstr ""
 msgid "Blocked post."
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:304
+#: src/view/screens/ProfileList.tsx:311
 msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you."
 msgstr ""
 
@@ -531,7 +531,7 @@ msgstr ""
 msgid "Copy"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:375
+#: src/view/screens/ProfileList.tsx:382
 msgid "Copy link to list"
 msgstr ""
 
@@ -555,7 +555,7 @@ msgstr ""
 msgid "Could not load feed"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:752
+#: src/view/screens/ProfileList.tsx:761
 msgid "Could not load list"
 msgstr ""
 
@@ -601,8 +601,8 @@ msgstr ""
 msgid "Delete app password"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:344
-#: src/view/screens/ProfileList.tsx:402
+#: src/view/screens/ProfileList.tsx:351
+#: src/view/screens/ProfileList.tsx:409
 msgid "Delete List"
 msgstr ""
 
@@ -691,7 +691,7 @@ msgstr ""
 msgid "Edit image"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:390
+#: src/view/screens/ProfileList.tsx:397
 msgid "Edit list details"
 msgstr ""
 
@@ -739,6 +739,10 @@ msgstr ""
 msgid "Enable this setting to only see replies between people you follow."
 msgstr ""
 
+#: src/view/screens/Profile.tsx:454
+msgid "End of feed"
+msgstr ""
+
 #: src/view/com/auth/create/Step1.tsx:71
 msgid "Enter the address of your provider:"
 msgstr ""
@@ -888,8 +892,8 @@ msgstr ""
 
 #: src/view/screens/ProfileFeed.tsx:111
 #: src/view/screens/ProfileFeed.tsx:116
-#: src/view/screens/ProfileList.tsx:761
-#: src/view/screens/ProfileList.tsx:766
+#: src/view/screens/ProfileList.tsx:770
+#: src/view/screens/ProfileList.tsx:775
 msgid "Go Back"
 msgstr ""
 
@@ -920,23 +924,23 @@ msgstr ""
 msgid "Hide user list"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:101
+#: src/view/com/posts/FeedErrorMessage.tsx:102
 msgid "Hmm, some kind of issue occured when contacting the feed server. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:89
+#: src/view/com/posts/FeedErrorMessage.tsx:90
 msgid "Hmm, the feed server appears to be misconfigured. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:95
+#: src/view/com/posts/FeedErrorMessage.tsx:96
 msgid "Hmm, the feed server appears to be offline. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:92
+#: src/view/com/posts/FeedErrorMessage.tsx:93
 msgid "Hmm, the feed server gave a bad response. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:86
+#: src/view/com/posts/FeedErrorMessage.tsx:87
 msgid "Hmmm, we're having trouble finding this feed. It may have been deleted."
 msgstr ""
 
@@ -1074,7 +1078,7 @@ msgstr ""
 #~ msgid "Light"
 #~ msgstr ""
 
-#: src/view/screens/ProfileFeed.tsx:627
+#: src/view/screens/ProfileFeed.tsx:630
 msgid "Like this feed"
 msgstr ""
 
@@ -1122,7 +1126,7 @@ msgstr ""
 msgid "Login to account that is not listed"
 msgstr ""
 
-#: src/view/screens/ProfileFeed.tsx:479
+#: src/view/screens/ProfileFeed.tsx:480
 msgid "Looks like this feed is only available to users with a Bluesky account. Please sign up or sign in to view this feed!"
 msgstr ""
 
@@ -1152,7 +1156,7 @@ msgstr ""
 
 #: src/view/com/profile/ProfileHeader.tsx:520
 #: src/view/screens/ProfileFeed.tsx:369
-#: src/view/screens/ProfileList.tsx:506
+#: src/view/screens/ProfileList.tsx:513
 msgid "More options"
 msgstr ""
 
@@ -1164,11 +1168,11 @@ msgstr ""
 msgid "Mute Account"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:434
+#: src/view/screens/ProfileList.tsx:441
 msgid "Mute accounts"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:267
+#: src/view/screens/ProfileList.tsx:274
 msgid "Mute these accounts?"
 msgstr ""
 
@@ -1188,7 +1192,7 @@ msgstr ""
 msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private."
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:269
+#: src/view/screens/ProfileList.tsx:276
 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them."
 msgstr ""
 
@@ -1223,10 +1227,10 @@ msgstr ""
 
 #: src/view/com/feeds/FeedPage.tsx:188
 #: src/view/screens/Feeds.tsx:510
-#: src/view/screens/Profile.tsx:382
-#: src/view/screens/ProfileFeed.tsx:449
-#: src/view/screens/ProfileList.tsx:199
-#: src/view/screens/ProfileList.tsx:231
+#: src/view/screens/Profile.tsx:384
+#: src/view/screens/ProfileFeed.tsx:450
+#: src/view/screens/ProfileList.tsx:206
+#: src/view/screens/ProfileList.tsx:238
 #: src/view/shell/desktop/LeftNav.tsx:254
 msgid "New post"
 msgstr ""
@@ -1255,8 +1259,8 @@ msgstr ""
 msgid "No"
 msgstr ""
 
-#: src/view/screens/ProfileFeed.tsx:620
-#: src/view/screens/ProfileList.tsx:632
+#: src/view/screens/ProfileFeed.tsx:623
+#: src/view/screens/ProfileList.tsx:641
 msgid "No description"
 msgstr ""
 
@@ -1527,7 +1531,7 @@ msgstr ""
 msgid "Remove account"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:118
+#: src/view/com/posts/FeedErrorMessage.tsx:122
 msgid "Remove feed"
 msgstr ""
 
@@ -1544,7 +1548,7 @@ msgstr ""
 msgid "Remove image preview"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:119
+#: src/view/com/posts/FeedErrorMessage.tsx:123
 msgid "Remove this feed from your saved feeds?"
 msgstr ""
 
@@ -1569,7 +1573,7 @@ msgstr ""
 msgid "Report feed"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:416
+#: src/view/screens/ProfileList.tsx:423
 msgid "Report List"
 msgstr ""
 
@@ -1782,7 +1786,7 @@ msgstr ""
 
 #: src/view/com/profile/ProfileHeader.tsx:312
 #: src/view/com/util/forms/PostDropdownBtn.tsx:126
-#: src/view/screens/ProfileList.tsx:375
+#: src/view/screens/ProfileList.tsx:382
 msgid "Share"
 msgstr ""
 
@@ -1899,11 +1903,11 @@ msgstr ""
 msgid "Storybook"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:497
+#: src/view/screens/ProfileList.tsx:504
 msgid "Subscribe"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:493
+#: src/view/screens/ProfileList.tsx:500
 msgid "Subscribe to this list"
 msgstr ""
 
@@ -2108,7 +2112,7 @@ msgstr ""
 msgid "Username or email address"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:659
+#: src/view/screens/ProfileList.tsx:668
 msgid "Users"
 msgstr ""
 
@@ -2145,10 +2149,14 @@ msgstr ""
 msgid "We're so excited to have you join us!"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:98
+#: src/view/com/posts/FeedErrorMessage.tsx:99
 msgid "We're sorry, but this content is not viewable without a Bluesky account."
 msgstr ""
 
+#: src/view/com/posts/FeedErrorMessage.tsx:105
+msgid "We're sorry, but this feed is currently receiving high traffic and is temporarily unavailable. Please try again later."
+msgstr ""
+
 #: src/view/screens/Search/Search.tsx:236
 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes."
 msgstr ""
diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po
index 5e0aec468..330bec614 100644
--- a/src/locale/locales/en/messages.po
+++ b/src/locale/locales/en/messages.po
@@ -83,7 +83,7 @@ msgstr ""
 
 #: src/view/com/modals/ListAddRemoveUsers.tsx:264
 #: src/view/com/modals/UserAddRemoveLists.tsx:187
-#: src/view/screens/ProfileList.tsx:675
+#: src/view/screens/ProfileList.tsx:684
 msgid "Add"
 msgstr ""
 
@@ -91,7 +91,7 @@ msgstr ""
 msgid "Add a content warning"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:665
+#: src/view/screens/ProfileList.tsx:674
 msgid "Add a user to this list"
 msgstr ""
 
@@ -199,7 +199,7 @@ msgstr ""
 msgid "Are you sure you'd like to discard this draft?"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:345
+#: src/view/screens/ProfileList.tsx:352
 msgid "Are you sure?"
 msgstr ""
 
@@ -242,11 +242,11 @@ msgstr ""
 msgid "Block Account"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:446
+#: src/view/screens/ProfileList.tsx:453
 msgid "Block accounts"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:302
+#: src/view/screens/ProfileList.tsx:309
 msgid "Block these accounts?"
 msgstr ""
 
@@ -270,7 +270,7 @@ msgstr ""
 msgid "Blocked post."
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:304
+#: src/view/screens/ProfileList.tsx:311
 msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you."
 msgstr ""
 
@@ -531,7 +531,7 @@ msgstr ""
 msgid "Copy"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:375
+#: src/view/screens/ProfileList.tsx:382
 msgid "Copy link to list"
 msgstr ""
 
@@ -555,7 +555,7 @@ msgstr ""
 msgid "Could not load feed"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:752
+#: src/view/screens/ProfileList.tsx:761
 msgid "Could not load list"
 msgstr ""
 
@@ -601,8 +601,8 @@ msgstr ""
 msgid "Delete app password"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:344
-#: src/view/screens/ProfileList.tsx:402
+#: src/view/screens/ProfileList.tsx:351
+#: src/view/screens/ProfileList.tsx:409
 msgid "Delete List"
 msgstr ""
 
@@ -691,7 +691,7 @@ msgstr ""
 msgid "Edit image"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:390
+#: src/view/screens/ProfileList.tsx:397
 msgid "Edit list details"
 msgstr ""
 
@@ -739,6 +739,10 @@ msgstr ""
 msgid "Enable this setting to only see replies between people you follow."
 msgstr ""
 
+#: src/view/screens/Profile.tsx:454
+msgid "End of feed"
+msgstr ""
+
 #: src/view/com/auth/create/Step1.tsx:71
 msgid "Enter the address of your provider:"
 msgstr ""
@@ -888,8 +892,8 @@ msgstr ""
 
 #: src/view/screens/ProfileFeed.tsx:111
 #: src/view/screens/ProfileFeed.tsx:116
-#: src/view/screens/ProfileList.tsx:761
-#: src/view/screens/ProfileList.tsx:766
+#: src/view/screens/ProfileList.tsx:770
+#: src/view/screens/ProfileList.tsx:775
 msgid "Go Back"
 msgstr ""
 
@@ -920,23 +924,23 @@ msgstr ""
 msgid "Hide user list"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:101
+#: src/view/com/posts/FeedErrorMessage.tsx:102
 msgid "Hmm, some kind of issue occured when contacting the feed server. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:89
+#: src/view/com/posts/FeedErrorMessage.tsx:90
 msgid "Hmm, the feed server appears to be misconfigured. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:95
+#: src/view/com/posts/FeedErrorMessage.tsx:96
 msgid "Hmm, the feed server appears to be offline. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:92
+#: src/view/com/posts/FeedErrorMessage.tsx:93
 msgid "Hmm, the feed server gave a bad response. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:86
+#: src/view/com/posts/FeedErrorMessage.tsx:87
 msgid "Hmmm, we're having trouble finding this feed. It may have been deleted."
 msgstr ""
 
@@ -1074,7 +1078,7 @@ msgstr ""
 #~ msgid "Light"
 #~ msgstr ""
 
-#: src/view/screens/ProfileFeed.tsx:627
+#: src/view/screens/ProfileFeed.tsx:630
 msgid "Like this feed"
 msgstr ""
 
@@ -1122,7 +1126,7 @@ msgstr ""
 msgid "Login to account that is not listed"
 msgstr ""
 
-#: src/view/screens/ProfileFeed.tsx:479
+#: src/view/screens/ProfileFeed.tsx:480
 msgid "Looks like this feed is only available to users with a Bluesky account. Please sign up or sign in to view this feed!"
 msgstr ""
 
@@ -1152,7 +1156,7 @@ msgstr ""
 
 #: src/view/com/profile/ProfileHeader.tsx:520
 #: src/view/screens/ProfileFeed.tsx:369
-#: src/view/screens/ProfileList.tsx:506
+#: src/view/screens/ProfileList.tsx:513
 msgid "More options"
 msgstr ""
 
@@ -1164,11 +1168,11 @@ msgstr ""
 msgid "Mute Account"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:434
+#: src/view/screens/ProfileList.tsx:441
 msgid "Mute accounts"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:267
+#: src/view/screens/ProfileList.tsx:274
 msgid "Mute these accounts?"
 msgstr ""
 
@@ -1188,7 +1192,7 @@ msgstr ""
 msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private."
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:269
+#: src/view/screens/ProfileList.tsx:276
 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them."
 msgstr ""
 
@@ -1223,10 +1227,10 @@ msgstr ""
 
 #: src/view/com/feeds/FeedPage.tsx:188
 #: src/view/screens/Feeds.tsx:510
-#: src/view/screens/Profile.tsx:382
-#: src/view/screens/ProfileFeed.tsx:449
-#: src/view/screens/ProfileList.tsx:199
-#: src/view/screens/ProfileList.tsx:231
+#: src/view/screens/Profile.tsx:384
+#: src/view/screens/ProfileFeed.tsx:450
+#: src/view/screens/ProfileList.tsx:206
+#: src/view/screens/ProfileList.tsx:238
 #: src/view/shell/desktop/LeftNav.tsx:254
 msgid "New post"
 msgstr ""
@@ -1255,8 +1259,8 @@ msgstr ""
 msgid "No"
 msgstr ""
 
-#: src/view/screens/ProfileFeed.tsx:620
-#: src/view/screens/ProfileList.tsx:632
+#: src/view/screens/ProfileFeed.tsx:623
+#: src/view/screens/ProfileList.tsx:641
 msgid "No description"
 msgstr ""
 
@@ -1527,7 +1531,7 @@ msgstr ""
 msgid "Remove account"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:118
+#: src/view/com/posts/FeedErrorMessage.tsx:122
 msgid "Remove feed"
 msgstr ""
 
@@ -1544,7 +1548,7 @@ msgstr ""
 msgid "Remove image preview"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:119
+#: src/view/com/posts/FeedErrorMessage.tsx:123
 msgid "Remove this feed from your saved feeds?"
 msgstr ""
 
@@ -1569,7 +1573,7 @@ msgstr ""
 msgid "Report feed"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:416
+#: src/view/screens/ProfileList.tsx:423
 msgid "Report List"
 msgstr ""
 
@@ -1782,7 +1786,7 @@ msgstr ""
 
 #: src/view/com/profile/ProfileHeader.tsx:312
 #: src/view/com/util/forms/PostDropdownBtn.tsx:126
-#: src/view/screens/ProfileList.tsx:375
+#: src/view/screens/ProfileList.tsx:382
 msgid "Share"
 msgstr ""
 
@@ -1899,11 +1903,11 @@ msgstr ""
 msgid "Storybook"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:497
+#: src/view/screens/ProfileList.tsx:504
 msgid "Subscribe"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:493
+#: src/view/screens/ProfileList.tsx:500
 msgid "Subscribe to this list"
 msgstr ""
 
@@ -2108,7 +2112,7 @@ msgstr ""
 msgid "Username or email address"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:659
+#: src/view/screens/ProfileList.tsx:668
 msgid "Users"
 msgstr ""
 
@@ -2145,10 +2149,14 @@ msgstr ""
 msgid "We're so excited to have you join us!"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:98
+#: src/view/com/posts/FeedErrorMessage.tsx:99
 msgid "We're sorry, but this content is not viewable without a Bluesky account."
 msgstr ""
 
+#: src/view/com/posts/FeedErrorMessage.tsx:105
+msgid "We're sorry, but this feed is currently receiving high traffic and is temporarily unavailable. Please try again later."
+msgstr ""
+
 #: src/view/screens/Search/Search.tsx:236
 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes."
 msgstr ""
diff --git a/src/locale/locales/es/messages.po b/src/locale/locales/es/messages.po
index baab22c72..ae43a7323 100644
--- a/src/locale/locales/es/messages.po
+++ b/src/locale/locales/es/messages.po
@@ -83,7 +83,7 @@ msgstr ""
 
 #: src/view/com/modals/ListAddRemoveUsers.tsx:264
 #: src/view/com/modals/UserAddRemoveLists.tsx:187
-#: src/view/screens/ProfileList.tsx:675
+#: src/view/screens/ProfileList.tsx:684
 msgid "Add"
 msgstr ""
 
@@ -91,7 +91,7 @@ msgstr ""
 msgid "Add a content warning"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:665
+#: src/view/screens/ProfileList.tsx:674
 msgid "Add a user to this list"
 msgstr ""
 
@@ -199,7 +199,7 @@ msgstr ""
 msgid "Are you sure you'd like to discard this draft?"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:345
+#: src/view/screens/ProfileList.tsx:352
 msgid "Are you sure?"
 msgstr ""
 
@@ -242,11 +242,11 @@ msgstr ""
 msgid "Block Account"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:446
+#: src/view/screens/ProfileList.tsx:453
 msgid "Block accounts"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:302
+#: src/view/screens/ProfileList.tsx:309
 msgid "Block these accounts?"
 msgstr ""
 
@@ -270,7 +270,7 @@ msgstr ""
 msgid "Blocked post."
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:304
+#: src/view/screens/ProfileList.tsx:311
 msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you."
 msgstr ""
 
@@ -531,7 +531,7 @@ msgstr ""
 msgid "Copy"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:375
+#: src/view/screens/ProfileList.tsx:382
 msgid "Copy link to list"
 msgstr ""
 
@@ -555,7 +555,7 @@ msgstr ""
 msgid "Could not load feed"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:752
+#: src/view/screens/ProfileList.tsx:761
 msgid "Could not load list"
 msgstr ""
 
@@ -601,8 +601,8 @@ msgstr ""
 msgid "Delete app password"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:344
-#: src/view/screens/ProfileList.tsx:402
+#: src/view/screens/ProfileList.tsx:351
+#: src/view/screens/ProfileList.tsx:409
 msgid "Delete List"
 msgstr ""
 
@@ -691,7 +691,7 @@ msgstr ""
 msgid "Edit image"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:390
+#: src/view/screens/ProfileList.tsx:397
 msgid "Edit list details"
 msgstr ""
 
@@ -739,6 +739,10 @@ msgstr ""
 msgid "Enable this setting to only see replies between people you follow."
 msgstr ""
 
+#: src/view/screens/Profile.tsx:454
+msgid "End of feed"
+msgstr ""
+
 #: src/view/com/auth/create/Step1.tsx:71
 msgid "Enter the address of your provider:"
 msgstr ""
@@ -888,8 +892,8 @@ msgstr ""
 
 #: src/view/screens/ProfileFeed.tsx:111
 #: src/view/screens/ProfileFeed.tsx:116
-#: src/view/screens/ProfileList.tsx:761
-#: src/view/screens/ProfileList.tsx:766
+#: src/view/screens/ProfileList.tsx:770
+#: src/view/screens/ProfileList.tsx:775
 msgid "Go Back"
 msgstr ""
 
@@ -920,23 +924,23 @@ msgstr ""
 msgid "Hide user list"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:101
+#: src/view/com/posts/FeedErrorMessage.tsx:102
 msgid "Hmm, some kind of issue occured when contacting the feed server. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:89
+#: src/view/com/posts/FeedErrorMessage.tsx:90
 msgid "Hmm, the feed server appears to be misconfigured. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:95
+#: src/view/com/posts/FeedErrorMessage.tsx:96
 msgid "Hmm, the feed server appears to be offline. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:92
+#: src/view/com/posts/FeedErrorMessage.tsx:93
 msgid "Hmm, the feed server gave a bad response. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:86
+#: src/view/com/posts/FeedErrorMessage.tsx:87
 msgid "Hmmm, we're having trouble finding this feed. It may have been deleted."
 msgstr ""
 
@@ -1074,7 +1078,7 @@ msgstr ""
 #~ msgid "Light"
 #~ msgstr ""
 
-#: src/view/screens/ProfileFeed.tsx:627
+#: src/view/screens/ProfileFeed.tsx:630
 msgid "Like this feed"
 msgstr ""
 
@@ -1122,7 +1126,7 @@ msgstr ""
 msgid "Login to account that is not listed"
 msgstr ""
 
-#: src/view/screens/ProfileFeed.tsx:479
+#: src/view/screens/ProfileFeed.tsx:480
 msgid "Looks like this feed is only available to users with a Bluesky account. Please sign up or sign in to view this feed!"
 msgstr ""
 
@@ -1152,7 +1156,7 @@ msgstr ""
 
 #: src/view/com/profile/ProfileHeader.tsx:520
 #: src/view/screens/ProfileFeed.tsx:369
-#: src/view/screens/ProfileList.tsx:506
+#: src/view/screens/ProfileList.tsx:513
 msgid "More options"
 msgstr ""
 
@@ -1164,11 +1168,11 @@ msgstr ""
 msgid "Mute Account"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:434
+#: src/view/screens/ProfileList.tsx:441
 msgid "Mute accounts"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:267
+#: src/view/screens/ProfileList.tsx:274
 msgid "Mute these accounts?"
 msgstr ""
 
@@ -1188,7 +1192,7 @@ msgstr ""
 msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private."
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:269
+#: src/view/screens/ProfileList.tsx:276
 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them."
 msgstr ""
 
@@ -1223,10 +1227,10 @@ msgstr ""
 
 #: src/view/com/feeds/FeedPage.tsx:188
 #: src/view/screens/Feeds.tsx:510
-#: src/view/screens/Profile.tsx:382
-#: src/view/screens/ProfileFeed.tsx:449
-#: src/view/screens/ProfileList.tsx:199
-#: src/view/screens/ProfileList.tsx:231
+#: src/view/screens/Profile.tsx:384
+#: src/view/screens/ProfileFeed.tsx:450
+#: src/view/screens/ProfileList.tsx:206
+#: src/view/screens/ProfileList.tsx:238
 #: src/view/shell/desktop/LeftNav.tsx:254
 msgid "New post"
 msgstr ""
@@ -1255,8 +1259,8 @@ msgstr ""
 msgid "No"
 msgstr ""
 
-#: src/view/screens/ProfileFeed.tsx:620
-#: src/view/screens/ProfileList.tsx:632
+#: src/view/screens/ProfileFeed.tsx:623
+#: src/view/screens/ProfileList.tsx:641
 msgid "No description"
 msgstr ""
 
@@ -1527,7 +1531,7 @@ msgstr ""
 msgid "Remove account"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:118
+#: src/view/com/posts/FeedErrorMessage.tsx:122
 msgid "Remove feed"
 msgstr ""
 
@@ -1544,7 +1548,7 @@ msgstr ""
 msgid "Remove image preview"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:119
+#: src/view/com/posts/FeedErrorMessage.tsx:123
 msgid "Remove this feed from your saved feeds?"
 msgstr ""
 
@@ -1569,7 +1573,7 @@ msgstr ""
 msgid "Report feed"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:416
+#: src/view/screens/ProfileList.tsx:423
 msgid "Report List"
 msgstr ""
 
@@ -1782,7 +1786,7 @@ msgstr ""
 
 #: src/view/com/profile/ProfileHeader.tsx:312
 #: src/view/com/util/forms/PostDropdownBtn.tsx:126
-#: src/view/screens/ProfileList.tsx:375
+#: src/view/screens/ProfileList.tsx:382
 msgid "Share"
 msgstr ""
 
@@ -1899,11 +1903,11 @@ msgstr ""
 msgid "Storybook"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:497
+#: src/view/screens/ProfileList.tsx:504
 msgid "Subscribe"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:493
+#: src/view/screens/ProfileList.tsx:500
 msgid "Subscribe to this list"
 msgstr ""
 
@@ -2108,7 +2112,7 @@ msgstr ""
 msgid "Username or email address"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:659
+#: src/view/screens/ProfileList.tsx:668
 msgid "Users"
 msgstr ""
 
@@ -2145,10 +2149,14 @@ msgstr ""
 msgid "We're so excited to have you join us!"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:98
+#: src/view/com/posts/FeedErrorMessage.tsx:99
 msgid "We're sorry, but this content is not viewable without a Bluesky account."
 msgstr ""
 
+#: src/view/com/posts/FeedErrorMessage.tsx:105
+msgid "We're sorry, but this feed is currently receiving high traffic and is temporarily unavailable. Please try again later."
+msgstr ""
+
 #: src/view/screens/Search/Search.tsx:236
 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes."
 msgstr ""
diff --git a/src/locale/locales/fr/messages.po b/src/locale/locales/fr/messages.po
index 95b10a094..4c5351c89 100644
--- a/src/locale/locales/fr/messages.po
+++ b/src/locale/locales/fr/messages.po
@@ -83,7 +83,7 @@ msgstr ""
 
 #: src/view/com/modals/ListAddRemoveUsers.tsx:264
 #: src/view/com/modals/UserAddRemoveLists.tsx:187
-#: src/view/screens/ProfileList.tsx:675
+#: src/view/screens/ProfileList.tsx:684
 msgid "Add"
 msgstr ""
 
@@ -91,7 +91,7 @@ msgstr ""
 msgid "Add a content warning"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:665
+#: src/view/screens/ProfileList.tsx:674
 msgid "Add a user to this list"
 msgstr ""
 
@@ -199,7 +199,7 @@ msgstr ""
 msgid "Are you sure you'd like to discard this draft?"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:345
+#: src/view/screens/ProfileList.tsx:352
 msgid "Are you sure?"
 msgstr ""
 
@@ -242,11 +242,11 @@ msgstr ""
 msgid "Block Account"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:446
+#: src/view/screens/ProfileList.tsx:453
 msgid "Block accounts"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:302
+#: src/view/screens/ProfileList.tsx:309
 msgid "Block these accounts?"
 msgstr ""
 
@@ -270,7 +270,7 @@ msgstr ""
 msgid "Blocked post."
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:304
+#: src/view/screens/ProfileList.tsx:311
 msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you."
 msgstr ""
 
@@ -531,7 +531,7 @@ msgstr ""
 msgid "Copy"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:375
+#: src/view/screens/ProfileList.tsx:382
 msgid "Copy link to list"
 msgstr ""
 
@@ -555,7 +555,7 @@ msgstr ""
 msgid "Could not load feed"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:752
+#: src/view/screens/ProfileList.tsx:761
 msgid "Could not load list"
 msgstr ""
 
@@ -601,8 +601,8 @@ msgstr ""
 msgid "Delete app password"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:344
-#: src/view/screens/ProfileList.tsx:402
+#: src/view/screens/ProfileList.tsx:351
+#: src/view/screens/ProfileList.tsx:409
 msgid "Delete List"
 msgstr ""
 
@@ -691,7 +691,7 @@ msgstr ""
 msgid "Edit image"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:390
+#: src/view/screens/ProfileList.tsx:397
 msgid "Edit list details"
 msgstr ""
 
@@ -739,6 +739,10 @@ msgstr ""
 msgid "Enable this setting to only see replies between people you follow."
 msgstr ""
 
+#: src/view/screens/Profile.tsx:454
+msgid "End of feed"
+msgstr ""
+
 #: src/view/com/auth/create/Step1.tsx:71
 msgid "Enter the address of your provider:"
 msgstr ""
@@ -888,8 +892,8 @@ msgstr ""
 
 #: src/view/screens/ProfileFeed.tsx:111
 #: src/view/screens/ProfileFeed.tsx:116
-#: src/view/screens/ProfileList.tsx:761
-#: src/view/screens/ProfileList.tsx:766
+#: src/view/screens/ProfileList.tsx:770
+#: src/view/screens/ProfileList.tsx:775
 msgid "Go Back"
 msgstr ""
 
@@ -920,23 +924,23 @@ msgstr ""
 msgid "Hide user list"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:101
+#: src/view/com/posts/FeedErrorMessage.tsx:102
 msgid "Hmm, some kind of issue occured when contacting the feed server. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:89
+#: src/view/com/posts/FeedErrorMessage.tsx:90
 msgid "Hmm, the feed server appears to be misconfigured. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:95
+#: src/view/com/posts/FeedErrorMessage.tsx:96
 msgid "Hmm, the feed server appears to be offline. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:92
+#: src/view/com/posts/FeedErrorMessage.tsx:93
 msgid "Hmm, the feed server gave a bad response. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:86
+#: src/view/com/posts/FeedErrorMessage.tsx:87
 msgid "Hmmm, we're having trouble finding this feed. It may have been deleted."
 msgstr ""
 
@@ -1074,7 +1078,7 @@ msgstr ""
 #~ msgid "Light"
 #~ msgstr ""
 
-#: src/view/screens/ProfileFeed.tsx:627
+#: src/view/screens/ProfileFeed.tsx:630
 msgid "Like this feed"
 msgstr ""
 
@@ -1122,7 +1126,7 @@ msgstr ""
 msgid "Login to account that is not listed"
 msgstr ""
 
-#: src/view/screens/ProfileFeed.tsx:479
+#: src/view/screens/ProfileFeed.tsx:480
 msgid "Looks like this feed is only available to users with a Bluesky account. Please sign up or sign in to view this feed!"
 msgstr ""
 
@@ -1152,7 +1156,7 @@ msgstr ""
 
 #: src/view/com/profile/ProfileHeader.tsx:520
 #: src/view/screens/ProfileFeed.tsx:369
-#: src/view/screens/ProfileList.tsx:506
+#: src/view/screens/ProfileList.tsx:513
 msgid "More options"
 msgstr ""
 
@@ -1164,11 +1168,11 @@ msgstr ""
 msgid "Mute Account"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:434
+#: src/view/screens/ProfileList.tsx:441
 msgid "Mute accounts"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:267
+#: src/view/screens/ProfileList.tsx:274
 msgid "Mute these accounts?"
 msgstr ""
 
@@ -1188,7 +1192,7 @@ msgstr ""
 msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private."
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:269
+#: src/view/screens/ProfileList.tsx:276
 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them."
 msgstr ""
 
@@ -1223,10 +1227,10 @@ msgstr ""
 
 #: src/view/com/feeds/FeedPage.tsx:188
 #: src/view/screens/Feeds.tsx:510
-#: src/view/screens/Profile.tsx:382
-#: src/view/screens/ProfileFeed.tsx:449
-#: src/view/screens/ProfileList.tsx:199
-#: src/view/screens/ProfileList.tsx:231
+#: src/view/screens/Profile.tsx:384
+#: src/view/screens/ProfileFeed.tsx:450
+#: src/view/screens/ProfileList.tsx:206
+#: src/view/screens/ProfileList.tsx:238
 #: src/view/shell/desktop/LeftNav.tsx:254
 msgid "New post"
 msgstr ""
@@ -1255,8 +1259,8 @@ msgstr ""
 msgid "No"
 msgstr ""
 
-#: src/view/screens/ProfileFeed.tsx:620
-#: src/view/screens/ProfileList.tsx:632
+#: src/view/screens/ProfileFeed.tsx:623
+#: src/view/screens/ProfileList.tsx:641
 msgid "No description"
 msgstr ""
 
@@ -1527,7 +1531,7 @@ msgstr ""
 msgid "Remove account"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:118
+#: src/view/com/posts/FeedErrorMessage.tsx:122
 msgid "Remove feed"
 msgstr ""
 
@@ -1544,7 +1548,7 @@ msgstr ""
 msgid "Remove image preview"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:119
+#: src/view/com/posts/FeedErrorMessage.tsx:123
 msgid "Remove this feed from your saved feeds?"
 msgstr ""
 
@@ -1569,7 +1573,7 @@ msgstr ""
 msgid "Report feed"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:416
+#: src/view/screens/ProfileList.tsx:423
 msgid "Report List"
 msgstr ""
 
@@ -1782,7 +1786,7 @@ msgstr ""
 
 #: src/view/com/profile/ProfileHeader.tsx:312
 #: src/view/com/util/forms/PostDropdownBtn.tsx:126
-#: src/view/screens/ProfileList.tsx:375
+#: src/view/screens/ProfileList.tsx:382
 msgid "Share"
 msgstr ""
 
@@ -1899,11 +1903,11 @@ msgstr ""
 msgid "Storybook"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:497
+#: src/view/screens/ProfileList.tsx:504
 msgid "Subscribe"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:493
+#: src/view/screens/ProfileList.tsx:500
 msgid "Subscribe to this list"
 msgstr ""
 
@@ -2108,7 +2112,7 @@ msgstr ""
 msgid "Username or email address"
 msgstr ""
 
-#: src/view/screens/ProfileList.tsx:659
+#: src/view/screens/ProfileList.tsx:668
 msgid "Users"
 msgstr ""
 
@@ -2145,10 +2149,14 @@ msgstr ""
 msgid "We're so excited to have you join us!"
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:98
+#: src/view/com/posts/FeedErrorMessage.tsx:99
 msgid "We're sorry, but this content is not viewable without a Bluesky account."
 msgstr ""
 
+#: src/view/com/posts/FeedErrorMessage.tsx:105
+msgid "We're sorry, but this feed is currently receiving high traffic and is temporarily unavailable. Please try again later."
+msgstr ""
+
 #: src/view/screens/Search/Search.tsx:236
 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes."
 msgstr ""
diff --git a/src/locale/locales/hi/messages.po b/src/locale/locales/hi/messages.po
index e442483db..9e85e0a5c 100644
--- a/src/locale/locales/hi/messages.po
+++ b/src/locale/locales/hi/messages.po
@@ -83,7 +83,7 @@ msgstr "अकाउंट के विकलà¥à¤ª"
 
 #: src/view/com/modals/ListAddRemoveUsers.tsx:264
 #: src/view/com/modals/UserAddRemoveLists.tsx:187
-#: src/view/screens/ProfileList.tsx:675
+#: src/view/screens/ProfileList.tsx:684
 msgid "Add"
 msgstr "à¤à¤¡ करो"
 
@@ -91,7 +91,7 @@ msgstr "à¤à¤¡ करो"
 msgid "Add a content warning"
 msgstr "सामगà¥à¤°à¥€ चेतावनी जोड़ें"
 
-#: src/view/screens/ProfileList.tsx:665
+#: src/view/screens/ProfileList.tsx:674
 msgid "Add a user to this list"
 msgstr "इस सूची में किसी को जोड़ें"
 
@@ -199,7 +199,7 @@ msgstr "कà¥à¤¯à¤¾ आप वाकई à¤à¤ª पासवरà¥à¤¡ \"{name}\"
 msgid "Are you sure you'd like to discard this draft?"
 msgstr "कà¥à¤¯à¤¾ आप वाकई इस डà¥à¤°à¤¾à¤«à¥à¤Ÿ को हटाना करना चाहेंगे?"
 
-#: src/view/screens/ProfileList.tsx:345
+#: src/view/screens/ProfileList.tsx:352
 msgid "Are you sure?"
 msgstr "कà¥à¤¯à¤¾ आप वासà¥à¤¤à¤µ में इसे करना चाहते हैं?"
 
@@ -242,11 +242,11 @@ msgstr "जनà¥à¤®à¤¦à¤¿à¤¨:"
 msgid "Block Account"
 msgstr "खाता बà¥à¤²à¥‰à¤• करें"
 
-#: src/view/screens/ProfileList.tsx:446
+#: src/view/screens/ProfileList.tsx:453
 msgid "Block accounts"
 msgstr "खाता बà¥à¤²à¥‰à¤• करें"
 
-#: src/view/screens/ProfileList.tsx:302
+#: src/view/screens/ProfileList.tsx:309
 msgid "Block these accounts?"
 msgstr "खाता बà¥à¤²à¥‰à¤• करें?"
 
@@ -270,7 +270,7 @@ msgstr "अवरà¥à¤¦à¥à¤§ खाते आपके थà¥à¤°à¥‡à¤¡à¥à¤¸ à¤
 msgid "Blocked post."
 msgstr "बà¥à¤²à¥‰à¤• पोसà¥à¤Ÿà¥¤"
 
-#: src/view/screens/ProfileList.tsx:304
+#: src/view/screens/ProfileList.tsx:311
 msgid "Blocking is public. Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you."
 msgstr "अवरोधन सारà¥à¤µà¤œà¤¨à¤¿à¤• है. अवरà¥à¤¦à¥à¤§ खाते आपके थà¥à¤°à¥‡à¤¡à¥à¤¸ में उतà¥à¤¤à¤° नहीं दे सकते, आपका उलà¥à¤²à¥‡à¤– नहीं कर सकते, या अनà¥à¤¯à¤¥à¤¾ आपके साथ बातचीत नहीं कर सकते।"
 
@@ -527,7 +527,7 @@ msgstr "कॉपी कर ली"
 msgid "Copy"
 msgstr "कॉपी"
 
-#: src/view/screens/ProfileList.tsx:375
+#: src/view/screens/ProfileList.tsx:382
 msgid "Copy link to list"
 msgstr ""
 
@@ -551,7 +551,7 @@ msgstr "कॉपीराइट नीति"
 msgid "Could not load feed"
 msgstr "फ़ीड लोड नहीं कर सकता"
 
-#: src/view/screens/ProfileList.tsx:752
+#: src/view/screens/ProfileList.tsx:761
 msgid "Could not load list"
 msgstr "सूची लोड नहीं कर सकता"
 
@@ -597,8 +597,8 @@ msgstr "खाता हटाà¤à¤‚"
 msgid "Delete app password"
 msgstr "अपà¥à¤ª पासवरà¥à¤¡ हटाà¤à¤‚"
 
-#: src/view/screens/ProfileList.tsx:344
-#: src/view/screens/ProfileList.tsx:402
+#: src/view/screens/ProfileList.tsx:351
+#: src/view/screens/ProfileList.tsx:409
 msgid "Delete List"
 msgstr "सूची हटाà¤à¤"
 
@@ -687,7 +687,7 @@ msgstr "पà¥à¤°à¤¤à¥à¤¯à¥‡à¤• कोड à¤à¤• बार काम करतà
 msgid "Edit image"
 msgstr "छवि संपादित करें"
 
-#: src/view/screens/ProfileList.tsx:390
+#: src/view/screens/ProfileList.tsx:397
 msgid "Edit list details"
 msgstr "सूची विवरण संपादित करें"
 
@@ -735,6 +735,10 @@ msgstr "ईमेल:"
 msgid "Enable this setting to only see replies between people you follow."
 msgstr "इस सेटिंग को केवल उन लोगों के बीच जवाब देखने में सकà¥à¤·à¤® करें जिनà¥à¤¹à¥‡à¤‚ आप फॉलो करते हैं।।"
 
+#: src/view/screens/Profile.tsx:454
+msgid "End of feed"
+msgstr ""
+
 #: src/view/com/auth/create/Step1.tsx:71
 msgid "Enter the address of your provider:"
 msgstr "अपने पà¥à¤°à¤¦à¤¾à¤¤à¤¾ का पता दरà¥à¤œ करें:"
@@ -880,8 +884,8 @@ msgstr "वापस जाओ"
 
 #: src/view/screens/ProfileFeed.tsx:111
 #: src/view/screens/ProfileFeed.tsx:116
-#: src/view/screens/ProfileList.tsx:761
-#: src/view/screens/ProfileList.tsx:766
+#: src/view/screens/ProfileList.tsx:770
+#: src/view/screens/ProfileList.tsx:775
 msgid "Go Back"
 msgstr "वापस जाओ"
 
@@ -912,23 +916,23 @@ msgstr "इसे छिपाà¤à¤‚"
 msgid "Hide user list"
 msgstr "उपयोगकरà¥à¤¤à¤¾ सूची छà¥à¤ªà¤¾à¤à¤"
 
-#: src/view/com/posts/FeedErrorMessage.tsx:101
+#: src/view/com/posts/FeedErrorMessage.tsx:102
 msgid "Hmm, some kind of issue occured when contacting the feed server. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:89
+#: src/view/com/posts/FeedErrorMessage.tsx:90
 msgid "Hmm, the feed server appears to be misconfigured. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:95
+#: src/view/com/posts/FeedErrorMessage.tsx:96
 msgid "Hmm, the feed server appears to be offline. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:92
+#: src/view/com/posts/FeedErrorMessage.tsx:93
 msgid "Hmm, the feed server gave a bad response. Please let the feed owner know about this issue."
 msgstr ""
 
-#: src/view/com/posts/FeedErrorMessage.tsx:86
+#: src/view/com/posts/FeedErrorMessage.tsx:87
 msgid "Hmmm, we're having trouble finding this feed. It may have been deleted."
 msgstr ""
 
@@ -1066,7 +1070,7 @@ msgstr "चितà¥à¤° पà¥à¤¸à¥à¤¤à¤•ालय"
 #~ msgid "Light"
 #~ msgstr "लाइट मोड"
 
-#: src/view/screens/ProfileFeed.tsx:627
+#: src/view/screens/ProfileFeed.tsx:630
 msgid "Like this feed"
 msgstr "इस फ़ीड को लाइक करो"
 
@@ -1114,7 +1118,7 @@ msgstr "सà¥à¤¥à¤¾à¤¨à¥€à¤¯ देव सरà¥à¤µà¤°"
 msgid "Login to account that is not listed"
 msgstr "उस खाते में लॉग इन करें जो सूचीबदà¥à¤§ नहीं है"
 
-#: src/view/screens/ProfileFeed.tsx:479
+#: src/view/screens/ProfileFeed.tsx:480
 msgid "Looks like this feed is only available to users with a Bluesky account. Please sign up or sign in to view this feed!"
 msgstr ""
 
@@ -1144,7 +1148,7 @@ msgstr "अधिक फ़ीड"
 
 #: src/view/com/profile/ProfileHeader.tsx:520
 #: src/view/screens/ProfileFeed.tsx:369
-#: src/view/screens/ProfileList.tsx:506
+#: src/view/screens/ProfileList.tsx:513
 msgid "More options"
 msgstr "अधिक विकलà¥à¤ª"
 
@@ -1156,11 +1160,11 @@ msgstr "अधिक विकलà¥à¤ª"
 msgid "Mute Account"
 msgstr "खाता मà¥à¤¯à¥‚ट करें"
 
-#: src/view/screens/ProfileList.tsx:434
+#: src/view/screens/ProfileList.tsx:441
 msgid "Mute accounts"
 msgstr "खातों को मà¥à¤¯à¥‚ट करें"
 
-#: src/view/screens/ProfileList.tsx:267
+#: src/view/screens/ProfileList.tsx:274
 msgid "Mute these accounts?"
 msgstr "इन खातों को मà¥à¤¯à¥‚ट करें?"
 
@@ -1180,7 +1184,7 @@ msgstr "मà¥à¤¯à¥‚ट किठगठखाते"
 msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private."
 msgstr "मà¥à¤¯à¥‚ट किठगठखातों की पोसà¥à¤Ÿ आपके फ़ीड और आपकी सूचनाओं से हटा दी जाती हैं। मà¥à¤¯à¥‚ट पूरी तरह से निजी हैं."
 
-#: src/view/screens/ProfileList.tsx:269
+#: src/view/screens/ProfileList.tsx:276
 msgid "Muting is private. Muted accounts can interact with you, but you will not see their posts or receive notifications from them."
 msgstr "मà¥à¤¯à¥‚ट करना निजी है. मà¥à¤¯à¥‚ट किठगठखाते आपके साथ इंटरैकà¥à¤Ÿ कर सकते हैं, लेकिन आप उनकी पोसà¥à¤Ÿ नहीं देखेंगे या उनसे सूचनाà¤à¤‚ पà¥à¤°à¤¾à¤ªà¥à¤¤ नहीं करेंगे।"
 
@@ -1215,10 +1219,10 @@ msgstr "नया"
 
 #: src/view/com/feeds/FeedPage.tsx:188
 #: src/view/screens/Feeds.tsx:510
-#: src/view/screens/Profile.tsx:382
-#: src/view/screens/ProfileFeed.tsx:449
-#: src/view/screens/ProfileList.tsx:199
-#: src/view/screens/ProfileList.tsx:231
+#: src/view/screens/Profile.tsx:384
+#: src/view/screens/ProfileFeed.tsx:450
+#: src/view/screens/ProfileList.tsx:206
+#: src/view/screens/ProfileList.tsx:238
 #: src/view/shell/desktop/LeftNav.tsx:254
 msgid "New post"
 msgstr "नई पोसà¥à¤Ÿ"
@@ -1247,8 +1251,8 @@ msgstr "अगली फोटो"
 msgid "No"
 msgstr "नहीं"
 
-#: src/view/screens/ProfileFeed.tsx:620
-#: src/view/screens/ProfileList.tsx:632
+#: src/view/screens/ProfileFeed.tsx:623
+#: src/view/screens/ProfileList.tsx:641
 msgid "No description"
 msgstr "कोई विवरण नहीं"
 
@@ -1519,7 +1523,7 @@ msgstr "मेरे फ़ीड से {0} हटाà¤à¤‚?"
 msgid "Remove account"
 msgstr "खाता हटाà¤à¤‚"
 
-#: src/view/com/posts/FeedErrorMessage.tsx:118
+#: src/view/com/posts/FeedErrorMessage.tsx:122
 msgid "Remove feed"
 msgstr "फ़ीड हटाà¤à¤"
 
@@ -1536,7 +1540,7 @@ msgstr "छवि निकालें"
 msgid "Remove image preview"
 msgstr "छवि पूरà¥à¤µà¤¾à¤µà¤²à¥‹à¤•न निकालें"
 
-#: src/view/com/posts/FeedErrorMessage.tsx:119
+#: src/view/com/posts/FeedErrorMessage.tsx:123
 msgid "Remove this feed from your saved feeds?"
 msgstr "इस फ़ीड को सहेजे गठफ़ीड से हटा दें?"
 
@@ -1561,7 +1565,7 @@ msgstr "रिपोरà¥à¤Ÿ"
 msgid "Report feed"
 msgstr "रिपोरà¥à¤Ÿ फ़ीड"
 
-#: src/view/screens/ProfileList.tsx:416
+#: src/view/screens/ProfileList.tsx:423
 msgid "Report List"
 msgstr "रिपोरà¥à¤Ÿ सूची"
 
@@ -1774,7 +1778,7 @@ msgstr "यौन गतिविधि या कामà¥à¤• नगà¥à¤¨à¤¤à¤
 
 #: src/view/com/profile/ProfileHeader.tsx:312
 #: src/view/com/util/forms/PostDropdownBtn.tsx:126
-#: src/view/screens/ProfileList.tsx:375
+#: src/view/screens/ProfileList.tsx:382
 msgid "Share"
 msgstr "शेयर"
 
@@ -1891,11 +1895,11 @@ msgstr "सà¥à¤¥à¤¿à¤¤à¤¿ पृषà¥à¤ "
 msgid "Storybook"
 msgstr "Storybook"
 
-#: src/view/screens/ProfileList.tsx:497
+#: src/view/screens/ProfileList.tsx:504
 msgid "Subscribe"
 msgstr "सबà¥à¤¸à¤•à¥à¤°à¤¾à¤‡à¤¬"
 
-#: src/view/screens/ProfileList.tsx:493
+#: src/view/screens/ProfileList.tsx:500
 msgid "Subscribe to this list"
 msgstr "इस सूची को सबà¥à¤¸à¤•à¥à¤°à¤¾à¤‡à¤¬ करें"
 
@@ -2100,7 +2104,7 @@ msgstr "लोग सूचियाà¤"
 msgid "Username or email address"
 msgstr "यूजर नाम या ईमेल पता"
 
-#: src/view/screens/ProfileList.tsx:659
+#: src/view/screens/ProfileList.tsx:668
 msgid "Users"
 msgstr "यूजर लोग"
 
@@ -2137,10 +2141,14 @@ msgstr "साइट पर जाà¤à¤‚"
 msgid "We're so excited to have you join us!"
 msgstr "हम आपके हमारी सेवा में शामिल होने को लेकर बहà¥à¤¤ उतà¥à¤¸à¤¾à¤¹à¤¿à¤¤ हैं!"
 
-#: src/view/com/posts/FeedErrorMessage.tsx:98
+#: src/view/com/posts/FeedErrorMessage.tsx:99
 msgid "We're sorry, but this content is not viewable without a Bluesky account."
 msgstr ""
 
+#: src/view/com/posts/FeedErrorMessage.tsx:105
+msgid "We're sorry, but this feed is currently receiving high traffic and is temporarily unavailable. Please try again later."
+msgstr ""
+
 #: src/view/screens/Search/Search.tsx:236
 msgid "We're sorry, but your search could not be completed. Please try again in a few minutes."
 msgstr ""
diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx
index 6f058d39e..7336f3b95 100644
--- a/src/view/com/composer/Composer.tsx
+++ b/src/view/com/composer/Composer.tsx
@@ -201,7 +201,7 @@ export const ComposePost = observer(function ComposePost({
 
     setError('')
 
-    if (richtext.text.trim().length === 0 && gallery.isEmpty) {
+    if (richtext.text.trim().length === 0 && gallery.isEmpty && !extLink) {
       setError('Did you want to say anything?')
       return
     }
diff --git a/src/view/com/composer/text-input/TextInput.web.tsx b/src/view/com/composer/text-input/TextInput.web.tsx
index 4c31da338..206a3205b 100644
--- a/src/view/com/composer/text-input/TextInput.web.tsx
+++ b/src/view/com/composer/text-input/TextInput.web.tsx
@@ -116,6 +116,16 @@ export const TextInput = React.forwardRef(function TextInputImpl(
       autofocus: 'end',
       editable: true,
       injectCSS: true,
+      onCreate({editor: editorProp}) {
+        // HACK
+        // the 'enter' animation sometimes causes autofocus to fail
+        // (see Composer.web.tsx in shell)
+        // so we wait 200ms (the anim is 150ms) and then focus manually
+        // -prf
+        setTimeout(() => {
+          editorProp.chain().focus('end').run()
+        }, 200)
+      },
       onUpdate({editor: editorProp}) {
         const json = editorProp.getJSON()
 
diff --git a/src/view/com/feeds/FeedPage.tsx b/src/view/com/feeds/FeedPage.tsx
index f06716fb0..f3f07a8bd 100644
--- a/src/view/com/feeds/FeedPage.tsx
+++ b/src/view/com/feeds/FeedPage.tsx
@@ -158,9 +158,9 @@ export function FeedPage({
     <View testID={testID} style={s.h100pct}>
       <Feed
         testID={testID ? `${testID}-feed` : undefined}
+        enabled={isPageFocused}
         feed={feed}
         feedParams={feedParams}
-        enabled={isPageFocused}
         pollInterval={POLL_FREQ}
         scrollElRef={scrollElRef}
         onScroll={onMainScroll}
diff --git a/src/view/com/pager/Pager.tsx b/src/view/com/pager/Pager.tsx
index d70087504..61c3609f2 100644
--- a/src/view/com/pager/Pager.tsx
+++ b/src/view/com/pager/Pager.tsx
@@ -81,12 +81,14 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
         if (scrollState.current === 'settling') {
           if (lastDirection.current === -1 && offset < lastOffset.current) {
             onPageSelecting?.(position)
+            setSelectedPage(position)
             lastDirection.current = 0
           } else if (
             lastDirection.current === 1 &&
             offset > lastOffset.current
           ) {
             onPageSelecting?.(position + 1)
+            setSelectedPage(position + 1)
             lastDirection.current = 0
           }
         } else {
diff --git a/src/view/com/pager/PagerWithHeader.tsx b/src/view/com/pager/PagerWithHeader.tsx
index 487c589e3..dcfc1eebb 100644
--- a/src/view/com/pager/PagerWithHeader.tsx
+++ b/src/view/com/pager/PagerWithHeader.tsx
@@ -69,13 +69,19 @@ export const PagerWithHeader = React.forwardRef<PagerRef, PagerWithHeaderProps>(
     // capture the header bar sizing
     const onTabBarLayout = React.useCallback(
       (evt: LayoutChangeEvent) => {
-        setTabBarHeight(evt.nativeEvent.layout.height)
+        const height = evt.nativeEvent.layout.height
+        if (height > 0) {
+          setTabBarHeight(height)
+        }
       },
       [setTabBarHeight],
     )
     const onHeaderOnlyLayout = React.useCallback(
       (evt: LayoutChangeEvent) => {
-        setHeaderOnlyHeight(evt.nativeEvent.layout.height)
+        const height = evt.nativeEvent.layout.height
+        if (height > 0) {
+          setHeaderOnlyHeight(height)
+        }
       },
       [setHeaderOnlyHeight],
     )
@@ -248,11 +254,14 @@ let PagerTabBar = ({
   }))
   return (
     <Animated.View
+      pointerEvents="box-none"
       style={[
         isMobile ? styles.tabBarMobile : styles.tabBarDesktop,
         headerTransform,
       ]}>
-      <View onLayout={onHeaderOnlyLayout}>{renderHeader?.()}</View>
+      <View onLayout={onHeaderOnlyLayout} pointerEvents="box-none">
+        {renderHeader?.()}
+      </View>
       <View
         onLayout={onTabBarLayout}
         style={{
diff --git a/src/view/com/post-thread/PostThreadItem.tsx b/src/view/com/post-thread/PostThreadItem.tsx
index a4b7a4a9c..86ea4eb39 100644
--- a/src/view/com/post-thread/PostThreadItem.tsx
+++ b/src/view/com/post-thread/PostThreadItem.tsx
@@ -351,11 +351,14 @@ let PostThreadItemLoaded = ({
               {post.embed && (
                 <ContentHider
                   moderation={moderation.embed}
+                  moderationDecisions={moderation.decisions}
                   ignoreMute={isEmbedByEmbedder(post.embed, post.author.did)}
+                  ignoreQuoteDecisions
                   style={s.mb10}>
                   <PostEmbeds
                     embed={post.embed}
                     moderation={moderation.embed}
+                    moderationDecisions={moderation.decisions}
                   />
                 </ContentHider>
               )}
@@ -414,7 +417,7 @@ let PostThreadItemLoaded = ({
       </>
     )
   } else {
-    const isThreadedChild = treeView && depth > 1
+    const isThreadedChild = treeView && depth > 0
     return (
       <PostOuterWrapper
         post={post}
@@ -426,7 +429,11 @@ let PostThreadItemLoaded = ({
           testID={`postThreadItem-by-${post.author.handle}`}
           href={postHref}
           style={[pal.view]}
-          moderation={moderation.content}>
+          moderation={moderation.content}
+          iconSize={isThreadedChild ? 26 : 38}
+          iconStyles={
+            isThreadedChild ? {marginRight: 4} : {marginLeft: 2, marginRight: 2}
+          }>
           <PostSandboxWarning />
 
           <View
@@ -491,10 +498,10 @@ let PostThreadItemLoaded = ({
                 timestamp={post.indexedAt}
                 postHref={postHref}
                 showAvatar={isThreadedChild}
-                avatarSize={26}
+                avatarSize={20}
                 displayNameType="md-bold"
                 displayNameStyle={isThreadedChild && s.ml2}
-                style={isThreadedChild && s.mb5}
+                style={isThreadedChild && s.mb2}
               />
               <PostAlerts
                 moderation={moderation.content}
@@ -522,10 +529,14 @@ let PostThreadItemLoaded = ({
               {post.embed && (
                 <ContentHider
                   style={styles.contentHider}
-                  moderation={moderation.embed}>
+                  moderation={moderation.embed}
+                  moderationDecisions={moderation.decisions}
+                  ignoreMute={isEmbedByEmbedder(post.embed, post.author.did)}
+                  ignoreQuoteDecisions>
                   <PostEmbeds
                     embed={post.embed}
                     moderation={moderation.embed}
+                    moderationDecisions={moderation.decisions}
                   />
                 </ContentHider>
               )}
@@ -583,7 +594,7 @@ function PostOuterWrapper({
   const {isMobile} = useWebMediaQueries()
   const pal = usePalette('default')
   const styles = useStyles()
-  if (treeView && depth > 1) {
+  if (treeView && depth > 0) {
     return (
       <View
         style={[
@@ -592,9 +603,9 @@ function PostOuterWrapper({
           styles.cursor,
           {
             flexDirection: 'row',
-            paddingLeft: 20,
+            paddingLeft: depth === 1 ? 10 : 20,
             borderTopWidth: depth === 1 ? 1 : 0,
-            paddingTop: depth === 1 ? 8 : 0,
+            paddingTop: depth === 1 ? 6 : 0,
           },
         ]}>
         {Array.from(Array(depth - 1)).map((_, n: number) => (
@@ -603,8 +614,8 @@ function PostOuterWrapper({
             style={{
               borderLeftWidth: 2,
               borderLeftColor: pal.colors.border,
-              marginLeft: n === 0 ? 14 : isMobile ? 6 : 14,
-              paddingLeft: n === 0 ? 18 : isMobile ? 6 : 12,
+              marginLeft: isMobile ? 6 : 14,
+              paddingLeft: isMobile ? 6 : 12,
             }}
           />
         ))}
diff --git a/src/view/com/post/Post.tsx b/src/view/com/post/Post.tsx
index 2e8019e71..9b1bf7a49 100644
--- a/src/view/com/post/Post.tsx
+++ b/src/view/com/post/Post.tsx
@@ -196,8 +196,14 @@ function PostInner({
             {post.embed ? (
               <ContentHider
                 moderation={moderation.embed}
+                moderationDecisions={moderation.decisions}
+                ignoreQuoteDecisions
                 style={styles.contentHider}>
-                <PostEmbeds embed={post.embed} moderation={moderation.embed} />
+                <PostEmbeds
+                  embed={post.embed}
+                  moderation={moderation.embed}
+                  moderationDecisions={moderation.decisions}
+                />
               </ContentHider>
             ) : null}
           </ContentHider>
diff --git a/src/view/com/posts/Feed.tsx b/src/view/com/posts/Feed.tsx
index 393c1bc91..b9ca9abdc 100644
--- a/src/view/com/posts/Feed.tsx
+++ b/src/view/com/posts/Feed.tsx
@@ -26,6 +26,7 @@ import {
   pollLatest,
 } from '#/state/queries/post-feed'
 import {useModerationOpts} from '#/state/queries/preferences'
+import {isWeb} from '#/platform/detection'
 
 const LOADING_ITEM = {_reactKey: '__loading__'}
 const EMPTY_FEED_ITEM = {_reactKey: '__empty__'}
@@ -89,7 +90,7 @@ let Feed = ({
   const isEmpty = !isFetching && !data?.pages[0]?.slices.length
 
   const checkForNew = React.useCallback(async () => {
-    if (!data?.pages[0] || isFetching || !onHasNew) {
+    if (!data?.pages[0] || isFetching || !onHasNew || !enabled) {
       return
     }
     try {
@@ -99,7 +100,7 @@ let Feed = ({
     } catch (e) {
       logger.error('Poll latest failed', {feed, error: String(e)})
     }
-  }, [feed, data, isFetching, onHasNew])
+  }, [feed, data, isFetching, onHasNew, enabled])
 
   React.useEffect(() => {
     // we store the interval handler in a ref to avoid needless
@@ -216,19 +217,25 @@ let Feed = ({
 
   const shouldRenderEndOfFeed =
     !hasNextPage && !isEmpty && !isFetching && !isError && !!renderEndOfFeed
-  const FeedFooter = React.useCallback(
-    () =>
-      isFetchingNextPage ? (
-        <View style={styles.feedFooter}>
-          <ActivityIndicator />
-        </View>
-      ) : shouldRenderEndOfFeed ? (
-        renderEndOfFeed()
-      ) : (
-        <View />
-      ),
-    [isFetchingNextPage, shouldRenderEndOfFeed, renderEndOfFeed],
-  )
+  const FeedFooter = React.useCallback(() => {
+    /**
+     * A bit of padding at the bottom of the feed as you scroll and when you
+     * reach the end, so that content isn't cut off by the bottom of the
+     * screen.
+     */
+    const offset = Math.max(headerOffset, 32) * (isWeb ? 1 : 2)
+
+    return isFetchingNextPage ? (
+      <View style={[styles.feedFooter]}>
+        <ActivityIndicator />
+        <View style={{height: offset}} />
+      </View>
+    ) : shouldRenderEndOfFeed ? (
+      <View style={{minHeight: offset}}>{renderEndOfFeed()}</View>
+    ) : (
+      <View style={{height: offset}} />
+    )
+  }, [isFetchingNextPage, shouldRenderEndOfFeed, renderEndOfFeed, headerOffset])
 
   const scrollHandler = useAnimatedScrollHandler(onScroll || {})
   return (
diff --git a/src/view/com/posts/FeedErrorMessage.tsx b/src/view/com/posts/FeedErrorMessage.tsx
index 63d9d5956..f63bc1a88 100644
--- a/src/view/com/posts/FeedErrorMessage.tsx
+++ b/src/view/com/posts/FeedErrorMessage.tsx
@@ -25,6 +25,7 @@ export enum KnownError {
   FeedgenOffline = 'FeedgenOffline',
   FeedgenUnknown = 'FeedgenUnknown',
   FeedNSFPublic = 'FeedNSFPublic',
+  FeedTooManyRequests = 'FeedTooManyRequests',
   Unknown = 'Unknown',
 }
 
@@ -100,6 +101,9 @@ function FeedgenErrorMessage({
         [KnownError.FeedgenUnknown]: _l(
           msgLingui`Hmm, some kind of issue occured when contacting the feed server. Please let the feed owner know about this issue.`,
         ),
+        [KnownError.FeedTooManyRequests]: _l(
+          msgLingui`We're sorry, but this feed is currently receiving high traffic and is temporarily unavailable. Please try again later.`,
+        ),
       }[knownError]),
     [_l, knownError],
   )
@@ -203,6 +207,13 @@ function detectKnownError(
   ) {
     return KnownError.Block
   }
+
+  // check status codes
+  if (error?.status === 429) {
+    return KnownError.FeedTooManyRequests
+  }
+
+  // convert error to string and continue
   if (typeof error !== 'string') {
     error = error.toString()
   }
diff --git a/src/view/com/posts/FeedItem.tsx b/src/view/com/posts/FeedItem.tsx
index dfb0cfcf6..b6c509e92 100644
--- a/src/view/com/posts/FeedItem.tsx
+++ b/src/view/com/posts/FeedItem.tsx
@@ -320,9 +320,15 @@ let FeedItemInner = ({
               <ContentHider
                 testID="contentHider-embed"
                 moderation={moderation.embed}
+                moderationDecisions={moderation.decisions}
                 ignoreMute={isEmbedByEmbedder(post.embed, post.author.did)}
+                ignoreQuoteDecisions
                 style={styles.embed}>
-                <PostEmbeds embed={post.embed} moderation={moderation.embed} />
+                <PostEmbeds
+                  embed={post.embed}
+                  moderation={moderation.embed}
+                  moderationDecisions={moderation.decisions}
+                />
               </ContentHider>
             ) : null}
           </ContentHider>
diff --git a/src/view/com/posts/FollowingEndOfFeed.tsx b/src/view/com/posts/FollowingEndOfFeed.tsx
index 48724d8b3..6630b9a83 100644
--- a/src/view/com/posts/FollowingEndOfFeed.tsx
+++ b/src/view/com/posts/FollowingEndOfFeed.tsx
@@ -1,5 +1,5 @@
 import React from 'react'
-import {StyleSheet, View} from 'react-native'
+import {StyleSheet, View, Dimensions} from 'react-native'
 import {useNavigation} from '@react-navigation/native'
 import {
   FontAwesomeIcon,
@@ -36,7 +36,12 @@ export function FollowingEndOfFeed() {
   }, [navigation])
 
   return (
-    <View style={[styles.container, pal.border]}>
+    <View
+      style={[
+        styles.container,
+        pal.border,
+        {minHeight: Dimensions.get('window').height * 0.75},
+      ]}>
       <View style={styles.inner}>
         <Text type="xl-medium" style={[s.textCenter, pal.text]}>
           You've reached the end of your feed! Find some more accounts to
diff --git a/src/view/com/profile/ProfileCard.tsx b/src/view/com/profile/ProfileCard.tsx
index 279e00d75..21972f274 100644
--- a/src/view/com/profile/ProfileCard.tsx
+++ b/src/view/com/profile/ProfileCard.tsx
@@ -228,6 +228,7 @@ const styles = StyleSheet.create({
   outer: {
     borderTopWidth: 1,
     paddingHorizontal: 6,
+    paddingVertical: 4,
   },
   outerNoBorder: {
     borderTopWidth: 0,
@@ -237,7 +238,7 @@ const styles = StyleSheet.create({
     alignItems: 'center',
   },
   layoutAvi: {
-    alignSelf: 'baseline',
+    alignSelf: 'flex-start',
     width: 54,
     paddingLeft: 4,
     paddingTop: 10,
diff --git a/src/view/com/profile/ProfileHeader.tsx b/src/view/com/profile/ProfileHeader.tsx
index c1de10aa5..16e98ddf2 100644
--- a/src/view/com/profile/ProfileHeader.tsx
+++ b/src/view/com/profile/ProfileHeader.tsx
@@ -412,10 +412,12 @@ let ProfileHeaderLoaded = ({
   const pluralizedFollowers = pluralize(profile.followersCount || 0, 'follower')
 
   return (
-    <View style={pal.view}>
-      <UserBanner banner={profile.banner} moderation={moderation.avatar} />
-      <View style={styles.content}>
-        <View style={[styles.buttonsLine]}>
+    <View style={pal.view} pointerEvents="box-none">
+      <View pointerEvents="none">
+        <UserBanner banner={profile.banner} moderation={moderation.avatar} />
+      </View>
+      <View style={styles.content} pointerEvents="box-none">
+        <View style={[styles.buttonsLine]} pointerEvents="box-none">
           {isMe ? (
             <TouchableOpacity
               testID="profileHeaderEditProfileButton"
@@ -468,7 +470,7 @@ let ProfileHeaderLoaded = ({
                       pal.text,
                       {
                         color: showSuggestedFollows
-                          ? colors.white
+                          ? pal.textInverted.color
                           : pal.text.color,
                       },
                     ]}
@@ -525,7 +527,7 @@ let ProfileHeaderLoaded = ({
             </NativeDropdown>
           ) : undefined}
         </View>
-        <View>
+        <View pointerEvents="none">
           <Text
             testID="profileHeaderDisplayName"
             type="title-2xl"
@@ -536,7 +538,7 @@ let ProfileHeaderLoaded = ({
             )}
           </Text>
         </View>
-        <View style={styles.handleLine}>
+        <View style={styles.handleLine} pointerEvents="none">
           {profile.viewer?.followedBy && !blockHide ? (
             <View style={[styles.pill, pal.btn, s.mr5]}>
               <Text type="xs" style={[pal.text]}>
@@ -557,7 +559,7 @@ let ProfileHeaderLoaded = ({
         </View>
         {!blockHide && (
           <>
-            <View style={styles.metricsLine}>
+            <View style={styles.metricsLine} pointerEvents="box-none">
               <Link
                 testID="profileHeaderFollowersButton"
                 style={[s.flexRow, s.mr10]}
@@ -604,12 +606,14 @@ let ProfileHeaderLoaded = ({
               </Text>
             </View>
             {descriptionRT && !moderation.profile.blur ? (
-              <RichText
-                testID="profileHeaderDescription"
-                style={[styles.description, pal.text]}
-                numberOfLines={15}
-                richText={descriptionRT}
-              />
+              <View pointerEvents="none">
+                <RichText
+                  testID="profileHeaderDescription"
+                  style={[styles.description, pal.text]}
+                  numberOfLines={15}
+                  richText={descriptionRT}
+                />
+              </View>
             ) : undefined}
           </>
         )}
diff --git a/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx b/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx
index f648c9801..1d550aa5c 100644
--- a/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx
+++ b/src/view/com/profile/ProfileHeaderSuggestedFollows.tsx
@@ -70,15 +70,19 @@ export function ProfileHeaderSuggestedFollows({
   })
 
   return (
-    <Animated.View style={[{overflow: 'hidden', opacity: 0}, animatedStyles]}>
-      <View style={{paddingVertical: OUTER_PADDING}}>
+    <Animated.View
+      pointerEvents="box-none"
+      style={[{overflow: 'hidden', opacity: 0}, animatedStyles]}>
+      <View style={{paddingVertical: OUTER_PADDING}} pointerEvents="box-none">
         <View
+          pointerEvents="box-none"
           style={{
             backgroundColor: pal.viewLight.backgroundColor,
             height: '100%',
             paddingTop: INNER_PADDING / 2,
           }}>
           <View
+            pointerEvents="box-none"
             style={{
               flexDirection: 'row',
               justifyContent: 'space-between',
diff --git a/src/view/com/util/LoadingPlaceholder.tsx b/src/view/com/util/LoadingPlaceholder.tsx
index 74e36ff7b..a07b33325 100644
--- a/src/view/com/util/LoadingPlaceholder.tsx
+++ b/src/view/com/util/LoadingPlaceholder.tsx
@@ -7,7 +7,7 @@ import {
   DimensionValue,
 } from 'react-native'
 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
-import {HeartIcon} from 'lib/icons'
+import {HeartIcon, HeartIconSolid} from 'lib/icons'
 import {s} from 'lib/styles'
 import {useTheme} from 'lib/ThemeContext'
 import {usePalette} from 'lib/hooks/usePalette'
@@ -46,12 +46,22 @@ export function PostLoadingPlaceholder({
   const pal = usePalette('default')
   return (
     <View style={[styles.post, pal.view, style]}>
-      <LoadingPlaceholder width={52} height={52} style={styles.avatar} />
+      <LoadingPlaceholder
+        width={52}
+        height={52}
+        style={[
+          styles.avatar,
+          {
+            position: 'relative',
+            top: -6,
+          },
+        ]}
+      />
       <View style={[s.flex1]}>
-        <LoadingPlaceholder width={100} height={8} style={[s.mb10]} />
-        <LoadingPlaceholder width={200} height={8} style={[s.mb5]} />
-        <LoadingPlaceholder width={200} height={8} style={[s.mb5]} />
-        <LoadingPlaceholder width={120} height={8} style={[s.mb10]} />
+        <LoadingPlaceholder width={100} height={6} style={{marginBottom: 10}} />
+        <LoadingPlaceholder width="95%" height={6} style={{marginBottom: 8}} />
+        <LoadingPlaceholder width="95%" height={6} style={{marginBottom: 8}} />
+        <LoadingPlaceholder width="80%" height={6} style={{marginBottom: 15}} />
         <View style={s.flexRow}>
           <View style={s.flex1}>
             <FontAwesomeIcon
@@ -90,6 +100,8 @@ export function PostFeedLoadingPlaceholder() {
       <PostLoadingPlaceholder />
       <PostLoadingPlaceholder />
       <PostLoadingPlaceholder />
+      <PostLoadingPlaceholder />
+      <PostLoadingPlaceholder />
     </View>
   )
 }
@@ -102,11 +114,23 @@ export function NotificationLoadingPlaceholder({
   const pal = usePalette('default')
   return (
     <View style={[styles.notification, pal.view, style]}>
-      <View style={[s.flexRow, s.mb10]}>
-        <LoadingPlaceholder width={30} height={30} style={styles.smallAvatar} />
+      <View style={{paddingLeft: 30, paddingRight: 10}}>
+        <HeartIconSolid
+          style={{color: pal.colors.backgroundLight} as ViewStyle}
+          size={30}
+        />
+      </View>
+      <View style={{flex: 1}}>
+        <View style={[s.flexRow, s.mb10]}>
+          <LoadingPlaceholder
+            width={30}
+            height={30}
+            style={styles.smallAvatar}
+          />
+        </View>
+        <LoadingPlaceholder width="90%" height={6} style={[s.mb5]} />
+        <LoadingPlaceholder width="70%" height={6} style={[s.mb5]} />
       </View>
-      <LoadingPlaceholder width={200} height={8} style={[s.mb5]} />
-      <LoadingPlaceholder width={120} height={8} style={[s.mb5]} />
     </View>
   )
 }
@@ -239,18 +263,19 @@ const styles = StyleSheet.create({
   },
   post: {
     flexDirection: 'row',
-    padding: 10,
-    margin: 1,
+    alignItems: 'flex-start',
+    paddingHorizontal: 10,
+    paddingTop: 20,
+    paddingBottom: 5,
   },
   avatar: {
     borderRadius: 26,
     marginRight: 10,
-    marginLeft: 6,
+    marginLeft: 8,
   },
   notification: {
+    flexDirection: 'row',
     padding: 10,
-    paddingLeft: 46,
-    margin: 1,
   },
   profileCard: {
     flexDirection: 'row',
diff --git a/src/view/com/util/moderation/ContentHider.tsx b/src/view/com/util/moderation/ContentHider.tsx
index a13aae2b5..b1ea76621 100644
--- a/src/view/com/util/moderation/ContentHider.tsx
+++ b/src/view/com/util/moderation/ContentHider.tsx
@@ -1,36 +1,44 @@
 import React from 'react'
 import {Pressable, StyleProp, StyleSheet, View, ViewStyle} from 'react-native'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {usePalette} from 'lib/hooks/usePalette'
-import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
-import {ModerationUI} from '@atproto/api'
+import {ModerationUI, PostModeration} from '@atproto/api'
 import {Text} from '../text/Text'
 import {ShieldExclamation} from 'lib/icons'
 import {describeModerationCause} from 'lib/moderation'
 import {useLingui} from '@lingui/react'
 import {msg} from '@lingui/macro'
 import {useModalControls} from '#/state/modals'
+import {isPostMediaBlurred} from 'lib/moderation'
 
 export function ContentHider({
   testID,
   moderation,
+  moderationDecisions,
   ignoreMute,
+  ignoreQuoteDecisions,
   style,
   childContainerStyle,
   children,
 }: React.PropsWithChildren<{
   testID?: string
   moderation: ModerationUI
+  moderationDecisions?: PostModeration['decisions']
   ignoreMute?: boolean
+  ignoreQuoteDecisions?: boolean
   style?: StyleProp<ViewStyle>
   childContainerStyle?: StyleProp<ViewStyle>
 }>) {
   const pal = usePalette('default')
   const {_} = useLingui()
-  const {isMobile} = useWebMediaQueries()
   const [override, setOverride] = React.useState(false)
   const {openModal} = useModalControls()
 
-  if (!moderation.blur || (ignoreMute && moderation.cause?.type === 'muted')) {
+  if (
+    !moderation.blur ||
+    (ignoreMute && moderation.cause?.type === 'muted') ||
+    shouldIgnoreQuote(moderationDecisions, ignoreQuoteDecisions)
+  ) {
     return (
       <View testID={testID} style={[styles.outer, style]}>
         {children}
@@ -38,6 +46,7 @@ export function ContentHider({
     )
   }
 
+  const isMute = moderation.cause?.type === 'muted'
   const desc = describeModerationCause(moderation.cause, 'content')
   return (
     <View testID={testID} style={[styles.outer, style]}>
@@ -58,7 +67,6 @@ export function ContentHider({
         accessibilityLabel=""
         style={[
           styles.cover,
-          {paddingRight: isMobile ? 22 : 18},
           moderation.noOverride
             ? {borderWidth: 1, borderColor: pal.colors.borderDark}
             : pal.viewLight,
@@ -74,14 +82,22 @@ export function ContentHider({
           accessibilityRole="button"
           accessibilityLabel={_(msg`Learn more about this warning`)}
           accessibilityHint="">
-          <ShieldExclamation size={18} style={pal.text} />
+          {isMute ? (
+            <FontAwesomeIcon
+              icon={['far', 'eye-slash']}
+              size={18}
+              color={pal.colors.textLight}
+            />
+          ) : (
+            <ShieldExclamation size={18} style={pal.textLight} />
+          )}
         </Pressable>
-        <Text type="lg" style={pal.text}>
+        <Text type="md" style={pal.text}>
           {desc.name}
         </Text>
         {!moderation.noOverride && (
           <View style={styles.showBtn}>
-            <Text type="xl" style={pal.link}>
+            <Text type="lg" style={pal.link}>
               {override ? 'Hide' : 'Show'}
             </Text>
           </View>
@@ -92,6 +108,16 @@ export function ContentHider({
   )
 }
 
+function shouldIgnoreQuote(
+  decisions: PostModeration['decisions'] | undefined,
+  ignore: boolean | undefined,
+): boolean {
+  if (!decisions || !ignore) {
+    return false
+  }
+  return !isPostMediaBlurred(decisions)
+}
+
 const styles = StyleSheet.create({
   outer: {
     overflow: 'hidden',
@@ -104,6 +130,7 @@ const styles = StyleSheet.create({
     marginTop: 4,
     paddingVertical: 14,
     paddingLeft: 14,
+    paddingRight: 18,
   },
   showBtn: {
     marginLeft: 'auto',
diff --git a/src/view/com/util/moderation/PostHider.tsx b/src/view/com/util/moderation/PostHider.tsx
index c2b857f54..bffb7ea1a 100644
--- a/src/view/com/util/moderation/PostHider.tsx
+++ b/src/view/com/util/moderation/PostHider.tsx
@@ -1,8 +1,8 @@
 import React, {ComponentProps} from 'react'
-import {StyleSheet, Pressable, View} from 'react-native'
+import {StyleSheet, Pressable, View, ViewStyle, StyleProp} from 'react-native'
 import {ModerationUI} from '@atproto/api'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {usePalette} from 'lib/hooks/usePalette'
-import {useWebMediaQueries} from 'lib/hooks/useWebMediaQueries'
 import {Link} from '../Link'
 import {Text} from '../text/Text'
 import {addStyle} from 'lib/styles'
@@ -13,9 +13,8 @@ import {msg} from '@lingui/macro'
 import {useModalControls} from '#/state/modals'
 
 interface Props extends ComponentProps<typeof Link> {
-  // testID?: string
-  // href?: string
-  // style: StyleProp<ViewStyle>
+  iconSize: number
+  iconStyles: StyleProp<ViewStyle>
   moderation: ModerationUI
 }
 
@@ -25,11 +24,12 @@ export function PostHider({
   moderation,
   style,
   children,
+  iconSize,
+  iconStyles,
   ...props
 }: Props) {
   const pal = usePalette('default')
   const {_} = useLingui()
-  const {isMobile} = useWebMediaQueries()
   const [override, setOverride] = React.useState(false)
   const {openModal} = useModalControls()
 
@@ -47,57 +47,74 @@ export function PostHider({
     )
   }
 
+  const isMute = moderation.cause?.type === 'muted'
   const desc = describeModerationCause(moderation.cause, 'content')
-  return (
-    <>
+  return !override ? (
+    <Pressable
+      onPress={() => {
+        if (!moderation.noOverride) {
+          setOverride(v => !v)
+        }
+      }}
+      accessibilityRole="button"
+      accessibilityHint={override ? 'Hide the content' : 'Show the content'}
+      accessibilityLabel=""
+      style={[
+        styles.description,
+        override ? {paddingBottom: 0} : undefined,
+        pal.view,
+      ]}>
       <Pressable
         onPress={() => {
-          if (!moderation.noOverride) {
-            setOverride(v => !v)
-          }
+          openModal({
+            name: 'moderation-details',
+            context: 'content',
+            moderation,
+          })
         }}
         accessibilityRole="button"
-        accessibilityHint={override ? 'Hide the content' : 'Show the content'}
-        accessibilityLabel=""
-        style={[
-          styles.description,
-          {paddingRight: isMobile ? 22 : 18},
-          pal.viewLight,
-        ]}>
-        <Pressable
-          onPress={() => {
-            openModal({
-              name: 'moderation-details',
-              context: 'content',
-              moderation,
-            })
-          }}
-          accessibilityRole="button"
-          accessibilityLabel={_(msg`Learn more about this warning`)}
-          accessibilityHint="">
-          <ShieldExclamation size={18} style={pal.text} />
-        </Pressable>
-        <Text type="lg" style={[{flex: 1}, pal.text]} numberOfLines={1}>
-          {desc.name}
-        </Text>
-        {!moderation.noOverride && (
-          <Text type="xl" style={[styles.showBtn, pal.link]}>
-            {override ? 'Hide' : 'Show'}
-          </Text>
-        )}
-      </Pressable>
-      {override && (
-        <View style={[styles.childrenContainer, pal.border, pal.viewLight]}>
-          <Link
-            testID={testID}
-            style={addStyle(style, styles.child)}
-            href={href}
-            noFeedback>
-            {children}
-          </Link>
+        accessibilityLabel={_(msg`Learn more about this warning`)}
+        accessibilityHint="">
+        <View
+          style={[
+            pal.viewLight,
+            {
+              width: iconSize,
+              height: iconSize,
+              borderRadius: iconSize,
+              alignItems: 'center',
+              justifyContent: 'center',
+            },
+            iconStyles,
+          ]}>
+          {isMute ? (
+            <FontAwesomeIcon
+              icon={['far', 'eye-slash']}
+              size={14}
+              color={pal.colors.textLight}
+            />
+          ) : (
+            <ShieldExclamation size={14} style={pal.textLight} />
+          )}
         </View>
+      </Pressable>
+      <Text type="sm" style={[{flex: 1}, pal.textLight]} numberOfLines={1}>
+        {desc.name}
+      </Text>
+      {!moderation.noOverride && (
+        <Text type="sm" style={[styles.showBtn, pal.link]}>
+          {override ? 'Hide' : 'Show'}
+        </Text>
       )}
-    </>
+    </Pressable>
+  ) : (
+    <Link
+      testID={testID}
+      style={addStyle(style, styles.child)}
+      href={href}
+      noFeedback>
+      {children}
+    </Link>
   )
 }
 
@@ -106,18 +123,15 @@ const styles = StyleSheet.create({
     flexDirection: 'row',
     alignItems: 'center',
     gap: 4,
-    paddingVertical: 14,
-    paddingLeft: 18,
+    paddingVertical: 10,
+    paddingLeft: 6,
+    paddingRight: 18,
     marginTop: 1,
   },
   showBtn: {
     marginLeft: 'auto',
     alignSelf: 'center',
   },
-  childrenContainer: {
-    paddingHorizontal: 4,
-    paddingBottom: 6,
-  },
   child: {
     borderWidth: 0,
     borderTopWidth: 0,
diff --git a/src/view/com/util/moderation/ProfileHeaderAlerts.tsx b/src/view/com/util/moderation/ProfileHeaderAlerts.tsx
index d2675ca54..0f07b679b 100644
--- a/src/view/com/util/moderation/ProfileHeaderAlerts.tsx
+++ b/src/view/com/util/moderation/ProfileHeaderAlerts.tsx
@@ -10,6 +10,7 @@ import {
 } from 'lib/moderation'
 import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
+import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import {useModalControls} from '#/state/modals'
 
 export function ProfileHeaderAlerts({
@@ -31,6 +32,7 @@ export function ProfileHeaderAlerts({
   return (
     <View style={styles.grid}>
       {causes.map(cause => {
+        const isMute = cause.type === 'muted'
         const desc = describeModerationCause(cause, 'account')
         return (
           <Pressable
@@ -47,11 +49,19 @@ export function ProfileHeaderAlerts({
             accessibilityLabel={_(msg`Learn more about this warning`)}
             accessibilityHint=""
             style={[styles.container, pal.viewLight, style]}>
-            <ShieldExclamation style={pal.text} size={24} />
-            <Text type="lg" style={[{flex: 1}, pal.text]}>
+            {isMute ? (
+              <FontAwesomeIcon
+                icon={['far', 'eye-slash']}
+                size={14}
+                color={pal.colors.textLight}
+              />
+            ) : (
+              <ShieldExclamation style={pal.text} size={18} />
+            )}
+            <Text type="sm" style={[{flex: 1}, pal.text]}>
               {desc.name}
             </Text>
-            <Text type="lg" style={[pal.link, styles.learnMoreBtn]}>
+            <Text type="sm" style={[pal.link, styles.learnMoreBtn]}>
               <Trans>Learn More</Trans>
             </Text>
           </Pressable>
diff --git a/src/view/com/util/post-embeds/index.tsx b/src/view/com/util/post-embeds/index.tsx
index ca3bf1104..5c16a3b3e 100644
--- a/src/view/com/util/post-embeds/index.tsx
+++ b/src/view/com/util/post-embeds/index.tsx
@@ -16,6 +16,7 @@ import {
   AppBskyFeedDefs,
   AppBskyGraphDefs,
   ModerationUI,
+  PostModeration,
 } from '@atproto/api'
 import {Link} from '../Link'
 import {ImageLayoutGrid} from '../images/ImageLayoutGrid'
@@ -28,8 +29,9 @@ import {getYoutubeVideoId} from 'lib/strings/url-helpers'
 import {MaybeQuoteEmbed} from './QuoteEmbed'
 import {AutoSizedImage} from '../images/AutoSizedImage'
 import {ListEmbed} from './ListEmbed'
-import {isCauseALabelOnUri} from 'lib/moderation'
+import {isCauseALabelOnUri, isQuoteBlurred} from 'lib/moderation'
 import {FeedSourceCard} from 'view/com/feeds/FeedSourceCard'
+import {ContentHider} from '../moderation/ContentHider'
 
 type Embed =
   | AppBskyEmbedRecord.View
@@ -41,10 +43,12 @@ type Embed =
 export function PostEmbeds({
   embed,
   moderation,
+  moderationDecisions,
   style,
 }: {
   embed?: Embed
   moderation: ModerationUI
+  moderationDecisions?: PostModeration['decisions']
   style?: StyleProp<ViewStyle>
 }) {
   const pal = usePalette('default')
@@ -55,14 +59,17 @@ export function PostEmbeds({
   // =
   if (AppBskyEmbedRecordWithMedia.isView(embed)) {
     const isModOnQuote =
-      AppBskyEmbedRecord.isViewRecord(embed.record.record) &&
-      isCauseALabelOnUri(moderation.cause, embed.record.record.uri)
+      (AppBskyEmbedRecord.isViewRecord(embed.record.record) &&
+        isCauseALabelOnUri(moderation.cause, embed.record.record.uri)) ||
+      (moderationDecisions && isQuoteBlurred(moderationDecisions))
     const mediaModeration = isModOnQuote ? {} : moderation
     const quoteModeration = isModOnQuote ? moderation : {}
     return (
       <View style={[styles.stackContainer, style]}>
         <PostEmbeds embed={embed.media} moderation={mediaModeration} />
-        <MaybeQuoteEmbed embed={embed.record} moderation={quoteModeration} />
+        <ContentHider moderation={quoteModeration}>
+          <MaybeQuoteEmbed embed={embed.record} moderation={quoteModeration} />
+        </ContentHider>
       </View>
     )
   }
diff --git a/src/view/screens/Home.tsx b/src/view/screens/Home.tsx
index 6100d42db..d07fa0434 100644
--- a/src/view/screens/Home.tsx
+++ b/src/view/screens/Home.tsx
@@ -1,6 +1,6 @@
 import React from 'react'
 import {View, ActivityIndicator, StyleSheet} from 'react-native'
-import {useFocusEffect} from '@react-navigation/native'
+import {useFocusEffect, useIsFocused} from '@react-navigation/native'
 import {NativeStackScreenProps, HomeTabNavigatorParams} from 'lib/routes/types'
 import {FeedDescriptor, FeedParams} from '#/state/queries/post-feed'
 import {FollowingEmptyState} from 'view/com/posts/FollowingEmptyState'
@@ -65,6 +65,7 @@ function HomeScreenReady({
   const {hasSession} = useSession()
   const setMinimalShellMode = useSetMinimalShellMode()
   const setDrawerSwipeDisabled = useSetDrawerSwipeDisabled()
+  const isPageFocused = useIsFocused()
   const [selectedPage, setSelectedPage] = React.useState<string>(initialPage)
 
   /**
@@ -174,7 +175,7 @@ function HomeScreenReady({
       <FeedPage
         key="1"
         testID="followingFeedPage"
-        isPageFocused={selectedPageIndex === 0}
+        isPageFocused={selectedPageIndex === 0 && isPageFocused}
         feed={homeFeedParams.mergeFeedEnabled ? 'home' : 'following'}
         feedParams={homeFeedParams}
         renderEmptyState={renderFollowingEmptyState}
@@ -185,7 +186,7 @@ function HomeScreenReady({
           <FeedPage
             key={f}
             testID="customFeedPage"
-            isPageFocused={selectedPageIndex === 1 + index}
+            isPageFocused={selectedPageIndex === 1 + index && isPageFocused}
             feed={f}
             renderEmptyState={renderCustomFeedEmptyState}
           />
@@ -201,7 +202,7 @@ function HomeScreenReady({
       tabBarPosition="top">
       <FeedPage
         testID="customFeedPage"
-        isPageFocused
+        isPageFocused={isPageFocused}
         feed={`feedgen|at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot`}
         renderEmptyState={renderCustomFeedEmptyState}
       />
diff --git a/src/view/screens/Profile.tsx b/src/view/screens/Profile.tsx
index d5e378ccb..ea19515b5 100644
--- a/src/view/screens/Profile.tsx
+++ b/src/view/screens/Profile.tsx
@@ -2,7 +2,7 @@ import React, {useMemo} from 'react'
 import {StyleSheet, View} from 'react-native'
 import {useFocusEffect} from '@react-navigation/native'
 import {AppBskyActorDefs, moderateProfile, ModerationOpts} from '@atproto/api'
-import {msg} from '@lingui/macro'
+import {msg, Trans} from '@lingui/macro'
 import {useLingui} from '@lingui/react'
 import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types'
 import {CenteredView, FlatList} from '../com/util/Views'
@@ -36,6 +36,8 @@ import {useQueryClient} from '@tanstack/react-query'
 import {useComposerControls} from '#/state/shell/composer'
 import {listenSoftReset} from '#/state/events'
 import {truncateAndInvalidate} from '#/state/queries/util'
+import {Text} from '#/view/com/util/text/Text'
+import {usePalette} from 'lib/hooks/usePalette'
 
 interface SectionRef {
   scrollToTop: () => void
@@ -420,6 +422,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
       <View>
         <Feed
           testID="postsFeed"
+          enabled={isFocused}
           feed={feed}
           pollInterval={30e3}
           scrollElRef={scrollElRef}
@@ -428,7 +431,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
           scrollEventThrottle={1}
           renderEmptyState={renderPostsEmpty}
           headerOffset={headerHeight}
-          enabled={isFocused}
+          renderEndOfFeed={ProfileEndOfFeed}
         />
         {(isScrolledDown || hasNew) && (
           <LoadLatestBtn
@@ -442,6 +445,18 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
   },
 )
 
+function ProfileEndOfFeed() {
+  const pal = usePalette('default')
+
+  return (
+    <View style={[pal.border, {paddingTop: 32, borderTopWidth: 1}]}>
+      <Text style={[pal.textLight, pal.border, {textAlign: 'center'}]}>
+        <Trans>End of feed</Trans>
+      </Text>
+    </View>
+  )
+}
+
 const styles = StyleSheet.create({
   container: {
     flexDirection: 'column',
diff --git a/src/view/screens/ProfileFeed.tsx b/src/view/screens/ProfileFeed.tsx
index 659560a25..3a0bdcc0f 100644
--- a/src/view/screens/ProfileFeed.tsx
+++ b/src/view/screens/ProfileFeed.tsx
@@ -402,7 +402,7 @@ export function ProfileFeedScreenInner({
         isHeaderReady={true}
         renderHeader={renderHeader}
         onCurrentPageSelected={onCurrentPageSelected}>
-        {({onScroll, headerHeight, isScrolledDown, scrollElRef}) =>
+        {({onScroll, headerHeight, isScrolledDown, scrollElRef, isFocused}) =>
           isPublic ? (
             <FeedSection
               ref={feedSectionRef}
@@ -413,6 +413,7 @@ export function ProfileFeedScreenInner({
               scrollElRef={
                 scrollElRef as React.MutableRefObject<FlatList<any> | null>
               }
+              isFocused={isFocused}
             />
           ) : (
             <CenteredView sideBorders style={[{paddingTop: headerHeight}]}>
@@ -492,10 +493,11 @@ interface FeedSectionProps {
   headerHeight: number
   isScrolledDown: boolean
   scrollElRef: React.MutableRefObject<FlatList<any> | null>
+  isFocused: boolean
 }
 const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
   function FeedSectionImpl(
-    {feed, onScroll, headerHeight, isScrolledDown, scrollElRef},
+    {feed, onScroll, headerHeight, isScrolledDown, scrollElRef, isFocused},
     ref,
   ) {
     const [hasNew, setHasNew] = React.useState(false)
@@ -518,6 +520,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
     return (
       <View>
         <Feed
+          enabled={isFocused}
           feed={feed}
           pollInterval={30e3}
           scrollElRef={scrollElRef}
diff --git a/src/view/screens/ProfileList.tsx b/src/view/screens/ProfileList.tsx
index 1396b8269..3e568c8cc 100644
--- a/src/view/screens/ProfileList.tsx
+++ b/src/view/screens/ProfileList.tsx
@@ -56,6 +56,12 @@ import {useSession} from '#/state/session'
 import {useComposerControls} from '#/state/shell/composer'
 import {isWeb} from '#/platform/detection'
 import {truncateAndInvalidate} from '#/state/queries/util'
+import {
+  usePreferencesQuery,
+  usePinFeedMutation,
+  useUnpinFeedMutation,
+} from '#/state/queries/preferences'
+import {logger} from '#/logger'
 
 const SECTION_TITLES_CURATE = ['Posts', 'About']
 const SECTION_TITLES_MOD = ['About']
@@ -129,7 +135,6 @@ function ProfileListScreenLoaded({
       list,
       onChange() {
         if (isCurateList) {
-          // TODO(eric) should construct these strings with a fn too
           truncateAndInvalidate(queryClient, FEED_RQKEY(`list|${list.uri}`))
         }
       },
@@ -159,7 +164,13 @@ function ProfileListScreenLoaded({
           isHeaderReady={true}
           renderHeader={renderHeader}
           onCurrentPageSelected={onCurrentPageSelected}>
-          {({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
+          {({
+            onScroll,
+            headerHeight,
+            isScrolledDown,
+            scrollElRef,
+            isFocused,
+          }) => (
             <FeedSection
               ref={feedSectionRef}
               feed={`list|${uri}`}
@@ -169,6 +180,7 @@ function ProfileListScreenLoaded({
               onScroll={onScroll}
               headerHeight={headerHeight}
               isScrolledDown={isScrolledDown}
+              isFocused={isFocused}
             />
           )}
           {({onScroll, headerHeight, isScrolledDown, scrollElRef}) => (
@@ -247,19 +259,31 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
   const listDeleteMutation = useListDeleteMutation()
   const isCurateList = list.purpose === 'app.bsky.graph.defs#curatelist'
   const isModList = list.purpose === 'app.bsky.graph.defs#modlist'
-  const isPinned = false // TODO
   const isBlocking = !!list.viewer?.blocked
   const isMuting = !!list.viewer?.muted
   const isOwner = list.creator.did === currentAccount?.did
+  const {isPending: isPinPending, mutateAsync: pinFeed} = usePinFeedMutation()
+  const {isPending: isUnpinPending, mutateAsync: unpinFeed} =
+    useUnpinFeedMutation()
+  const isPending = isPinPending || isUnpinPending
+  const {data: preferences} = usePreferencesQuery()
 
-  const onTogglePinned = useCallback(async () => {
+  const isPinned = preferences?.feeds?.pinned?.includes(list.uri)
+
+  const onTogglePinned = React.useCallback(async () => {
     Haptics.default()
-    // TODO
-    // list.togglePin().catch(e => {
-    //   Toast.show('There was an issue contacting the server')
-    //   logger.error('Failed to toggle pinned list', {error: e})
-    // })
-  }, [])
+
+    try {
+      if (isPinned) {
+        await unpinFeed({uri: list.uri})
+      } else {
+        await pinFeed({uri: list.uri})
+      }
+    } catch (e) {
+      Toast.show('There was an issue contacting the server')
+      logger.error('Failed to toggle pinned feed', {error: e})
+    }
+  }, [list.uri, isPinned, pinFeed, unpinFeed])
 
   const onSubscribeMute = useCallback(() => {
     openModal({
@@ -466,10 +490,11 @@ function Header({rkey, list}: {rkey: string; list: AppBskyGraphDefs.ListView}) {
       avatarType="list">
       {isCurateList || isPinned ? (
         <Button
-          testID={list.isPinned ? 'unpinBtn' : 'pinBtn'}
-          type={list.isPinned ? 'default' : 'inverted'}
-          label={list.isPinned ? 'Unpin' : 'Pin to home'}
+          testID={isPinned ? 'unpinBtn' : 'pinBtn'}
+          type={isPinned ? 'default' : 'inverted'}
+          label={isPinned ? 'Unpin' : 'Pin to home'}
           onPress={onTogglePinned}
+          disabled={isPending}
         />
       ) : isModList ? (
         isBlocking ? (
@@ -519,10 +544,11 @@ interface FeedSectionProps {
   headerHeight: number
   isScrolledDown: boolean
   scrollElRef: React.MutableRefObject<FlatList<any> | null>
+  isFocused: boolean
 }
 const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
   function FeedSectionImpl(
-    {feed, scrollElRef, onScroll, headerHeight, isScrolledDown},
+    {feed, scrollElRef, onScroll, headerHeight, isScrolledDown, isFocused},
     ref,
   ) {
     const queryClient = useQueryClient()
@@ -545,6 +571,7 @@ const FeedSection = React.forwardRef<SectionRef, FeedSectionProps>(
       <View>
         <Feed
           testID="listFeed"
+          enabled={isFocused}
           feed={feed}
           pollInterval={30e3}
           scrollElRef={scrollElRef}
diff --git a/src/view/shell/createNativeStackNavigatorWithAuth.tsx b/src/view/shell/createNativeStackNavigatorWithAuth.tsx
index c7b5d1d2e..43dc28159 100644
--- a/src/view/shell/createNativeStackNavigatorWithAuth.tsx
+++ b/src/view/shell/createNativeStackNavigatorWithAuth.tsx
@@ -1,5 +1,6 @@
 import * as React from 'react'
 import {View} from 'react-native'
+import {PWI_ENABLED} from '#/lib/build-flags'
 
 // Based on @react-navigation/native-stack/src/createNativeStackNavigator.ts
 // MIT License
@@ -99,7 +100,7 @@ function NativeStackNavigator({
   const {showLoggedOut} = useLoggedOutView()
   const {setShowLoggedOut} = useLoggedOutViewControls()
   const {isMobile} = useWebMediaQueries()
-  if (activeRouteRequiresAuth && !hasSession) {
+  if ((!PWI_ENABLED || activeRouteRequiresAuth) && !hasSession) {
     return <LoggedOut />
   }
   if (showLoggedOut) {