Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] main from bluesky-social:main #107

Merged
merged 9 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bsky.app",
"version": "1.96.1",
"version": "1.96.2",
"private": true,
"engines": {
"node": ">=20"
Expand Down Expand Up @@ -69,7 +69,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-video": "0.2.4",
"@haileyok/bluesky-video": "0.2.5",
"@ipld/dag-cbor": "^9.2.0",
"@lingui/react": "^4.14.1",
"@mattermost/react-native-paste-input": "^0.7.1",
Expand Down
19 changes: 19 additions & 0 deletions patches/expo-media-library+17.0.3.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
diff --git a/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt b/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
index b928b8f..7175cf6 100644
--- a/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
+++ b/node_modules/expo-media-library/android/src/main/java/expo/modules/medialibrary/MediaLibraryModule.kt
@@ -99,12 +99,12 @@ class MediaLibraryModule : Module() {
}

AsyncFunction("createAssetAsync") { localUri: String, promise: Promise ->
- throwUnlessPermissionsGranted {
+ //throwUnlessPermissionsGranted {
withModuleScope(promise) {
CreateAsset(context, localUri, promise)
.execute()
}
- }
+ //}
}

AsyncFunction("addAssetsToAlbumAsync") { assetsId: List<String>, albumId: String, copyToAlbum: Boolean, promise: Promise ->
28 changes: 22 additions & 6 deletions src/screens/Messages/components/MessageInput.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {Pressable, StyleSheet, View} from 'react-native'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import Graphemer from 'graphemer'
import {flushSync} from 'react-dom'
import TextareaAutosize from 'react-textarea-autosize'

import {isSafari, isTouchDevice} from '#/lib/browser'
Expand Down Expand Up @@ -106,11 +107,19 @@ export function MessageInput({

const onEmojiInserted = React.useCallback(
(emoji: Emoji) => {
const position = textAreaRef.current?.selectionStart ?? 0
setMessage(
message =>
message.slice(0, position) + emoji.native + message.slice(position),
)
if (!textAreaRef.current) {
return
}
const position = textAreaRef.current.selectionStart ?? 0
textAreaRef.current.focus()
flushSync(() => {
setMessage(
message =>
message.slice(0, position) + emoji.native + message.slice(position),
)
})
textAreaRef.current.selectionStart = position + emoji.native.length
textAreaRef.current.selectionEnd = position + emoji.native.length
},
[setMessage],
)
Expand Down Expand Up @@ -148,7 +157,14 @@ export function MessageInput({
<Button
onPress={e => {
e.currentTarget.measure((_fx, _fy, _width, _height, px, py) => {
openEmojiPicker?.({top: py, left: px, right: px, bottom: py})
openEmojiPicker?.({
top: py,
left: px,
right: px,
bottom: py,
nextFocusRef:
textAreaRef as unknown as React.MutableRefObject<HTMLElement>,
})
})
}}
style={[
Expand Down
2 changes: 1 addition & 1 deletion src/screens/Messages/components/MessagesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export function MessagesList({
const [emojiPickerState, setEmojiPickerState] =
React.useState<EmojiPickerState>({
isOpen: false,
pos: {top: 0, left: 0, right: 0, bottom: 0},
pos: {top: 0, left: 0, right: 0, bottom: 0, nextFocusRef: null},
})

// We need to keep track of when the scroll offset is at the bottom of the list to know when to scroll as new items
Expand Down
3 changes: 2 additions & 1 deletion src/state/shell/composer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
import {postUriToRelativePath, toBskyAppUrl} from '#/lib/strings/url-helpers'
import {purgeTemporaryImageFiles} from '#/state/gallery'
import {precacheResolveLinkQuery} from '#/state/queries/resolve-link'
import type {EmojiPickerPosition} from '#/view/com/composer/text-input/web/EmojiPicker.web'
import * as Toast from '#/view/com/util/Toast'

export interface ComposerOptsPostRef {
Expand All @@ -29,7 +30,7 @@ export interface ComposerOpts {
onPost?: (postUri: string | undefined) => void
quote?: AppBskyFeedDefs.PostView
mention?: string // handle of user to mention
openEmojiPicker?: (pos: DOMRect | undefined) => void
openEmojiPicker?: (pos: EmojiPickerPosition | undefined) => void
text?: string
imageUris?: {uri: string; width: number; height: number; altText?: string}[]
videoUri?: {uri: string; width: number; height: number}
Expand Down
9 changes: 8 additions & 1 deletion src/view/com/composer/Composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,14 @@ export const ComposePost = ({
}

const onEmojiButtonPress = useCallback(() => {
openEmojiPicker?.(textInput.current?.getCursorPosition())
const rect = textInput.current?.getCursorPosition()
if (rect) {
openEmojiPicker?.({
...rect,
nextFocusRef:
textInput as unknown as React.MutableRefObject<HTMLElement>,
})
}
}, [openEmojiPicker])

const scrollViewRef = useAnimatedRef<Animated.ScrollView>()
Expand Down
87 changes: 51 additions & 36 deletions src/view/com/composer/text-input/web/EmojiPicker.web.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import React from 'react'
import {
GestureResponderEvent,
TouchableWithoutFeedback,
useWindowDimensions,
View,
} from 'react-native'
import {Pressable, useWindowDimensions, View} from 'react-native'
import Picker from '@emoji-mart/react'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {DismissableLayer} from '@radix-ui/react-dismissable-layer'
import {FocusScope} from '@radix-ui/react-focus-scope'

import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter'
import {atoms as a} from '#/alf'
import {atoms as a, flatten} from '#/alf'
import {Portal} from '#/components/Portal'

const HEIGHT_OFFSET = 40
Expand All @@ -33,6 +31,7 @@ export interface EmojiPickerPosition {
left: number
right: number
bottom: number
nextFocusRef: React.MutableRefObject<HTMLElement> | null
}

export interface EmojiPickerState {
Expand All @@ -51,6 +50,7 @@ interface IProps {
}

export function EmojiPicker({state, close, pinToTop}: IProps) {
const {_} = useLingui()
const {height, width} = useWindowDimensions()

const isShiftDown = React.useRef(false)
Expand Down Expand Up @@ -119,48 +119,63 @@ export function EmojiPicker({state, close, pinToTop}: IProps) {

if (!state.isOpen) return null

const onPressBackdrop = (e: GestureResponderEvent) => {
// @ts-ignore web only
if (e.nativeEvent?.pointerId === -1) return
close()
}

return (
<Portal>
<TouchableWithoutFeedback
accessibilityRole="button"
onPress={onPressBackdrop}
accessibilityViewIsModal>
<FocusScope
loop
trapped
onUnmountAutoFocus={e => {
const nextFocusRef = state.pos.nextFocusRef
const node = nextFocusRef?.current
if (node) {
e.preventDefault()
node.focus()
}
}}>
<Pressable
accessible
accessibilityLabel={_(msg`Close emoji picker`)}
accessibilityHint={_(msg`Tap to close the emoji picker`)}
onPress={close}
style={[a.fixed, a.inset_0]}
/>

<View
style={[
style={flatten([
a.fixed,
a.w_full,
a.h_full,
a.align_center,
a.z_10,
{
top: 0,
left: 0,
right: 0,
},
]}>
{/* eslint-disable-next-line react-native-a11y/has-valid-accessibility-descriptors */}
<TouchableWithoutFeedback onPress={e => e.stopPropagation()}>
<View style={[{position: 'absolute'}, position]}>
<DismissableLayer
onFocusOutside={evt => evt.preventDefault()}
onDismiss={close}>
<Picker
data={async () => {
return (await import('./EmojiPickerData.json')).default
}}
onEmojiSelect={onInsert}
autoFocus={true}
/>
</DismissableLayer>
</View>
</TouchableWithoutFeedback>
])}>
<View style={[{position: 'absolute'}, position]}>
<DismissableLayer
onFocusOutside={evt => evt.preventDefault()}
onDismiss={close}>
<Picker
data={async () => {
return (await import('./EmojiPickerData.json')).default
}}
onEmojiSelect={onInsert}
autoFocus={true}
/>
</DismissableLayer>
</View>
</View>
</TouchableWithoutFeedback>

<Pressable
accessible
accessibilityLabel={_(msg`Close emoji picker`)}
accessibilityHint={_(msg`Tap to close the emoji picker`)}
onPress={close}
style={[a.fixed, a.inset_0]}
/>
</FocusScope>
</Portal>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,8 @@
* LICENSE file in the root directory of this source tree.
*
*/
import {
SafeAreaView,
StyleSheet,
TouchableOpacity,
ViewStyle,
} from 'react-native'
import {StyleSheet, TouchableOpacity, ViewStyle} from 'react-native'
import {SafeAreaView} from 'react-native-safe-area-context'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'
Expand Down
4 changes: 2 additions & 2 deletions src/view/com/lightbox/ImageViewing/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ type Rect = {x: number; y: number; width: number; height: number}

const PIXEL_RATIO = PixelRatio.get()
const EDGES =
Platform.OS === 'android'
Platform.OS === 'android' && Platform.Version < 35
? (['top', 'bottom', 'left', 'right'] satisfies Edge[])
: (['left', 'right'] satisfies Edge[]) // iOS, so no top/bottom safe area
: (['left', 'right'] satisfies Edge[]) // iOS or Android 15+, so no top/bottom safe area

const SLOW_SPRING: WithSpringConfig = {
mass: isIOS ? 1.25 : 0.75,
Expand Down
34 changes: 22 additions & 12 deletions src/view/com/lists/MyLists.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
ViewStyle,
} from 'react-native'
import {AppBskyGraphDefs as GraphDefs} from '@atproto/api'
import {Trans} from '@lingui/macro'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'

import {usePalette} from '#/lib/hooks/usePalette'
import {cleanError} from '#/lib/strings/errors'
Expand Down Expand Up @@ -42,6 +43,7 @@ export function MyLists({
}) {
const pal = usePalette('default')
const t = useTheme()
const {_} = useLingui()
const moderationOpts = useModerationOpts()
const [isPTRing, setIsPTRing] = React.useState(false)
const {data, isFetching, isFetched, isError, error, refetch} =
Expand All @@ -63,6 +65,23 @@ export function MyLists({
return items
}, [isError, isEmpty, isFetched, isFetching, moderationOpts, data])

let emptyText
switch (filter) {
case 'curate':
emptyText = _(
msg`Public, sharable lists which can be used to drive feeds.`,
)
break
case 'mod':
emptyText = _(
msg`Public, sharable lists of users to mute or block in bulk.`,
)
break
default:
emptyText = _(msg`You have no lists.`)
break
}

// events
// =

Expand Down Expand Up @@ -108,16 +127,7 @@ export function MyLists({
maxWidth: 200,
},
]}>
{filter === 'curate' && (
<Trans>
Public, sharable lists which can be used to drive feeds.
</Trans>
)}
{filter === 'mod' && (
<Trans>
Public, sharable lists of users to mute or block in bulk.
</Trans>
)}
{emptyText}
</Text>
</View>
)
Expand Down Expand Up @@ -149,7 +159,7 @@ export function MyLists({
</View>
)
},
[t, renderItem, error, onRefresh, filter],
[t, renderItem, error, onRefresh, emptyText],
)

if (inline) {
Expand Down
4 changes: 4 additions & 0 deletions src/view/com/util/forms/NativeDropdown.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ export function NativeDropdown({
const menuRef = React.useRef<HTMLDivElement>(null)

React.useEffect(() => {
if (!open) {
return
}

function clickHandler(e: MouseEvent) {
const t = e.target

Expand Down
Loading
Loading