Re-enable group invite link management (#10407)
This commit is contained in:
+1
-1
@@ -81,7 +81,7 @@
|
|||||||
"icons:optimize": "svgo -f ./assets/icons"
|
"icons:optimize": "svgo -f ./assets/icons"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@atproto/api": "^0.19.11",
|
"@atproto/api": "^0.19.12",
|
||||||
"@atproto/syntax": "0.5.2",
|
"@atproto/syntax": "0.5.2",
|
||||||
"@bitdrift/react-native": "^0.6.8",
|
"@bitdrift/react-native": "^0.6.8",
|
||||||
"@braintree/sanitize-url": "^6.0.2",
|
"@braintree/sanitize-url": "^6.0.2",
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export function Member({
|
|||||||
true,
|
true,
|
||||||
moderateProfile(profile.kind.addedBy, moderationOpts).ui('displayName'),
|
moderateProfile(profile.kind.addedBy, moderationOpts).ui('displayName'),
|
||||||
)}`
|
)}`
|
||||||
: `Added by invite link`
|
: l`Added by invite link`
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SubtleHoverWrapper>
|
<SubtleHoverWrapper>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {useState} from 'react'
|
import {useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
import {ChatBskyActorDefs, ChatBskyConvoDefs} from '@atproto/api'
|
||||||
import {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
import {StackActions, useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
import {useBottomBarOffset} from '#/lib/hooks/useBottomBarOffset'
|
import {useBottomBarOffset} from '#/lib/hooks/useBottomBarOffset'
|
||||||
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||||
@@ -38,7 +38,6 @@ import {
|
|||||||
} from '#/components/icons/Bell2'
|
} from '#/components/icons/Bell2'
|
||||||
import {ChainLink_Stroke2_Corner0_Rounded as ChainLinkIcon} from '#/components/icons/ChainLink'
|
import {ChainLink_Stroke2_Corner0_Rounded as ChainLinkIcon} from '#/components/icons/ChainLink'
|
||||||
import {type Props as SVGIconProps} from '#/components/icons/common'
|
import {type Props as SVGIconProps} from '#/components/icons/common'
|
||||||
import {DotGrid3x1_Stroke2_Corner0_Rounded as EllipsisIcon} from '#/components/icons/DotGrid'
|
|
||||||
import {EditBig_Stroke2_Corner2_Rounded as EditIcon} from '#/components/icons/EditBig'
|
import {EditBig_Stroke2_Corner2_Rounded as EditIcon} from '#/components/icons/EditBig'
|
||||||
import {Flag_Stroke2_Corner0_Rounded as FlagIcon} from '#/components/icons/Flag'
|
import {Flag_Stroke2_Corner0_Rounded as FlagIcon} from '#/components/icons/Flag'
|
||||||
import {Lock_Stroke2_Corner0_Rounded as LockIcon} from '#/components/icons/Lock'
|
import {Lock_Stroke2_Corner0_Rounded as LockIcon} from '#/components/icons/Lock'
|
||||||
@@ -47,18 +46,13 @@ import {Loader} from '#/components/Loader'
|
|||||||
import * as Prompt from '#/components/Prompt'
|
import * as Prompt from '#/components/Prompt'
|
||||||
import * as Toast from '#/components/Toast'
|
import * as Toast from '#/components/Toast'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
|
import * as bsky from '#/types/bsky'
|
||||||
import {InviteLinkDialog} from '../components/InviteLinkDialog'
|
import {InviteLinkDialog} from '../components/InviteLinkDialog'
|
||||||
import {AddMembersLink} from './AddMembersLink'
|
import {AddMembersLink} from './AddMembersLink'
|
||||||
import {Member, MemberPlaceholder} from './Member'
|
import {Member, MemberPlaceholder} from './Member'
|
||||||
import {MembersAndRequests} from './MembersAndRequests'
|
import {MembersAndRequests} from './MembersAndRequests'
|
||||||
import {EditNamePrompt, LeaveChatPrompt, LockChatPrompt} from './prompts'
|
import {EditNamePrompt, LeaveChatPrompt, LockChatPrompt} from './prompts'
|
||||||
|
|
||||||
const dateFormatter = new Intl.DateTimeFormat(undefined, {
|
|
||||||
month: 'long',
|
|
||||||
day: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
})
|
|
||||||
|
|
||||||
type Item =
|
type Item =
|
||||||
| {type: 'MEMBERS_AND_REQUESTS'; key: string}
|
| {type: 'MEMBERS_AND_REQUESTS'; key: string}
|
||||||
| {type: 'ADD_MEMBERS_LINK'; key: string}
|
| {type: 'ADD_MEMBERS_LINK'; key: string}
|
||||||
@@ -119,11 +113,9 @@ function SettingsInner() {
|
|||||||
|
|
||||||
if (!isConvoActive(convoState)) {
|
if (!isConvoActive(convoState)) {
|
||||||
return (
|
return (
|
||||||
<Layout.Content>
|
<View style={[a.flex_1, a.align_center, a.justify_center]}>
|
||||||
<View style={[a.align_center, a.justify_center, a.flex_1, a.py_4xl]}>
|
|
||||||
<Loader size="xl" />
|
<Loader size="xl" />
|
||||||
</View>
|
</View>
|
||||||
</Layout.Content>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +142,19 @@ function keyExtractor(item: Item) {
|
|||||||
return item.key
|
return item.key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isGroupMember(
|
||||||
|
member: ChatBskyActorDefs.ProfileViewBasic,
|
||||||
|
): member is GroupConvoMember {
|
||||||
|
// Kind is missing when the account has been deleted.
|
||||||
|
return (
|
||||||
|
member.kind === undefined ||
|
||||||
|
bsky.dangerousIsType<ChatBskyActorDefs.GroupConvoMember>(
|
||||||
|
member.kind,
|
||||||
|
ChatBskyActorDefs.isGroupConvoMember,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function GroupSettings({
|
function GroupSettings({
|
||||||
convo,
|
convo,
|
||||||
}: {
|
}: {
|
||||||
@@ -160,12 +165,12 @@ function GroupSettings({
|
|||||||
|
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
|
|
||||||
const primaryMember = convo?.primaryMember
|
const primaryMember = convo.primaryMember
|
||||||
const isOwner = !!primaryMember && primaryMember.did === currentAccount?.did
|
const isOwner = primaryMember.did === currentAccount?.did
|
||||||
|
|
||||||
const {data: memberListData = [], isPending} = useListConvoMembersQuery({
|
const {data: memberListData = [], isPending} = useListConvoMembersQuery({
|
||||||
convoId: convo.view.id,
|
convoId: convo.view.id,
|
||||||
placeholderData: convo?.members,
|
placeholderData: convo.members,
|
||||||
})
|
})
|
||||||
|
|
||||||
// TODO Need this data in order to populate this array. -dsb
|
// TODO Need this data in order to populate this array. -dsb
|
||||||
@@ -193,18 +198,19 @@ function GroupSettings({
|
|||||||
]
|
]
|
||||||
if (isPending) {
|
if (isPending) {
|
||||||
// should never be pending if we correctly set the query cache data
|
// should never be pending if we correctly set the query cache data
|
||||||
Array.from({length: 5}).forEach((_, i) =>
|
items.push(
|
||||||
items.push({
|
...Array.from({length: 5}, (_, i) => ({
|
||||||
type: 'CHAT_MEMBER_PLACEHOLDER',
|
type: 'CHAT_MEMBER_PLACEHOLDER' as const,
|
||||||
key: `chat-member-placeholder-${i}`,
|
key: `chat-member-placeholder-${i}`,
|
||||||
}),
|
})),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
items.push(
|
items.push(
|
||||||
...memberListData
|
...memberListData
|
||||||
|
.filter(isGroupMember)
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
const aIsOwner = a.did === primaryMember?.did
|
const aIsOwner = a.did === primaryMember.did
|
||||||
const bIsOwner = b.did === primaryMember?.did
|
const bIsOwner = b.did === primaryMember.did
|
||||||
const aIsSelf = a.did === currentAccount?.did
|
const aIsSelf = a.did === currentAccount?.did
|
||||||
const bIsSelf = b.did === currentAccount?.did
|
const bIsSelf = b.did === currentAccount?.did
|
||||||
if (aIsOwner !== bIsOwner) return aIsOwner ? -1 : 1
|
if (aIsOwner !== bIsOwner) return aIsOwner ? -1 : 1
|
||||||
@@ -215,9 +221,9 @@ function GroupSettings({
|
|||||||
(profile): Item => ({
|
(profile): Item => ({
|
||||||
type: 'CHAT_MEMBER',
|
type: 'CHAT_MEMBER',
|
||||||
key: profile.did,
|
key: profile.did,
|
||||||
profile: profile as GroupConvoMember,
|
profile,
|
||||||
status:
|
status:
|
||||||
primaryMember?.did === profile.did
|
primaryMember.did === profile.did
|
||||||
? 'owner'
|
? 'owner'
|
||||||
: invites.includes(profile.did)
|
: invites.includes(profile.did)
|
||||||
? 'invited'
|
? 'invited'
|
||||||
@@ -239,16 +245,16 @@ function GroupSettings({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
case 'ADD_MEMBERS_LINK':
|
case 'ADD_MEMBERS_LINK':
|
||||||
return convo ? <AddMembersLink convo={convo} /> : null
|
return <AddMembersLink convo={convo} />
|
||||||
case 'CHAT_MEMBER':
|
case 'CHAT_MEMBER':
|
||||||
return convo ? (
|
return (
|
||||||
<Member
|
<Member
|
||||||
convo={convo}
|
convo={convo}
|
||||||
profile={item.profile}
|
profile={item.profile}
|
||||||
status={item.status}
|
status={item.status}
|
||||||
isOwner={isOwner}
|
isOwner={isOwner}
|
||||||
/>
|
/>
|
||||||
) : null
|
)
|
||||||
case 'CHAT_MEMBER_PLACEHOLDER':
|
case 'CHAT_MEMBER_PLACEHOLDER':
|
||||||
return <MemberPlaceholder />
|
return <MemberPlaceholder />
|
||||||
default:
|
default:
|
||||||
@@ -265,13 +271,7 @@ function GroupSettings({
|
|||||||
desktopFixedHeight
|
desktopFixedHeight
|
||||||
initialNumToRender={initialNumToRender}
|
initialNumToRender={initialNumToRender}
|
||||||
keyExtractor={keyExtractor}
|
keyExtractor={keyExtractor}
|
||||||
ListHeaderComponent={
|
ListHeaderComponent={<SettingsHeader convo={convo} isOwner={isOwner} />}
|
||||||
convo?.kind === 'group' ? (
|
|
||||||
<SettingsHeader convo={convo} isOwner={isOwner} />
|
|
||||||
) : (
|
|
||||||
<SettingsHeaderPlaceholder />
|
|
||||||
)
|
|
||||||
}
|
|
||||||
renderItem={renderItem}
|
renderItem={renderItem}
|
||||||
sideBorders={false}
|
sideBorders={false}
|
||||||
windowSize={11}
|
windowSize={11}
|
||||||
@@ -287,7 +287,7 @@ function SettingsHeader({
|
|||||||
isOwner: boolean
|
isOwner: boolean
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {t: l} = useLingui()
|
const {i18n, t: l} = useLingui()
|
||||||
|
|
||||||
const navigation = useNavigation<NavigationProp>()
|
const navigation = useNavigation<NavigationProp>()
|
||||||
|
|
||||||
@@ -296,16 +296,17 @@ function SettingsHeader({
|
|||||||
|
|
||||||
const lockStatus = convo.details.lockStatus
|
const lockStatus = convo.details.lockStatus
|
||||||
|
|
||||||
// TODO Enable this once the feature is working end-to-end. -dsb
|
const {joinLink} = convo.details
|
||||||
// const {joinLink} = convo.details
|
const isJoinLinkEnabled = isOwner || joinLink?.enabledStatus === 'enabled'
|
||||||
const isJoinLinkEnabled = false
|
|
||||||
// const isJoinLinkEnabled =
|
|
||||||
// isOwner || (!isOwner && joinLink?.enabledStatus === 'enabled')
|
|
||||||
|
|
||||||
// TODO Enable this once the feature is working end-to-end. -dsb
|
// TODO Enable this once the feature is working end-to-end. -dsb
|
||||||
const isReportLinkEnabled = false
|
const isReportLinkEnabled = false
|
||||||
|
|
||||||
const {mutate: editGroupName} = useEditGroupChatName(convo.view.id, {
|
const {mutate: editGroupName, isPending: isEditingName} =
|
||||||
|
useEditGroupChatName(convo.view.id, {
|
||||||
|
onSuccess: () => {
|
||||||
|
Toast.show(l({message: 'Group chat name updated', context: 'toast'}))
|
||||||
|
},
|
||||||
onError: e => {
|
onError: e => {
|
||||||
setNewGroupName(groupName)
|
setNewGroupName(groupName)
|
||||||
logger.error('Failed to edit group chat name', {message: e})
|
logger.error('Failed to edit group chat name', {message: e})
|
||||||
@@ -313,7 +314,7 @@ function SettingsHeader({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const {mutate: muteConvo} = useMuteConvo(convo.view.id, {
|
const {mutate: muteConvo, isPending: isMuting} = useMuteConvo(convo.view.id, {
|
||||||
onSuccess: data => {
|
onSuccess: data => {
|
||||||
if (data.convo.muted) {
|
if (data.convo.muted) {
|
||||||
Toast.show(l({message: 'Group chat muted', context: 'toast'}))
|
Toast.show(l({message: 'Group chat muted', context: 'toast'}))
|
||||||
@@ -327,23 +328,28 @@ function SettingsHeader({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const {mutate: leaveConvo} = useLeaveConvo(convo.view.id, {
|
const {mutate: leaveConvo, isPending: isLeaving} = useLeaveConvo(
|
||||||
|
convo.view.id,
|
||||||
|
{
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
// Settings > Chat > Chat list
|
navigation.replace('Messages', {animation: 'pop'})
|
||||||
navigation.dispatch(StackActions.pop(2))
|
|
||||||
},
|
},
|
||||||
onError: e => {
|
onError: e => {
|
||||||
logger.error('Failed to leave group chat', {message: e})
|
logger.error('Failed to leave group chat', {message: e})
|
||||||
Toast.show(l({message: 'Failed to leave group chat', context: 'toast'}), {
|
Toast.show(
|
||||||
type: 'error',
|
l({message: 'Failed to leave group chat', context: 'toast'}),
|
||||||
})
|
{type: 'error'},
|
||||||
|
)
|
||||||
},
|
},
|
||||||
})
|
},
|
||||||
|
)
|
||||||
|
|
||||||
const {mutate: lockConvo} = useLockConvo(convo.view.id, {
|
const {mutate: lockConvo, isPending: isLocking} = useLockConvo(
|
||||||
|
convo.view.id,
|
||||||
|
{
|
||||||
onSuccess: data => {
|
onSuccess: data => {
|
||||||
const kind = data.convo.kind as ChatBskyConvoDefs.GroupConvo
|
if (!ChatBskyConvoDefs.isGroupConvo(data.convo.kind)) return
|
||||||
if (kind.lockStatus === 'locked') {
|
if (data.convo.kind.lockStatus === 'locked') {
|
||||||
Toast.show(l({message: 'Group chat locked', context: 'toast'}))
|
Toast.show(l({message: 'Group chat locked', context: 'toast'}))
|
||||||
} else {
|
} else {
|
||||||
Toast.show(l({message: 'Group chat unlocked', context: 'toast'}))
|
Toast.show(l({message: 'Group chat unlocked', context: 'toast'}))
|
||||||
@@ -358,7 +364,8 @@ function SettingsHeader({
|
|||||||
Toast.show(l`Failed to unlock group chat`, {type: 'error'})
|
Toast.show(l`Failed to unlock group chat`, {type: 'error'})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
},
|
||||||
|
)
|
||||||
|
|
||||||
const inviteLinkDialog = Dialog.useDialogControl()
|
const inviteLinkDialog = Dialog.useDialogControl()
|
||||||
const editNamePrompt = Prompt.usePromptControl()
|
const editNamePrompt = Prompt.usePromptControl()
|
||||||
@@ -389,9 +396,7 @@ function SettingsHeader({
|
|||||||
lockConvo({lock: false})
|
lockConvo({lock: false})
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO The creation date doesn't exist yet. -dsb
|
const createdAt = new Date(convo.details.createdAt)
|
||||||
const showCreatedAt = false
|
|
||||||
const createdAt = new Date()
|
|
||||||
|
|
||||||
const canLockGroupChat = isOwner && lockStatus !== 'locked-permanently'
|
const canLockGroupChat = isOwner && lockStatus !== 'locked-permanently'
|
||||||
|
|
||||||
@@ -412,7 +417,6 @@ function SettingsHeader({
|
|||||||
]}>
|
]}>
|
||||||
{groupName}
|
{groupName}
|
||||||
</Text>
|
</Text>
|
||||||
{showCreatedAt ? (
|
|
||||||
<Text
|
<Text
|
||||||
style={[
|
style={[
|
||||||
a.text_sm,
|
a.text_sm,
|
||||||
@@ -421,9 +425,15 @@ function SettingsHeader({
|
|||||||
a.px_xl,
|
a.px_xl,
|
||||||
t.atoms.text_contrast_high,
|
t.atoms.text_contrast_high,
|
||||||
]}>
|
]}>
|
||||||
<Trans>Created {dateFormatter.format(createdAt)}</Trans>
|
<Trans>
|
||||||
|
Created{' '}
|
||||||
|
{i18n.date(createdAt, {
|
||||||
|
month: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
year: 'numeric',
|
||||||
|
})}
|
||||||
|
</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
) : null}
|
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
a.flex_row,
|
a.flex_row,
|
||||||
@@ -434,6 +444,7 @@ function SettingsHeader({
|
|||||||
]}>
|
]}>
|
||||||
<SettingsButton
|
<SettingsButton
|
||||||
color={convo.view.muted ? 'negative_subtle' : 'secondary'}
|
color={convo.view.muted ? 'negative_subtle' : 'secondary'}
|
||||||
|
disabled={isMuting}
|
||||||
icon={convo.view.muted ? BellOffIcon : BellIcon}
|
icon={convo.view.muted ? BellOffIcon : BellIcon}
|
||||||
label={
|
label={
|
||||||
convo.view.muted
|
convo.view.muted
|
||||||
@@ -445,6 +456,7 @@ function SettingsHeader({
|
|||||||
/>
|
/>
|
||||||
{isOwner ? (
|
{isOwner ? (
|
||||||
<SettingsButton
|
<SettingsButton
|
||||||
|
disabled={isEditingName}
|
||||||
icon={EditIcon}
|
icon={EditIcon}
|
||||||
label={l`Edit this group chat’s name`}
|
label={l`Edit this group chat’s name`}
|
||||||
text={l`Edit name`}
|
text={l`Edit name`}
|
||||||
@@ -453,6 +465,7 @@ function SettingsHeader({
|
|||||||
) : null}
|
) : null}
|
||||||
{isJoinLinkEnabled ? (
|
{isJoinLinkEnabled ? (
|
||||||
<SettingsButton
|
<SettingsButton
|
||||||
|
disabled={lockStatus !== 'unlocked'}
|
||||||
icon={ChainLinkIcon}
|
icon={ChainLinkIcon}
|
||||||
label={
|
label={
|
||||||
isOwner
|
isOwner
|
||||||
@@ -466,6 +479,7 @@ function SettingsHeader({
|
|||||||
{canLockGroupChat ? (
|
{canLockGroupChat ? (
|
||||||
<SettingsButton
|
<SettingsButton
|
||||||
color={lockStatus === 'locked' ? 'negative_subtle' : 'secondary'}
|
color={lockStatus === 'locked' ? 'negative_subtle' : 'secondary'}
|
||||||
|
disabled={isLocking}
|
||||||
icon={LockIcon}
|
icon={LockIcon}
|
||||||
label={
|
label={
|
||||||
lockStatus === 'locked'
|
lockStatus === 'locked'
|
||||||
@@ -478,18 +492,17 @@ function SettingsHeader({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
{isOwner ? null : isReportLinkEnabled ? (
|
{!isOwner && isReportLinkEnabled && (
|
||||||
<SettingsButton
|
<SettingsButton
|
||||||
color="secondary"
|
|
||||||
icon={FlagIcon}
|
icon={FlagIcon}
|
||||||
label={l`Report this group chat`}
|
label={l`Report this group chat`}
|
||||||
text={l`Report`}
|
text={l`Report`}
|
||||||
onPress={handleReportChat}
|
onPress={handleReportChat}
|
||||||
/>
|
/>
|
||||||
) : null}
|
)}
|
||||||
{isOwner ? null : (
|
{!isOwner && (
|
||||||
<SettingsButton
|
<SettingsButton
|
||||||
color="secondary"
|
disabled={isLeaving}
|
||||||
icon={ArrowBoxLeftIcon}
|
icon={ArrowBoxLeftIcon}
|
||||||
label={l`Leave this group chat`}
|
label={l`Leave this group chat`}
|
||||||
text={l`Leave`}
|
text={l`Leave`}
|
||||||
@@ -519,45 +532,6 @@ function SettingsHeader({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function SettingsHeaderPlaceholder() {
|
|
||||||
const t = useTheme()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={[a.px_xl, a.py_4xl, a.border_b, t.atoms.border_contrast_low]}>
|
|
||||||
<View style={[a.align_center, a.justify_center]}>
|
|
||||||
<AvatarBubbles profiles={[]} />
|
|
||||||
</View>
|
|
||||||
<Text
|
|
||||||
style={[a.text_2xl, a.font_bold, a.text_center, a.pt_lg, t.atoms.text]}>
|
|
||||||
…
|
|
||||||
</Text>
|
|
||||||
<Text
|
|
||||||
style={[
|
|
||||||
a.text_sm,
|
|
||||||
a.text_center,
|
|
||||||
a.pt_xs,
|
|
||||||
a.px_xl,
|
|
||||||
t.atoms.text_contrast_high,
|
|
||||||
]}>
|
|
||||||
…
|
|
||||||
</Text>
|
|
||||||
<View
|
|
||||||
style={[
|
|
||||||
a.flex_row,
|
|
||||||
a.align_center,
|
|
||||||
a.justify_center,
|
|
||||||
a.gap_2xl,
|
|
||||||
a.pt_2xl,
|
|
||||||
]}>
|
|
||||||
<SettingsButtonPlaceholder />
|
|
||||||
<SettingsButtonPlaceholder />
|
|
||||||
<SettingsButtonPlaceholder />
|
|
||||||
<SettingsButtonPlaceholder />
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
function SettingsButton({
|
function SettingsButton({
|
||||||
color = 'secondary',
|
color = 'secondary',
|
||||||
disabled,
|
disabled,
|
||||||
@@ -606,27 +580,3 @@ function SettingsButton({
|
|||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function SettingsButtonPlaceholder() {
|
|
||||||
const t = useTheme()
|
|
||||||
const {t: l} = useLingui()
|
|
||||||
|
|
||||||
return (
|
|
||||||
<View style={[a.align_center]}>
|
|
||||||
<Button color="secondary" size="large" shape="round" label={l`Loading…`}>
|
|
||||||
<ButtonIcon icon={EllipsisIcon} size="md" />
|
|
||||||
</Button>
|
|
||||||
<Text
|
|
||||||
numberOfLines={1}
|
|
||||||
style={[
|
|
||||||
a.text_xs,
|
|
||||||
a.font_medium,
|
|
||||||
a.text_center,
|
|
||||||
a.pt_xs,
|
|
||||||
t.atoms.text,
|
|
||||||
]}>
|
|
||||||
…
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ export function EditNamePrompt({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Prompt.Outer control={control}>
|
<Prompt.Outer control={control}>
|
||||||
<>
|
|
||||||
<Prompt.Content>
|
<Prompt.Content>
|
||||||
<Prompt.TitleText>
|
<Prompt.TitleText>
|
||||||
<Trans>Edit group name</Trans>
|
<Trans>Edit group name</Trans>
|
||||||
@@ -47,7 +46,6 @@ export function EditNamePrompt({
|
|||||||
<Prompt.Action cta={l`Save`} onPress={onConfirm} />
|
<Prompt.Action cta={l`Save`} onPress={onConfirm} />
|
||||||
<Prompt.Cancel />
|
<Prompt.Cancel />
|
||||||
</Prompt.Actions>
|
</Prompt.Actions>
|
||||||
</>
|
|
||||||
</Prompt.Outer>
|
</Prompt.Outer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,10 @@
|
|||||||
"@jridgewell/gen-mapping" "^0.3.0"
|
"@jridgewell/gen-mapping" "^0.3.0"
|
||||||
"@jridgewell/trace-mapping" "^0.3.9"
|
"@jridgewell/trace-mapping" "^0.3.9"
|
||||||
|
|
||||||
"@atproto/api@^0.19.11":
|
"@atproto/api@^0.19.12":
|
||||||
version "0.19.11"
|
version "0.19.12"
|
||||||
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.19.11.tgz#73885a47959907f22b68d671011ee70f80afd44b"
|
resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.19.12.tgz#0c21d7de070270f6596f908e6d8dd590b2933395"
|
||||||
integrity sha512-7V4Sg6hcv/UxoXobjfvy/Ox2ioKQtZ3DzbsiFndYCcBfsZ5GO8rNEroHPq3hT0CFBJK1NAD6JfOtTBN2z267Xg==
|
integrity sha512-5CxDPBPxWx30ZM0UwjsmY67l+Kl8lTiLnH/8QvymsuJuRwA47CVfqo+QzEwJSkojNm7s0mTp7Ln2mR+OcFGBuw==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@atproto/common-web" "^0.4.21"
|
"@atproto/common-web" "^0.4.21"
|
||||||
"@atproto/lexicon" "^0.6.2"
|
"@atproto/lexicon" "^0.6.2"
|
||||||
|
|||||||
Reference in New Issue
Block a user