···11import * as SystemUI from 'expo-system-ui'
22import {type Theme} from '@bsky.app/alf'
3344+import {logger} from '#/logger'
45import {isAndroid} from '#/platform/detection'
5667export function setSystemUITheme(themeType: 'theme' | 'lightbox', t: Theme) {
78 if (isAndroid) {
88- if (themeType === 'theme') {
99- SystemUI.setBackgroundColorAsync(t.atoms.bg.backgroundColor)
1010- } else {
1111- SystemUI.setBackgroundColorAsync('black')
99+ try {
1010+ if (themeType === 'theme') {
1111+ SystemUI.setBackgroundColorAsync(t.atoms.bg.backgroundColor)
1212+ } else {
1313+ SystemUI.setBackgroundColorAsync('black')
1414+ }
1515+ } catch (error) {
1616+ // Can reject with 'The current activity is no longer available' - no big deal
1717+ logger.debug('Could not set system UI theme', {safeMessage: error})
1218 }
1319 }
1420}
···169169 if (isNative && screen !== 'NotFound') {
170170 const state = navigation.getState()
171171 // if screen is not in the current navigator, it means it's
172172- // most likely a tab screen
173173- if (!state.routeNames.includes(screen)) {
172172+ // most likely a tab screen. note: state can be undefined
173173+ if (!state?.routeNames.includes(screen)) {
174174 const parent = navigation.getParent()
175175 if (
176176 parent &&
···148148 */
149149 const shouldHandleScroll = useRef(true)
150150 /**
151151- * Called any time the content size of the list changes, _just_ before paint.
151151+ * Called any time the content size of the list changes. Could be a fresh
152152+ * render, items being added to the list, or any resize that changes the
153153+ * scrollable size of the content.
152154 *
153155 * We want this to fire every time we change params (which will reset
154156 * `deferParents` via `onLayout` on the anchor post, due to the key change),
···193195 * will give us a _positive_ offset, which will scroll the anchor post
194196 * back _up_ to the top of the screen.
195197 */
196196- list.scrollToOffset({
197197- offset: anchorOffsetTop - headerHeight,
198198- })
198198+ const offset = anchorOffsetTop - headerHeight
199199+ list.scrollToOffset({offset})
199200200201 /*
201201- * After the second pass, `deferParents` will be `false`, and we need
202202- * to ensure this doesn't run again until scroll handling is requested
203203- * again via `shouldHandleScroll.current === true` and a params
204204- * change via `prepareForParamsUpdate`.
202202+ * After we manage to do a positive adjustment, we need to ensure this
203203+ * doesn't run again until scroll handling is requested again via
204204+ * `shouldHandleScroll.current === true` and a params change via
205205+ * `prepareForParamsUpdate`.
205206 *
206207 * The `isRoot` here is needed because if we're looking at the anchor
207208 * post, this handler will not fire after `deferParents` is set to
208209 * `false`, since there are no parents to render above it. In this case,
209209- * we want to make sure `shouldHandleScroll` is set to `false` so that
210210- * subsequent size changes unrelated to a params change (like pagination)
211211- * do not affect scroll.
210210+ * we want to make sure `shouldHandleScroll` is set to `false` right away
211211+ * so that subsequent size changes unrelated to a params change (like
212212+ * pagination) do not affect scroll.
212213 */
213213- if (!deferParents || isRoot) shouldHandleScroll.current = false
214214+ if (offset > 0 || isRoot) shouldHandleScroll.current = false
214215 }
215216 })
216217
···11-import {View} from 'react-native'
21import {type AppBskyNotificationDeclaration} from '@atproto/api'
32import {msg, Trans} from '@lingui/macro'
43import {useLingui} from '@lingui/react'
···112111 <Admonition.Outer type="tip" style={[a.flex_1]}>
113112 <Admonition.Row>
114113 <Admonition.Icon />
115115- <View style={[a.flex_1, a.gap_sm]}>
114114+ <Admonition.Content>
116115 <Admonition.Text>
117116 <Trans>
118117 Note: Bluesky is an open and public network. This setting
···131130 <Trans>Learn more about what is public on Bluesky.</Trans>
132131 </InlineLinkText>
133132 </Admonition.Text>
134134- </View>
133133+ </Admonition.Content>
135134 </Admonition.Row>
136135 </Admonition.Outer>
137136 </SettingsList.Item>
+15-3
src/state/feed-feedback.tsx
···28282929export const FEEDBACK_FEEDS = [...PROD_FEEDS, ...STAGING_FEEDS]
30303131-export const DIRECT_FEEDBACK_INTERACTIONS = new Set<
3131+export const THIRD_PARTY_ALLOWED_INTERACTIONS = new Set<
3232 AppBskyFeedDefs.Interaction['event']
3333->(['app.bsky.feed.defs#requestLess', 'app.bsky.feed.defs#requestMore'])
3333+>([
3434+ // These are explicit actions and are therefore fine to send.
3535+ 'app.bsky.feed.defs#requestLess',
3636+ 'app.bsky.feed.defs#requestMore',
3737+ // These can be inferred from the firehose and are therefore fine to send.
3838+ 'app.bsky.feed.defs#interactionLike',
3939+ 'app.bsky.feed.defs#interactionQuote',
4040+ 'app.bsky.feed.defs#interactionReply',
4141+ 'app.bsky.feed.defs#interactionRepost',
4242+ // This can be inferred from pagination requests for everything except the very last page
4343+ // so it is fine to send. It is crucial for third party algorithmic feeds to receive these.
4444+ 'app.bsky.feed.defs#interactionSeen',
4545+])
34463547const logger = Logger.create(Logger.Context.FeedFeedback)
3648···228240 return false
229241 }
230242 const isDiscover = isDiscoverFeed(feed.feedDescriptor)
231231- return isDiscover ? true : DIRECT_FEEDBACK_INTERACTIONS.has(interaction)
243243+ return isDiscover ? true : THIRD_PARTY_ALLOWED_INTERACTIONS.has(interaction)
232244}
233245234246function toString(interaction: AppBskyFeedDefs.Interaction): string {
+74-3
src/view/screens/Storybook/Admonitions.tsx
···11-import {View} from 'react-native'
11+import {Text as RNText, View} from 'react-native'
22+import {msg, Trans} from '@lingui/macro'
33+import {useLingui} from '@lingui/react'
2433-import {atoms as a} from '#/alf'
44-import {Admonition} from '#/components/Admonition'
55+import {atoms as a, useTheme} from '#/alf'
66+import {
77+ Admonition,
88+ Button as AdmonitionButton,
99+ Content as AdmonitionContent,
1010+ Icon as AdmonitionIcon,
1111+ Outer as AdmonitionOuter,
1212+ Row as AdmonitionRow,
1313+ Text as AdmonitionText,
1414+} from '#/components/Admonition'
1515+import {ButtonIcon, ButtonText} from '#/components/Button'
1616+import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as Retry} from '#/components/icons/ArrowRotateCounterClockwise'
1717+import {BellRinging_Filled_Corner0_Rounded as BellRingingFilledIcon} from '#/components/icons/BellRinging'
518import {InlineLinkText} from '#/components/Link'
619import {H1} from '#/components/Typography'
720821export function Admonitions() {
2222+ const {_} = useLingui()
2323+ const t = useTheme()
2424+925 return (
1026 <View style={[a.gap_md]}>
1127 <H1>Admonitions</H1>
···3046 <Admonition type="error">
3147 The quick brown fox jumps over the lazy dog.
3248 </Admonition>
4949+5050+ <AdmonitionOuter type="error">
5151+ <AdmonitionRow>
5252+ <AdmonitionIcon />
5353+ <AdmonitionContent>
5454+ <AdmonitionText>
5555+ <Trans>Something went wrong, please try again</Trans>
5656+ </AdmonitionText>
5757+ </AdmonitionContent>
5858+ <AdmonitionButton
5959+ color="negative_subtle"
6060+ label={_(msg`Retry loading report options`)}
6161+ onPress={() => {}}>
6262+ <ButtonText>
6363+ <Trans>Retry</Trans>
6464+ </ButtonText>
6565+ <ButtonIcon icon={Retry} />
6666+ </AdmonitionButton>
6767+ </AdmonitionRow>
6868+ </AdmonitionOuter>
6969+7070+ <AdmonitionOuter type="tip">
7171+ <AdmonitionRow>
7272+ <AdmonitionIcon />
7373+ <AdmonitionContent>
7474+ <AdmonitionText>
7575+ <Trans>
7676+ Enable notifications for an account by visiting their profile
7777+ and pressing the{' '}
7878+ <RNText style={[a.font_bold, t.atoms.text_contrast_high]}>
7979+ bell icon
8080+ </RNText>{' '}
8181+ <BellRingingFilledIcon
8282+ size="xs"
8383+ style={t.atoms.text_contrast_high}
8484+ />
8585+ .
8686+ </Trans>
8787+ </AdmonitionText>
8888+ <AdmonitionText>
8989+ <Trans>
9090+ If you want to restrict who can receive notifications for your
9191+ account's activity, you can change this in{' '}
9292+ <InlineLinkText
9393+ label={_(msg`Privacy and Security settings`)}
9494+ to={{screen: 'ActivityPrivacySettings'}}
9595+ style={[a.font_bold]}>
9696+ Settings → Privacy and Security
9797+ </InlineLinkText>
9898+ .
9999+ </Trans>
100100+ </AdmonitionText>
101101+ </AdmonitionContent>
102102+ </AdmonitionRow>
103103+ </AdmonitionOuter>
33104 </View>
34105 )
35106}