flip the component type imports to the generated lexicons
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import {View} from 'react-native'
|
||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {chat} from '#/lexicons'
|
||||
import {MessageContextMenu} from '#/components/dms/MessageContextMenu'
|
||||
import {useMessageReplies} from '#/components/dms/MessageReplies'
|
||||
import {SwipeToReply} from '#/components/dms/SwipeToReply'
|
||||
@@ -15,7 +15,7 @@ export function ActionsWrapper({
|
||||
moderationOpts,
|
||||
children,
|
||||
}: {
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
message: chat.bsky.convo.defs.MessageView
|
||||
isFromSelf: boolean
|
||||
senderProfile?: bsky.profile.AnyProfileView
|
||||
moderationOpts: ModerationOpts | undefined
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {useCallback, useRef, useState} from 'react'
|
||||
import {Pressable, View} from 'react-native'
|
||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {plural} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {chat} from '#/lexicons'
|
||||
import {EMOJI_REACTION_LIMIT} from '#/lib/constants'
|
||||
import {useMaybeProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {useConvoActive} from '#/state/messages/convo'
|
||||
@@ -29,7 +29,7 @@ export function ActionsWrapper({
|
||||
moderationOpts,
|
||||
children,
|
||||
}: {
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
message: chat.bsky.convo.defs.MessageView
|
||||
isFromSelf: boolean
|
||||
senderProfile?: bsky.profile.AnyProfileView
|
||||
moderationOpts: ModerationOpts | undefined
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {memo, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {StackActions, useNavigation} from '@react-navigation/native'
|
||||
|
||||
import {app} from '#/lexicons'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
|
||||
@@ -113,7 +113,7 @@ function DoneStep({
|
||||
}: {
|
||||
convoId: string
|
||||
currentScreen: 'list' | 'conversation'
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
}) {
|
||||
const {t: l} = useLingui()
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {memo, useState} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {StackActions, useNavigation} from '@react-navigation/native'
|
||||
|
||||
import {app} from '#/lexicons'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
||||
import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
|
||||
@@ -116,7 +116,7 @@ function DoneStep({
|
||||
}: {
|
||||
convoId: string
|
||||
currentScreen: 'list' | 'conversation'
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
}) {
|
||||
const {t: l} = useLingui()
|
||||
const navigation = useNavigation<NavigationProp>()
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import {View} from 'react-native'
|
||||
import {ChatBskyGroupDefs} from '@atproto/api'
|
||||
import {Plural, Trans} from '@lingui/react/macro'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {chat} from '#/lexicons'
|
||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||
import {makeProfileLink} from '#/lib/routes/links'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
@@ -21,7 +22,8 @@ export function Card({size}: {size: 'large' | 'small'}) {
|
||||
const t = useTheme()
|
||||
const {preview, hasFixedHeight} = useChatInvite()
|
||||
|
||||
if (!ChatBskyGroupDefs.isJoinLinkPreviewView(preview)) return null
|
||||
if (!bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview))
|
||||
return null
|
||||
|
||||
const ownerDisplayName = createSanitizedDisplayName(preview.owner)
|
||||
const ownerHandle = sanitizeHandle(preview.owner.handle, '@')
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import {setStringAsync} from 'expo-clipboard'
|
||||
import {ChatBskyGroupDefs} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {chat} from '#/lexicons'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {
|
||||
type ChatInvitePreview,
|
||||
@@ -71,7 +72,7 @@ export function Root({
|
||||
status = 'loading'
|
||||
} else if (error) {
|
||||
status = 'error'
|
||||
} else if (ChatBskyGroupDefs.isJoinLinkPreviewView(preview)) {
|
||||
} else if (bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview)) {
|
||||
status = 'available'
|
||||
} else {
|
||||
// Resolved to a disabled/invalid/unrecognized preview - nothing to join.
|
||||
@@ -79,7 +80,7 @@ export function Root({
|
||||
}
|
||||
|
||||
let action: ChatInviteAction | undefined
|
||||
if (ChatBskyGroupDefs.isJoinLinkPreviewView(preview)) {
|
||||
if (bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview)) {
|
||||
const convoId = preview.convo?.id
|
||||
const isFollowing = preview.owner.viewer?.followedBy ?? false
|
||||
const hasRequested = !convoId && preview.viewer?.requestedAt != null
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {useMemo, useState} from 'react'
|
||||
import {useWindowDimensions, View} from 'react-native'
|
||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
|
||||
import {chat} from '#/lexicons'
|
||||
import {useSession} from '#/state/session'
|
||||
import {atoms as a, tokens, useTheme} from '#/alf'
|
||||
import * as ContextMenu from '#/components/ContextMenu'
|
||||
@@ -21,7 +21,7 @@ export function EmojiReactionPicker({
|
||||
message,
|
||||
onEmojiSelect,
|
||||
}: {
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
message: chat.bsky.convo.defs.MessageView
|
||||
children?: TriggerProps['children']
|
||||
onEmojiSelect: (emoji: string) => void
|
||||
}) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {useState} from 'react'
|
||||
import {Pressable, View} from 'react-native'
|
||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
import {DropdownMenu} from 'radix-ui'
|
||||
|
||||
import {chat} from '#/lexicons'
|
||||
import {useSession} from '#/state/session'
|
||||
import {atoms as a, flatten, useTheme} from '#/alf'
|
||||
import * as EmojiPicker from '#/components/EmojiPicker'
|
||||
@@ -17,7 +17,7 @@ export function EmojiReactionPicker({
|
||||
children,
|
||||
onEmojiSelect,
|
||||
}: {
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
message: chat.bsky.convo.defs.MessageView
|
||||
children?: EmojiPicker.TriggerProps['children']
|
||||
onEmojiSelect: (emoji: string) => void
|
||||
}) {
|
||||
@@ -40,7 +40,7 @@ function MenuInner({
|
||||
message,
|
||||
onEmojiSelect,
|
||||
}: {
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
message: chat.bsky.convo.defs.MessageView
|
||||
onEmojiSelect: (emoji: string) => void
|
||||
}) {
|
||||
const t = useTheme()
|
||||
|
||||
@@ -2,12 +2,12 @@ import {memo, useCallback} from 'react'
|
||||
import {Platform} from 'react-native'
|
||||
import {type GestureType} from 'react-native-gesture-handler'
|
||||
import * as Clipboard from 'expo-clipboard'
|
||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {RichText} from '@bsky.app/sdk/richtext'
|
||||
import {plural} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {chat} from '#/lexicons'
|
||||
import {EMOJI_REACTION_LIMIT} from '#/lib/constants'
|
||||
import {useGoogleTranslate} from '#/lib/hooks/useGoogleTranslate'
|
||||
import {asSdkFacets, richTextToString} from '#/lib/strings/rich-text-helpers'
|
||||
@@ -39,7 +39,7 @@ export let MessageContextMenu = ({
|
||||
children,
|
||||
swipeGesture,
|
||||
}: {
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
message: chat.bsky.convo.defs.MessageView
|
||||
senderProfile?: bsky.profile.AnyProfileView
|
||||
moderationOpts: ModerationOpts | undefined
|
||||
children: TriggerProps['children']
|
||||
|
||||
@@ -22,17 +22,13 @@ import Animated, {
|
||||
ZoomIn,
|
||||
ZoomOut,
|
||||
} from 'react-native-reanimated'
|
||||
import {
|
||||
AppBskyEmbedRecord,
|
||||
type ChatBskyActorDefs,
|
||||
ChatBskyConvoDefs,
|
||||
ChatBskyEmbedJoinLink,
|
||||
} from '@atproto/api'
|
||||
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||
import {plural} from '@lingui/core/macro'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {app, chat} from '#/lexicons'
|
||||
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
|
||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||
import {moderateProfile} from '#/lib/moderation/subjects'
|
||||
@@ -77,16 +73,19 @@ const SQUARED_BORDER_RADIUS = 4
|
||||
const DISPLAY_NAME_INSET = 20
|
||||
|
||||
export type MessageItemNeighbor =
|
||||
| ChatBskyConvoDefs.MessageView
|
||||
| ChatBskyConvoDefs.DeletedMessageView
|
||||
| chat.bsky.convo.defs.MessageView
|
||||
| chat.bsky.convo.defs.DeletedMessageView
|
||||
| null
|
||||
|
||||
function messageIsReply(message: MessageItemNeighbor): boolean {
|
||||
return (
|
||||
ChatBskyConvoDefs.isMessageView(message) &&
|
||||
(ChatBskyConvoDefs.isMessageView(message.replyTo) ||
|
||||
ChatBskyConvoDefs.isDeletedMessageView(message.replyTo) ||
|
||||
ChatBskyConvoDefs.isMessageBeforeUserJoinedGroupView(message.replyTo))
|
||||
bsky.isType(chat.bsky.convo.defs.messageView, message) &&
|
||||
(bsky.isType(chat.bsky.convo.defs.messageView, message.replyTo) ||
|
||||
bsky.isType(chat.bsky.convo.defs.deletedMessageView, message.replyTo) ||
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.messageBeforeUserJoinedGroupView,
|
||||
message.replyTo,
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -98,7 +97,7 @@ function isWithinClusterBoundary({
|
||||
direction,
|
||||
}: {
|
||||
isPending: boolean
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
message: chat.bsky.convo.defs.MessageView
|
||||
adjacentMessage: MessageItemNeighbor
|
||||
isFromSameSender: boolean
|
||||
direction: 'prev' | 'next'
|
||||
@@ -110,7 +109,7 @@ function isWithinClusterBoundary({
|
||||
return true
|
||||
}
|
||||
if (!isFromSameSender) return true
|
||||
if (ChatBskyConvoDefs.isMessageView(adjacentMessage)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.messageView, adjacentMessage)) {
|
||||
const currentSentAt = message.sentAt
|
||||
const thisDate = new Date(currentSentAt)
|
||||
const adjDate = new Date(adjacentMessage.sentAt)
|
||||
@@ -137,7 +136,7 @@ let MessageItem = ({
|
||||
isGroupChat?: boolean
|
||||
prevMessage: MessageItemNeighbor
|
||||
nextMessage: MessageItemNeighbor
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||
}): React.ReactNode => {
|
||||
const t = useTheme()
|
||||
const {currentAccount} = useSession()
|
||||
@@ -155,13 +154,17 @@ let MessageItem = ({
|
||||
// tombstone, or a before-joined placeholder. Narrow away the open-union
|
||||
// fallback so we only render shapes we understand.
|
||||
const replyTo =
|
||||
ChatBskyConvoDefs.isMessageView(message.replyTo) ||
|
||||
ChatBskyConvoDefs.isDeletedMessageView(message.replyTo) ||
|
||||
ChatBskyConvoDefs.isMessageBeforeUserJoinedGroupView(message.replyTo)
|
||||
bsky.isType(chat.bsky.convo.defs.messageView, message.replyTo) ||
|
||||
bsky.isType(chat.bsky.convo.defs.deletedMessageView, message.replyTo) ||
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.messageBeforeUserJoinedGroupView,
|
||||
message.replyTo,
|
||||
)
|
||||
? message.replyTo
|
||||
: undefined
|
||||
const replyToMessageId =
|
||||
replyTo && !ChatBskyConvoDefs.isMessageBeforeUserJoinedGroupView(replyTo)
|
||||
replyTo &&
|
||||
!bsky.isType(chat.bsky.convo.defs.messageBeforeUserJoinedGroupView, replyTo)
|
||||
? replyTo.id
|
||||
: undefined
|
||||
const onPressReplyTo = replyToMessageId
|
||||
@@ -175,8 +178,14 @@ let MessageItem = ({
|
||||
const isFromSelf =
|
||||
message.sender?.did != null && message.sender.did === currentAccount?.did
|
||||
|
||||
const prevIsMessage = ChatBskyConvoDefs.isMessageView(prevMessage)
|
||||
const nextIsMessage = ChatBskyConvoDefs.isMessageView(nextMessage)
|
||||
const prevIsMessage = bsky.isType(
|
||||
chat.bsky.convo.defs.messageView,
|
||||
prevMessage,
|
||||
)
|
||||
const nextIsMessage = bsky.isType(
|
||||
chat.bsky.convo.defs.messageView,
|
||||
nextMessage,
|
||||
)
|
||||
|
||||
const isPrevFromSameSender =
|
||||
prevIsMessage &&
|
||||
@@ -204,7 +213,7 @@ let MessageItem = ({
|
||||
})
|
||||
|
||||
const hasLargeGapFromPrev =
|
||||
!ChatBskyConvoDefs.isMessageView(prevMessage) ||
|
||||
!bsky.isType(chat.bsky.convo.defs.messageView, prevMessage) ||
|
||||
new Date(message.sentAt).getTime() -
|
||||
new Date(prevMessage.sentAt).getTime() >
|
||||
MESSAGE_GAP_THRESHOLD_MS
|
||||
@@ -254,8 +263,8 @@ let MessageItem = ({
|
||||
const isEmojiOnly = isOnlyEmoji(message.text)
|
||||
|
||||
const hasEmbed =
|
||||
AppBskyEmbedRecord.isView(message.embed) ||
|
||||
ChatBskyEmbedJoinLink.isView(message.embed)
|
||||
bsky.isType(app.bsky.embed.record.view, message.embed) ||
|
||||
bsky.isType(chat.bsky.embed.joinLink.view, message.embed)
|
||||
const hasEmbedAndText = hasEmbed && rt.text.length > 0
|
||||
|
||||
const targetBottomRadius = squaredBottomCorner
|
||||
@@ -516,7 +525,7 @@ let MessageItem = ({
|
||||
message={message}
|
||||
senderProfile={profile}
|
||||
moderationOpts={moderationOpts}>
|
||||
{AppBskyEmbedRecord.isView(message.embed) && (
|
||||
{bsky.isType(app.bsky.embed.record.view, message.embed) && (
|
||||
<MessageItemEmbed
|
||||
embed={message.embed}
|
||||
isFromSelf={isFromSelf}
|
||||
@@ -528,7 +537,10 @@ let MessageItem = ({
|
||||
highlightSV={highlightSV}
|
||||
/>
|
||||
)}
|
||||
{ChatBskyEmbedJoinLink.isView(message.embed) && (
|
||||
{bsky.isType(
|
||||
chat.bsky.embed.joinLink.view,
|
||||
message.embed,
|
||||
) && (
|
||||
<MessageItemInviteEmbed
|
||||
embed={message.embed}
|
||||
isFromSelf={isFromSelf}
|
||||
@@ -666,7 +678,7 @@ function BlockedPlaceholder({
|
||||
profile,
|
||||
style,
|
||||
}: {
|
||||
profile: Shadow<ChatBskyActorDefs.ProfileViewBasic>
|
||||
profile: Shadow<chat.bsky.actor.defs.ProfileViewBasic>
|
||||
style?: AnimatedStyle<ViewStyle>
|
||||
}) {
|
||||
const {t: l} = useLingui()
|
||||
@@ -776,13 +788,13 @@ function ReplyCaption({
|
||||
onPress,
|
||||
}: {
|
||||
replyTo:
|
||||
| ChatBskyConvoDefs.MessageView
|
||||
| ChatBskyConvoDefs.DeletedMessageView
|
||||
| ChatBskyConvoDefs.MessageBeforeUserJoinedGroupView
|
||||
| chat.bsky.convo.defs.MessageView
|
||||
| chat.bsky.convo.defs.DeletedMessageView
|
||||
| chat.bsky.convo.defs.MessageBeforeUserJoinedGroupView
|
||||
isFromSelf: boolean
|
||||
isGroupChat: boolean
|
||||
replierDisplayName: string | null
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||
onPress?: () => void
|
||||
}) {
|
||||
const t = useTheme()
|
||||
@@ -791,8 +803,8 @@ function ReplyCaption({
|
||||
|
||||
let caption: string = ''
|
||||
if (
|
||||
ChatBskyConvoDefs.isMessageView(replyTo) ||
|
||||
ChatBskyConvoDefs.isDeletedMessageView(replyTo)
|
||||
bsky.isType(chat.bsky.convo.defs.messageView, replyTo) ||
|
||||
bsky.isType(chat.bsky.convo.defs.deletedMessageView, replyTo)
|
||||
) {
|
||||
const originalSenderIsSelf = replyTo.sender.did === currentAccount?.did
|
||||
const originalProfile = relatedProfiles.get(replyTo.sender.did)
|
||||
@@ -865,11 +877,11 @@ function ReplyQuote({
|
||||
onPress,
|
||||
}: {
|
||||
replyTo:
|
||||
| ChatBskyConvoDefs.MessageView
|
||||
| ChatBskyConvoDefs.DeletedMessageView
|
||||
| ChatBskyConvoDefs.MessageBeforeUserJoinedGroupView
|
||||
| chat.bsky.convo.defs.MessageView
|
||||
| chat.bsky.convo.defs.DeletedMessageView
|
||||
| chat.bsky.convo.defs.MessageBeforeUserJoinedGroupView
|
||||
isFromSelf: boolean
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||
onPress?: () => void
|
||||
}) {
|
||||
const t = useTheme()
|
||||
@@ -877,8 +889,8 @@ function ReplyQuote({
|
||||
const getReplyPreviewText = useReplyPreviewText()
|
||||
|
||||
const senderDid =
|
||||
ChatBskyConvoDefs.isMessageView(replyTo) ||
|
||||
ChatBskyConvoDefs.isDeletedMessageView(replyTo)
|
||||
bsky.isType(chat.bsky.convo.defs.messageView, replyTo) ||
|
||||
bsky.isType(chat.bsky.convo.defs.deletedMessageView, replyTo)
|
||||
? replyTo.sender.did
|
||||
: undefined
|
||||
const senderProfile = useMaybeProfileShadow(
|
||||
@@ -908,9 +920,11 @@ function ReplyQuote({
|
||||
comment: 'A reply summary in chat',
|
||||
})
|
||||
subtle = true
|
||||
} else if (ChatBskyConvoDefs.isMessageView(replyTo)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.messageView, replyTo)) {
|
||||
;({text, subtle} = getReplyPreviewText(replyTo))
|
||||
} else if (ChatBskyConvoDefs.isMessageBeforeUserJoinedGroupView(replyTo)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.messageBeforeUserJoinedGroupView, replyTo)
|
||||
) {
|
||||
text = l({
|
||||
message: `(message sent before you joined)`,
|
||||
comment: 'A reply summary in chat',
|
||||
|
||||
@@ -5,8 +5,9 @@ import Animated, {
|
||||
type SharedValue,
|
||||
useAnimatedStyle,
|
||||
} from 'react-native-reanimated'
|
||||
import {type $Typed, type AppBskyEmbedRecord} from '@atproto/api'
|
||||
|
||||
import {type $Typed} from '@atproto/lex'
|
||||
import {app} from '#/lexicons'
|
||||
import {atoms as a, native, useTheme, web} from '#/alf'
|
||||
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
|
||||
import {MessageContextProvider} from './MessageContext'
|
||||
@@ -22,7 +23,7 @@ let MessageItemEmbed = ({
|
||||
squaredBottomCorner,
|
||||
highlightSV,
|
||||
}: {
|
||||
embed: $Typed<AppBskyEmbedRecord.View>
|
||||
embed: $Typed<app.bsky.embed.record.View>
|
||||
isFromSelf: boolean
|
||||
isGroupChat: boolean
|
||||
squaredTopCorner: boolean
|
||||
|
||||
@@ -5,8 +5,9 @@ import Animated, {
|
||||
type SharedValue,
|
||||
useAnimatedStyle,
|
||||
} from 'react-native-reanimated'
|
||||
import {type $Typed, type ChatBskyEmbedJoinLink} from '@atproto/api'
|
||||
|
||||
import {type $Typed} from '@atproto/lex'
|
||||
import {chat} from '#/lexicons'
|
||||
import {useConvoActive} from '#/state/messages/convo'
|
||||
import {isKnownJoinLinkPreview} from '#/state/queries/join-links'
|
||||
import {atoms as a, native, useTheme, web} from '#/alf'
|
||||
@@ -24,7 +25,7 @@ let MessageItemInviteEmbed = ({
|
||||
squaredBottomCorner,
|
||||
highlightSV,
|
||||
}: {
|
||||
embed: $Typed<ChatBskyEmbedJoinLink.View>
|
||||
embed: $Typed<chat.bsky.embed.joinLink.View>
|
||||
isFromSelf: boolean
|
||||
isGroupChat: boolean
|
||||
squaredTopCorner: boolean
|
||||
|
||||
@@ -7,10 +7,10 @@ import {
|
||||
useState,
|
||||
} from 'react'
|
||||
import {LayoutAnimation} from 'react-native'
|
||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {chat} from '#/lexicons'
|
||||
import {useConvoActive} from '#/state/messages/convo'
|
||||
import {unstableCacheProfileView} from '#/state/queries/unstable-profile-cache'
|
||||
import {useDialogControl} from '#/components/Dialog'
|
||||
@@ -23,12 +23,12 @@ import * as Toast from '#/components/Toast'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
|
||||
type MessageDialogsContextType = {
|
||||
openDeleteMessage: (message: ChatBskyConvoDefs.MessageView) => void
|
||||
openDeleteMessage: (message: chat.bsky.convo.defs.MessageView) => void
|
||||
openReportMessage: (
|
||||
message: ChatBskyConvoDefs.MessageView,
|
||||
message: chat.bsky.convo.defs.MessageView,
|
||||
senderProfile: bsky.profile.AnyProfileView | undefined,
|
||||
) => void
|
||||
openReactions: (message: ChatBskyConvoDefs.MessageView) => void
|
||||
openReactions: (message: chat.bsky.convo.defs.MessageView) => void
|
||||
}
|
||||
|
||||
const Context = createContext<MessageDialogsContextType | null>(null)
|
||||
@@ -52,18 +52,18 @@ export function MessageOverlays({children}: {children: React.ReactNode}) {
|
||||
const reactionsControl = useDialogControl()
|
||||
|
||||
const [deleteTarget, setDeleteTarget] =
|
||||
useState<ChatBskyConvoDefs.MessageView | null>(null)
|
||||
useState<chat.bsky.convo.defs.MessageView | null>(null)
|
||||
const [reportTarget, setReportTarget] = useState<{
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
message: chat.bsky.convo.defs.MessageView
|
||||
senderProfile: bsky.profile.AnyProfileView | undefined
|
||||
} | null>(null)
|
||||
const [afterReportTarget, setAfterReportTarget] =
|
||||
useState<ChatBskyConvoDefs.MessageView | null>(null)
|
||||
useState<chat.bsky.convo.defs.MessageView | null>(null)
|
||||
const [reactionsTarget, setReactionsTarget] =
|
||||
useState<ChatBskyConvoDefs.MessageView | null>(null)
|
||||
useState<chat.bsky.convo.defs.MessageView | null>(null)
|
||||
|
||||
const openDeleteMessage = useCallback(
|
||||
(message: ChatBskyConvoDefs.MessageView) => {
|
||||
(message: chat.bsky.convo.defs.MessageView) => {
|
||||
setDeleteTarget(message)
|
||||
deleteControl.open()
|
||||
},
|
||||
@@ -72,7 +72,7 @@ export function MessageOverlays({children}: {children: React.ReactNode}) {
|
||||
|
||||
const openReportMessage = useCallback(
|
||||
(
|
||||
message: ChatBskyConvoDefs.MessageView,
|
||||
message: chat.bsky.convo.defs.MessageView,
|
||||
senderProfile: bsky.profile.AnyProfileView | undefined,
|
||||
) => {
|
||||
setReportTarget({message, senderProfile})
|
||||
@@ -82,7 +82,7 @@ export function MessageOverlays({children}: {children: React.ReactNode}) {
|
||||
)
|
||||
|
||||
const openReactions = useCallback(
|
||||
(message: ChatBskyConvoDefs.MessageView) => {
|
||||
(message: chat.bsky.convo.defs.MessageView) => {
|
||||
setReactionsTarget(message)
|
||||
},
|
||||
[],
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import {useCallback} from 'react'
|
||||
import {View} from 'react-native'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {Trans} from '@lingui/react/macro'
|
||||
import {useNavigation} from '@react-navigation/native'
|
||||
|
||||
import {app} from '#/lexicons'
|
||||
import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
|
||||
import {type NavigationProp} from '#/lib/routes/types'
|
||||
import {useGetConvoAvailabilityQuery} from '#/state/queries/messages/get-convo-availability'
|
||||
@@ -20,7 +20,7 @@ import {useAnalytics} from '#/analytics'
|
||||
export function MessageProfileButton({
|
||||
profile,
|
||||
}: {
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
}) {
|
||||
const {_} = useLingui()
|
||||
const t = useTheme()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import {chat} from '#/lexicons'
|
||||
import {
|
||||
createContext,
|
||||
useCallback,
|
||||
@@ -7,7 +8,6 @@ import {
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react'
|
||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
||||
|
||||
/**
|
||||
* How long a message stays highlighted after scrolling to it, before the flash
|
||||
@@ -28,8 +28,8 @@ type MessageRepliesContextType = {
|
||||
/**
|
||||
* The message currently staged for reply in the composer, or null.
|
||||
*/
|
||||
replyTo: ChatBskyConvoDefs.MessageView | null
|
||||
setReply: (message: ChatBskyConvoDefs.MessageView) => void
|
||||
replyTo: chat.bsky.convo.defs.MessageView | null
|
||||
setReply: (message: chat.bsky.convo.defs.MessageView) => void
|
||||
clearReply: () => void
|
||||
/**
|
||||
* Scroll the list to a message, if it's currently loaded, and flash it. No-op
|
||||
@@ -66,9 +66,8 @@ export function MessageRepliesProvider({
|
||||
*/
|
||||
scrollToMessage: (messageId: string) => boolean
|
||||
}) {
|
||||
const [replyTo, setReplyTo] = useState<ChatBskyConvoDefs.MessageView | null>(
|
||||
null,
|
||||
)
|
||||
const [replyTo, setReplyTo] =
|
||||
useState<chat.bsky.convo.defs.MessageView | null>(null)
|
||||
const [highlightedMessage, setHighlightedMessage] =
|
||||
useState<HighlightedMessage | null>(null)
|
||||
const highlightKey = useRef(0)
|
||||
@@ -76,7 +75,7 @@ export function MessageRepliesProvider({
|
||||
null,
|
||||
)
|
||||
|
||||
const setReply = useCallback((message: ChatBskyConvoDefs.MessageView) => {
|
||||
const setReply = useCallback((message: chat.bsky.convo.defs.MessageView) => {
|
||||
setReplyTo(message)
|
||||
}, [])
|
||||
|
||||
|
||||
@@ -6,9 +6,9 @@ import {
|
||||
useWindowDimensions,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import {type ChatBskyActorDefs, type ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {Trans, useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {chat} from '#/lexicons'
|
||||
import {HITSLOP_10} from '#/lib/constants'
|
||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
@@ -28,7 +28,7 @@ import type * as bsky from '#/types/bsky'
|
||||
type Reaction = {
|
||||
key: string
|
||||
value: string
|
||||
senders: ChatBskyConvoDefs.ReactionViewSender[]
|
||||
senders: chat.bsky.convo.defs.ReactionViewSender[]
|
||||
count: number
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ export function ReactionsDialog({
|
||||
onClose,
|
||||
}: {
|
||||
control: Dialog.DialogControlProps
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||
message: chat.bsky.convo.defs.MessageView
|
||||
onClose?: () => void
|
||||
}) {
|
||||
const {t: l} = useLingui()
|
||||
@@ -142,10 +142,10 @@ function ReactionRow({
|
||||
control: Dialog.DialogControlProps
|
||||
convo: ActiveConvoStates
|
||||
currentAccount?: SessionAccount
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
message: chat.bsky.convo.defs.MessageView
|
||||
profile: bsky.profile.AnyProfileView
|
||||
reaction: ChatBskyConvoDefs.ReactionView
|
||||
allReactions: ChatBskyConvoDefs.ReactionView[]
|
||||
reaction: chat.bsky.convo.defs.ReactionView
|
||||
allReactions: chat.bsky.convo.defs.ReactionView[]
|
||||
selected: string
|
||||
setSelected: React.Dispatch<React.SetStateAction<string>>
|
||||
}) {
|
||||
@@ -398,7 +398,7 @@ function ReactionTab({
|
||||
}
|
||||
|
||||
export function groupReactions(
|
||||
reactions: ChatBskyConvoDefs.ReactionView[] | undefined,
|
||||
reactions: chat.bsky.convo.defs.ReactionView[] | undefined,
|
||||
): Reaction[] {
|
||||
const grouped = new Map<string, Reaction>()
|
||||
for (const reaction of reactions ?? []) {
|
||||
|
||||
@@ -7,10 +7,10 @@ import Animated, {
|
||||
useDerivedValue,
|
||||
withTiming,
|
||||
} from 'react-native-reanimated'
|
||||
import {type ChatBskyActorDefs} from '@atproto/api'
|
||||
import {plural} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {chat} from '#/lexicons'
|
||||
import {HITSLOP_10} from '#/lib/constants'
|
||||
import {type SystemMessageGroupItem} from '#/screens/Messages/components/groupSystemMessages'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
@@ -29,7 +29,7 @@ export function SystemMessageGroup({
|
||||
item: SystemMessageGroupItem
|
||||
expanded: boolean
|
||||
onToggle: (key: string) => void
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {t: l} = useLingui()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {View} from 'react-native'
|
||||
import {type ChatBskyActorDefs} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
|
||||
import {chat} from '#/lexicons'
|
||||
import {makeProfileLink} from '#/lib/routes/links'
|
||||
import {type ConvoItem} from '#/state/messages/convo/types'
|
||||
import {useInviteLinkDialog} from '#/screens/Messages/components/InviteLinkDialogProvider'
|
||||
@@ -16,7 +16,7 @@ export function SystemMessageItem({
|
||||
relatedProfiles,
|
||||
}: {
|
||||
item: ConvoItem & {type: 'system-message'}
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {i18n, t: l} = useLingui()
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import {
|
||||
AppBskyEmbedRecord,
|
||||
type ChatBskyActorDefs,
|
||||
ChatBskyConvoDefs,
|
||||
ChatBskyEmbedJoinLink,
|
||||
} from '@atproto/api'
|
||||
import {type I18n} from '@lingui/core'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
|
||||
import {app, chat} from '#/lexicons'
|
||||
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
|
||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||
import {
|
||||
@@ -14,12 +9,12 @@ import {
|
||||
toBskyAppUrl,
|
||||
toShortUrl,
|
||||
} from '#/lib/strings/url-helpers'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
export type UserMessageInfo = {
|
||||
message: string | null
|
||||
sentAt: string
|
||||
reportableMessage?: ChatBskyConvoDefs.MessageView
|
||||
reportableMessage?: chat.bsky.convo.defs.MessageView
|
||||
isBlockedMessage: boolean
|
||||
}
|
||||
|
||||
@@ -36,7 +31,7 @@ export function isDidBlockedInConvo({
|
||||
primaryProfile,
|
||||
}: {
|
||||
did: string | undefined
|
||||
members: ChatBskyActorDefs.ProfileViewBasic[]
|
||||
members: chat.bsky.actor.defs.ProfileViewBasic[]
|
||||
primaryProfile?: bsky.profile.AnyProfileView
|
||||
}): boolean {
|
||||
if (!did) return false
|
||||
@@ -53,12 +48,12 @@ export function getMessageInfo({
|
||||
primaryProfile,
|
||||
i18n,
|
||||
}: {
|
||||
convo: ChatBskyConvoDefs.ConvoView
|
||||
convo: chat.bsky.convo.defs.ConvoView
|
||||
currentAccountDid: string | undefined
|
||||
primaryProfile?: bsky.profile.AnyProfileView
|
||||
i18n: I18n
|
||||
}): UserMessageInfo | null {
|
||||
if (!ChatBskyConvoDefs.isMessageView(convo.lastMessage)) {
|
||||
if (!bsky.isType(chat.bsky.convo.defs.messageView, convo.lastMessage)) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -67,7 +62,7 @@ export function getMessageInfo({
|
||||
const senderDid = lastMessage.sender?.did
|
||||
const sender = convo.members.find(m => m.did === senderDid)
|
||||
const name = sender ? createSanitizedDisplayName(sender) : null
|
||||
const isGroup = ChatBskyConvoDefs.isGroupConvo(convo.kind)
|
||||
const isGroup = bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)
|
||||
|
||||
const reportableMessage = isFromMe ? undefined : lastMessage
|
||||
const isBlockedMessage = isDidBlockedInConvo({
|
||||
@@ -105,10 +100,10 @@ export function getMessageInfo({
|
||||
msg`(contains embedded content)`,
|
||||
)
|
||||
|
||||
if (AppBskyEmbedRecord.isView(lastMessage.embed)) {
|
||||
if (bsky.isType(app.bsky.embed.record.view, lastMessage.embed)) {
|
||||
const embed = lastMessage.embed
|
||||
|
||||
if (AppBskyEmbedRecord.isViewRecord(embed.record)) {
|
||||
if (bsky.isType(app.bsky.embed.record.viewRecord, embed.record)) {
|
||||
const record = embed.record
|
||||
const path = postUriToRelativePath(record.uri, {
|
||||
handle: record.author.handle,
|
||||
@@ -119,7 +114,7 @@ export function getMessageInfo({
|
||||
} else {
|
||||
message = prefix(defaultEmbeddedContentMessage)
|
||||
}
|
||||
} else if (ChatBskyEmbedJoinLink.isView(lastMessage.embed)) {
|
||||
} else if (bsky.isType(chat.bsky.embed.joinLink.view, lastMessage.embed)) {
|
||||
message = prefix(i18n._(msg`(chat invite link)`))
|
||||
} else {
|
||||
message = prefix(defaultEmbeddedContentMessage)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {type I18n} from '@lingui/core'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
|
||||
import {chat} from '#/lexicons'
|
||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||
import {isDidBlockedInConvo} from '#/components/dms/getMessageInfo'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
export type UserReactionInfo = {
|
||||
message: string
|
||||
@@ -18,12 +18,17 @@ export function getReactionInfo({
|
||||
primaryProfile,
|
||||
i18n,
|
||||
}: {
|
||||
convo: ChatBskyConvoDefs.ConvoView
|
||||
convo: chat.bsky.convo.defs.ConvoView
|
||||
currentAccountDid: string | undefined
|
||||
primaryProfile?: bsky.profile.AnyProfileView
|
||||
i18n: I18n
|
||||
}): UserReactionInfo | null {
|
||||
if (!ChatBskyConvoDefs.isMessageAndReactionView(convo.lastReaction)) {
|
||||
if (
|
||||
!bsky.isType(
|
||||
chat.bsky.convo.defs.messageAndReactionView,
|
||||
convo.lastReaction,
|
||||
)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import {type ChatBskyActorDefs, ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {type MessageDescriptor} from '@lingui/core'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {chat} from '#/lexicons'
|
||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||
import {ArrowBoxLeft_Stroke2_Corner0_Rounded as LeaveIcon} from '#/components/icons/ArrowBoxLeft'
|
||||
import {ArrowBoxRight_Stroke2_Corner3_Rounded as JoinIcon} from '#/components/icons/ArrowBoxRight'
|
||||
@@ -19,7 +20,7 @@ import {PencilLine_Stroke2_Corner0_Rounded as PencilIcon} from '#/components/ico
|
||||
export type SystemMessageAction =
|
||||
| {
|
||||
kind: 'profile'
|
||||
profile: ChatBskyActorDefs.ProfileViewBasic
|
||||
profile: chat.bsky.actor.defs.ProfileViewBasic
|
||||
displayName: string
|
||||
}
|
||||
| {kind: 'inviteLink'}
|
||||
@@ -31,8 +32,8 @@ export type SystemMessageInfo = {
|
||||
}
|
||||
|
||||
function getProfileAction(
|
||||
user: ChatBskyConvoDefs.SystemMessageReferredUser,
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>,
|
||||
user: chat.bsky.convo.defs.SystemMessageReferredUser,
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>,
|
||||
): Extract<SystemMessageAction, {kind: 'profile'}> | null {
|
||||
const profile = relatedProfiles.get(user.did)
|
||||
if (!profile) return null
|
||||
@@ -44,11 +45,11 @@ function getProfileAction(
|
||||
}
|
||||
|
||||
export function getSystemMessageInfo(
|
||||
data: ChatBskyConvoDefs.SystemMessageView['data'],
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>,
|
||||
data: chat.bsky.convo.defs.SystemMessageView['data'],
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>,
|
||||
opts = {short: false},
|
||||
): SystemMessageInfo | null {
|
||||
if (ChatBskyConvoDefs.isSystemMessageDataAddMember(data)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.systemMessageDataAddMember, data)) {
|
||||
const action = getProfileAction(data.member, relatedProfiles)
|
||||
return {
|
||||
Icon: JoinIcon,
|
||||
@@ -61,7 +62,9 @@ export function getSystemMessageInfo(
|
||||
: msg`Someone was added to the group`,
|
||||
action: action ?? undefined,
|
||||
}
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageDataRemoveMember(data)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.systemMessageDataRemoveMember, data)
|
||||
) {
|
||||
const action = getProfileAction(data.member, relatedProfiles)
|
||||
return {
|
||||
Icon: LeaveIcon,
|
||||
@@ -74,7 +77,9 @@ export function getSystemMessageInfo(
|
||||
: msg`Someone was removed from the group`,
|
||||
action: action ?? undefined,
|
||||
}
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageDataMemberJoin(data)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.systemMessageDataMemberJoin, data)
|
||||
) {
|
||||
const action = getProfileAction(data.member, relatedProfiles)
|
||||
return {
|
||||
Icon: JoinIcon,
|
||||
@@ -87,7 +92,9 @@ export function getSystemMessageInfo(
|
||||
: msg`Someone joined the group`,
|
||||
action: action ?? undefined,
|
||||
}
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageDataMemberLeave(data)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.systemMessageDataMemberLeave, data)
|
||||
) {
|
||||
const action = getProfileAction(data.member, relatedProfiles)
|
||||
return {
|
||||
Icon: LeaveIcon,
|
||||
@@ -100,13 +107,24 @@ export function getSystemMessageInfo(
|
||||
: msg`Someone left the group`,
|
||||
action: action ?? undefined,
|
||||
}
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageDataLockConvo(data)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.systemMessageDataLockConvo, data)
|
||||
) {
|
||||
return {Icon: LockIcon, message: msg`Chat locked`}
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageDataUnlockConvo(data)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.systemMessageDataUnlockConvo, data)
|
||||
) {
|
||||
return {Icon: UnlockIcon, message: msg`Chat unlocked`}
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageDataLockConvoPermanently(data)) {
|
||||
} else if (
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.systemMessageDataLockConvoPermanently,
|
||||
data,
|
||||
)
|
||||
) {
|
||||
return {Icon: LockIcon, message: msg`Chat ended`}
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageDataEditGroup(data)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.systemMessageDataEditGroup, data)
|
||||
) {
|
||||
return {
|
||||
Icon: PencilIcon,
|
||||
message:
|
||||
@@ -114,25 +132,33 @@ export function getSystemMessageInfo(
|
||||
? msg`Chat title changed to ${data.newName}`
|
||||
: msg`Chat title changed`,
|
||||
}
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageDataCreateJoinLink(data)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.systemMessageDataCreateJoinLink, data)
|
||||
) {
|
||||
return {
|
||||
Icon: ChainLinkIcon,
|
||||
message: msg`Invite link created`,
|
||||
action: {kind: 'inviteLink'},
|
||||
}
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageDataEditJoinLink(data)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.systemMessageDataEditJoinLink, data)
|
||||
) {
|
||||
return {
|
||||
Icon: ChainLinkIcon,
|
||||
message: msg`Invite link edited`,
|
||||
action: {kind: 'inviteLink'},
|
||||
}
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageDataEnableJoinLink(data)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.systemMessageDataEnableJoinLink, data)
|
||||
) {
|
||||
return {
|
||||
Icon: ChainLinkIcon,
|
||||
message: msg`Invite link enabled`,
|
||||
action: {kind: 'inviteLink'},
|
||||
}
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageDataDisableJoinLink(data)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.systemMessageDataDisableJoinLink, data)
|
||||
) {
|
||||
return {
|
||||
Icon: ChainLinkBrokenIcon,
|
||||
message: msg`Invite link disabled`,
|
||||
|
||||
@@ -1,12 +1,7 @@
|
||||
import {
|
||||
AppBskyEmbedExternal,
|
||||
AppBskyEmbedRecord,
|
||||
type ChatBskyConvoDefs,
|
||||
ChatBskyEmbedJoinLink,
|
||||
ChatBskyGroupDefs,
|
||||
} from '@atproto/api'
|
||||
import {useLingui} from '@lingui/react/macro'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {app, chat} from '#/lexicons'
|
||||
import {BSKY_APP_HOST, toShortUrl} from '#/lib/strings/url-helpers'
|
||||
|
||||
/**
|
||||
@@ -21,13 +16,13 @@ type ReplyEmbedSummary =
|
||||
| {type: 'unknown'}
|
||||
|
||||
function summarizeReplyEmbed(
|
||||
embed: ChatBskyConvoDefs.MessageView['embed'],
|
||||
embed: chat.bsky.convo.defs.MessageView['embed'],
|
||||
): ReplyEmbedSummary {
|
||||
if (!AppBskyEmbedRecord.isView(embed)) return {type: 'unknown'}
|
||||
if (!bsky.isType(app.bsky.embed.record.view, embed)) return {type: 'unknown'}
|
||||
const {record} = embed
|
||||
if (AppBskyEmbedRecord.isViewRecord(record)) {
|
||||
if (bsky.isType(app.bsky.embed.record.viewRecord, record)) {
|
||||
const inner = record.embeds?.[0]
|
||||
if (AppBskyEmbedExternal.isView(inner)) {
|
||||
if (bsky.isType(app.bsky.embed.external.view, inner)) {
|
||||
return {type: 'external', uri: inner.external.uri}
|
||||
}
|
||||
return {type: 'post'}
|
||||
@@ -45,25 +40,32 @@ function summarizeReplyEmbed(
|
||||
* callers can render it in a muted/italic style.
|
||||
*/
|
||||
export function useReplyPreviewText(): (
|
||||
message: ChatBskyConvoDefs.MessageView,
|
||||
message: chat.bsky.convo.defs.MessageView,
|
||||
) => {text: string; subtle: boolean} {
|
||||
const {t: l} = useLingui()
|
||||
|
||||
return (message: ChatBskyConvoDefs.MessageView) => {
|
||||
return (message: chat.bsky.convo.defs.MessageView) => {
|
||||
const text = message.text
|
||||
if (text.trim()) {
|
||||
return {text, subtle: false}
|
||||
}
|
||||
|
||||
if (ChatBskyEmbedJoinLink.isView(message.embed)) {
|
||||
if (bsky.isType(chat.bsky.embed.joinLink.view, message.embed)) {
|
||||
const {joinLinkPreview} = message.embed
|
||||
if (ChatBskyGroupDefs.isJoinLinkPreviewView(joinLinkPreview)) {
|
||||
if (
|
||||
bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, joinLinkPreview)
|
||||
) {
|
||||
return {
|
||||
text: `${BSKY_APP_HOST}/chat/${joinLinkPreview.code}`,
|
||||
subtle: true,
|
||||
}
|
||||
}
|
||||
if (ChatBskyGroupDefs.isDisabledJoinLinkPreviewView(joinLinkPreview)) {
|
||||
if (
|
||||
bsky.isType(
|
||||
chat.bsky.group.defs.disabledJoinLinkPreviewView,
|
||||
joinLinkPreview,
|
||||
)
|
||||
) {
|
||||
return {
|
||||
text: l({
|
||||
message: '(disabled chat invite link)',
|
||||
@@ -72,7 +74,12 @@ export function useReplyPreviewText(): (
|
||||
subtle: true,
|
||||
}
|
||||
}
|
||||
if (ChatBskyGroupDefs.isInvalidJoinLinkPreviewView(joinLinkPreview)) {
|
||||
if (
|
||||
bsky.isType(
|
||||
chat.bsky.group.defs.invalidJoinLinkPreviewView,
|
||||
joinLinkPreview,
|
||||
)
|
||||
) {
|
||||
return {
|
||||
text: l({
|
||||
message: '(invalid chat invite link)',
|
||||
|
||||
+19
-33
@@ -1,6 +1,7 @@
|
||||
import {type $Typed, ChatBskyActorDefs, ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
|
||||
import {type $Typed} from '@atproto/lex'
|
||||
import {chat} from '#/lexicons'
|
||||
import {EMOJI_REACTION_LIMIT} from '#/lib/constants'
|
||||
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
|
||||
import {moderateProfile} from '#/lib/moderation/subjects'
|
||||
@@ -77,7 +78,7 @@ export function localDateString(date: Date) {
|
||||
}
|
||||
|
||||
export function hasAlreadyReacted(
|
||||
message: ChatBskyConvoDefs.MessageView,
|
||||
message: chat.bsky.convo.defs.MessageView,
|
||||
myDid: string | undefined,
|
||||
emoji: string,
|
||||
): boolean {
|
||||
@@ -98,9 +99,9 @@ export function hasAlreadyReacted(
|
||||
* already render anonymously ("Someone reacted").
|
||||
*/
|
||||
export function filterBlockedReactions(
|
||||
reactions: ChatBskyConvoDefs.ReactionView[] | undefined,
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>,
|
||||
): ChatBskyConvoDefs.ReactionView[] {
|
||||
reactions: chat.bsky.convo.defs.ReactionView[] | undefined,
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>,
|
||||
): chat.bsky.convo.defs.ReactionView[] {
|
||||
if (!reactions) return []
|
||||
return reactions.filter(reaction => {
|
||||
const profile = relatedProfiles.get(reaction.sender.did)
|
||||
@@ -109,7 +110,7 @@ export function filterBlockedReactions(
|
||||
}
|
||||
|
||||
export function hasReachedReactionLimit(
|
||||
message: ChatBskyConvoDefs.MessageView,
|
||||
message: chat.bsky.convo.defs.MessageView,
|
||||
myDid: string | undefined,
|
||||
): boolean {
|
||||
if (!message.reactions) {
|
||||
@@ -170,25 +171,25 @@ export function canReact({
|
||||
return true
|
||||
}
|
||||
|
||||
export type GroupConvoMember = ChatBskyActorDefs.ProfileViewBasic & {
|
||||
export type GroupConvoMember = chat.bsky.actor.defs.ProfileViewBasic & {
|
||||
// can be missing if account deleted
|
||||
kind?: $Typed<ChatBskyActorDefs.GroupConvoMember>
|
||||
kind?: $Typed<chat.bsky.actor.defs.GroupConvoMember>
|
||||
}
|
||||
|
||||
export type DirectConvoMember = ChatBskyActorDefs.ProfileViewBasic & {
|
||||
kind: $Typed<ChatBskyActorDefs.DirectConvoMember>
|
||||
export type DirectConvoMember = chat.bsky.actor.defs.ProfileViewBasic & {
|
||||
kind: $Typed<chat.bsky.actor.defs.DirectConvoMember>
|
||||
}
|
||||
|
||||
export type ConvoWithDetails = {view: ChatBskyConvoDefs.ConvoView} & (
|
||||
export type ConvoWithDetails = {view: chat.bsky.convo.defs.ConvoView} & (
|
||||
| {
|
||||
kind: 'group'
|
||||
details: $Typed<ChatBskyConvoDefs.GroupConvo>
|
||||
details: $Typed<chat.bsky.convo.defs.GroupConvo>
|
||||
primaryMember?: GroupConvoMember // the owner - may have left, thus optional
|
||||
members: Array<GroupConvoMember>
|
||||
}
|
||||
| {
|
||||
kind: 'direct'
|
||||
details: $Typed<ChatBskyConvoDefs.DirectConvo>
|
||||
details: $Typed<chat.bsky.convo.defs.DirectConvo>
|
||||
primaryMember: DirectConvoMember // the other user
|
||||
members: Array<DirectConvoMember>
|
||||
}
|
||||
@@ -199,24 +200,14 @@ export type ConvoWithDetails = {view: ChatBskyConvoDefs.ConvoView} & (
|
||||
* and enforces the correct type for convo members.
|
||||
*/
|
||||
export function parseConvoView(
|
||||
convoView: ChatBskyConvoDefs.ConvoView,
|
||||
convoView: chat.bsky.convo.defs.ConvoView,
|
||||
ownDid: string | undefined,
|
||||
): ConvoWithDetails | null {
|
||||
if (
|
||||
bsky.dangerousIsType<ChatBskyConvoDefs.GroupConvo>(
|
||||
convoView.kind,
|
||||
ChatBskyConvoDefs.isGroupConvo,
|
||||
)
|
||||
) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.groupConvo, convoView.kind)) {
|
||||
let owner: GroupConvoMember | undefined = undefined
|
||||
|
||||
for (const member of convoView.members) {
|
||||
if (
|
||||
bsky.dangerousIsType<ChatBskyActorDefs.GroupConvoMember>(
|
||||
member.kind,
|
||||
ChatBskyActorDefs.isGroupConvoMember,
|
||||
)
|
||||
) {
|
||||
if (bsky.isType(chat.bsky.actor.defs.groupConvoMember, member.kind)) {
|
||||
if (member.kind.role === 'owner') {
|
||||
// have to do a type assertion here
|
||||
// this works: {...member, kind: member.kind}
|
||||
@@ -238,12 +229,7 @@ export function parseConvoView(
|
||||
primaryMember: owner,
|
||||
members: convoView.members as Array<GroupConvoMember>,
|
||||
}
|
||||
} else if (
|
||||
bsky.dangerousIsType<ChatBskyConvoDefs.DirectConvo>(
|
||||
convoView.kind,
|
||||
ChatBskyConvoDefs.isDirectConvo,
|
||||
)
|
||||
) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.directConvo, convoView.kind)) {
|
||||
const otherUser = convoView.members.find(m => m.did !== ownDid)
|
||||
|
||||
if (!otherUser) {
|
||||
@@ -286,7 +272,7 @@ export function getConvoReportSubject(
|
||||
|
||||
const lastMessage = convo.view.lastMessage
|
||||
const reportableMessage =
|
||||
ChatBskyConvoDefs.isMessageView(lastMessage) &&
|
||||
bsky.isType(chat.bsky.convo.defs.messageView, lastMessage) &&
|
||||
lastMessage.sender?.did !== ownDid
|
||||
? lastMessage
|
||||
: null
|
||||
|
||||
Reference in New Issue
Block a user