minor styling fixes
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import {View} from 'react-native'
|
||||
import {Modal, Pressable, View} from 'react-native'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {atoms as a, useTheme, web} from '#/alf'
|
||||
import {Button, ButtonText} from '#/components/Button'
|
||||
import * as Dialog from '#/components/Dialog'
|
||||
import {Robot_Filled_Corner2_Rounded as RobotIcon} from '#/components/icons/Robot'
|
||||
@@ -12,58 +12,132 @@ import {navigate} from '#/Navigation'
|
||||
|
||||
export function BotAccountInfoDialog({
|
||||
control,
|
||||
isMe,
|
||||
}: {
|
||||
control: Dialog.DialogControlProps
|
||||
isMe?: boolean
|
||||
}) {
|
||||
return (
|
||||
<Dialog.Outer control={control}>
|
||||
<Dialog.Handle />
|
||||
<BotAccountInfoDialogInner control={control} isMe={isMe} />
|
||||
<BotAccountInfoDialogInner control={control} />
|
||||
</Dialog.Outer>
|
||||
)
|
||||
}
|
||||
|
||||
function BotAccountInfoDialogInner({
|
||||
control,
|
||||
isMe,
|
||||
export function BotAccountOwnAlert({
|
||||
visible,
|
||||
onClose,
|
||||
}: {
|
||||
control: Dialog.DialogControlProps
|
||||
isMe?: boolean
|
||||
visible: boolean
|
||||
onClose: (cb?: () => void) => void
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
const t = useTheme()
|
||||
|
||||
return (
|
||||
<Dialog.ScrollableInner label={_(msg`Automated account`)}>
|
||||
<View style={[a.align_center, a.gap_2xl, a.py_md]}>
|
||||
<View style={[t.atoms.shadow_sm]}>
|
||||
<RobotIcon width={48} fill={t.atoms.text_contrast_medium.color} />
|
||||
</View>
|
||||
<Text style={[a.text_lg, a.text_center, a.font_semi_bold]}>
|
||||
{isMe ? (
|
||||
<Modal
|
||||
visible={visible}
|
||||
transparent
|
||||
animationType="fade"
|
||||
onRequestClose={() => onClose()}
|
||||
accessibilityLabel={_(msg`Automated account`)}
|
||||
accessibilityViewIsModal>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={_(msg`Close`)}
|
||||
onPress={() => onClose()}
|
||||
style={[
|
||||
a.flex_1,
|
||||
a.justify_center,
|
||||
a.align_center,
|
||||
a.px_xl,
|
||||
{backgroundColor: 'rgba(0,0,0,0.5)'},
|
||||
]}>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
onPress={e => e.stopPropagation()}
|
||||
style={[
|
||||
t.atoms.bg,
|
||||
a.w_full,
|
||||
{borderRadius: 48},
|
||||
a.p_2xl,
|
||||
{maxWidth: 280},
|
||||
]}>
|
||||
<View style={[a.align_center, a.gap_md]}>
|
||||
<View style={[t.atoms.shadow_sm]}>
|
||||
<RobotIcon width={48} fill={t.atoms.text_contrast_medium.color} />
|
||||
</View>
|
||||
|
||||
<Text style={[a.text_md, a.text_center, a.py_sm]}>
|
||||
<Trans>
|
||||
You have marked this account as automated. You can remove it at
|
||||
any time from your account settings.
|
||||
</Trans>
|
||||
</Text>
|
||||
|
||||
<Button
|
||||
label={_(msg`Okay`)}
|
||||
onPress={() => onClose()}
|
||||
color="primary"
|
||||
size="large"
|
||||
style={[a.w_full]}>
|
||||
<ButtonText>
|
||||
<Trans>Okay</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
<Button
|
||||
label={_(msg`Open settings`)}
|
||||
onPress={() => {
|
||||
onClose(() => {
|
||||
navigate('AutomationLabelSettings')
|
||||
})
|
||||
}}
|
||||
color="secondary"
|
||||
size="large"
|
||||
style={[a.w_full]}>
|
||||
<ButtonText>
|
||||
<Trans>Open settings</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
</View>
|
||||
</Pressable>
|
||||
</Pressable>
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export function BotAccountOwnAlertWeb({
|
||||
control,
|
||||
}: {
|
||||
control: Dialog.DialogControlProps
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
const t = useTheme()
|
||||
|
||||
return (
|
||||
<Dialog.Outer control={control} webOptions={{alignCenter: true}}>
|
||||
<Dialog.ScrollableInner
|
||||
label={_(msg`Automated account`)}
|
||||
style={web([{maxWidth: 320, borderRadius: 36}])}>
|
||||
<View style={[a.align_center, a.gap_2xl, a.py_md]}>
|
||||
<View style={[t.atoms.shadow_sm]}>
|
||||
<RobotIcon width={48} fill={t.atoms.text_contrast_medium.color} />
|
||||
</View>
|
||||
<Text style={[a.text_md, a.text_center]}>
|
||||
<Trans>
|
||||
You have marked this account as automated. You can remove it at
|
||||
any time from your account settings.
|
||||
</Trans>
|
||||
) : (
|
||||
<Trans>
|
||||
This account has been marked as automated by its owner
|
||||
</Trans>
|
||||
)}
|
||||
</Text>
|
||||
<Button
|
||||
label={_(msg`Okay`)}
|
||||
onPress={() => control.close()}
|
||||
color="primary"
|
||||
size="large"
|
||||
style={[a.w_full]}>
|
||||
<ButtonText>
|
||||
<Trans>Okay</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
{isMe && (
|
||||
</Text>
|
||||
<Button
|
||||
label={_(msg`Okay`)}
|
||||
onPress={() => control.close()}
|
||||
color="primary"
|
||||
size="large"
|
||||
style={[a.w_full]}>
|
||||
<ButtonText>
|
||||
<Trans>Okay</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
<Button
|
||||
label={_(msg`Open settings`)}
|
||||
onPress={() => {
|
||||
@@ -79,7 +153,40 @@ function BotAccountInfoDialogInner({
|
||||
<Trans>Open settings</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
)}
|
||||
</View>
|
||||
<Dialog.Close />
|
||||
</Dialog.ScrollableInner>
|
||||
</Dialog.Outer>
|
||||
)
|
||||
}
|
||||
|
||||
function BotAccountInfoDialogInner({
|
||||
control,
|
||||
}: {
|
||||
control: Dialog.DialogControlProps
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
const t = useTheme()
|
||||
|
||||
return (
|
||||
<Dialog.ScrollableInner label={_(msg`Automated account`)}>
|
||||
<View style={[a.align_center, a.gap_2xl, a.py_md]}>
|
||||
<View style={[t.atoms.shadow_sm]}>
|
||||
<RobotIcon width={48} fill={t.atoms.text_contrast_medium.color} />
|
||||
</View>
|
||||
<Text style={[a.text_lg, a.text_center, a.font_semi_bold]}>
|
||||
<Trans>This account has been marked as automated by its owner</Trans>
|
||||
</Text>
|
||||
<Button
|
||||
label={_(msg`Okay`)}
|
||||
onPress={() => control.close()}
|
||||
color="primary"
|
||||
size="large"
|
||||
style={[a.w_full]}>
|
||||
<ButtonText>
|
||||
<Trans>Okay</Trans>
|
||||
</ButtonText>
|
||||
</Button>
|
||||
</View>
|
||||
<Dialog.Close />
|
||||
</Dialog.ScrollableInner>
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
import {useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type ComAtprotoLabelDefs} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {isBotAccount} from '#/lib/bots'
|
||||
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
|
||||
import {BotAccountInfoDialog} from '#/components/BotAccountInfoDialog'
|
||||
import {
|
||||
BotAccountInfoDialog,
|
||||
BotAccountOwnAlert,
|
||||
BotAccountOwnAlertWeb,
|
||||
} from '#/components/BotAccountInfoDialog'
|
||||
import {Button} from '#/components/Button'
|
||||
import {useDialogControl} from '#/components/Dialog'
|
||||
import {Robot_Filled_Corner2_Rounded as RobotIcon} from '#/components/icons/Robot'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
|
||||
export function BotBadge({
|
||||
profile,
|
||||
@@ -47,6 +53,7 @@ export function BotBadgeButton({
|
||||
const {_} = useLingui()
|
||||
const {gtPhone} = useBreakpoints()
|
||||
const control = useDialogControl()
|
||||
const [alertVisible, setAlertVisible] = useState(false)
|
||||
|
||||
if (!isBotAccount(profile)) {
|
||||
return null
|
||||
@@ -59,6 +66,8 @@ export function BotBadgeButton({
|
||||
dimensions = 14
|
||||
}
|
||||
|
||||
const useNativeAlert = isMe && IS_NATIVE
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
@@ -67,7 +76,11 @@ export function BotBadgeButton({
|
||||
onPress={evt => {
|
||||
evt.preventDefault()
|
||||
ax.metric('bot:badge:click', {})
|
||||
control.open()
|
||||
if (useNativeAlert) {
|
||||
setAlertVisible(true)
|
||||
} else {
|
||||
control.open()
|
||||
}
|
||||
}}>
|
||||
{({hovered}) => (
|
||||
<View
|
||||
@@ -88,7 +101,19 @@ export function BotBadgeButton({
|
||||
</View>
|
||||
)}
|
||||
</Button>
|
||||
<BotAccountInfoDialog control={control} isMe={isMe} />
|
||||
{useNativeAlert ? (
|
||||
<BotAccountOwnAlert
|
||||
visible={alertVisible}
|
||||
onClose={cb => {
|
||||
setAlertVisible(false)
|
||||
cb?.()
|
||||
}}
|
||||
/>
|
||||
) : isMe ? (
|
||||
<BotAccountOwnAlertWeb control={control} />
|
||||
) : (
|
||||
<BotAccountInfoDialog control={control} />
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -273,7 +273,14 @@ function InlineNameAndHandle({
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
<BotBadge profile={profile} />
|
||||
<View
|
||||
style={[
|
||||
a.pl_2xs,
|
||||
a.self_center,
|
||||
{marginTop: platform({default: 0, android: -1})},
|
||||
]}>
|
||||
<BotBadge profile={profile} />
|
||||
</View>
|
||||
<Text
|
||||
emoji
|
||||
style={[
|
||||
@@ -328,7 +335,9 @@ export function Name({
|
||||
/>
|
||||
</View>
|
||||
)}
|
||||
<BotBadge profile={profile} />
|
||||
<View style={[a.pl_xs]}>
|
||||
<BotBadge profile={profile} />
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type $Typed, ComAtprotoLabelDefs} from '@atproto/api'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
@@ -8,6 +9,8 @@ import {type NativeStackScreenProps} from '@react-navigation/native-stack'
|
||||
|
||||
import {useAnalytics} from '#/analytics'
|
||||
import {type CommonNavigatorParams} from '#/lib/routes/types'
|
||||
import {RQKEY_ROOT as POST_FEED_RQKEY_ROOT} from '#/state/queries/post-feed'
|
||||
import {postThreadQueryKeyRoot} from '#/state/queries/usePostThread/types'
|
||||
import {
|
||||
useProfileQuery,
|
||||
useProfileUpdateMutation,
|
||||
@@ -32,6 +35,7 @@ export function AutomationLabelSettingsScreen({}: Props) {
|
||||
const t = useTheme()
|
||||
const ax = useAnalytics()
|
||||
const {_} = useLingui()
|
||||
const queryClient = useQueryClient()
|
||||
const {currentAccount} = useSession()
|
||||
const {data: profile} = useProfileQuery({did: currentAccount?.did})
|
||||
const updateProfile = useProfileUpdateMutation()
|
||||
@@ -48,41 +52,50 @@ export function AutomationLabelSettingsScreen({}: Props) {
|
||||
}
|
||||
let wasAdded = false
|
||||
ax.metric('bot:label:toggle', {state: isBotLabeled ? 'remove' : 'add'})
|
||||
updateProfile.mutate({
|
||||
profile,
|
||||
updates: existing => {
|
||||
const labels: $Typed<ComAtprotoLabelDefs.SelfLabels> = bsky.validate(
|
||||
existing.labels,
|
||||
ComAtprotoLabelDefs.validateSelfLabels,
|
||||
)
|
||||
? existing.labels
|
||||
: {
|
||||
$type: 'com.atproto.label.defs#selfLabels',
|
||||
values: [],
|
||||
}
|
||||
updateProfile.mutate(
|
||||
{
|
||||
profile,
|
||||
updates: existing => {
|
||||
const labels: $Typed<ComAtprotoLabelDefs.SelfLabels> =
|
||||
bsky.validate(
|
||||
existing.labels,
|
||||
ComAtprotoLabelDefs.validateSelfLabels,
|
||||
)
|
||||
? existing.labels
|
||||
: {
|
||||
$type: 'com.atproto.label.defs#selfLabels',
|
||||
values: [],
|
||||
}
|
||||
|
||||
const hasLabel = labels.values.some(l => l.val === 'bot')
|
||||
if (hasLabel) {
|
||||
wasAdded = false
|
||||
labels.values = labels.values.filter(l => l.val !== 'bot')
|
||||
} else {
|
||||
wasAdded = true
|
||||
labels.values.push({val: 'bot'})
|
||||
}
|
||||
const hasLabel = labels.values.some(l => l.val === 'bot')
|
||||
if (hasLabel) {
|
||||
wasAdded = false
|
||||
labels.values = labels.values.filter(l => l.val !== 'bot')
|
||||
} else {
|
||||
wasAdded = true
|
||||
labels.values.push({val: 'bot'})
|
||||
}
|
||||
|
||||
if (labels.values.length === 0) {
|
||||
delete existing.labels
|
||||
} else {
|
||||
existing.labels = labels
|
||||
}
|
||||
if (labels.values.length === 0) {
|
||||
delete existing.labels
|
||||
} else {
|
||||
existing.labels = labels
|
||||
}
|
||||
|
||||
return existing
|
||||
return existing
|
||||
},
|
||||
checkCommitted: res => {
|
||||
const exists = !!res.data.labels?.some(l => l.val === 'bot')
|
||||
return exists === wasAdded
|
||||
},
|
||||
},
|
||||
checkCommitted: res => {
|
||||
const exists = !!res.data.labels?.some(l => l.val === 'bot')
|
||||
return exists === wasAdded
|
||||
{
|
||||
onSuccess() {
|
||||
queryClient.invalidateQueries({queryKey: [POST_FEED_RQKEY_ROOT]})
|
||||
queryClient.invalidateQueries({queryKey: [postThreadQueryKeyRoot]})
|
||||
},
|
||||
},
|
||||
})
|
||||
)
|
||||
}, [updateProfile, profile])
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user