[Sheets] [Pt. 7] Part seven rework, much simplier! (#5582)
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import {Button, ButtonProps} from '#/components/Button'
|
||||||
|
import {NormalizedRNGHPressable} from '#/components/NormalizedRNGHPressable'
|
||||||
|
|
||||||
|
export function BottomSheetButton({children, ...rest}: ButtonProps) {
|
||||||
|
return (
|
||||||
|
<Button {...rest} Component={NormalizedRNGHPressable}>
|
||||||
|
{children}
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,92 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {StackActions, useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {NavigationProp} from '#/lib/routes/types'
|
||||||
|
import {flatten, useTheme} from '#/alf'
|
||||||
|
import {useDialogContext} from '#/components/Dialog'
|
||||||
|
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||||
|
import {InlineLinkProps, useLink} from '#/components/Link'
|
||||||
|
import {NormalizedRNGHPressable} from '#/components/NormalizedRNGHPressable'
|
||||||
|
import {Text} from '#/components/Typography'
|
||||||
|
import {router} from '#/routes'
|
||||||
|
|
||||||
|
export function BottomSheetInlineLinkText({
|
||||||
|
children,
|
||||||
|
to,
|
||||||
|
action = 'push',
|
||||||
|
disableMismatchWarning,
|
||||||
|
style,
|
||||||
|
onPress: outerOnPress,
|
||||||
|
label,
|
||||||
|
shareOnLongPress,
|
||||||
|
disableUnderline,
|
||||||
|
...rest
|
||||||
|
}: InlineLinkProps) {
|
||||||
|
const t = useTheme()
|
||||||
|
const stringChildren = typeof children === 'string'
|
||||||
|
const navigation = useNavigation<NavigationProp>()
|
||||||
|
const dialog = useDialogContext()
|
||||||
|
|
||||||
|
const {href, isExternal, onLongPress} = useLink({
|
||||||
|
to,
|
||||||
|
displayText: stringChildren ? children : '',
|
||||||
|
action,
|
||||||
|
disableMismatchWarning,
|
||||||
|
onPress: outerOnPress,
|
||||||
|
shareOnLongPress,
|
||||||
|
})
|
||||||
|
const {
|
||||||
|
state: pressed,
|
||||||
|
onIn: onPressIn,
|
||||||
|
onOut: onPressOut,
|
||||||
|
} = useInteractionState()
|
||||||
|
|
||||||
|
const onPress = () => {
|
||||||
|
if (isExternal) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.close()
|
||||||
|
|
||||||
|
if (action === 'push') {
|
||||||
|
navigation.dispatch(StackActions.push(...router.matchPath(href)))
|
||||||
|
} else if (action === 'replace') {
|
||||||
|
navigation.dispatch(StackActions.replace(...router.matchPath(href)))
|
||||||
|
} else if (action === 'navigate') {
|
||||||
|
// @ts-ignore
|
||||||
|
navigation.navigate(...router.matchPath(href))
|
||||||
|
} else {
|
||||||
|
throw Error('Unsupported navigator action.')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const flattenedStyle = flatten(style) || {}
|
||||||
|
|
||||||
|
// eslint-disable-next-line bsky-internal/avoid-unwrapped-text
|
||||||
|
return (
|
||||||
|
<NormalizedRNGHPressable
|
||||||
|
onPress={onPress}
|
||||||
|
onLongPress={onLongPress}
|
||||||
|
onPressIn={onPressIn}
|
||||||
|
onPressOut={onPressOut}
|
||||||
|
role="link"
|
||||||
|
accessibilityLabel={label}
|
||||||
|
accessibilityHint=""
|
||||||
|
style={{flexDirection: 'row'}}>
|
||||||
|
<Text
|
||||||
|
{...rest}
|
||||||
|
style={[
|
||||||
|
{color: t.palette.primary_500},
|
||||||
|
pressed &&
|
||||||
|
!disableUnderline && {
|
||||||
|
textDecorationLine: 'underline',
|
||||||
|
textDecorationColor:
|
||||||
|
flattenedStyle.color ?? t.palette.primary_500,
|
||||||
|
},
|
||||||
|
flattenedStyle,
|
||||||
|
]}>
|
||||||
|
{children}
|
||||||
|
</Text>
|
||||||
|
</NormalizedRNGHPressable>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import {Link as BottomSheetLink} from './Link'
|
||||||
|
|
||||||
|
export {BottomSheetLink}
|
||||||
@@ -15,7 +15,9 @@ import {
|
|||||||
import {LinearGradient} from 'expo-linear-gradient'
|
import {LinearGradient} from 'expo-linear-gradient'
|
||||||
|
|
||||||
import {atoms as a, flatten, select, tokens, useTheme, web} from '#/alf'
|
import {atoms as a, flatten, select, tokens, useTheme, web} from '#/alf'
|
||||||
|
import {useDialogContext} from '#/components/Dialog'
|
||||||
import {Props as SVGIconProps} from '#/components/icons/common'
|
import {Props as SVGIconProps} from '#/components/icons/common'
|
||||||
|
import {NormalizedRNGHPressable} from '#/components/NormalizedRNGHPressable'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'gradient'
|
export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'gradient'
|
||||||
@@ -87,6 +89,7 @@ export type ButtonProps = Pick<
|
|||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
hoverStyle?: StyleProp<ViewStyle>
|
hoverStyle?: StyleProp<ViewStyle>
|
||||||
children: NonTextElements | ((context: ButtonContext) => NonTextElements)
|
children: NonTextElements | ((context: ButtonContext) => NonTextElements)
|
||||||
|
Component?: React.ComponentType<PressableProps>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ButtonTextProps = TextProps & VariantProps & {disabled?: boolean}
|
export type ButtonTextProps = TextProps & VariantProps & {disabled?: boolean}
|
||||||
@@ -114,10 +117,22 @@ export const Button = React.forwardRef<View, ButtonProps>(
|
|||||||
disabled = false,
|
disabled = false,
|
||||||
style,
|
style,
|
||||||
hoverStyle: hoverStyleProp,
|
hoverStyle: hoverStyleProp,
|
||||||
|
Component,
|
||||||
...rest
|
...rest
|
||||||
},
|
},
|
||||||
ref,
|
ref,
|
||||||
) => {
|
) => {
|
||||||
|
// 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 (insideDialog) {
|
||||||
|
Component = NormalizedRNGHPressable
|
||||||
|
} else {
|
||||||
|
Component = Pressable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const [state, setState] = React.useState({
|
const [state, setState] = React.useState({
|
||||||
pressed: false,
|
pressed: false,
|
||||||
@@ -449,10 +464,11 @@ export const Button = React.forwardRef<View, ButtonProps>(
|
|||||||
const flattenedBaseStyles = flatten([baseStyles, style])
|
const flattenedBaseStyles = flatten([baseStyles, style])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Pressable
|
<Component
|
||||||
role="button"
|
role="button"
|
||||||
accessibilityHint={undefined} // optional
|
accessibilityHint={undefined} // optional
|
||||||
{...rest}
|
{...rest}
|
||||||
|
// @ts-expect-error ref type
|
||||||
ref={ref}
|
ref={ref}
|
||||||
aria-label={label}
|
aria-label={label}
|
||||||
aria-pressed={state.pressed}
|
aria-pressed={state.pressed}
|
||||||
@@ -500,7 +516,7 @@ export const Button = React.forwardRef<View, ButtonProps>(
|
|||||||
<Context.Provider value={context}>
|
<Context.Provider value={context}>
|
||||||
{typeof children === 'function' ? children(context) : children}
|
{typeof children === 'function' ? children(context) : children}
|
||||||
</Context.Provider>
|
</Context.Provider>
|
||||||
</Pressable>
|
</Component>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
|
|
||||||
export const Context = React.createContext<DialogContextProps>({
|
export const Context = React.createContext<DialogContextProps>({
|
||||||
close: () => {},
|
close: () => {},
|
||||||
|
insideDialog: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
export function useDialogContext() {
|
export function useDialogContext() {
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export function Outer({
|
|||||||
[open, close],
|
[open, close],
|
||||||
)
|
)
|
||||||
|
|
||||||
const context = React.useMemo(() => ({close}), [close])
|
const context = React.useMemo(() => ({close, insideDialog: true}), [close])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Portal>
|
<Portal>
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ export type DialogControlProps = DialogControlRefProps & {
|
|||||||
|
|
||||||
export type DialogContextProps = {
|
export type DialogContextProps = {
|
||||||
close: DialogControlProps['close']
|
close: DialogControlProps['close']
|
||||||
|
insideDialog: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DialogControlOpenOptions = {
|
export type DialogControlOpenOptions = {
|
||||||
|
|||||||
+43
-3
@@ -23,6 +23,7 @@ import {shouldClickOpenNewTab} from '#/platform/urls'
|
|||||||
import {useModalControls} from '#/state/modals'
|
import {useModalControls} from '#/state/modals'
|
||||||
import {useOpenLink} from '#/state/preferences/in-app-browser'
|
import {useOpenLink} from '#/state/preferences/in-app-browser'
|
||||||
import {atoms as a, flatten, TextStyleProp, useTheme, web} from '#/alf'
|
import {atoms as a, flatten, TextStyleProp, useTheme, web} from '#/alf'
|
||||||
|
import {BottomSheetButton} from '#/components/BottomSheetButton'
|
||||||
import {Button, ButtonProps} from '#/components/Button'
|
import {Button, ButtonProps} from '#/components/Button'
|
||||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||||
import {Text, TextProps} from '#/components/Typography'
|
import {Text, TextProps} from '#/components/Typography'
|
||||||
@@ -103,17 +104,17 @@ export function useLink({
|
|||||||
linkRequiresWarning(href, displayText),
|
linkRequiresWarning(href, displayText),
|
||||||
)
|
)
|
||||||
|
|
||||||
if (requiresWarning) {
|
if (isWeb) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requiresWarning) {
|
||||||
openModal({
|
openModal({
|
||||||
name: 'link-warning',
|
name: 'link-warning',
|
||||||
text: displayText,
|
text: displayText,
|
||||||
href: href,
|
href: href,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
if (isExternal) {
|
if (isExternal) {
|
||||||
openLink(href)
|
openLink(href)
|
||||||
} else {
|
} else {
|
||||||
@@ -241,6 +242,45 @@ export function Link({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function BottomSheetLink({
|
||||||
|
children,
|
||||||
|
to,
|
||||||
|
action = 'push',
|
||||||
|
onPress: outerOnPress,
|
||||||
|
download,
|
||||||
|
...rest
|
||||||
|
}: LinkProps) {
|
||||||
|
const {href, isExternal, onPress} = useLink({
|
||||||
|
to,
|
||||||
|
displayText: typeof children === 'string' ? children : '',
|
||||||
|
action,
|
||||||
|
onPress: outerOnPress,
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BottomSheetButton
|
||||||
|
{...rest}
|
||||||
|
style={[a.justify_start, flatten(rest.style)]}
|
||||||
|
role="link"
|
||||||
|
accessibilityRole="link"
|
||||||
|
href={href}
|
||||||
|
onPress={download ? undefined : onPress}
|
||||||
|
{...web({
|
||||||
|
hrefAttrs: {
|
||||||
|
target: download ? undefined : isExternal ? 'blank' : undefined,
|
||||||
|
rel: isExternal ? 'noopener noreferrer' : undefined,
|
||||||
|
download,
|
||||||
|
},
|
||||||
|
dataSet: {
|
||||||
|
// no underline, only `InlineLink` has underlines
|
||||||
|
noUnderline: '1',
|
||||||
|
},
|
||||||
|
})}>
|
||||||
|
{children}
|
||||||
|
</BottomSheetButton>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export type InlineLinkProps = React.PropsWithChildren<
|
export type InlineLinkProps = React.PropsWithChildren<
|
||||||
BaseLinkProps & TextStyleProp & Pick<TextProps, 'selectable'>
|
BaseLinkProps & TextStyleProp & Pick<TextProps, 'selectable'>
|
||||||
> &
|
> &
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {StyleProp, View, ViewStyle} from 'react-native'
|
import {StyleProp, View, ViewStyle} from 'react-native'
|
||||||
import {BlueskyBottomSheetPressable as Pressable} from '@haileyok/bluesky-bottom-sheet'
|
|
||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import flattenReactChildren from 'react-keyed-flatten-children'
|
import flattenReactChildren from 'react-keyed-flatten-children'
|
||||||
@@ -19,6 +18,7 @@ import {
|
|||||||
ItemTextProps,
|
ItemTextProps,
|
||||||
TriggerProps,
|
TriggerProps,
|
||||||
} from '#/components/Menu/types'
|
} from '#/components/Menu/types'
|
||||||
|
import {NormalizedRNGHPressable} from '#/components/NormalizedRNGHPressable'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
@@ -117,7 +117,7 @@ export function Item({children, label, style, onPress, ...rest}: ItemProps) {
|
|||||||
} = useInteractionState()
|
} = useInteractionState()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Pressable
|
<NormalizedRNGHPressable
|
||||||
{...rest}
|
{...rest}
|
||||||
accessibilityHint=""
|
accessibilityHint=""
|
||||||
accessibilityLabel={label}
|
accessibilityLabel={label}
|
||||||
@@ -151,7 +151,7 @@ export function Item({children, label, style, onPress, ...rest}: ItemProps) {
|
|||||||
<ItemContext.Provider value={{disabled: Boolean(rest.disabled)}}>
|
<ItemContext.Provider value={{disabled: Boolean(rest.disabled)}}>
|
||||||
{children}
|
{children}
|
||||||
</ItemContext.Provider>
|
</ItemContext.Provider>
|
||||||
</Pressable>
|
</NormalizedRNGHPressable>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import {
|
|||||||
GestureResponderEvent,
|
GestureResponderEvent,
|
||||||
PressableProps,
|
PressableProps,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {PressableEvent} from 'react-native-gesture-handler/lib/typescript/components/Pressable/PressableProps'
|
|
||||||
import {BueskyBottomSheetPressableProps} from '@haileyok/bluesky-bottom-sheet'
|
|
||||||
|
|
||||||
import {TextStyleProp, ViewStyleProp} from '#/alf'
|
import {TextStyleProp, ViewStyleProp} from '#/alf'
|
||||||
import * as Dialog from '#/components/Dialog'
|
import * as Dialog from '#/components/Dialog'
|
||||||
@@ -89,10 +87,10 @@ export type TriggerChildProps =
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type ItemProps = React.PropsWithChildren<
|
export type ItemProps = React.PropsWithChildren<
|
||||||
Omit<BueskyBottomSheetPressableProps, 'style'> &
|
Omit<PressableProps, 'style'> &
|
||||||
ViewStyleProp & {
|
ViewStyleProp & {
|
||||||
label: string
|
label: string
|
||||||
onPress: (e: PressableEvent | GestureResponderEvent) => void
|
onPress: (e: GestureResponderEvent) => void
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {
|
||||||
|
GestureResponderEvent,
|
||||||
|
MeasureOnSuccessCallback,
|
||||||
|
NativeMouseEvent,
|
||||||
|
NativeSyntheticEvent,
|
||||||
|
PressableProps,
|
||||||
|
} from 'react-native'
|
||||||
|
import {Pressable as BSPressable} from 'react-native-gesture-handler'
|
||||||
|
import {PressableEvent} from 'react-native-gesture-handler/lib/typescript/components/Pressable/PressableProps'
|
||||||
|
|
||||||
|
function pressableEventToGestureResponderEvent(
|
||||||
|
event: PressableEvent,
|
||||||
|
target: NormalizedRNGHPressable,
|
||||||
|
): GestureResponderEvent {
|
||||||
|
return {
|
||||||
|
nativeEvent: {
|
||||||
|
...event.nativeEvent,
|
||||||
|
touches: [],
|
||||||
|
changedTouches: [],
|
||||||
|
identifier: event.nativeEvent.identifier.toString(),
|
||||||
|
target: event.nativeEvent.target.toString(),
|
||||||
|
},
|
||||||
|
// @ts-expect-error
|
||||||
|
target: target,
|
||||||
|
// @ts-expect-error
|
||||||
|
currentTarget: target,
|
||||||
|
preventDefault() {},
|
||||||
|
stopPropagation() {},
|
||||||
|
cancelable: false,
|
||||||
|
defaultPrevented: false,
|
||||||
|
eventPhase: 0,
|
||||||
|
isTrusted: false,
|
||||||
|
bubbles: false,
|
||||||
|
timeStamp: event.nativeEvent.timestamp,
|
||||||
|
isDefaultPrevented(): boolean {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
isPropagationStopped(): boolean {
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
persist() {},
|
||||||
|
type: 'press',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function pressableEventToMouseEvent(
|
||||||
|
event: PressableEvent,
|
||||||
|
target: NormalizedRNGHPressable,
|
||||||
|
): MouseEvent & NativeSyntheticEvent<NativeMouseEvent> {
|
||||||
|
return {
|
||||||
|
...event.nativeEvent,
|
||||||
|
// @ts-expect-error
|
||||||
|
target: target,
|
||||||
|
// @ts-expect-error
|
||||||
|
currentTarget: target,
|
||||||
|
preventDefault() {},
|
||||||
|
stopPropagation() {},
|
||||||
|
cancelable: false,
|
||||||
|
defaultPrevented: false,
|
||||||
|
eventPhase: 0,
|
||||||
|
isTrusted: false,
|
||||||
|
bubbles: false,
|
||||||
|
timeStamp: event.nativeEvent.timestamp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class NormalizedRNGHPressable extends React.Component<PressableProps> {
|
||||||
|
static displayName = 'Pressable'
|
||||||
|
|
||||||
|
measure = (_: MeasureOnSuccessCallback) => {}
|
||||||
|
|
||||||
|
measureLayout = (_: number) => {}
|
||||||
|
|
||||||
|
measureInWindow = (
|
||||||
|
_: (x: number, y: number, width: number, height: number) => void,
|
||||||
|
) => {}
|
||||||
|
|
||||||
|
setNativeProps = (_: PressableProps) => {}
|
||||||
|
|
||||||
|
focus = () => {}
|
||||||
|
|
||||||
|
blur = () => {}
|
||||||
|
|
||||||
|
onPress = (event: PressableEvent) => {
|
||||||
|
if (!this.props.onPress) return
|
||||||
|
this.props.onPress(pressableEventToGestureResponderEvent(event, this))
|
||||||
|
}
|
||||||
|
|
||||||
|
onLongPress = (event: PressableEvent) => {
|
||||||
|
if (!this.props.onLongPress) return
|
||||||
|
this.props.onLongPress(pressableEventToGestureResponderEvent(event, this))
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressIn = (event: PressableEvent) => {
|
||||||
|
if (!this.props.onPressIn) return
|
||||||
|
this.props.onPressIn(pressableEventToGestureResponderEvent(event, this))
|
||||||
|
}
|
||||||
|
|
||||||
|
onPressOut = (event: PressableEvent) => {
|
||||||
|
if (!this.props.onPressOut) return
|
||||||
|
this.props.onPressOut(pressableEventToGestureResponderEvent(event, this))
|
||||||
|
}
|
||||||
|
|
||||||
|
onHoverIn = (event: PressableEvent) => {
|
||||||
|
if (!this.props.onHoverIn) return
|
||||||
|
this.props.onHoverIn(pressableEventToMouseEvent(event, this))
|
||||||
|
}
|
||||||
|
|
||||||
|
onHoverOut = (event: PressableEvent) => {
|
||||||
|
if (!this.props.onHoverOut) return
|
||||||
|
this.props.onHoverOut(pressableEventToMouseEvent(event, this))
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<BSPressable
|
||||||
|
{...this.props}
|
||||||
|
onPress={this.onPress}
|
||||||
|
onLongPress={this.onLongPress}
|
||||||
|
onPressIn={this.onPressIn}
|
||||||
|
onPressOut={this.onPressOut}
|
||||||
|
onHoverIn={this.onHoverIn}
|
||||||
|
onHoverOut={this.onHoverOut}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import {Pressable as NormalizedRNGHPressable} from 'react-native'
|
||||||
|
|
||||||
|
export {NormalizedRNGHPressable}
|
||||||
@@ -4,10 +4,10 @@ import {AppBskyLabelerDefs} from '@atproto/api'
|
|||||||
import {msg, Trans} from '@lingui/macro'
|
import {msg, Trans} from '@lingui/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
export {useDialogControl as useReportDialogControl} from '#/components/Dialog'
|
|
||||||
import {getLabelingServiceTitle} from '#/lib/moderation'
|
import {getLabelingServiceTitle} from '#/lib/moderation'
|
||||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||||
import {Button, useButtonContext} from '#/components/Button'
|
import {BottomSheetButton} from '#/components/BottomSheetButton'
|
||||||
|
import {useButtonContext} from '#/components/Button'
|
||||||
import {Divider} from '#/components/Divider'
|
import {Divider} from '#/components/Divider'
|
||||||
import * as LabelingServiceCard from '#/components/LabelingServiceCard'
|
import * as LabelingServiceCard from '#/components/LabelingServiceCard'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
@@ -39,12 +39,12 @@ export function SelectLabelerView({
|
|||||||
<View style={[a.gap_sm]}>
|
<View style={[a.gap_sm]}>
|
||||||
{props.labelers.map(labeler => {
|
{props.labelers.map(labeler => {
|
||||||
return (
|
return (
|
||||||
<Button
|
<BottomSheetButton
|
||||||
key={labeler.creator.did}
|
key={labeler.creator.did}
|
||||||
label={_(msg`Send report to ${labeler.creator.displayName}`)}
|
label={_(msg`Send report to ${labeler.creator.displayName}`)}
|
||||||
onPress={() => props.onSelectLabeler(labeler.creator.did)}>
|
onPress={() => props.onSelectLabeler(labeler.creator.did)}>
|
||||||
<LabelerButton labeler={labeler} />
|
<LabelerButton labeler={labeler} />
|
||||||
</Button>
|
</BottomSheetButton>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {msg, Trans} from '@lingui/macro'
|
|||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
import {ReportOption, useReportOptions} from '#/lib/moderation/useReportOptions'
|
import {ReportOption, useReportOptions} from '#/lib/moderation/useReportOptions'
|
||||||
import {Link} from '#/components/Link'
|
import {BottomSheetLink} from '#/components/Link'
|
||||||
import {DMCA_LINK} from '#/components/ReportDialog/const'
|
import {DMCA_LINK} from '#/components/ReportDialog/const'
|
||||||
export {useDialogControl as useReportDialogControl} from '#/components/Dialog'
|
export {useDialogControl as useReportDialogControl} from '#/components/Dialog'
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ export function SelectReportOptionView({
|
|||||||
]}>
|
]}>
|
||||||
<Trans>Need to report a copyright violation?</Trans>
|
<Trans>Need to report a copyright violation?</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
<Link
|
<BottomSheetLink
|
||||||
to={DMCA_LINK}
|
to={DMCA_LINK}
|
||||||
label={_(msg`View details for reporting a copyright violation`)}
|
label={_(msg`View details for reporting a copyright violation`)}
|
||||||
size="small"
|
size="small"
|
||||||
@@ -139,7 +139,7 @@ export function SelectReportOptionView({
|
|||||||
<Trans>View details</Trans>
|
<Trans>View details</Trans>
|
||||||
</ButtonText>
|
</ButtonText>
|
||||||
<ButtonIcon position="right" icon={SquareArrowTopRight} />
|
<ButtonIcon position="right" icon={SquareArrowTopRight} />
|
||||||
</Link>
|
</BottomSheetLink>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ import {logger} from '#/logger'
|
|||||||
import {useAgent, useSession} from '#/state/session'
|
import {useAgent, useSession} from '#/state/session'
|
||||||
import * as Toast from '#/view/com/util/Toast'
|
import * as Toast from '#/view/com/util/Toast'
|
||||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {BottomSheetButton} from '#/components/BottomSheetButton'
|
||||||
|
import {BottomSheetInlineLinkText} from '#/components/BottomSheetLink'
|
||||||
|
import {ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
import * as Dialog from '#/components/Dialog'
|
import * as Dialog from '#/components/Dialog'
|
||||||
import {InlineLinkText} from '#/components/Link'
|
import {InlineLinkText} from '#/components/Link'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
@@ -139,7 +141,7 @@ function Label({
|
|||||||
</View>
|
</View>
|
||||||
{!isSelfLabel && (
|
{!isSelfLabel && (
|
||||||
<View>
|
<View>
|
||||||
<Button
|
<BottomSheetButton
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
size="small"
|
size="small"
|
||||||
@@ -148,7 +150,7 @@ function Label({
|
|||||||
<ButtonText>
|
<ButtonText>
|
||||||
<Trans>Appeal</Trans>
|
<Trans>Appeal</Trans>
|
||||||
</ButtonText>
|
</ButtonText>
|
||||||
</Button>
|
</BottomSheetButton>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
@@ -156,23 +158,25 @@ function Label({
|
|||||||
<Divider />
|
<Divider />
|
||||||
|
|
||||||
<View style={[a.px_md, a.py_sm, t.atoms.bg_contrast_25]}>
|
<View style={[a.px_md, a.py_sm, t.atoms.bg_contrast_25]}>
|
||||||
<Text style={[t.atoms.text_contrast_medium]}>
|
{isSelfLabel ? (
|
||||||
{isSelfLabel ? (
|
<Text style={[t.atoms.text_contrast_medium]}>
|
||||||
<Trans>This label was applied by you.</Trans>
|
<Trans>This label was applied by you.</Trans>
|
||||||
) : (
|
</Text>
|
||||||
<Trans>
|
) : (
|
||||||
Source:{' '}
|
<View style={{flexDirection: 'row'}}>
|
||||||
<InlineLinkText
|
<Text style={[t.atoms.text_contrast_medium]}>
|
||||||
label={sourceName}
|
<Trans>Source: </Trans>{' '}
|
||||||
to={makeProfileLink(
|
</Text>
|
||||||
labeler ? labeler.creator : {did: label.src, handle: ''},
|
<BottomSheetInlineLinkText
|
||||||
)}
|
label={sourceName}
|
||||||
onPress={() => control.close()}>
|
to={makeProfileLink(
|
||||||
{sourceName}
|
labeler ? labeler.creator : {did: label.src, handle: ''},
|
||||||
</InlineLinkText>
|
)}
|
||||||
</Trans>
|
onPress={() => control.close()}>
|
||||||
)}
|
{sourceName}
|
||||||
</Text>
|
</BottomSheetInlineLinkText>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
@@ -275,7 +279,7 @@ function AppealForm({
|
|||||||
? [a.flex_row, a.justify_between]
|
? [a.flex_row, a.justify_between]
|
||||||
: [{flexDirection: 'column-reverse'}, a.gap_sm]
|
: [{flexDirection: 'column-reverse'}, a.gap_sm]
|
||||||
}>
|
}>
|
||||||
<Button
|
<BottomSheetButton
|
||||||
testID="backBtn"
|
testID="backBtn"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="secondary"
|
color="secondary"
|
||||||
@@ -283,8 +287,8 @@ function AppealForm({
|
|||||||
onPress={onPressBack}
|
onPress={onPressBack}
|
||||||
label={_(msg`Back`)}>
|
label={_(msg`Back`)}>
|
||||||
<ButtonText>{_(msg`Back`)}</ButtonText>
|
<ButtonText>{_(msg`Back`)}</ButtonText>
|
||||||
</Button>
|
</BottomSheetButton>
|
||||||
<Button
|
<BottomSheetButton
|
||||||
testID="submitBtn"
|
testID="submitBtn"
|
||||||
variant="solid"
|
variant="solid"
|
||||||
color="primary"
|
color="primary"
|
||||||
@@ -293,7 +297,7 @@ function AppealForm({
|
|||||||
label={_(msg`Submit`)}>
|
label={_(msg`Submit`)}>
|
||||||
<ButtonText>{_(msg`Submit`)}</ButtonText>
|
<ButtonText>{_(msg`Submit`)}</ButtonText>
|
||||||
{isPending && <ButtonIcon icon={Loader} />}
|
{isPending && <ButtonIcon icon={Loader} />}
|
||||||
</Button>
|
</BottomSheetButton>
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user