diff --git a/.prettierignore b/.prettierignore
index 8ccbae2148..e107e129a4 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -15,3 +15,6 @@ android
ios
src/locale/locales
lib/react-compiler-runtime
+bskyweb/static
+coverage
+web-build
diff --git a/bskyweb/cmd/bskyweb/server.go b/bskyweb/cmd/bskyweb/server.go
index 0f49ce5c3a..54c5f075ac 100644
--- a/bskyweb/cmd/bskyweb/server.go
+++ b/bskyweb/cmd/bskyweb/server.go
@@ -255,6 +255,7 @@ func serve(cctx *cli.Context) error {
e.GET("/support/community-guidelines", server.WebGeneric)
e.GET("/support/copyright", server.WebGeneric)
e.GET("/intent/compose", server.WebGeneric)
+ e.GET("/intent/verify-email", server.WebGeneric)
e.GET("/messages", server.WebGeneric)
e.GET("/messages/:conversation", server.WebGeneric)
diff --git a/package.json b/package.json
index 273d8ddb35..e40634685f 100644
--- a/package.json
+++ b/package.json
@@ -68,7 +68,7 @@
"@fortawesome/free-regular-svg-icons": "^6.1.1",
"@fortawesome/free-solid-svg-icons": "^6.1.1",
"@fortawesome/react-native-fontawesome": "^0.3.2",
- "@haileyok/bluesky-bottom-sheet": "^0.1.1-alpha.9",
+ "@haileyok/bluesky-bottom-sheet": "^0.1.1-alpha.11",
"@haileyok/bluesky-video": "0.1.10",
"@lingui/react": "^4.5.0",
"@mattermost/react-native-paste-input": "^0.7.1",
diff --git a/src/Navigation.tsx b/src/Navigation.tsx
index 53e8274d54..323f668b79 100644
--- a/src/Navigation.tsx
+++ b/src/Navigation.tsx
@@ -78,8 +78,8 @@ import {BottomBar} from '#/view/shell/bottom-bar/BottomBar'
import {createNativeStackNavigatorWithAuth} from '#/view/shell/createNativeStackNavigatorWithAuth'
import {SharedPreferencesTesterScreen} from '#/screens/E2E/SharedPreferencesTesterScreen'
import HashtagScreen from '#/screens/Hashtag'
+import {MessagesScreen} from '#/screens/Messages/ChatList'
import {MessagesConversationScreen} from '#/screens/Messages/Conversation'
-import {MessagesScreen} from '#/screens/Messages/List'
import {MessagesSettingsScreen} from '#/screens/Messages/Settings'
import {ModerationScreen} from '#/screens/Moderation'
import {PostLikedByScreen} from '#/screens/Post/PostLikedBy'
diff --git a/src/alf/atoms.ts b/src/alf/atoms.ts
index 0c8eb330d7..2625beda27 100644
--- a/src/alf/atoms.ts
+++ b/src/alf/atoms.ts
@@ -901,4 +901,32 @@ export const atoms = {
hidden: {
display: 'none',
},
+
+ /*
+ * Transition
+ */
+ transition_none: web({
+ transitionProperty: 'none',
+ }),
+ transition_all: web({
+ transitionProperty: 'all',
+ transitionTimingFunction: 'cubic-bezier(0.17, 0.73, 0.14, 1)',
+ transitionDuration: '100ms',
+ }),
+ transition_color: web({
+ transitionProperty:
+ 'color, background-color, border-color, text-decoration-color, fill, stroke',
+ transitionTimingFunction: 'cubic-bezier(0.17, 0.73, 0.14, 1)',
+ transitionDuration: '100ms',
+ }),
+ transition_opacity: web({
+ transitionProperty: 'opacity',
+ transitionTimingFunction: 'cubic-bezier(0.17, 0.73, 0.14, 1)',
+ transitionDuration: '100ms',
+ }),
+ transition_transform: web({
+ transitionProperty: 'transform',
+ transitionTimingFunction: 'cubic-bezier(0.17, 0.73, 0.14, 1)',
+ transitionDuration: '100ms',
+ }),
} as const
diff --git a/src/alf/fonts.ts b/src/alf/fonts.ts
index ae2aaa97a0..54fe7a34e0 100644
--- a/src/alf/fonts.ts
+++ b/src/alf/fonts.ts
@@ -1,3 +1,5 @@
+import {useFonts} from 'expo-font'
+
import {isWeb} from '#/platform/detection'
import {Device, device} from '#/storage'
@@ -63,3 +65,15 @@ export function applyFonts(
*/
style.fontVariant = ['no-contextual']
}
+
+/*
+ * IMPORTANT: This is unused. Expo statically extracts these fonts.
+ *
+ * All used fonts MUST be configured here. Unused fonts can be commented out.
+ */
+export function DO_NOT_USE() {
+ return useFonts({
+ InterVariable: require('../../assets/fonts/inter/InterVariable.ttf'),
+ 'InterVariable-Italic': require('../../assets/fonts/inter/InterVariable-Italic.ttf'),
+ })
+}
diff --git a/src/components/BottomSheetButton.tsx b/src/components/BottomSheetButton.tsx
deleted file mode 100644
index 9eaee55deb..0000000000
--- a/src/components/BottomSheetButton.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react'
-
-import {Button, ButtonProps} from '#/components/Button'
-import {NormalizedRNGHPressable} from '#/components/NormalizedRNGHPressable'
-
-export function BottomSheetButton({children, ...rest}: ButtonProps) {
- return (
-
- )
-}
diff --git a/src/components/Button.tsx b/src/components/Button.tsx
index 98ad1709c4..0c7c1ac46d 100644
--- a/src/components/Button.tsx
+++ b/src/components/Button.tsx
@@ -89,7 +89,7 @@ export type ButtonProps = Pick<
style?: StyleProp
hoverStyle?: StyleProp
children: NonTextElements | ((context: ButtonContext) => NonTextElements)
- Component?: React.ComponentType
+ PressableComponent?: React.ComponentType
}
export type ButtonTextProps = TextProps & VariantProps & {disabled?: boolean}
@@ -117,7 +117,7 @@ export const Button = React.forwardRef(
disabled = false,
style,
hoverStyle: hoverStyleProp,
- Component,
+ PressableComponent,
...rest
},
ref,
@@ -125,11 +125,11 @@ export const Button = React.forwardRef(
// This will pick the correct default pressable to use. If we are inside a dialog, we need to use the RNGH
// pressable so that it is usable inside the dialog.
const {insideDialog} = useDialogContext()
- if (!Component) {
+ if (!PressableComponent) {
if (insideDialog) {
- Component = NormalizedRNGHPressable
+ PressableComponent = NormalizedRNGHPressable
} else {
- Component = Pressable
+ PressableComponent = Pressable
}
}
@@ -464,7 +464,7 @@ export const Button = React.forwardRef(
const flattenedBaseStyles = flatten([baseStyles, style])
return (
- (
{typeof children === 'function' ? children(context) : children}
-
+
)
},
)
diff --git a/src/components/Menu/index.tsx b/src/components/Menu/index.tsx
index 809df96908..bfdcf4099d 100644
--- a/src/components/Menu/index.tsx
+++ b/src/components/Menu/index.tsx
@@ -105,11 +105,7 @@ export function Outer({
export function Item({children, label, style, onPress, ...rest}: ItemProps) {
const t = useTheme()
const {control} = React.useContext(Context)
- const {
- state: focused,
- onIn: onHoverIn,
- onOut: onHoverOut,
- } = useInteractionState()
+ const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState()
const {
state: pressed,
onIn: onPressIn,
@@ -121,9 +117,15 @@ export function Item({children, label, style, onPress, ...rest}: ItemProps) {
{...rest}
accessibilityHint=""
accessibilityLabel={label}
+ onFocus={onFocus}
+ onBlur={onBlur}
onPress={e => {
control?.close()
onPress(e)
+
+ if (!e.defaultPrevented) {
+ control?.close()
+ }
}}
onPressIn={e => {
onPressIn()
@@ -133,8 +135,6 @@ export function Item({children, label, style, onPress, ...rest}: ItemProps) {
onPressOut()
rest.onPressOut?.(e)
}}
- onHoverIn={onHoverIn}
- onHoverOut={onHoverOut}
style={[
a.flex_row,
a.align_center,
diff --git a/src/components/ReportDialog/SubmitView.tsx b/src/components/ReportDialog/SubmitView.tsx
index e323d15042..682e918c2d 100644
--- a/src/components/ReportDialog/SubmitView.tsx
+++ b/src/components/ReportDialog/SubmitView.tsx
@@ -16,6 +16,7 @@ import * as Toggle from '#/components/forms/Toggle'
import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
import {ChevronLeft_Stroke2_Corner0_Rounded as ChevronLeft} from '#/components/icons/Chevron'
import {Loader} from '#/components/Loader'
+import {NormalizedRNGHPressable} from '#/components/NormalizedRNGHPressable'
import {Text} from '#/components/Typography'
import {ReportDialogProps} from './types'
@@ -153,7 +154,8 @@ export function SubmitView({
+ label={title}
+ PressableComponent={NormalizedRNGHPressable}>
)
diff --git a/src/components/dialogs/MutedWords.tsx b/src/components/dialogs/MutedWords.tsx
index daa18f94e7..55fd98d711 100644
--- a/src/components/dialogs/MutedWords.tsx
+++ b/src/components/dialogs/MutedWords.tsx
@@ -30,6 +30,7 @@ import {PageText_Stroke2_Corner0_Rounded as PageText} from '#/components/icons/P
import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
import {Loader} from '#/components/Loader'
+import {NormalizedRNGHPressable} from '#/components/NormalizedRNGHPressable'
import * as Prompt from '#/components/Prompt'
import {Text} from '#/components/Typography'
@@ -168,7 +169,8 @@ function MutedWordsInner() {
+ style={[a.flex_1]}
+ PressableComponent={NormalizedRNGHPressable}>
@@ -183,7 +185,8 @@ function MutedWordsInner() {
+ style={[a.flex_1]}
+ PressableComponent={NormalizedRNGHPressable}>
@@ -207,7 +210,8 @@ function MutedWordsInner() {
+ style={[a.flex_1]}
+ PressableComponent={NormalizedRNGHPressable}>
@@ -222,7 +226,8 @@ function MutedWordsInner() {
+ style={[a.flex_1]}
+ PressableComponent={NormalizedRNGHPressable}>
@@ -256,7 +261,8 @@ function MutedWordsInner() {
+ style={[a.flex_1]}
+ PressableComponent={NormalizedRNGHPressable}>
@@ -272,7 +278,8 @@ function MutedWordsInner() {
+ style={[a.flex_1]}
+ PressableComponent={NormalizedRNGHPressable}>
@@ -302,7 +309,8 @@ function MutedWordsInner() {
name="exclude_following"
style={[a.flex_row, a.justify_between]}
value={excludeFollowing}
- onChange={setExcludeFollowing}>
+ onChange={setExcludeFollowing}
+ PressableComponent={NormalizedRNGHPressable}>
diff --git a/src/components/dialogs/PostInteractionSettingsDialog.tsx b/src/components/dialogs/PostInteractionSettingsDialog.tsx
index 93be838542..cc8b4fc9bf 100644
--- a/src/components/dialogs/PostInteractionSettingsDialog.tsx
+++ b/src/components/dialogs/PostInteractionSettingsDialog.tsx
@@ -37,6 +37,7 @@ import * as Toggle from '#/components/forms/Toggle'
import {Check_Stroke2_Corner0_Rounded as Check} from '#/components/icons/Check'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
import {Loader} from '#/components/Loader'
+import {NormalizedRNGHPressable} from '#/components/NormalizedRNGHPressable'
import {Text} from '#/components/Typography'
export type PostInteractionSettingsFormProps = {
@@ -303,7 +304,8 @@ export function PostInteractionSettingsForm({
}
value={quotesEnabled}
onChange={onChangeQuotesEnabled}
- style={[, a.justify_between, a.pt_xs]}>
+ style={[, a.justify_between, a.pt_xs]}
+ PressableComponent={NormalizedRNGHPressable}>
{quotesEnabled ? (
Quote posts enabled
diff --git a/src/components/dms/MessagesNUX.tsx b/src/components/dms/MessagesNUX.tsx
deleted file mode 100644
index 723696a04d..0000000000
--- a/src/components/dms/MessagesNUX.tsx
+++ /dev/null
@@ -1,174 +0,0 @@
-import React, {useCallback, useEffect} from 'react'
-import {View} from 'react-native'
-import {ChatBskyActorDeclaration} from '@atproto/api'
-import {msg, Trans} from '@lingui/macro'
-import {useLingui} from '@lingui/react'
-
-import {useUpdateActorDeclaration} from '#/state/queries/messages/actor-declaration'
-import {useProfileQuery} from '#/state/queries/profile'
-import {useSession} from '#/state/session'
-import * as Toast from '#/view/com/util/Toast'
-import {atoms as a, useTheme, web} from '#/alf'
-import {Button, ButtonText} from '#/components/Button'
-import * as Dialog from '#/components/Dialog'
-import * as Toggle from '#/components/forms/Toggle'
-import {Message_Stroke2_Corner0_Rounded} from '#/components/icons/Message'
-import {Text} from '#/components/Typography'
-
-export function MessagesNUX() {
- const control = Dialog.useDialogControl()
-
- const {currentAccount} = useSession()
- const {data: profile} = useProfileQuery({
- did: currentAccount!.did,
- })
-
- useEffect(() => {
- if (profile && typeof profile.associated?.chat === 'undefined') {
- const timeout = setTimeout(() => {
- control.open()
- }, 1000)
-
- return () => {
- clearTimeout(timeout)
- }
- }
- }, [profile, control])
-
- if (!profile) return null
-
- return (
-
-
-
- )
-}
-
-function DialogInner({
- chatDeclation,
-}: {
- chatDeclation?: ChatBskyActorDeclaration.Record
-}) {
- const control = Dialog.useDialogContext()
- const {_} = useLingui()
- const t = useTheme()
-
- const [initialized, setInitialzed] = React.useState(false)
- const {mutate: updateDeclaration} = useUpdateActorDeclaration({
- onError: () => {
- Toast.show(_(msg`Failed to update settings`), 'xmark')
- },
- })
-
- const onSelectItem = useCallback(
- (keys: string[]) => {
- const key = keys[0]
- if (!key) return
- updateDeclaration(key as 'all' | 'none' | 'following')
- },
- [updateDeclaration],
- )
-
- useEffect(() => {
- if (!chatDeclation && !initialized) {
- updateDeclaration('following')
- setInitialzed(true)
- }
- }, [chatDeclation, updateDeclaration, initialized])
-
- return (
-
-
-
-
-
- Direct messages are here!
-
-
- Privately chat with other users.
-
-
-
-
-
- Who can message you?
-
-
- You can change this at any time.
-
-
-
-
-
-
-
- Everyone
-
-
-
-
-
- Users I follow
-
-
-
-
-
- No one
-
-
-
-
-
-
-
-
-
-
-
- )
-}
diff --git a/src/components/forms/Toggle.tsx b/src/components/forms/Toggle.tsx
index 6dc387b239..bb5f154df0 100644
--- a/src/components/forms/Toggle.tsx
+++ b/src/components/forms/Toggle.tsx
@@ -1,9 +1,9 @@
import React from 'react'
-import {Pressable, View, ViewStyle} from 'react-native'
+import {Pressable, PressableProps, View, ViewStyle} from 'react-native'
import Animated, {LinearTransition} from 'react-native-reanimated'
+import {HITSLOP_10} from '#/lib/constants'
import {isNative} from '#/platform/detection'
-import {HITSLOP_10} from 'lib/constants'
import {
atoms as a,
flatten,
@@ -68,6 +68,7 @@ export type ItemProps = ViewStyleProp & {
onChange?: (selected: boolean) => void
isInvalid?: boolean
children: ((props: ItemState) => React.ReactNode) | React.ReactNode
+ PressableComponent?: React.ComponentType
}
export function useItemContext() {
@@ -159,6 +160,7 @@ export function Item({
style,
type = 'checkbox',
label,
+ PressableComponent = Pressable,
...rest
}: ItemProps) {
const {
@@ -206,7 +208,7 @@ export function Item({
return (
-
{typeof children === 'function' ? children(state) : children}
-
+
)
}
diff --git a/src/components/intents/VerifyEmailIntentDialog.tsx b/src/components/intents/VerifyEmailIntentDialog.tsx
index 9f3808020a..070ba7c40e 100644
--- a/src/components/intents/VerifyEmailIntentDialog.tsx
+++ b/src/components/intents/VerifyEmailIntentDialog.tsx
@@ -3,11 +3,14 @@ import {View} from 'react-native'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
+import {isNative} from '#/platform/detection'
import {useAgent, useSession} from '#/state/session'
-import {atoms as a} from '#/alf'
-import {Button, ButtonText} from '#/components/Button'
+import {atoms as a, useBreakpoints, useTheme} from '#/alf'
+import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import {DialogControlProps} from '#/components/Dialog'
+import {Divider} from '#/components/Divider'
+import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as Resend} from '#/components/icons/ArrowRotateCounterClockwise'
import {useIntentDialogs} from '#/components/intents/IntentDialogs'
import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
@@ -22,7 +25,9 @@ export function VerifyEmailIntentDialog() {
)
}
-function Inner({control}: {control: DialogControlProps}) {
+function Inner({}: {control: DialogControlProps}) {
+ const t = useTheme()
+ const {gtMobile} = useBreakpoints()
const {_} = useLingui()
const {verifyEmailState: state} = useIntentDialogs()
const [status, setStatus] = React.useState<
@@ -57,43 +62,47 @@ function Inner({control}: {control: DialogControlProps}) {
}
return (
-
-
+
{status === 'loading' ? (
-
+
) : status === 'success' ? (
- <>
-
+
+
Email Verified
-
+
- Thanks, you have successfully verified your email address.
+ Thanks, you have successfully verified your email address. You
+ can close this dialog.
- >
+
) : status === 'failure' ? (
- <>
-
+
+
Invalid Verification Code
-
+
The verification code you have provided is invalid. Please make
sure that you have used the correct verification link or request
a new one.
- >
+
) : (
- <>
-
+
+
Email Resent
-
+
We have sent another verification email to{' '}
@@ -102,38 +111,29 @@ function Inner({control}: {control: DialogControlProps}) {
.
- >
+
)}
- {status !== 'loading' ? (
-
+
+ {status === 'failure' && (
+ <>
+
- {status === 'failure' ? (
-
- ) : null}
-
- ) : null}
+ >
+ )}
+
+
)
}
diff --git a/src/screens/Messages/List/index.tsx b/src/screens/Messages/ChatList.tsx
similarity index 98%
rename from src/screens/Messages/List/index.tsx
rename to src/screens/Messages/ChatList.tsx
index efd717f0b4..9912456e13 100644
--- a/src/screens/Messages/List/index.tsx
+++ b/src/screens/Messages/ChatList.tsx
@@ -22,7 +22,6 @@ import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {DialogControlProps, useDialogControl} from '#/components/Dialog'
import {NewChat} from '#/components/dms/dialogs/NewChatDialog'
-import {MessagesNUX} from '#/components/dms/MessagesNUX'
import {useRefreshOnFocus} from '#/components/hooks/useRefreshOnFocus'
import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as Retry} from '#/components/icons/ArrowRotateCounterClockwise'
import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
@@ -33,7 +32,7 @@ import {Link} from '#/components/Link'
import {ListFooter} from '#/components/Lists'
import {Loader} from '#/components/Loader'
import {Text} from '#/components/Typography'
-import {ChatListItem} from './ChatListItem'
+import {ChatListItem} from './components/ChatListItem'
type Props = NativeStackScreenProps
@@ -151,8 +150,6 @@ export function MessagesScreen({navigation, route}: Props) {
if (conversations.length < 1) {
return (
-
-
{gtMobile ? (
-
{!gtMobile && (
(
return (
-
-
-
-
-
+
+
+
+
+
+
+
)
},
diff --git a/src/view/com/auth/server-input/index.tsx b/src/view/com/auth/server-input/index.tsx
index de7ed6d15b..659ff7f733 100644
--- a/src/view/com/auth/server-input/index.tsx
+++ b/src/view/com/auth/server-input/index.tsx
@@ -12,6 +12,7 @@ import * as TextField from '#/components/forms/TextField'
import * as ToggleButton from '#/components/forms/ToggleButton'
import {Globe_Stroke2_Corner0_Rounded as Globe} from '#/components/icons/Globe'
import {InlineLinkText} from '#/components/Link'
+import {NormalizedRNGHPressable} from '#/components/NormalizedRNGHPressable'
import {P, Text} from '#/components/Typography'
export function ServerInputDialog({
@@ -82,7 +83,10 @@ export function ServerInputDialog({
label="Preferences"
values={fixedOption}
onChange={setFixedOption}>
-
+
{_(msg`Bluesky`)}
@@ -90,7 +94,8 @@ export function ServerInputDialog({
+ label={_(msg`Custom`)}
+ PressableComponent={NormalizedRNGHPressable}>
{_(msg`Custom`)}
diff --git a/src/view/com/post-thread/PostThreadComposePrompt.tsx b/src/view/com/post-thread/PostThreadComposePrompt.tsx
index 67981618e1..5ad4c256dd 100644
--- a/src/view/com/post-thread/PostThreadComposePrompt.tsx
+++ b/src/view/com/post-thread/PostThreadComposePrompt.tsx
@@ -5,12 +5,12 @@ import {useLingui} from '@lingui/react'
import {PressableScale} from '#/lib/custom-animations/PressableScale'
import {useHaptics} from '#/lib/haptics'
-import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries'
import {useHapticsDisabled} from '#/state/preferences'
import {useProfileQuery} from '#/state/queries/profile'
import {useSession} from '#/state/session'
import {UserAvatar} from '#/view/com/util/UserAvatar'
-import {atoms as a, useTheme} from '#/alf'
+import {atoms as a, useBreakpoints, useTheme} from '#/alf'
+import {useInteractionState} from '#/components/hooks/useInteractionState'
import {Text} from '#/components/Typography'
export function PostThreadComposePrompt({
@@ -21,10 +21,15 @@ export function PostThreadComposePrompt({
const {currentAccount} = useSession()
const {data: profile} = useProfileQuery({did: currentAccount?.did})
const {_} = useLingui()
- const {isTabletOrDesktop} = useWebMediaQueries()
+ const {gtMobile} = useBreakpoints()
const t = useTheme()
const playHaptics = useHaptics()
const isHapticsDisabled = useHapticsDisabled()
+ const {
+ state: hovered,
+ onIn: onHoverIn,
+ onOut: onHoverOut,
+ } = useInteractionState()
const onPress = () => {
playHaptics('Light')
@@ -42,13 +47,15 @@ export function PostThreadComposePrompt({
accessibilityLabel={_(msg`Compose reply`)}
accessibilityHint={_(msg`Opens composer`)}
style={[
- {paddingTop: 8, paddingBottom: isTabletOrDesktop ? 8 : 11},
- a.px_sm,
+ gtMobile ? a.py_xs : {paddingTop: 8, paddingBottom: 11},
+ gtMobile ? {paddingLeft: 6, paddingRight: 6} : a.px_sm,
a.border_t,
t.atoms.border_contrast_low,
t.atoms.bg,
]}
- onPress={onPress}>
+ onPress={onPress}
+ onHoverIn={onHoverIn}
+ onHoverOut={onHoverOut}>
diff --git a/src/view/com/util/post-ctrls/RepostButton.tsx b/src/view/com/util/post-ctrls/RepostButton.tsx
index 14c869df8d..896e197b65 100644
--- a/src/view/com/util/post-ctrls/RepostButton.tsx
+++ b/src/view/com/util/post-ctrls/RepostButton.tsx
@@ -156,7 +156,6 @@ let RepostButton = ({