flip the component type imports to the generated lexicons
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
import {Fragment, useCallback} from 'react'
|
import {Fragment, useCallback} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyActorDefs} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {isJwtExpired} from '#/lib/jwt'
|
import {isJwtExpired} from '#/lib/jwt'
|
||||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
@@ -107,7 +107,7 @@ function AccountItem({
|
|||||||
isCurrentAccount,
|
isCurrentAccount,
|
||||||
isPendingAccount,
|
isPendingAccount,
|
||||||
}: {
|
}: {
|
||||||
profile?: AppBskyActorDefs.ProfileViewDetailed
|
profile?: app.bsky.actor.defs.ProfileViewDetailed
|
||||||
account: SessionAccount
|
account: SessionAccount
|
||||||
onSelect: (account: SessionAccount) => void
|
onSelect: (account: SessionAccount) => void
|
||||||
isCurrentAccount: boolean
|
isCurrentAccount: boolean
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {type Insets, View} from 'react-native'
|
import {type Insets, View} from 'react-native'
|
||||||
import {type ComAtprotoLabelDefs} from '@atproto/api'
|
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {com} from '#/lexicons'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {BotAccountAlert} from '#/components/BotAccountAlert'
|
import {BotAccountAlert} from '#/components/BotAccountAlert'
|
||||||
import {Button} from '#/components/Button'
|
import {Button} from '#/components/Button'
|
||||||
@@ -12,7 +12,7 @@ import type * as bsky from '#/types/bsky'
|
|||||||
|
|
||||||
export function isBotAccount(profile: {
|
export function isBotAccount(profile: {
|
||||||
did: string
|
did: string
|
||||||
labels?: ComAtprotoLabelDefs.Label[]
|
labels?: com.atproto.label.defs.Label[]
|
||||||
}): boolean {
|
}): boolean {
|
||||||
return (
|
return (
|
||||||
profile.labels?.some(l => l.val === 'bot' && l.src === profile.did) ?? false
|
profile.labels?.some(l => l.val === 'bot' && l.src === profile.did) ?? false
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import {useCallback, useEffect, useMemo} from 'react'
|
import {useCallback, useEffect, useMemo} from 'react'
|
||||||
import {type GestureResponderEvent, View} from 'react-native'
|
import {type GestureResponderEvent, View} from 'react-native'
|
||||||
import {type AppBskyFeedDefs, type AppBskyGraphDefs, AtUri} from '@atproto/api'
|
|
||||||
import {RichText as RichTextApi} from '@bsky.app/sdk/richtext'
|
import {RichText as RichTextApi} from '@bsky.app/sdk/richtext'
|
||||||
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {precacheFeedFromGeneratorView} from '#/state/queries/feed'
|
import {precacheFeedFromGeneratorView} from '#/state/queries/feed'
|
||||||
@@ -35,7 +36,7 @@ import type * as bsky from '#/types/bsky'
|
|||||||
import {Trash_Stroke2_Corner0_Rounded as TrashIcon} from './icons/Trash'
|
import {Trash_Stroke2_Corner0_Rounded as TrashIcon} from './icons/Trash'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
view: AppBskyFeedDefs.GeneratorView
|
view: app.bsky.feed.defs.GeneratorView
|
||||||
onPress?: () => void
|
onPress?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,7 +255,7 @@ export function SaveButton({
|
|||||||
pin,
|
pin,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
view: AppBskyFeedDefs.GeneratorView | AppBskyGraphDefs.ListView
|
view: app.bsky.feed.defs.GeneratorView | app.bsky.graph.defs.ListView
|
||||||
pin?: boolean
|
pin?: boolean
|
||||||
text?: boolean
|
text?: boolean
|
||||||
} & Partial<ButtonProps>) {
|
} & Partial<ButtonProps>) {
|
||||||
@@ -269,7 +270,7 @@ function SaveButtonInner({
|
|||||||
text = true,
|
text = true,
|
||||||
...buttonProps
|
...buttonProps
|
||||||
}: {
|
}: {
|
||||||
view: AppBskyFeedDefs.GeneratorView | AppBskyGraphDefs.ListView
|
view: app.bsky.feed.defs.GeneratorView | app.bsky.graph.defs.ListView
|
||||||
pin?: boolean
|
pin?: boolean
|
||||||
text?: boolean
|
text?: boolean
|
||||||
} & Partial<ButtonProps>) {
|
} & Partial<ButtonProps>) {
|
||||||
@@ -379,7 +380,7 @@ function SaveButtonInner({
|
|||||||
export function createProfileFeedHref({
|
export function createProfileFeedHref({
|
||||||
feed,
|
feed,
|
||||||
}: {
|
}: {
|
||||||
feed: AppBskyFeedDefs.GeneratorView
|
feed: app.bsky.feed.defs.GeneratorView
|
||||||
}) {
|
}) {
|
||||||
const urip = new AtUri(feed.uri)
|
const urip = new AtUri(feed.uri)
|
||||||
const handleOrDid = feed.creator.handle || feed.creator.did
|
const handleOrDid = feed.creator.handle || feed.creator.did
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import Animated, {
|
|||||||
LayoutAnimationConfig,
|
LayoutAnimationConfig,
|
||||||
LinearTransition,
|
LinearTransition,
|
||||||
} from 'react-native-reanimated'
|
} from 'react-native-reanimated'
|
||||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
|
||||||
import {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type NavigationProp} from '#/lib/routes/types'
|
import {type NavigationProp} from '#/lib/routes/types'
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {useGetPopularFeedsQuery} from '#/state/queries/feed'
|
import {useGetPopularFeedsQuery} from '#/state/queries/feed'
|
||||||
@@ -569,7 +569,7 @@ export function SuggestedFeeds() {
|
|||||||
const {gtMobile} = useBreakpoints()
|
const {gtMobile} = useBreakpoints()
|
||||||
|
|
||||||
const feeds = useMemo(() => {
|
const feeds = useMemo(() => {
|
||||||
const items: AppBskyFeedDefs.GeneratorView[] = []
|
const items: app.bsky.feed.defs.GeneratorView[] = []
|
||||||
|
|
||||||
if (!data) return items
|
if (!data) return items
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {useRef} from 'react'
|
import {useRef} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyActorDefs} from '@atproto/api'
|
|
||||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||||
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {moderateProfile} from '#/lib/moderation/subjects'
|
import {moderateProfile} from '#/lib/moderation/subjects'
|
||||||
import {makeProfileLink} from '#/lib/routes/links'
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||||
@@ -24,7 +24,7 @@ const AVI_BORDER = 1
|
|||||||
* `count` includes blocked users and `followers` does not.
|
* `count` includes blocked users and `followers` does not.
|
||||||
*/
|
*/
|
||||||
export function shouldShowKnownFollowers(
|
export function shouldShowKnownFollowers(
|
||||||
knownFollowers?: AppBskyActorDefs.KnownFollowers,
|
knownFollowers?: app.bsky.actor.defs.KnownFollowers,
|
||||||
) {
|
) {
|
||||||
return knownFollowers && knownFollowers.followers.length > 0
|
return knownFollowers && knownFollowers.followers.length > 0
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,9 @@ export function KnownFollowers({
|
|||||||
minimal?: boolean
|
minimal?: boolean
|
||||||
showIfEmpty?: boolean
|
showIfEmpty?: boolean
|
||||||
}) {
|
}) {
|
||||||
const cache = useRef<Map<string, AppBskyActorDefs.KnownFollowers>>(new Map())
|
const cache = useRef<Map<string, app.bsky.actor.defs.KnownFollowers>>(
|
||||||
|
new Map(),
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Results for `knownFollowers` are not sorted consistently, so when
|
* Results for `knownFollowers` are not sorted consistently, so when
|
||||||
@@ -83,7 +85,7 @@ function KnownFollowersInner({
|
|||||||
}: {
|
}: {
|
||||||
profile: bsky.profile.AnyProfileView
|
profile: bsky.profile.AnyProfileView
|
||||||
moderationOpts: ModerationOpts
|
moderationOpts: ModerationOpts
|
||||||
cachedKnownFollowers: AppBskyActorDefs.KnownFollowers
|
cachedKnownFollowers: app.bsky.actor.defs.KnownFollowers
|
||||||
onLinkPress?: LinkProps['onPress']
|
onLinkPress?: LinkProps['onPress']
|
||||||
minimal?: boolean
|
minimal?: boolean
|
||||||
showIfEmpty?: boolean
|
showIfEmpty?: boolean
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {useCallback, useMemo, useState} from 'react'
|
import {useCallback, useMemo, useState} from 'react'
|
||||||
import {type AppBskyFeedGetLikes as GetLikes} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||||
import {cleanError} from '#/lib/strings/errors'
|
import {cleanError} from '#/lib/strings/errors'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
@@ -12,7 +12,13 @@ import {ProfileCardWithFollowBtn} from '#/view/com/profile/ProfileCard'
|
|||||||
import {List} from '#/view/com/util/List'
|
import {List} from '#/view/com/util/List'
|
||||||
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
|
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
|
||||||
|
|
||||||
function renderItem({item, index}: {item: GetLikes.Like; index: number}) {
|
function renderItem({
|
||||||
|
item,
|
||||||
|
index,
|
||||||
|
}: {
|
||||||
|
item: app.bsky.feed.getLikes.Like
|
||||||
|
index: number
|
||||||
|
}) {
|
||||||
return (
|
return (
|
||||||
<ProfileCardWithFollowBtn
|
<ProfileCardWithFollowBtn
|
||||||
key={item.actor.did}
|
key={item.actor.did}
|
||||||
@@ -22,7 +28,7 @@ function renderItem({item, index}: {item: GetLikes.Like; index: number}) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function keyExtractor(item: GetLikes.Like) {
|
function keyExtractor(item: app.bsky.feed.getLikes.Like) {
|
||||||
return item.actor.did
|
return item.actor.did
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import {useEffect, useMemo} from 'react'
|
import {useEffect, useMemo} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyGraphDefs, AtUri} from '@atproto/api'
|
|
||||||
import {type ModerationUI} from '@bsky.app/sdk/moderation'
|
import {type ModerationUI} from '@bsky.app/sdk/moderation'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {moderateUserList} from '#/lib/moderation/subjects'
|
import {moderateUserList} from '#/lib/moderation/subjects'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
@@ -44,7 +45,7 @@ const CURATELIST = 'app.bsky.graph.defs#curatelist'
|
|||||||
const MODLIST = 'app.bsky.graph.defs#modlist'
|
const MODLIST = 'app.bsky.graph.defs#modlist'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
view: AppBskyGraphDefs.ListView
|
view: app.bsky.graph.defs.ListView
|
||||||
showPinButton?: boolean
|
showPinButton?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +109,7 @@ export function TitleAndByline({
|
|||||||
}: {
|
}: {
|
||||||
title: string
|
title: string
|
||||||
creator?: bsky.profile.AnyProfileView
|
creator?: bsky.profile.AnyProfileView
|
||||||
purpose?: AppBskyGraphDefs.ListView['purpose']
|
purpose?: app.bsky.graph.defs.ListView['purpose']
|
||||||
modUi?: ModerationUI
|
modUi?: ModerationUI
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
@@ -157,7 +158,7 @@ export function TitleAndByline({
|
|||||||
export function createProfileListHref({
|
export function createProfileListHref({
|
||||||
list,
|
list,
|
||||||
}: {
|
}: {
|
||||||
list: AppBskyGraphDefs.ListView
|
list: app.bsky.graph.defs.ListView
|
||||||
}) {
|
}) {
|
||||||
const urip = new AtUri(list.uri)
|
const urip = new AtUri(list.uri)
|
||||||
const handleOrDid = list.creator.handle || list.creator.did
|
const handleOrDid = list.creator.handle || list.creator.did
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
import {type StyleProp, StyleSheet, View, type ViewStyle} from 'react-native'
|
import {type StyleProp, StyleSheet, View, type ViewStyle} from 'react-native'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {
|
|
||||||
AppBskyEmbedGallery,
|
|
||||||
type AppBskyEmbedImages,
|
|
||||||
type AppBskyFeedDefs,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {shareImageModal} from '#/lib/media/manip'
|
import {shareImageModal} from '#/lib/media/manip'
|
||||||
import {useSaveImageToMediaLibrary} from '#/lib/media/save-image'
|
import {useSaveImageToMediaLibrary} from '#/lib/media/save-image'
|
||||||
import {isGifEmbed} from '#/lib/strings/embed-player'
|
import {isGifEmbed} from '#/lib/strings/embed-player'
|
||||||
@@ -27,7 +23,7 @@ export function Embed({
|
|||||||
style,
|
style,
|
||||||
peekable = false,
|
peekable = false,
|
||||||
}: {
|
}: {
|
||||||
embed: AppBskyFeedDefs.PostView['embed']
|
embed: app.bsky.feed.defs.PostView['embed']
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
peekable?: boolean
|
peekable?: boolean
|
||||||
}) {
|
}) {
|
||||||
@@ -59,9 +55,9 @@ export function Embed({
|
|||||||
const tiles: React.ReactNode[] = []
|
const tiles: React.ReactNode[] = []
|
||||||
for (const item of e.view.items) {
|
for (const item of e.view.items) {
|
||||||
if (tiles.length >= 4) break
|
if (tiles.length >= 4) break
|
||||||
if (!AppBskyEmbedGallery.isViewImage(item)) continue
|
if (!bsky.isType(app.bsky.embed.gallery.viewImage, item)) continue
|
||||||
if (peekable) {
|
if (peekable) {
|
||||||
const image: AppBskyEmbedImages.ViewImage = {
|
const image: app.bsky.embed.images.ViewImage = {
|
||||||
thumb: item.thumbnail,
|
thumb: item.thumbnail,
|
||||||
fullsize: item.fullsize,
|
fullsize: item.fullsize,
|
||||||
alt: item.alt,
|
alt: item.alt,
|
||||||
@@ -202,7 +198,7 @@ export function VideoItem({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function PeekableImageItem({image}: {image: AppBskyEmbedImages.ViewImage}) {
|
function PeekableImageItem({image}: {image: app.bsky.embed.images.ViewImage}) {
|
||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
const saveImage = useSaveImageToMediaLibrary()
|
const saveImage = useSaveImageToMediaLibrary()
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {useMemo, useState} from 'react'
|
import {useMemo, useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyActorDefs} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
import {differenceInSeconds} from 'date-fns'
|
import {differenceInSeconds} from 'date-fns'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {HITSLOP_10} from '#/lib/constants'
|
import {HITSLOP_10} from '#/lib/constants'
|
||||||
import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
|
import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
|
||||||
import {moderateProfile} from '#/lib/moderation/subjects'
|
import {moderateProfile} from '#/lib/moderation/subjects'
|
||||||
@@ -25,7 +25,7 @@ export function NewskieDialog({
|
|||||||
profile,
|
profile,
|
||||||
disabled,
|
disabled,
|
||||||
}: {
|
}: {
|
||||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
@@ -75,7 +75,7 @@ function DialogInner({
|
|||||||
createdAt,
|
createdAt,
|
||||||
now,
|
now,
|
||||||
}: {
|
}: {
|
||||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||||
createdAt: string
|
createdAt: string
|
||||||
now: number
|
now: number
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {type StyleProp, type ViewStyle} from 'react-native'
|
import {type StyleProp, type ViewStyle} from 'react-native'
|
||||||
import {type AppBskyEmbedExternal} from '@atproto/api'
|
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a} from '#/alf'
|
||||||
import * as ChatInvite from '#/components/dms/ChatInvite'
|
import * as ChatInvite from '#/components/dms/ChatInvite'
|
||||||
import {ExternalEmbed} from '#/components/Post/Embed/ExternalEmbed'
|
import {ExternalEmbed} from '#/components/Post/Embed/ExternalEmbed'
|
||||||
@@ -18,7 +18,7 @@ export function ChatInviteEmbed({
|
|||||||
style,
|
style,
|
||||||
}: {
|
}: {
|
||||||
code: string
|
code: string
|
||||||
link: AppBskyEmbedExternal.ViewExternal
|
link: app.bsky.embed.external.ViewExternal
|
||||||
onOpen?: () => void
|
onOpen?: () => void
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
}) {
|
}) {
|
||||||
@@ -34,7 +34,7 @@ function ChatInviteEmbedBody({
|
|||||||
onOpen,
|
onOpen,
|
||||||
style,
|
style,
|
||||||
}: {
|
}: {
|
||||||
link: AppBskyEmbedExternal.ViewExternal
|
link: app.bsky.embed.external.ViewExternal
|
||||||
onOpen?: () => void
|
onOpen?: () => void
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import {
|
|||||||
Pressable,
|
Pressable,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {type AppBskyEmbedExternal} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type EmbedPlayerParams} from '#/lib/strings/embed-player'
|
import {type EmbedPlayerParams} from '#/lib/strings/embed-player'
|
||||||
import {useExternalEmbedsPrefs} from '#/state/preferences'
|
import {useExternalEmbedsPrefs} from '#/state/preferences'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
@@ -22,7 +22,7 @@ export function ExternalGif({
|
|||||||
link,
|
link,
|
||||||
params,
|
params,
|
||||||
}: {
|
}: {
|
||||||
link: AppBskyEmbedExternal.ViewExternal
|
link: app.bsky.embed.external.ViewExternal
|
||||||
params: EmbedPlayerParams
|
params: EmbedPlayerParams
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
|||||||
@@ -15,11 +15,11 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context'
|
|||||||
import {WebView} from 'react-native-webview'
|
import {WebView} from 'react-native-webview'
|
||||||
import {scheduleOnRN} from 'react-native-worklets'
|
import {scheduleOnRN} from 'react-native-worklets'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {type AppBskyEmbedExternal} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type NavigationProp} from '#/lib/routes/types'
|
import {type NavigationProp} from '#/lib/routes/types'
|
||||||
import {
|
import {
|
||||||
type EmbedPlayerParams,
|
type EmbedPlayerParams,
|
||||||
@@ -122,7 +122,7 @@ export function ExternalPlayer({
|
|||||||
link,
|
link,
|
||||||
params,
|
params,
|
||||||
}: {
|
}: {
|
||||||
link: AppBskyEmbedExternal.ViewExternal
|
link: app.bsky.embed.external.ViewExternal
|
||||||
params: EmbedPlayerParams
|
params: EmbedPlayerParams
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {useMemo} from 'react'
|
import {useMemo} from 'react'
|
||||||
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {type AppBskyEmbedExternal} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {parseAltFromGIFDescription} from '#/lib/gif-alt-text'
|
import {parseAltFromGIFDescription} from '#/lib/gif-alt-text'
|
||||||
import {useHaptics} from '#/lib/haptics'
|
import {useHaptics} from '#/lib/haptics'
|
||||||
import {shareUrl} from '#/lib/sharing'
|
import {shareUrl} from '#/lib/sharing'
|
||||||
@@ -30,7 +30,7 @@ export const ExternalEmbed = ({
|
|||||||
style,
|
style,
|
||||||
hideAlt,
|
hideAlt,
|
||||||
}: {
|
}: {
|
||||||
link: AppBskyEmbedExternal.ViewExternal
|
link: app.bsky.embed.external.ViewExternal
|
||||||
onOpen?: () => void
|
onOpen?: () => void
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
hideAlt?: boolean
|
hideAlt?: boolean
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ import {useRef} from 'react'
|
|||||||
import {InteractionManager, View} from 'react-native'
|
import {InteractionManager, View} from 'react-native'
|
||||||
import {type AnimatedRef} from 'react-native-reanimated'
|
import {type AnimatedRef} from 'react-native-reanimated'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {AppBskyEmbedGallery, type AppBskyEmbedImages} from '@atproto/api'
|
|
||||||
|
|
||||||
|
import * as bsky from '#/types/bsky'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {atoms as a, tokens} from '#/alf'
|
import {atoms as a, tokens} from '#/alf'
|
||||||
import {AutoSizedImage} from '#/components/images/AutoSizedImage'
|
import {AutoSizedImage} from '#/components/images/AutoSizedImage'
|
||||||
import {Gallery} from '#/components/images/Gallery'
|
import {Gallery} from '#/components/images/Gallery'
|
||||||
@@ -29,14 +30,16 @@ export function ImageEmbed({
|
|||||||
}) {
|
}) {
|
||||||
const ax = useAnalytics()
|
const ax = useAnalytics()
|
||||||
const {openLightbox} = useLightboxControls()
|
const {openLightbox} = useLightboxControls()
|
||||||
const images: AppBskyEmbedImages.ViewImage[] =
|
const images: app.bsky.embed.images.ViewImage[] =
|
||||||
embed.type === 'gallery'
|
embed.type === 'gallery'
|
||||||
? embed.view.items.filter(AppBskyEmbedGallery.isViewImage).map(item => ({
|
? embed.view.items
|
||||||
thumb: item.thumbnail,
|
.filter(item => bsky.isType(app.bsky.embed.gallery.viewImage, item))
|
||||||
fullsize: item.fullsize,
|
.map(item => ({
|
||||||
alt: item.alt,
|
thumb: item.thumbnail,
|
||||||
aspectRatio: item.aspectRatio,
|
fullsize: item.fullsize,
|
||||||
}))
|
alt: item.alt,
|
||||||
|
aspectRatio: item.aspectRatio,
|
||||||
|
}))
|
||||||
: embed.view.images
|
: embed.view.images
|
||||||
const useExpandedLayout =
|
const useExpandedLayout =
|
||||||
embed.type === 'gallery'
|
embed.type === 'gallery'
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {Fragment, type ReactNode} from 'react'
|
import {Fragment, type ReactNode} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {AtUri} from '@atproto/api'
|
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
import {toNiceDomain} from '#/lib/strings/url-helpers'
|
import {toNiceDomain} from '#/lib/strings/url-helpers'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {type AppBskyEmbedExternal} from '@atproto/api'
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
import {Context, useAlf, utils} from '#/alf'
|
import {Context, useAlf, utils} from '#/alf'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12,7 +11,7 @@ export function StandardSiteThemeProvider({
|
|||||||
view,
|
view,
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
view: AppBskyEmbedExternal.ViewExternal
|
view: app.bsky.embed.external.ViewExternal
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
const alf = useAlf()
|
const alf = useAlf()
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {AtUri} from '@atproto/api'
|
|
||||||
import {plural} from '@lingui/core/macro'
|
import {plural} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
import {useHaptics} from '#/lib/haptics'
|
import {useHaptics} from '#/lib/haptics'
|
||||||
import {shareUrl} from '#/lib/sharing'
|
import {shareUrl} from '#/lib/sharing'
|
||||||
import {niceDate} from '#/lib/strings/time'
|
import {niceDate} from '#/lib/strings/time'
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {type AppBskyEmbedExternal} from '@atproto/api'
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
import {Leaflet} from '#/components/icons/community/Leaflet'
|
import {Leaflet} from '#/components/icons/community/Leaflet'
|
||||||
import {Offprint} from '#/components/icons/community/Offprint'
|
import {Offprint} from '#/components/icons/community/Offprint'
|
||||||
import {Pckt} from '#/components/icons/community/Pckt'
|
import {Pckt} from '#/components/icons/community/Pckt'
|
||||||
@@ -25,7 +24,7 @@ function hostFromUri(uri: string | undefined): string | null {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getStandardSitePublisherHost(
|
export function getStandardSitePublisherHost(
|
||||||
view: AppBskyEmbedExternal.ViewExternal,
|
view: app.bsky.embed.external.ViewExternal,
|
||||||
): string | null {
|
): string | null {
|
||||||
return hostFromUri(view.source?.uri)
|
return hostFromUri(view.source?.uri)
|
||||||
}
|
}
|
||||||
@@ -40,7 +39,7 @@ function matchByHost(host: string | null): StandardSitePublisher | null {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function matchStandardSitePublisher(
|
export function matchStandardSitePublisher(
|
||||||
view: AppBskyEmbedExternal.ViewExternal,
|
view: app.bsky.embed.external.ViewExternal,
|
||||||
): StandardSitePublisher | null {
|
): StandardSitePublisher | null {
|
||||||
return matchByHost(getStandardSitePublisherHost(view))
|
return matchByHost(getStandardSitePublisherHost(view))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {type AppBskyEmbedExternal} from '@atproto/api'
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
export type CommonProps = {
|
export type CommonProps = {
|
||||||
view: AppBskyEmbedExternal.ViewExternal
|
view: app.bsky.embed.external.ViewExternal
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PreviewProps = {
|
export type PreviewProps = {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import {type AppBskyEmbedExternal} from '@atproto/api'
|
|
||||||
|
|
||||||
import {isStandardSiteEmbed, isStandardSitePublicationEmbed} from './utils'
|
import {isStandardSiteEmbed, isStandardSitePublicationEmbed} from './utils'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
function makeView(
|
function makeView(
|
||||||
partial: Record<string, unknown>,
|
partial: Record<string, unknown>,
|
||||||
): AppBskyEmbedExternal.ViewExternal {
|
): app.bsky.embed.external.ViewExternal {
|
||||||
return {
|
return {
|
||||||
uri: 'https://example.com/post',
|
uri: 'https://example.com/post',
|
||||||
title: 'title',
|
title: 'title',
|
||||||
|
|||||||
@@ -1,29 +1,30 @@
|
|||||||
import {
|
import {AtUri} from '@atproto/syntax'
|
||||||
type AppBskyEmbedExternal,
|
import {app, com} from '#/lexicons'
|
||||||
AtUri,
|
|
||||||
type ComAtprotoRepoStrongRef,
|
|
||||||
} from '@atproto/api'
|
|
||||||
|
|
||||||
export function isStandardSiteDocumentUri(ref: ComAtprotoRepoStrongRef.Main) {
|
export function isStandardSiteDocumentUri(
|
||||||
|
ref: com.atproto.repo.strongRef.Main,
|
||||||
|
) {
|
||||||
return new AtUri(ref.uri).collection.startsWith('site.standard.document')
|
return new AtUri(ref.uri).collection.startsWith('site.standard.document')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isStandardSitePublicationUri(
|
export function isStandardSitePublicationUri(
|
||||||
ref: ComAtprotoRepoStrongRef.Main,
|
ref: com.atproto.repo.strongRef.Main,
|
||||||
) {
|
) {
|
||||||
return new AtUri(ref.uri).collection.startsWith('site.standard.publication')
|
return new AtUri(ref.uri).collection.startsWith('site.standard.publication')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isStandardSiteUri(ref: ComAtprotoRepoStrongRef.Main) {
|
export function isStandardSiteUri(ref: com.atproto.repo.strongRef.Main) {
|
||||||
return new AtUri(ref.uri).collection.startsWith('site.standard.')
|
return new AtUri(ref.uri).collection.startsWith('site.standard.')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isStandardSiteEmbed(view: AppBskyEmbedExternal.ViewExternal) {
|
export function isStandardSiteEmbed(
|
||||||
|
view: app.bsky.embed.external.ViewExternal,
|
||||||
|
) {
|
||||||
return view.associatedRefs?.some(ref => isStandardSiteUri(ref))
|
return view.associatedRefs?.some(ref => isStandardSiteUri(ref))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isStandardSitePublicationEmbed(
|
export function isStandardSitePublicationEmbed(
|
||||||
view: AppBskyEmbedExternal.ViewExternal,
|
view: app.bsky.embed.external.ViewExternal,
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
view.associatedRefs?.some(
|
view.associatedRefs?.some(
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {useImperativeHandle, useRef, useState} from 'react'
|
import {useImperativeHandle, useRef, useState} from 'react'
|
||||||
import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native'
|
import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native'
|
||||||
import {type AppBskyEmbedVideo} from '@atproto/api'
|
|
||||||
import {BlueskyVideoView} from '@bsky.app/video'
|
import {BlueskyVideoView} from '@bsky.app/video'
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {HITSLOP_30} from '#/lib/constants'
|
import {HITSLOP_30} from '#/lib/constants'
|
||||||
import {useAutoplayDisabled} from '#/state/preferences'
|
import {useAutoplayDisabled} from '#/state/preferences'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
@@ -29,7 +29,7 @@ export function VideoEmbedInnerNative({
|
|||||||
onError,
|
onError,
|
||||||
}: {
|
}: {
|
||||||
ref: React.Ref<{togglePlayback: () => void}>
|
ref: React.Ref<{togglePlayback: () => void}>
|
||||||
embed: AppBskyEmbedVideo.View
|
embed: app.bsky.embed.video.View
|
||||||
setStatus: (status: 'playing' | 'paused') => void
|
setStatus: (status: 'playing' | 'paused') => void
|
||||||
setIsLoading: (isLoading: boolean) => void
|
setIsLoading: (isLoading: boolean) => void
|
||||||
setIsActive: (isActive: boolean) => void
|
setIsActive: (isActive: boolean) => void
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {type AppBskyEmbedVideo} from '@atproto/api'
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
export type VideoEmbedInnerWebProps = {
|
export type VideoEmbedInnerWebProps = {
|
||||||
embed: AppBskyEmbedVideo.View
|
embed: app.bsky.embed.video.View
|
||||||
active: boolean
|
active: boolean
|
||||||
setActive: () => void
|
setActive: () => void
|
||||||
onScreen: boolean
|
onScreen: boolean
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import {useCallback, useEffect, useRef, useState} from 'react'
|
import {useCallback, useEffect, useRef, useState} from 'react'
|
||||||
import {ActivityIndicator, View} from 'react-native'
|
import {ActivityIndicator, View} from 'react-native'
|
||||||
import {ImageBackground} from 'expo-image'
|
import {ImageBackground} from 'expo-image'
|
||||||
import {type AppBskyEmbedVideo} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
@@ -10,6 +9,7 @@ import {
|
|||||||
createPlaybackTelemetry,
|
createPlaybackTelemetry,
|
||||||
type PlaybackTelemetry,
|
type PlaybackTelemetry,
|
||||||
} from '#/lib/media/video/playbackTelemetry'
|
} from '#/lib/media/video/playbackTelemetry'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
|
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
|
||||||
import {atoms as a, platform} from '#/alf'
|
import {atoms as a, platform} from '#/alf'
|
||||||
import {Button} from '#/components/Button'
|
import {Button} from '#/components/Button'
|
||||||
@@ -22,7 +22,7 @@ import {VideoEmbedInnerNative} from './VideoEmbedInner/VideoEmbedInnerNative'
|
|||||||
import * as VideoFallback from './VideoEmbedInner/VideoFallback'
|
import * as VideoFallback from './VideoEmbedInner/VideoFallback'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
embed: AppBskyEmbedVideo.View
|
embed: app.bsky.embed.video.View
|
||||||
}
|
}
|
||||||
|
|
||||||
export function VideoEmbed({embed}: Props) {
|
export function VideoEmbed({embed}: Props) {
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import {
|
|||||||
useState,
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyEmbedVideo} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
|
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
import {useIsWithinMessage} from '#/components/dms/MessageContext'
|
import {useIsWithinMessage} from '#/components/dms/MessageContext'
|
||||||
@@ -37,7 +37,7 @@ const noop = () => {}
|
|||||||
*/
|
*/
|
||||||
const MIN_CARD_WIDTH = 280
|
const MIN_CARD_WIDTH = 280
|
||||||
|
|
||||||
export function VideoEmbed({embed}: {embed: AppBskyEmbedVideo.View}) {
|
export function VideoEmbed({embed}: {embed: app.bsky.embed.video.View}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const ref = useRef<HTMLDivElement>(null)
|
const ref = useRef<HTMLDivElement>(null)
|
||||||
const {
|
const {
|
||||||
@@ -297,7 +297,7 @@ function VideoError({
|
|||||||
error,
|
error,
|
||||||
retry,
|
retry,
|
||||||
}: {
|
}: {
|
||||||
embed: AppBskyEmbedVideo.View
|
embed: app.bsky.embed.video.View
|
||||||
error: unknown
|
error: unknown
|
||||||
retry: () => void
|
retry: () => void
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
import {useCallback, useMemo} from 'react'
|
import {useCallback, useMemo} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {
|
|
||||||
type $Typed,
|
|
||||||
type AppBskyFeedDefs,
|
|
||||||
AppBskyFeedPost,
|
|
||||||
AtUri,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {type $Typed} from '@atproto/lex'
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {moderatePost} from '#/lib/moderation/subjects'
|
import {moderatePost} from '#/lib/moderation/subjects'
|
||||||
import {makeProfileLink} from '#/lib/routes/links'
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
import {asSdkFacets} from '#/lib/strings/rich-text-helpers'
|
import {asSdkFacets} from '#/lib/strings/rich-text-helpers'
|
||||||
@@ -267,7 +264,7 @@ export function QuoteEmbed({
|
|||||||
linkDisabled?: boolean
|
linkDisabled?: boolean
|
||||||
}) {
|
}) {
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
const quote = useMemo<$Typed<AppBskyFeedDefs.PostView>>(
|
const quote = useMemo<$Typed<app.bsky.feed.defs.PostView>>(
|
||||||
() => ({
|
() => ({
|
||||||
...embed.view,
|
...embed.view,
|
||||||
$type: 'app.bsky.feed.defs#postView',
|
$type: 'app.bsky.feed.defs#postView',
|
||||||
@@ -287,13 +284,7 @@ export function QuoteEmbed({
|
|||||||
const itemTitle = `Post by ${quote.author.handle}`
|
const itemTitle = `Post by ${quote.author.handle}`
|
||||||
|
|
||||||
const richText = useMemo(() => {
|
const richText = useMemo(() => {
|
||||||
if (
|
if (!bsky.isType(app.bsky.feed.post, quote.record)) return undefined
|
||||||
!bsky.dangerousIsType<AppBskyFeedPost.Record>(
|
|
||||||
quote.record,
|
|
||||||
AppBskyFeedPost.isRecord,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return undefined
|
|
||||||
const {text, facets} = quote.record
|
const {text, facets} = quote.record
|
||||||
return text.trim()
|
return text.trim()
|
||||||
? new RichTextAPI({text: text, facets: asSdkFacets(facets)})
|
? new RichTextAPI({text: text, facets: asSdkFacets(facets)})
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import {type StyleProp, type ViewStyle} from 'react-native'
|
import {type StyleProp, type ViewStyle} from 'react-native'
|
||||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
|
||||||
import {type ModerationDecision} from '@bsky.app/sdk/moderation'
|
import {type ModerationDecision} from '@bsky.app/sdk/moderation'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
export enum PostEmbedViewContext {
|
export enum PostEmbedViewContext {
|
||||||
ThreadHighlighted = 'ThreadHighlighted',
|
ThreadHighlighted = 'ThreadHighlighted',
|
||||||
@@ -20,10 +20,10 @@ export type CommonProps = {
|
|||||||
* events (post:photoEmbed:*). When the embed has no owning post (e.g.
|
* events (post:photoEmbed:*). When the embed has no owning post (e.g.
|
||||||
* composer previews), leave this undefined and no events will be emitted.
|
* composer previews), leave this undefined and no events will be emitted.
|
||||||
*/
|
*/
|
||||||
post?: AppBskyFeedDefs.PostView
|
post?: app.bsky.feed.defs.PostView
|
||||||
feedDescriptor?: string
|
feedDescriptor?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type EmbedProps = CommonProps & {
|
export type EmbedProps = CommonProps & {
|
||||||
embed?: AppBskyFeedDefs.PostView['embed']
|
embed?: app.bsky.feed.defs.PostView['embed']
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {useCallback, useMemo} from 'react'
|
import {useCallback, useMemo} from 'react'
|
||||||
import {Platform, type StyleProp, type TextStyle, View} from 'react-native'
|
import {Platform, type StyleProp, type TextStyle, View} from 'react-native'
|
||||||
import {type AppBskyFeedDefs, AppBskyFeedPost} from '@atproto/api'
|
|
||||||
import {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {HITSLOP_30} from '#/lib/constants'
|
import {HITSLOP_30} from '#/lib/constants'
|
||||||
import {useTranslate} from '#/lib/translation'
|
import {useTranslate} from '#/lib/translation'
|
||||||
import {
|
import {
|
||||||
@@ -38,7 +38,7 @@ export function TranslatedPost({
|
|||||||
postTextStyle = a.text_md,
|
postTextStyle = a.text_md,
|
||||||
}: {
|
}: {
|
||||||
hideTranslateLink?: boolean
|
hideTranslateLink?: boolean
|
||||||
post: AppBskyFeedDefs.PostView
|
post: app.bsky.feed.defs.PostView
|
||||||
postTextStyle?: StyleProp<TextStyle>
|
postTextStyle?: StyleProp<TextStyle>
|
||||||
}) {
|
}) {
|
||||||
const langPrefs = useLanguagePrefs()
|
const langPrefs = useLanguagePrefs()
|
||||||
@@ -46,11 +46,8 @@ export function TranslatedPost({
|
|||||||
key: post.uri,
|
key: post.uri,
|
||||||
})
|
})
|
||||||
|
|
||||||
const record = useMemo<AppBskyFeedPost.Record | undefined>(() => {
|
const record = useMemo<app.bsky.feed.post.Main | undefined>(() => {
|
||||||
return bsky.dangerousIsType<AppBskyFeedPost.Record>(
|
return bsky.isType(app.bsky.feed.post, post.record)
|
||||||
post.record,
|
|
||||||
AppBskyFeedPost.isRecord,
|
|
||||||
)
|
|
||||||
? post.record
|
? post.record
|
||||||
: undefined
|
: undefined
|
||||||
}, [post])
|
}, [post])
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {memo} from 'react'
|
import {memo} from 'react'
|
||||||
import {type Insets} from 'react-native'
|
import {type Insets} from 'react-native'
|
||||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {useCleanError} from '#/lib/hooks/useCleanError'
|
import {useCleanError} from '#/lib/hooks/useCleanError'
|
||||||
import {type Shadow} from '#/state/cache/post-shadow'
|
import {type Shadow} from '#/state/cache/post-shadow'
|
||||||
import {useFeedFeedbackContext} from '#/state/feed-feedback'
|
import {useFeedFeedbackContext} from '#/state/feed-feedback'
|
||||||
@@ -23,7 +23,7 @@ export const BookmarkButton = memo(function BookmarkButton({
|
|||||||
logContext,
|
logContext,
|
||||||
hitSlop,
|
hitSlop,
|
||||||
}: {
|
}: {
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>
|
post: Shadow<app.bsky.feed.defs.PostView>
|
||||||
big?: boolean
|
big?: boolean
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'ImmersiveVideo'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'ImmersiveVideo'
|
||||||
hitSlop?: Insets
|
hitSlop?: Insets
|
||||||
|
|||||||
@@ -6,17 +6,13 @@ import {
|
|||||||
type ViewStyle,
|
type ViewStyle,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import * as Clipboard from 'expo-clipboard'
|
import * as Clipboard from 'expo-clipboard'
|
||||||
import {
|
|
||||||
type AppBskyFeedDefs,
|
|
||||||
type AppBskyFeedPost,
|
|
||||||
type AppBskyFeedThreadgate,
|
|
||||||
AtUri,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {type RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
import {type RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||||
import {plural} from '@lingui/core/macro'
|
import {plural} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {DISCOVER_DEBUG_DIDS} from '#/lib/constants'
|
import {DISCOVER_DEBUG_DIDS} from '#/lib/constants'
|
||||||
import {useOpenLink} from '#/lib/hooks/useOpenLink'
|
import {useOpenLink} from '#/lib/hooks/useOpenLink'
|
||||||
import {getCurrentRoute} from '#/lib/routes/helpers'
|
import {getCurrentRoute} from '#/lib/routes/helpers'
|
||||||
@@ -110,17 +106,17 @@ let PostMenuItems = ({
|
|||||||
forceGoogleTranslate,
|
forceGoogleTranslate,
|
||||||
}: {
|
}: {
|
||||||
testID: string
|
testID: string
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>
|
post: Shadow<app.bsky.feed.defs.PostView>
|
||||||
postFeedContext: string | undefined
|
postFeedContext: string | undefined
|
||||||
postReqId: string | undefined
|
postReqId: string | undefined
|
||||||
record: AppBskyFeedPost.Record
|
record: app.bsky.feed.post.Main
|
||||||
richText: RichTextAPI
|
richText: RichTextAPI
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
hitSlop?: PressableProps['hitSlop']
|
hitSlop?: PressableProps['hitSlop']
|
||||||
size?: 'lg' | 'md' | 'sm'
|
size?: 'lg' | 'md' | 'sm'
|
||||||
timestamp: string
|
timestamp: string
|
||||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
threadgateRecord?: app.bsky.feed.threadgate.Main
|
||||||
onShowLess?: (interaction: AppBskyFeedDefs.Interaction) => void
|
onShowLess?: (interaction: app.bsky.feed.defs.Interaction) => void
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'ImmersiveVideo'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'ImmersiveVideo'
|
||||||
forceGoogleTranslate: boolean
|
forceGoogleTranslate: boolean
|
||||||
}): React.ReactNode => {
|
}): React.ReactNode => {
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
import {memo, useMemo, useState} from 'react'
|
import {memo, useMemo, useState} from 'react'
|
||||||
import {type Insets} from 'react-native'
|
import {type Insets} from 'react-native'
|
||||||
import {
|
|
||||||
type AppBskyFeedDefs,
|
|
||||||
type AppBskyFeedPost,
|
|
||||||
type AppBskyFeedThreadgate,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {type RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
import {type RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type Shadow} from '#/state/cache/post-shadow'
|
import {type Shadow} from '#/state/cache/post-shadow'
|
||||||
import {EventStopper} from '#/view/com/util/EventStopper'
|
import {EventStopper} from '#/view/com/util/EventStopper'
|
||||||
import {DotGrid3x1_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid'
|
import {DotGrid3x1_Stroke2_Corner0_Rounded as DotsHorizontal} from '#/components/icons/DotGrid'
|
||||||
@@ -32,15 +28,15 @@ let PostMenuButton = ({
|
|||||||
forceGoogleTranslate,
|
forceGoogleTranslate,
|
||||||
}: {
|
}: {
|
||||||
testID: string
|
testID: string
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>
|
post: Shadow<app.bsky.feed.defs.PostView>
|
||||||
postFeedContext: string | undefined
|
postFeedContext: string | undefined
|
||||||
postReqId: string | undefined
|
postReqId: string | undefined
|
||||||
big?: boolean
|
big?: boolean
|
||||||
record: AppBskyFeedPost.Record
|
record: app.bsky.feed.post.Main
|
||||||
richText: RichTextAPI
|
richText: RichTextAPI
|
||||||
timestamp: string
|
timestamp: string
|
||||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
threadgateRecord?: app.bsky.feed.threadgate.Main
|
||||||
onShowLess?: (interaction: AppBskyFeedDefs.Interaction) => void
|
onShowLess?: (interaction: app.bsky.feed.defs.Interaction) => void
|
||||||
hitSlop?: Insets
|
hitSlop?: Insets
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'ImmersiveVideo'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'ImmersiveVideo'
|
||||||
forceGoogleTranslate: boolean
|
forceGoogleTranslate: boolean
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {ScrollView, View} from 'react-native'
|
import {ScrollView, View} from 'react-native'
|
||||||
import {type ChatBskyActorDefs} from '@atproto/api'
|
|
||||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {chat} from '#/lexicons'
|
||||||
import {isBlockedOrBlocking, isMuted} from '#/lib/moderation/blocked-and-muted'
|
import {isBlockedOrBlocking, isMuted} from '#/lib/moderation/blocked-and-muted'
|
||||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||||
import {moderateProfile} from '#/lib/moderation/subjects'
|
import {moderateProfile} from '#/lib/moderation/subjects'
|
||||||
@@ -114,7 +114,7 @@ function RecentChatItem({
|
|||||||
onPress: () => void
|
onPress: () => void
|
||||||
moderationOpts: ModerationOpts
|
moderationOpts: ModerationOpts
|
||||||
convo: ConvoWithDetails
|
convo: ConvoWithDetails
|
||||||
primaryMember: ChatBskyActorDefs.ProfileViewBasic
|
primaryMember: chat.bsky.actor.defs.ProfileViewBasic
|
||||||
}) {
|
}) {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {memo, useMemo} from 'react'
|
import {memo, useMemo} from 'react'
|
||||||
import * as ExpoClipboard from 'expo-clipboard'
|
import * as ExpoClipboard from 'expo-clipboard'
|
||||||
import {AtUri} from '@atproto/api'
|
|
||||||
import {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
import {makeProfileLink} from '#/lib/routes/links'
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
import {type NavigationProp} from '#/lib/routes/types'
|
import {type NavigationProp} from '#/lib/routes/types'
|
||||||
import {shareText, shareUrl} from '#/lib/sharing'
|
import {shareText, shareUrl} from '#/lib/sharing'
|
||||||
|
|||||||
@@ -1,22 +1,18 @@
|
|||||||
import {type PressableProps, type StyleProp, type ViewStyle} from 'react-native'
|
import {type PressableProps, type StyleProp, type ViewStyle} from 'react-native'
|
||||||
import {
|
|
||||||
type AppBskyFeedDefs,
|
|
||||||
type AppBskyFeedPost,
|
|
||||||
type AppBskyFeedThreadgate,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {type RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
import {type RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type Shadow} from '#/state/cache/post-shadow'
|
import {type Shadow} from '#/state/cache/post-shadow'
|
||||||
|
|
||||||
export interface ShareMenuItemsProps {
|
export interface ShareMenuItemsProps {
|
||||||
testID: string
|
testID: string
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>
|
post: Shadow<app.bsky.feed.defs.PostView>
|
||||||
record: AppBskyFeedPost.Record
|
record: app.bsky.feed.post.Main
|
||||||
richText: RichTextAPI
|
richText: RichTextAPI
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
hitSlop?: PressableProps['hitSlop']
|
hitSlop?: PressableProps['hitSlop']
|
||||||
size?: 'lg' | 'md' | 'sm'
|
size?: 'lg' | 'md' | 'sm'
|
||||||
timestamp: string
|
timestamp: string
|
||||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
threadgateRecord?: app.bsky.feed.threadgate.Main
|
||||||
onShare: () => void
|
onShare: () => void
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {memo, useMemo} from 'react'
|
import {memo, useMemo} from 'react'
|
||||||
import {AtUri} from '@atproto/api'
|
|
||||||
import {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
import {makeProfileLink} from '#/lib/routes/links'
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
import {type NavigationProp} from '#/lib/routes/types'
|
import {type NavigationProp} from '#/lib/routes/types'
|
||||||
import {shareText, shareUrl} from '#/lib/sharing'
|
import {shareText, shareUrl} from '#/lib/sharing'
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
import {memo, useMemo, useState} from 'react'
|
import {memo, useMemo, useState} from 'react'
|
||||||
import {type Insets} from 'react-native'
|
import {type Insets} from 'react-native'
|
||||||
import {
|
|
||||||
type AppBskyFeedDefs,
|
|
||||||
type AppBskyFeedPost,
|
|
||||||
type AppBskyFeedThreadgate,
|
|
||||||
AtUri,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {type RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
import {type RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {makeProfileLink} from '#/lib/routes/links'
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
import {shareUrl} from '#/lib/sharing'
|
import {shareUrl} from '#/lib/sharing'
|
||||||
import {toShareUrl} from '#/lib/strings/url-helpers'
|
import {toShareUrl} from '#/lib/strings/url-helpers'
|
||||||
@@ -37,12 +33,12 @@ let ShareMenuButton = ({
|
|||||||
logContext,
|
logContext,
|
||||||
}: {
|
}: {
|
||||||
testID: string
|
testID: string
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>
|
post: Shadow<app.bsky.feed.defs.PostView>
|
||||||
big?: boolean
|
big?: boolean
|
||||||
record: AppBskyFeedPost.Record
|
record: app.bsky.feed.post.Main
|
||||||
richText: RichTextAPI
|
richText: RichTextAPI
|
||||||
timestamp: string
|
timestamp: string
|
||||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
threadgateRecord?: app.bsky.feed.threadgate.Main
|
||||||
onShare: () => void
|
onShare: () => void
|
||||||
hitSlop?: Insets
|
hitSlop?: Insets
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'ImmersiveVideo'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'ImmersiveVideo'
|
||||||
|
|||||||
@@ -1,14 +1,10 @@
|
|||||||
import {memo, useMemo, useState} from 'react'
|
import {memo, useMemo, useState} from 'react'
|
||||||
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
||||||
import {
|
|
||||||
type AppBskyFeedDefs,
|
|
||||||
type AppBskyFeedPost,
|
|
||||||
type AppBskyFeedThreadgate,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {type RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
import {type RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||||
import {plural} from '@lingui/core/macro'
|
import {plural} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {CountWheel} from '#/lib/custom-animations/CountWheel'
|
import {CountWheel} from '#/lib/custom-animations/CountWheel'
|
||||||
import {AnimatedLikeIcon} from '#/lib/custom-animations/LikeIcon'
|
import {AnimatedLikeIcon} from '#/lib/custom-animations/LikeIcon'
|
||||||
import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
|
import {useOpenComposer} from '#/lib/hooks/useOpenComposer'
|
||||||
@@ -57,8 +53,8 @@ let PostControls = ({
|
|||||||
forceGoogleTranslate = false,
|
forceGoogleTranslate = false,
|
||||||
}: {
|
}: {
|
||||||
big?: boolean
|
big?: boolean
|
||||||
post: Shadow<AppBskyFeedDefs.PostView>
|
post: Shadow<app.bsky.feed.defs.PostView>
|
||||||
record: AppBskyFeedPost.Record
|
record: app.bsky.feed.post.Main
|
||||||
richText: RichTextAPI
|
richText: RichTextAPI
|
||||||
feedContext?: string | undefined
|
feedContext?: string | undefined
|
||||||
reqId?: string | undefined
|
reqId?: string | undefined
|
||||||
@@ -66,8 +62,8 @@ let PostControls = ({
|
|||||||
onPressReply: () => void
|
onPressReply: () => void
|
||||||
onPostReply?: (postUri: string | undefined) => void
|
onPostReply?: (postUri: string | undefined) => void
|
||||||
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'ImmersiveVideo'
|
logContext: 'FeedItem' | 'PostThreadItem' | 'Post' | 'ImmersiveVideo'
|
||||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
threadgateRecord?: app.bsky.feed.threadgate.Main
|
||||||
onShowLess?: (interaction: AppBskyFeedDefs.Interaction) => void
|
onShowLess?: (interaction: app.bsky.feed.defs.Interaction) => void
|
||||||
viaRepost?: {uri: string; cid: string}
|
viaRepost?: {uri: string; cid: string}
|
||||||
variant?: 'compact' | 'normal' | 'large'
|
variant?: 'compact' | 'normal' | 'large'
|
||||||
forceGoogleTranslate?: boolean
|
forceGoogleTranslate?: boolean
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import {memo, useCallback, useEffect, useMemo, useReducer, useRef} from 'react'
|
import {memo, useCallback, useEffect, useMemo, useReducer, useRef} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyActorDefs} from '@atproto/api'
|
|
||||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||||
import {flip, offset, shift, size, useFloating} from '@floating-ui/react-dom'
|
import {flip, offset, shift, size, useFloating} from '@floating-ui/react-dom'
|
||||||
import {msg, plural} from '@lingui/core/macro'
|
import {msg, plural} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {getModerationCauseKey} from '#/lib/moderation'
|
import {getModerationCauseKey} from '#/lib/moderation'
|
||||||
import {moderateProfile} from '#/lib/moderation/subjects'
|
import {moderateProfile} from '#/lib/moderation/subjects'
|
||||||
import {makeProfileLink} from '#/lib/routes/links'
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
@@ -416,7 +416,7 @@ function Inner({
|
|||||||
moderationOpts,
|
moderationOpts,
|
||||||
hide,
|
hide,
|
||||||
}: {
|
}: {
|
||||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||||
moderationOpts: ModerationOpts
|
moderationOpts: ModerationOpts
|
||||||
hide: () => void
|
hide: () => void
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {forwardRef, useCallback, useImperativeHandle, useState} from 'react'
|
import {forwardRef, useCallback, useImperativeHandle, useState} from 'react'
|
||||||
import {type ListRenderItemInfo, View} from 'react-native'
|
import {type ListRenderItemInfo, View} from 'react-native'
|
||||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {useBottomBarOffset} from '#/lib/hooks/useBottomBarOffset'
|
import {useBottomBarOffset} from '#/lib/hooks/useBottomBarOffset'
|
||||||
import {List, type ListRef} from '#/view/com/util/List'
|
import {List, type ListRef} from '#/view/com/util/List'
|
||||||
import {type SectionRef} from '#/screens/Profile/Sections/types'
|
import {type SectionRef} from '#/screens/Profile/Sections/types'
|
||||||
@@ -9,12 +9,12 @@ import {atoms as a, useTheme} from '#/alf'
|
|||||||
import * as FeedCard from '#/components/FeedCard'
|
import * as FeedCard from '#/components/FeedCard'
|
||||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||||
|
|
||||||
function keyExtractor(item: AppBskyFeedDefs.GeneratorView) {
|
function keyExtractor(item: app.bsky.feed.defs.GeneratorView) {
|
||||||
return item.uri
|
return item.uri
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ProfilesListProps {
|
interface ProfilesListProps {
|
||||||
feeds: AppBskyFeedDefs.GeneratorView[]
|
feeds: app.bsky.feed.defs.GeneratorView[]
|
||||||
headerHeight: number
|
headerHeight: number
|
||||||
scrollElRef: ListRef
|
scrollElRef: ListRef
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ export const FeedsList = forwardRef<SectionRef, ProfilesListProps>(
|
|||||||
const renderItem = ({
|
const renderItem = ({
|
||||||
item,
|
item,
|
||||||
index,
|
index,
|
||||||
}: ListRenderItemInfo<AppBskyFeedDefs.GeneratorView>) => {
|
}: ListRenderItemInfo<app.bsky.feed.defs.GeneratorView>) => {
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
import {forwardRef, useCallback, useImperativeHandle, useState} from 'react'
|
import {forwardRef, useCallback, useImperativeHandle, useState} from 'react'
|
||||||
import {type ListRenderItemInfo, View} from 'react-native'
|
import {type ListRenderItemInfo, View} from 'react-native'
|
||||||
import {
|
|
||||||
type AppBskyActorDefs,
|
|
||||||
type AppBskyGraphGetList,
|
|
||||||
AtUri,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||||
import {
|
import {
|
||||||
type InfiniteData,
|
type InfiniteData,
|
||||||
type UseInfiniteQueryResult,
|
type UseInfiniteQueryResult,
|
||||||
} from '@tanstack/react-query'
|
} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {useBottomBarOffset} from '#/lib/hooks/useBottomBarOffset'
|
import {useBottomBarOffset} from '#/lib/hooks/useBottomBarOffset'
|
||||||
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||||
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
|
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
|
||||||
@@ -23,14 +20,14 @@ import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
|
|||||||
import {Default as ProfileCard} from '#/components/ProfileCard'
|
import {Default as ProfileCard} from '#/components/ProfileCard'
|
||||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||||
|
|
||||||
function keyExtractor(item: AppBskyActorDefs.ProfileView, index: number) {
|
function keyExtractor(item: app.bsky.actor.defs.ProfileView, index: number) {
|
||||||
return `${item.did}-${index}`
|
return `${item.did}-${index}`
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ProfilesListProps {
|
interface ProfilesListProps {
|
||||||
listUri: string
|
listUri: string
|
||||||
listMembersQuery: UseInfiniteQueryResult<
|
listMembersQuery: UseInfiniteQueryResult<
|
||||||
InfiniteData<AppBskyGraphGetList.OutputSchema>
|
InfiniteData<app.bsky.graph.getList.$OutputBody>
|
||||||
>
|
>
|
||||||
moderationOpts: ModerationOpts
|
moderationOpts: ModerationOpts
|
||||||
headerHeight: number
|
headerHeight: number
|
||||||
@@ -87,7 +84,7 @@ export const ProfilesList = forwardRef<SectionRef, ProfilesListProps>(
|
|||||||
const renderItem = ({
|
const renderItem = ({
|
||||||
item,
|
item,
|
||||||
index,
|
index,
|
||||||
}: ListRenderItemInfo<AppBskyActorDefs.ProfileView>) => {
|
}: ListRenderItemInfo<app.bsky.actor.defs.ProfileView>) => {
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import {
|
|||||||
View,
|
View,
|
||||||
type ViewStyle,
|
type ViewStyle,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {type AppBskyGraphDefs} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {useGenerateStarterPackMutation} from '#/lib/generate-starterpack'
|
import {useGenerateStarterPackMutation} from '#/lib/generate-starterpack'
|
||||||
import {useBottomBarOffset} from '#/lib/hooks/useBottomBarOffset'
|
import {useBottomBarOffset} from '#/lib/hooks/useBottomBarOffset'
|
||||||
import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
|
import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
|
||||||
@@ -57,7 +57,7 @@ interface ProfileFeedgensProps {
|
|||||||
emptyStateIcon?: React.ComponentType<any> | React.ReactElement
|
emptyStateIcon?: React.ComponentType<any> | React.ReactElement
|
||||||
}
|
}
|
||||||
|
|
||||||
function keyExtractor(item: AppBskyGraphDefs.StarterPackViewBasic) {
|
function keyExtractor(item: app.bsky.graph.defs.StarterPackViewBasic) {
|
||||||
return item.uri
|
return item.uri
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ export function ProfileStarterPacks({
|
|||||||
({
|
({
|
||||||
item,
|
item,
|
||||||
index,
|
index,
|
||||||
}: ListRenderItemInfo<AppBskyGraphDefs.StarterPackViewBasic>) => {
|
}: ListRenderItemInfo<app.bsky.graph.defs.StarterPackViewBasic>) => {
|
||||||
return (
|
return (
|
||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import {View} from 'react-native'
|
|||||||
// @ts-expect-error missing types
|
// @ts-expect-error missing types
|
||||||
import QRCode from 'react-native-qrcode-styled'
|
import QRCode from 'react-native-qrcode-styled'
|
||||||
import type ViewShot from 'react-native-view-shot'
|
import type ViewShot from 'react-native-view-shot'
|
||||||
import {type AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api'
|
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {Logo} from '#/view/icons/Logo'
|
import {Logo} from '#/view/icons/Logo'
|
||||||
import {Logotype} from '#/view/icons/Logotype'
|
import {Logotype} from '#/view/icons/Logotype'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
@@ -24,18 +24,13 @@ export function QrCode({
|
|||||||
link,
|
link,
|
||||||
ref,
|
ref,
|
||||||
}: {
|
}: {
|
||||||
starterPack: AppBskyGraphDefs.StarterPackView
|
starterPack: app.bsky.graph.defs.StarterPackView
|
||||||
link: string
|
link: string
|
||||||
ref: React.Ref<ViewShot>
|
ref: React.Ref<ViewShot>
|
||||||
}) {
|
}) {
|
||||||
const {record} = starterPack
|
const {record} = starterPack
|
||||||
|
|
||||||
if (
|
if (!bsky.isType(app.bsky.graph.starterpack, record)) {
|
||||||
!bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
|
|
||||||
record,
|
|
||||||
AppBskyGraphStarterpack.isRecord,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import {View} from 'react-native'
|
|||||||
import type ViewShot from 'react-native-view-shot'
|
import type ViewShot from 'react-native-view-shot'
|
||||||
import {requestPermissionsAsync, saveToLibraryAsync} from 'expo-media-library'
|
import {requestPermissionsAsync, saveToLibraryAsync} from 'expo-media-library'
|
||||||
import * as Sharing from 'expo-sharing'
|
import * as Sharing from 'expo-sharing'
|
||||||
import {type AppBskyGraphDefs, AppBskyGraphStarterpack} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {atoms as a, useBreakpoints} from '#/alf'
|
import {atoms as a, useBreakpoints} from '#/alf'
|
||||||
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
|
||||||
@@ -28,7 +28,7 @@ export function QrCodeDialog({
|
|||||||
link,
|
link,
|
||||||
control,
|
control,
|
||||||
}: {
|
}: {
|
||||||
starterPack: AppBskyGraphDefs.StarterPackView
|
starterPack: app.bsky.graph.defs.StarterPackView
|
||||||
link?: string
|
link?: string
|
||||||
control: DialogControlProps
|
control: DialogControlProps
|
||||||
}) {
|
}) {
|
||||||
@@ -87,12 +87,7 @@ export function QrCodeDialog({
|
|||||||
} else {
|
} else {
|
||||||
setIsSaveProcessing(true)
|
setIsSaveProcessing(true)
|
||||||
|
|
||||||
if (
|
if (!bsky.matches(app.bsky.graph.starterpack, starterPack.record)) {
|
||||||
!bsky.validate(
|
|
||||||
starterPack.record,
|
|
||||||
AppBskyGraphStarterpack.validateRecord,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {type AppBskyGraphDefs} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {useSaveImageToMediaLibrary} from '#/lib/media/save-image'
|
import {useSaveImageToMediaLibrary} from '#/lib/media/save-image'
|
||||||
import {shareUrl} from '#/lib/sharing'
|
import {shareUrl} from '#/lib/sharing'
|
||||||
import {getStarterPackOgCard} from '#/lib/strings/starter-pack'
|
import {getStarterPackOgCard} from '#/lib/strings/starter-pack'
|
||||||
@@ -21,7 +21,7 @@ import {useAnalytics} from '#/analytics'
|
|||||||
import {IS_NATIVE, IS_WEB} from '#/env'
|
import {IS_NATIVE, IS_WEB} from '#/env'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
starterPack: AppBskyGraphDefs.StarterPackView
|
starterPack: app.bsky.graph.defs.StarterPackView
|
||||||
link?: string
|
link?: string
|
||||||
imageLoaded?: boolean
|
imageLoaded?: boolean
|
||||||
qrDialogControl: DialogControlProps
|
qrDialogControl: DialogControlProps
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import {useMemo} from 'react'
|
import {useMemo} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {AppBskyGraphStarterpack, AtUri} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Plural, Trans} from '@lingui/react/macro'
|
import {Plural, Trans} from '@lingui/react/macro'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
import {getStarterPackOgCard} from '#/lib/strings/starter-pack'
|
import {getStarterPackOgCard} from '#/lib/strings/starter-pack'
|
||||||
import {precacheResolvedUri} from '#/state/queries/resolve-uri'
|
import {precacheResolvedUri} from '#/state/queries/resolve-uri'
|
||||||
@@ -62,12 +63,7 @@ export function Card({
|
|||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
|
|
||||||
if (
|
if (!bsky.isType(app.bsky.graph.starterpack, record)) {
|
||||||
!bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
|
|
||||||
record,
|
|
||||||
AppBskyGraphStarterpack.isRecord,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,10 +123,7 @@ export function useStarterPackLink({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
to: `/starter-pack/${handleOrDid}/${rkey}`,
|
to: `/starter-pack/${handleOrDid}/${rkey}`,
|
||||||
label: bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
|
label: bsky.isType(app.bsky.graph.starterpack, view.record)
|
||||||
view.record,
|
|
||||||
AppBskyGraphStarterpack.isRecord,
|
|
||||||
)
|
|
||||||
? _(msg`Navigate to ${view.record.name}`)
|
? _(msg`Navigate to ${view.record.name}`)
|
||||||
: _(msg`Navigate to starter pack`),
|
: _(msg`Navigate to starter pack`),
|
||||||
precache,
|
precache,
|
||||||
@@ -154,12 +147,7 @@ export function Link({
|
|||||||
return {rkey, handleOrDid: creator.handle || creator.did}
|
return {rkey, handleOrDid: creator.handle || creator.did}
|
||||||
}, [starterPack])
|
}, [starterPack])
|
||||||
|
|
||||||
if (
|
if (!bsky.isType(app.bsky.graph.starterpack, record)) {
|
||||||
!bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
|
|
||||||
record,
|
|
||||||
AppBskyGraphStarterpack.isRecord,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import {useRef} from 'react'
|
import {useRef} from 'react'
|
||||||
import {type ListRenderItemInfo} from 'react-native'
|
import {type ListRenderItemInfo} from 'react-native'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyActorDefs, type AppBskyFeedDefs} from '@atproto/api'
|
|
||||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
import {useInitialNumToRender} from '#/lib/hooks/useInitialNumToRender'
|
||||||
import {type ListMethods} from '#/view/com/util/List'
|
import {type ListMethods} from '#/view/com/util/List'
|
||||||
import {
|
import {
|
||||||
@@ -24,7 +24,7 @@ import {Text} from '#/components/Typography'
|
|||||||
import {IS_WEB} from '#/env'
|
import {IS_WEB} from '#/env'
|
||||||
|
|
||||||
function keyExtractor(
|
function keyExtractor(
|
||||||
item: AppBskyActorDefs.ProfileViewBasic | AppBskyFeedDefs.GeneratorView,
|
item: app.bsky.actor.defs.ProfileViewBasic | app.bsky.feed.defs.GeneratorView,
|
||||||
index: number,
|
index: number,
|
||||||
) {
|
) {
|
||||||
return `${item.did}-${index}`
|
return `${item.did}-${index}`
|
||||||
@@ -41,7 +41,7 @@ export function WizardEditListDialog({
|
|||||||
state: WizardState
|
state: WizardState
|
||||||
dispatch: (action: WizardAction) => void
|
dispatch: (action: WizardAction) => void
|
||||||
moderationOpts: ModerationOpts
|
moderationOpts: ModerationOpts
|
||||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||||
}) {
|
}) {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {Keyboard, View} from 'react-native'
|
import {Keyboard, View} from 'react-native'
|
||||||
import {type AppBskyActorDefs, type AppBskyFeedDefs} from '@atproto/api'
|
|
||||||
import {type ModerationOpts, type ModerationUI} from '@bsky.app/sdk/moderation'
|
import {type ModerationOpts, type ModerationUI} from '@bsky.app/sdk/moderation'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {DISCOVER_FEED_URI, STARTER_PACK_MAX_SIZE} from '#/lib/constants'
|
import {DISCOVER_FEED_URI, STARTER_PACK_MAX_SIZE} from '#/lib/constants'
|
||||||
import {moderateFeedGenerator, moderateProfile} from '#/lib/moderation/subjects'
|
import {moderateFeedGenerator, moderateProfile} from '#/lib/moderation/subjects'
|
||||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||||
@@ -36,8 +36,8 @@ function WizardListCard({
|
|||||||
}: {
|
}: {
|
||||||
type: 'user' | 'algo'
|
type: 'user' | 'algo'
|
||||||
btnType: 'checkbox' | 'remove'
|
btnType: 'checkbox' | 'remove'
|
||||||
profile?: AppBskyActorDefs.ProfileViewBasic
|
profile?: app.bsky.actor.defs.ProfileViewBasic
|
||||||
feed?: AppBskyFeedDefs.GeneratorView
|
feed?: app.bsky.feed.defs.GeneratorView
|
||||||
displayName: string
|
displayName: string
|
||||||
subtitle: string
|
subtitle: string
|
||||||
onPress: () => void
|
onPress: () => void
|
||||||
@@ -178,7 +178,7 @@ export function WizardFeedCard({
|
|||||||
moderationOpts,
|
moderationOpts,
|
||||||
}: {
|
}: {
|
||||||
btnType: 'checkbox' | 'remove'
|
btnType: 'checkbox' | 'remove'
|
||||||
generator: AppBskyFeedDefs.GeneratorView
|
generator: app.bsky.feed.defs.GeneratorView
|
||||||
state: WizardState
|
state: WizardState
|
||||||
dispatch: (action: WizardAction) => void
|
dispatch: (action: WizardAction) => void
|
||||||
moderationOpts: ModerationOpts
|
moderationOpts: ModerationOpts
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import {useEffect, useMemo} from 'react'
|
import {useEffect, useMemo} from 'react'
|
||||||
import {type AppBskyUnspeccedDefs, type AtUri} from '@atproto/api'
|
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {type AtUri} from '@atproto/syntax'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {PressableScale} from '#/lib/custom-animations/PressableScale'
|
import {PressableScale} from '#/lib/custom-animations/PressableScale'
|
||||||
import {useCallOnce} from '#/lib/once'
|
import {useCallOnce} from '#/lib/once'
|
||||||
// import {makeProfileLink} from '#/lib/routes/links'
|
// import {makeProfileLink} from '#/lib/routes/links'
|
||||||
@@ -18,7 +19,7 @@ export function TrendingTopicLink({
|
|||||||
children,
|
children,
|
||||||
...rest
|
...rest
|
||||||
}: {
|
}: {
|
||||||
topic: AppBskyUnspeccedDefs.TrendView
|
topic: app.bsky.unspecced.defs.TrendView
|
||||||
metricContext: Metrics['trendingTopic:seen']['context']
|
metricContext: Metrics['trendingTopic:seen']['context']
|
||||||
rank: number
|
rank: number
|
||||||
recId?: string
|
recId?: string
|
||||||
@@ -75,7 +76,7 @@ type ParsedTrendingTopic =
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function useTopic(
|
export function useTopic(
|
||||||
raw: AppBskyUnspeccedDefs.TrendView,
|
raw: app.bsky.unspecced.defs.TrendView,
|
||||||
): ParsedTrendingTopic {
|
): ParsedTrendingTopic {
|
||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
|
|||||||
@@ -2,15 +2,10 @@ import {useMemo} from 'react'
|
|||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {LinearGradient} from 'expo-linear-gradient'
|
import {LinearGradient} from 'expo-linear-gradient'
|
||||||
import {
|
|
||||||
type AppBskyActorDefs,
|
|
||||||
AppBskyEmbedVideo,
|
|
||||||
type AppBskyFeedDefs,
|
|
||||||
AppBskyFeedPost,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {type ModerationDecision} from '@bsky.app/sdk/moderation'
|
import {type ModerationDecision} from '@bsky.app/sdk/moderation'
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
import {formatCount} from '#/view/com/util/numeric/format'
|
import {formatCount} from '#/view/com/util/numeric/format'
|
||||||
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
import {UserAvatar} from '#/view/com/util/UserAvatar'
|
||||||
@@ -42,7 +37,7 @@ export function VideoPostCard({
|
|||||||
moderation,
|
moderation,
|
||||||
onInteract,
|
onInteract,
|
||||||
}: {
|
}: {
|
||||||
post: AppBskyFeedDefs.PostView
|
post: app.bsky.feed.defs.PostView
|
||||||
sourceContext: VideoFeedSourceContext
|
sourceContext: VideoFeedSourceContext
|
||||||
moderation: ModerationDecision
|
moderation: ModerationDecision
|
||||||
/**
|
/**
|
||||||
@@ -75,13 +70,10 @@ export function VideoPostCard({
|
|||||||
* Filtering should be done at a higher level, such as `PostFeed` or
|
* Filtering should be done at a higher level, such as `PostFeed` or
|
||||||
* `PostFeedVideoGridRow`, but we need to protect here as well.
|
* `PostFeedVideoGridRow`, but we need to protect here as well.
|
||||||
*/
|
*/
|
||||||
if (!AppBskyEmbedVideo.isView(embed)) return null
|
if (!bsky.isType(app.bsky.embed.video.view, embed)) return null
|
||||||
|
|
||||||
const author = post.author
|
const author = post.author
|
||||||
const text = bsky.dangerousIsType<AppBskyFeedPost.Record>(
|
const text = bsky.isType(app.bsky.feed.post, post.record)
|
||||||
post.record,
|
|
||||||
AppBskyFeedPost.isRecord,
|
|
||||||
)
|
|
||||||
? post.record?.text
|
? post.record?.text
|
||||||
: ''
|
: ''
|
||||||
const likeCount = post?.likeCount ?? 0
|
const likeCount = post?.likeCount ?? 0
|
||||||
@@ -275,7 +267,7 @@ export function VideoPostCardPlaceholder() {
|
|||||||
export function VideoPostCardTextPlaceholder({
|
export function VideoPostCardTextPlaceholder({
|
||||||
author,
|
author,
|
||||||
}: {
|
}: {
|
||||||
author?: AppBskyActorDefs.ProfileViewBasic
|
author?: app.bsky.actor.defs.ProfileViewBasic
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
|
||||||
@@ -355,7 +347,7 @@ export function CompactVideoPostCard({
|
|||||||
moderation,
|
moderation,
|
||||||
onInteract,
|
onInteract,
|
||||||
}: {
|
}: {
|
||||||
post: AppBskyFeedDefs.PostView
|
post: app.bsky.feed.defs.PostView
|
||||||
sourceContext: VideoFeedSourceContext
|
sourceContext: VideoFeedSourceContext
|
||||||
moderation: ModerationDecision
|
moderation: ModerationDecision
|
||||||
/**
|
/**
|
||||||
@@ -386,7 +378,7 @@ export function CompactVideoPostCard({
|
|||||||
* Filtering should be done at a higher level, such as `PostFeed` or
|
* Filtering should be done at a higher level, such as `PostFeed` or
|
||||||
* `PostFeedVideoGridRow`, but we need to protect here as well.
|
* `PostFeedVideoGridRow`, but we need to protect here as well.
|
||||||
*/
|
*/
|
||||||
if (!AppBskyEmbedVideo.isView(embed)) return null
|
if (!bsky.isType(app.bsky.embed.video.view, embed)) return null
|
||||||
|
|
||||||
const likeCount = post?.likeCount ?? 0
|
const likeCount = post?.likeCount ?? 0
|
||||||
const showLikeCount = false
|
const showLikeCount = false
|
||||||
|
|||||||
@@ -6,16 +6,12 @@ import {
|
|||||||
View,
|
View,
|
||||||
type ViewStyle,
|
type ViewStyle,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {
|
|
||||||
type AppBskyFeedDefs,
|
|
||||||
AppBskyFeedPost,
|
|
||||||
type AppBskyGraphDefs,
|
|
||||||
AtUri,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {HITSLOP_10} from '#/lib/constants'
|
import {HITSLOP_10} from '#/lib/constants'
|
||||||
import {makeListLink, makeProfileLink} from '#/lib/routes/links'
|
import {makeListLink, makeProfileLink} from '#/lib/routes/links'
|
||||||
import {
|
import {
|
||||||
@@ -41,7 +37,7 @@ import {IS_NATIVE} from '#/env'
|
|||||||
import * as bsky from '#/types/bsky'
|
import * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
interface WhoCanReplyProps {
|
interface WhoCanReplyProps {
|
||||||
post: AppBskyFeedDefs.PostView
|
post: app.bsky.feed.defs.PostView
|
||||||
isThreadAuthor: boolean
|
isThreadAuthor: boolean
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
}
|
}
|
||||||
@@ -58,10 +54,7 @@ export function WhoCanReply({post, isThreadAuthor, style}: WhoCanReplyProps) {
|
|||||||
* unexpectedly, we should check to make sure it's for sure the root URI.
|
* unexpectedly, we should check to make sure it's for sure the root URI.
|
||||||
*/
|
*/
|
||||||
const rootUri =
|
const rootUri =
|
||||||
bsky.dangerousIsType<AppBskyFeedPost.Record>(
|
bsky.isType(app.bsky.feed.post, post.record) && post.record.reply?.root
|
||||||
post.record,
|
|
||||||
AppBskyFeedPost.isRecord,
|
|
||||||
) && post.record.reply?.root
|
|
||||||
? post.record.reply.root.uri
|
? post.record.reply.root.uri
|
||||||
: post.uri
|
: post.uri
|
||||||
const settings = useMemo(() => {
|
const settings = useMemo(() => {
|
||||||
@@ -209,7 +202,7 @@ function WhoCanReplyDialog({
|
|||||||
embeddingDisabled,
|
embeddingDisabled,
|
||||||
}: {
|
}: {
|
||||||
control: Dialog.DialogControlProps
|
control: Dialog.DialogControlProps
|
||||||
post: AppBskyFeedDefs.PostView
|
post: app.bsky.feed.defs.PostView
|
||||||
settings: ThreadgateAllowUISetting[]
|
settings: ThreadgateAllowUISetting[]
|
||||||
embeddingDisabled: boolean
|
embeddingDisabled: boolean
|
||||||
}) {
|
}) {
|
||||||
@@ -255,7 +248,7 @@ function Rules({
|
|||||||
settings,
|
settings,
|
||||||
embeddingDisabled,
|
embeddingDisabled,
|
||||||
}: {
|
}: {
|
||||||
post: AppBskyFeedDefs.PostView
|
post: app.bsky.feed.defs.PostView
|
||||||
settings: ThreadgateAllowUISetting[]
|
settings: ThreadgateAllowUISetting[]
|
||||||
embeddingDisabled: boolean
|
embeddingDisabled: boolean
|
||||||
}) {
|
}) {
|
||||||
@@ -313,8 +306,8 @@ function Rule({
|
|||||||
lists,
|
lists,
|
||||||
}: {
|
}: {
|
||||||
rule: ThreadgateAllowUISetting
|
rule: ThreadgateAllowUISetting
|
||||||
post: AppBskyFeedDefs.PostView
|
post: app.bsky.feed.defs.PostView
|
||||||
lists: AppBskyGraphDefs.ListViewBasic[] | undefined
|
lists: app.bsky.graph.defs.ListViewBasic[] | undefined
|
||||||
}) {
|
}) {
|
||||||
if (rule.type === 'mention') {
|
if (rule.type === 'mention') {
|
||||||
return <Trans>mentioned users</Trans>
|
return <Trans>mentioned users</Trans>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {useMemo, useState} from 'react'
|
import {useMemo, useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyNotificationDefs, type Un$Typed} from '@atproto/api'
|
|
||||||
import {type DidString} from '@atproto/syntax'
|
import {type DidString} from '@atproto/syntax'
|
||||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
@@ -12,6 +11,7 @@ import {
|
|||||||
useQueryClient,
|
useQueryClient,
|
||||||
} from '@tanstack/react-query'
|
} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {type Un$Typed} from '@atproto/lex'
|
||||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||||
import {cleanError} from '#/lib/strings/errors'
|
import {cleanError} from '#/lib/strings/errors'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
@@ -118,7 +118,7 @@ function DialogInner({
|
|||||||
error,
|
error,
|
||||||
} = useMutation({
|
} = useMutation({
|
||||||
mutationFn: async (
|
mutationFn: async (
|
||||||
activitySubscription: Un$Typed<AppBskyNotificationDefs.ActivitySubscription>,
|
activitySubscription: Un$Typed<app.bsky.notification.defs.ActivitySubscription>,
|
||||||
) => {
|
) => {
|
||||||
await client.call(app.bsky.notification.putActivitySubscription, {
|
await client.call(app.bsky.notification.putActivitySubscription, {
|
||||||
// the profile view carries an already-resolved did
|
// the profile view carries an already-resolved did
|
||||||
@@ -307,8 +307,8 @@ function DialogInner({
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseActivitySubscription(
|
function parseActivitySubscription(
|
||||||
sub?: AppBskyNotificationDefs.ActivitySubscription,
|
sub?: app.bsky.notification.defs.ActivitySubscription,
|
||||||
): Un$Typed<AppBskyNotificationDefs.ActivitySubscription> {
|
): Un$Typed<app.bsky.notification.defs.ActivitySubscription> {
|
||||||
if (!sub) return {post: false, reply: false}
|
if (!sub) return {post: false, reply: false}
|
||||||
const {post, reply} = sub
|
const {post, reply} = sub
|
||||||
return {post, reply}
|
return {post, reply}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {useState} from 'react'
|
import {useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {ToolsOzoneReportDefs} from '@atproto/api'
|
|
||||||
import {type DidString} from '@atproto/syntax'
|
import {type DidString} from '@atproto/syntax'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
@@ -18,7 +17,7 @@ import * as Toast from '#/components/Toast'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {logger} from '#/ageAssurance'
|
import {logger} from '#/ageAssurance'
|
||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import {com} from '#/lexicons'
|
import {com, tools} from '#/lexicons'
|
||||||
|
|
||||||
export function AgeAssuranceAppealDialog({
|
export function AgeAssuranceAppealDialog({
|
||||||
control,
|
control,
|
||||||
@@ -60,7 +59,7 @@ function Inner({control}: {control: Dialog.DialogControlProps}) {
|
|||||||
await client.call(
|
await client.call(
|
||||||
com.atproto.moderation.createReport,
|
com.atproto.moderation.createReport,
|
||||||
{
|
{
|
||||||
reasonType: ToolsOzoneReportDefs.REASONAPPEAL,
|
reasonType: tools.ozone.report.defs.reasonAppeal,
|
||||||
subject: {
|
subject: {
|
||||||
$type: 'com.atproto.admin.defs#repoRef',
|
$type: 'com.atproto.admin.defs#repoRef',
|
||||||
// the persisted account did is already resolved
|
// the persisted account did is already resolved
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {type AppBskyContactDefs} from '@atproto/api'
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
import {type CountryCode} from '#/lib/international-telephone-codes'
|
import {type CountryCode} from '#/lib/international-telephone-codes'
|
||||||
import {normalizePhoneNumber} from './phone-number'
|
import {normalizePhoneNumber} from './phone-number'
|
||||||
import {type Contact, type Match} from './state'
|
import {type Contact, type Match} from './state'
|
||||||
@@ -70,7 +69,7 @@ export function normalizeContactBook(
|
|||||||
|
|
||||||
export function filterMatchedNumbers(
|
export function filterMatchedNumbers(
|
||||||
contacts: Contact[],
|
contacts: Contact[],
|
||||||
results: AppBskyContactDefs.MatchAndContactIndex[],
|
results: app.bsky.contact.defs.MatchAndContactIndex[],
|
||||||
mapping: Map<number, Contact['id']>,
|
mapping: Map<number, Contact['id']>,
|
||||||
) {
|
) {
|
||||||
const filteredIds = new Set<Contact['id']>()
|
const filteredIds = new Set<Contact['id']>()
|
||||||
@@ -87,7 +86,7 @@ export function filterMatchedNumbers(
|
|||||||
|
|
||||||
export function getMatchedContacts(
|
export function getMatchedContacts(
|
||||||
contacts: Contact[],
|
contacts: Contact[],
|
||||||
results: AppBskyContactDefs.MatchAndContactIndex[],
|
results: app.bsky.contact.defs.MatchAndContactIndex[],
|
||||||
mapping: Map<number, Contact['id']>,
|
mapping: Map<number, Contact['id']>,
|
||||||
): Array<Match> {
|
): Array<Match> {
|
||||||
const contactsById = new Map(contacts.map(c => [c.id, c]))
|
const contactsById = new Map(contacts.map(c => [c.id, c]))
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
import {memo, useEffect, useMemo, useState} from 'react'
|
import {memo, useEffect, useMemo, useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyActorDefs, type AppBskyFeedPost, AtUri} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {EMBED_SCRIPT} from '#/lib/constants'
|
import {EMBED_SCRIPT} from '#/lib/constants'
|
||||||
import {niceDate} from '#/lib/strings/time'
|
import {niceDate} from '#/lib/strings/time'
|
||||||
import {toShareUrl} from '#/lib/strings/url-helpers'
|
import {toShareUrl} from '#/lib/strings/url-helpers'
|
||||||
@@ -25,10 +26,10 @@ export type ColorModeValues = 'system' | 'light' | 'dark'
|
|||||||
|
|
||||||
type EmbedDialogProps = {
|
type EmbedDialogProps = {
|
||||||
control: Dialog.DialogControlProps
|
control: Dialog.DialogControlProps
|
||||||
postAuthor: AppBskyActorDefs.ProfileViewBasic
|
postAuthor: app.bsky.actor.defs.ProfileViewBasic
|
||||||
postCid: string
|
postCid: string
|
||||||
postUri: string
|
postUri: string
|
||||||
record: AppBskyFeedPost.Record
|
record: app.bsky.feed.post.Main
|
||||||
timestamp: string
|
timestamp: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {useCallback, useMemo, useState} from 'react'
|
import {useCallback, useMemo, useState} from 'react'
|
||||||
import {LayoutAnimation, Text as NestedText, View} from 'react-native'
|
import {LayoutAnimation, Text as NestedText, View} from 'react-native'
|
||||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
|
||||||
import {AtUri} from '@atproto/syntax'
|
import {AtUri} from '@atproto/syntax'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
@@ -50,7 +49,7 @@ import * as Toast from '#/components/Toast'
|
|||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {useAnalytics} from '#/analytics'
|
import {useAnalytics} from '#/analytics'
|
||||||
import {IS_IOS} from '#/env'
|
import {IS_IOS} from '#/env'
|
||||||
import {type app} from '#/lexicons'
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
export type PostInteractionSettingsFormProps = {
|
export type PostInteractionSettingsFormProps = {
|
||||||
canSave?: boolean
|
canSave?: boolean
|
||||||
@@ -133,10 +132,10 @@ export type PostInteractionSettingsDialogProps = {
|
|||||||
*/
|
*/
|
||||||
rootPostUri: string
|
rootPostUri: string
|
||||||
/**
|
/**
|
||||||
* Optional initial {@link AppBskyFeedDefs.ThreadgateView} to use if we
|
* Optional initial {@link app.bsky.feed.defs.ThreadgateView} to use if we
|
||||||
* happen to have one before opening the settings dialog.
|
* happen to have one before opening the settings dialog.
|
||||||
*/
|
*/
|
||||||
initialThreadgateView?: AppBskyFeedDefs.ThreadgateView
|
initialThreadgateView?: app.bsky.feed.defs.ThreadgateView
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
import {useCallback} from 'react'
|
import {useCallback} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {
|
|
||||||
type AppBskyGraphGetStarterPacksWithMembership,
|
|
||||||
AppBskyGraphStarterpack,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Plural, Trans} from '@lingui/react/macro'
|
import {Plural, Trans} from '@lingui/react/macro'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
|
import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
|
||||||
import {type NavigationProp} from '#/lib/routes/types'
|
import {type NavigationProp} from '#/lib/routes/types'
|
||||||
import {isNetworkError} from '#/lib/strings/errors'
|
import {isNetworkError} from '#/lib/strings/errors'
|
||||||
@@ -36,7 +33,7 @@ import {IS_WEB} from '#/env'
|
|||||||
import * as bsky from '#/types/bsky'
|
import * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
type StarterPackWithMembership =
|
type StarterPackWithMembership =
|
||||||
AppBskyGraphGetStarterPacksWithMembership.StarterPackWithMembership
|
app.bsky.graph.getStarterPacksWithMembership.StarterPackWithMembership
|
||||||
|
|
||||||
export type StarterPackDialogProps = {
|
export type StarterPackDialogProps = {
|
||||||
control: Dialog.DialogControlProps
|
control: Dialog.DialogControlProps
|
||||||
@@ -324,12 +321,7 @@ function StarterPackItem({
|
|||||||
|
|
||||||
const {record} = starterPack
|
const {record} = starterPack
|
||||||
|
|
||||||
if (
|
if (!bsky.isType(app.bsky.graph.starterpack, record)) {
|
||||||
!bsky.dangerousIsType<AppBskyGraphStarterpack.Record>(
|
|
||||||
record,
|
|
||||||
AppBskyGraphStarterpack.isRecord,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyGraphDefs, type AppBskyGraphStarterpack} from '@atproto/api'
|
|
||||||
import {TID} from '@atproto/common-web'
|
import {TID} from '@atproto/common-web'
|
||||||
import {type $Typed} from '@atproto/lex'
|
import {type $Typed} from '@atproto/lex'
|
||||||
import {
|
import {
|
||||||
@@ -37,7 +36,7 @@ export function CreateListFromStarterPackDialog({
|
|||||||
starterPack,
|
starterPack,
|
||||||
}: {
|
}: {
|
||||||
control: Dialog.DialogControlProps
|
control: Dialog.DialogControlProps
|
||||||
starterPack: AppBskyGraphDefs.StarterPackView
|
starterPack: app.bsky.graph.defs.StarterPackView
|
||||||
}) {
|
}) {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
@@ -50,7 +49,7 @@ export function CreateListFromStarterPackDialog({
|
|||||||
const createDialogControl = Dialog.useDialogControl()
|
const createDialogControl = Dialog.useDialogControl()
|
||||||
const loadingDialogControl = Dialog.useDialogControl()
|
const loadingDialogControl = Dialog.useDialogControl()
|
||||||
|
|
||||||
const record = starterPack.record as AppBskyGraphStarterpack.Record
|
const record = starterPack.record as app.bsky.graph.starterpack.Main
|
||||||
|
|
||||||
const onPressCreate = () => {
|
const onPressCreate = () => {
|
||||||
control.close(() => createDialogControl.open())
|
control.close(() => createDialogControl.open())
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {useCallback, useEffect, useMemo, useState} from 'react'
|
import {useCallback, useEffect, useMemo, useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyGraphDefs} from '@atproto/api'
|
|
||||||
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Plural, Trans} from '@lingui/react/macro'
|
import {Plural, Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {cleanError} from '#/lib/strings/errors'
|
import {cleanError} from '#/lib/strings/errors'
|
||||||
import {isOverMaxGraphemeCount} from '#/lib/strings/helpers'
|
import {isOverMaxGraphemeCount} from '#/lib/strings/helpers'
|
||||||
import {asSdkFacets, richTextToString} from '#/lib/strings/rich-text-helpers'
|
import {asSdkFacets, richTextToString} from '#/lib/strings/rich-text-helpers'
|
||||||
@@ -46,8 +46,8 @@ export function CreateOrEditListDialog({
|
|||||||
initialValues,
|
initialValues,
|
||||||
}: {
|
}: {
|
||||||
control: Dialog.DialogControlProps
|
control: Dialog.DialogControlProps
|
||||||
list?: AppBskyGraphDefs.ListView
|
list?: app.bsky.graph.defs.ListView
|
||||||
purpose?: AppBskyGraphDefs.ListPurpose
|
purpose?: app.bsky.graph.defs.ListPurpose
|
||||||
onSave?: (uri: string) => void
|
onSave?: (uri: string) => void
|
||||||
initialValues?: InitialListValues
|
initialValues?: InitialListValues
|
||||||
}) {
|
}) {
|
||||||
@@ -114,8 +114,8 @@ function DialogInner({
|
|||||||
onPressCancel,
|
onPressCancel,
|
||||||
initialValues,
|
initialValues,
|
||||||
}: {
|
}: {
|
||||||
list?: AppBskyGraphDefs.ListView
|
list?: app.bsky.graph.defs.ListView
|
||||||
purpose?: AppBskyGraphDefs.ListPurpose
|
purpose?: app.bsky.graph.defs.ListPurpose
|
||||||
onSave?: (uri: string) => void
|
onSave?: (uri: string) => void
|
||||||
setDirty: (dirty: boolean) => void
|
setDirty: (dirty: boolean) => void
|
||||||
onPressCancel: () => void
|
onPressCancel: () => void
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {useCallback, useMemo} from 'react'
|
import {useCallback, useMemo} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyGraphDefs} from '@atproto/api'
|
|
||||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {cleanError} from '#/lib/strings/errors'
|
import {cleanError} from '#/lib/strings/errors'
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {useAllListMembersQuery} from '#/state/queries/list-members'
|
import {useAllListMembersQuery} from '#/state/queries/list-members'
|
||||||
@@ -31,7 +31,7 @@ export function ListAddRemoveUsersDialog({
|
|||||||
onChange,
|
onChange,
|
||||||
}: {
|
}: {
|
||||||
control: Dialog.DialogControlProps
|
control: Dialog.DialogControlProps
|
||||||
list: AppBskyGraphDefs.ListView
|
list: app.bsky.graph.defs.ListView
|
||||||
onChange?: (
|
onChange?: (
|
||||||
type: 'add' | 'remove',
|
type: 'add' | 'remove',
|
||||||
profile: bsky.profile.AnyProfileView,
|
profile: bsky.profile.AnyProfileView,
|
||||||
@@ -52,7 +52,7 @@ function DialogInner({
|
|||||||
list,
|
list,
|
||||||
onChange,
|
onChange,
|
||||||
}: {
|
}: {
|
||||||
list: AppBskyGraphDefs.ListView
|
list: app.bsky.graph.defs.ListView
|
||||||
onChange?: (
|
onChange?: (
|
||||||
type: 'add' | 'remove',
|
type: 'add' | 'remove',
|
||||||
profile: bsky.profile.AnyProfileView,
|
profile: bsky.profile.AnyProfileView,
|
||||||
@@ -89,7 +89,7 @@ function DialogInner({
|
|||||||
* Returns undefined for pending, false for not a member, and string for a member (the URI of the membership record)
|
* Returns undefined for pending, false for not a member, and string for a member (the URI of the membership record)
|
||||||
*/
|
*/
|
||||||
function getMembership(
|
function getMembership(
|
||||||
listMembers: AppBskyGraphDefs.ListItemView[] | undefined,
|
listMembers: app.bsky.graph.defs.ListItemView[] | undefined,
|
||||||
actorDid: string,
|
actorDid: string,
|
||||||
): string | false | undefined {
|
): string | false | undefined {
|
||||||
if (!listMembers) {
|
if (!listMembers) {
|
||||||
@@ -107,8 +107,8 @@ function UserResult({
|
|||||||
moderationOpts,
|
moderationOpts,
|
||||||
}: {
|
}: {
|
||||||
profile: bsky.profile.AnyProfileView
|
profile: bsky.profile.AnyProfileView
|
||||||
list: AppBskyGraphDefs.ListView
|
list: app.bsky.graph.defs.ListView
|
||||||
listMembers: AppBskyGraphDefs.ListItemView[] | undefined
|
listMembers: app.bsky.graph.defs.ListItemView[] | undefined
|
||||||
onChange?: (
|
onChange?: (
|
||||||
type: 'add' | 'remove',
|
type: 'add' | 'remove',
|
||||||
profile: bsky.profile.AnyProfileView,
|
profile: bsky.profile.AnyProfileView,
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import {
|
|||||||
useMemo,
|
useMemo,
|
||||||
useState,
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import {type AppBskyActorDefs} from '@atproto/api'
|
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {logger} from '#/logger'
|
import {logger} from '#/logger'
|
||||||
import {STALE} from '#/state/queries'
|
import {STALE} from '#/state/queries'
|
||||||
import {Nux, useNuxs, useResetNuxs, useSaveNux} from '#/state/queries/nuxs'
|
import {Nux, useNuxs, useResetNuxs, useSaveNux} from '#/state/queries/nuxs'
|
||||||
@@ -93,7 +93,7 @@ function Inner({
|
|||||||
preferences,
|
preferences,
|
||||||
}: {
|
}: {
|
||||||
currentAccount: SessionAccount
|
currentAccount: SessionAccount
|
||||||
currentProfile: AppBskyActorDefs.ProfileViewDetailed
|
currentProfile: app.bsky.actor.defs.ProfileViewDetailed
|
||||||
preferences: UsePreferencesQueryResponse
|
preferences: UsePreferencesQueryResponse
|
||||||
}) {
|
}) {
|
||||||
const ax = useAnalytics()
|
const ax = useAnalytics()
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {type AppBskyActorDefs} from '@atproto/api'
|
import {app} from '#/lexicons'
|
||||||
|
|
||||||
import {type UsePreferencesQueryResponse} from '#/state/queries/preferences'
|
import {type UsePreferencesQueryResponse} from '#/state/queries/preferences'
|
||||||
import {type SessionAccount} from '#/state/session'
|
import {type SessionAccount} from '#/state/session'
|
||||||
import {type AnalyticsContextType} from '#/analytics'
|
import {type AnalyticsContextType} from '#/analytics'
|
||||||
@@ -8,7 +7,7 @@ import {type Geolocation} from '#/geolocation'
|
|||||||
export type EnabledCheckProps = {
|
export type EnabledCheckProps = {
|
||||||
features: AnalyticsContextType['features']
|
features: AnalyticsContextType['features']
|
||||||
currentAccount: SessionAccount
|
currentAccount: SessionAccount
|
||||||
currentProfile: AppBskyActorDefs.ProfileViewDetailed
|
currentProfile: app.bsky.actor.defs.ProfileViewDetailed
|
||||||
preferences: UsePreferencesQueryResponse
|
preferences: UsePreferencesQueryResponse
|
||||||
geolocation: Geolocation
|
geolocation: Geolocation
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
|
||||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {chat} from '#/lexicons'
|
||||||
import {MessageContextMenu} from '#/components/dms/MessageContextMenu'
|
import {MessageContextMenu} from '#/components/dms/MessageContextMenu'
|
||||||
import {useMessageReplies} from '#/components/dms/MessageReplies'
|
import {useMessageReplies} from '#/components/dms/MessageReplies'
|
||||||
import {SwipeToReply} from '#/components/dms/SwipeToReply'
|
import {SwipeToReply} from '#/components/dms/SwipeToReply'
|
||||||
@@ -15,7 +15,7 @@ export function ActionsWrapper({
|
|||||||
moderationOpts,
|
moderationOpts,
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
message: ChatBskyConvoDefs.MessageView
|
message: chat.bsky.convo.defs.MessageView
|
||||||
isFromSelf: boolean
|
isFromSelf: boolean
|
||||||
senderProfile?: bsky.profile.AnyProfileView
|
senderProfile?: bsky.profile.AnyProfileView
|
||||||
moderationOpts: ModerationOpts | undefined
|
moderationOpts: ModerationOpts | undefined
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {useCallback, useRef, useState} from 'react'
|
import {useCallback, useRef, useState} from 'react'
|
||||||
import {Pressable, View} from 'react-native'
|
import {Pressable, View} from 'react-native'
|
||||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
|
||||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||||
import {plural} from '@lingui/core/macro'
|
import {plural} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {chat} from '#/lexicons'
|
||||||
import {EMOJI_REACTION_LIMIT} from '#/lib/constants'
|
import {EMOJI_REACTION_LIMIT} from '#/lib/constants'
|
||||||
import {useMaybeProfileShadow} from '#/state/cache/profile-shadow'
|
import {useMaybeProfileShadow} from '#/state/cache/profile-shadow'
|
||||||
import {useConvoActive} from '#/state/messages/convo'
|
import {useConvoActive} from '#/state/messages/convo'
|
||||||
@@ -29,7 +29,7 @@ export function ActionsWrapper({
|
|||||||
moderationOpts,
|
moderationOpts,
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
message: ChatBskyConvoDefs.MessageView
|
message: chat.bsky.convo.defs.MessageView
|
||||||
isFromSelf: boolean
|
isFromSelf: boolean
|
||||||
senderProfile?: bsky.profile.AnyProfileView
|
senderProfile?: bsky.profile.AnyProfileView
|
||||||
moderationOpts: ModerationOpts | undefined
|
moderationOpts: ModerationOpts | undefined
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {memo, useState} from 'react'
|
import {memo, useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyActorDefs} 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 {StackActions, useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type NavigationProp} from '#/lib/routes/types'
|
import {type NavigationProp} from '#/lib/routes/types'
|
||||||
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
||||||
import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
|
import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
|
||||||
@@ -113,7 +113,7 @@ function DoneStep({
|
|||||||
}: {
|
}: {
|
||||||
convoId: string
|
convoId: string
|
||||||
currentScreen: 'list' | 'conversation'
|
currentScreen: 'list' | 'conversation'
|
||||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||||
}) {
|
}) {
|
||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
const navigation = useNavigation<NavigationProp>()
|
const navigation = useNavigation<NavigationProp>()
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {memo, useState} from 'react'
|
import {memo, useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyActorDefs} 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 {StackActions, useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type NavigationProp} from '#/lib/routes/types'
|
import {type NavigationProp} from '#/lib/routes/types'
|
||||||
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
import {useProfileShadow} from '#/state/cache/profile-shadow'
|
||||||
import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
|
import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
|
||||||
@@ -116,7 +116,7 @@ function DoneStep({
|
|||||||
}: {
|
}: {
|
||||||
convoId: string
|
convoId: string
|
||||||
currentScreen: 'list' | 'conversation'
|
currentScreen: 'list' | 'conversation'
|
||||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||||
}) {
|
}) {
|
||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
const navigation = useNavigation<NavigationProp>()
|
const navigation = useNavigation<NavigationProp>()
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {ChatBskyGroupDefs} from '@atproto/api'
|
|
||||||
import {Plural, Trans} from '@lingui/react/macro'
|
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 {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||||
import {makeProfileLink} from '#/lib/routes/links'
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
@@ -21,7 +22,8 @@ export function Card({size}: {size: 'large' | 'small'}) {
|
|||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {preview, hasFixedHeight} = useChatInvite()
|
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 ownerDisplayName = createSanitizedDisplayName(preview.owner)
|
||||||
const ownerHandle = sanitizeHandle(preview.owner.handle, '@')
|
const ownerHandle = sanitizeHandle(preview.owner.handle, '@')
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import {setStringAsync} from 'expo-clipboard'
|
import {setStringAsync} from 'expo-clipboard'
|
||||||
import {ChatBskyGroupDefs} from '@atproto/api'
|
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
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 NavigationProp} from '#/lib/routes/types'
|
||||||
import {
|
import {
|
||||||
type ChatInvitePreview,
|
type ChatInvitePreview,
|
||||||
@@ -71,7 +72,7 @@ export function Root({
|
|||||||
status = 'loading'
|
status = 'loading'
|
||||||
} else if (error) {
|
} else if (error) {
|
||||||
status = 'error'
|
status = 'error'
|
||||||
} else if (ChatBskyGroupDefs.isJoinLinkPreviewView(preview)) {
|
} else if (bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview)) {
|
||||||
status = 'available'
|
status = 'available'
|
||||||
} else {
|
} else {
|
||||||
// Resolved to a disabled/invalid/unrecognized preview - nothing to join.
|
// Resolved to a disabled/invalid/unrecognized preview - nothing to join.
|
||||||
@@ -79,7 +80,7 @@ export function Root({
|
|||||||
}
|
}
|
||||||
|
|
||||||
let action: ChatInviteAction | undefined
|
let action: ChatInviteAction | undefined
|
||||||
if (ChatBskyGroupDefs.isJoinLinkPreviewView(preview)) {
|
if (bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview)) {
|
||||||
const convoId = preview.convo?.id
|
const convoId = preview.convo?.id
|
||||||
const isFollowing = preview.owner.viewer?.followedBy ?? false
|
const isFollowing = preview.owner.viewer?.followedBy ?? false
|
||||||
const hasRequested = !convoId && preview.viewer?.requestedAt != null
|
const hasRequested = !convoId && preview.viewer?.requestedAt != null
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {useMemo, useState} from 'react'
|
import {useMemo, useState} from 'react'
|
||||||
import {useWindowDimensions, View} from 'react-native'
|
import {useWindowDimensions, View} from 'react-native'
|
||||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
|
|
||||||
|
import {chat} from '#/lexicons'
|
||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {atoms as a, tokens, useTheme} from '#/alf'
|
import {atoms as a, tokens, useTheme} from '#/alf'
|
||||||
import * as ContextMenu from '#/components/ContextMenu'
|
import * as ContextMenu from '#/components/ContextMenu'
|
||||||
@@ -21,7 +21,7 @@ export function EmojiReactionPicker({
|
|||||||
message,
|
message,
|
||||||
onEmojiSelect,
|
onEmojiSelect,
|
||||||
}: {
|
}: {
|
||||||
message: ChatBskyConvoDefs.MessageView
|
message: chat.bsky.convo.defs.MessageView
|
||||||
children?: TriggerProps['children']
|
children?: TriggerProps['children']
|
||||||
onEmojiSelect: (emoji: string) => void
|
onEmojiSelect: (emoji: string) => void
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {useState} from 'react'
|
import {useState} from 'react'
|
||||||
import {Pressable, View} from 'react-native'
|
import {Pressable, View} from 'react-native'
|
||||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
import {DropdownMenu} from 'radix-ui'
|
import {DropdownMenu} from 'radix-ui'
|
||||||
|
|
||||||
|
import {chat} from '#/lexicons'
|
||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {atoms as a, flatten, useTheme} from '#/alf'
|
import {atoms as a, flatten, useTheme} from '#/alf'
|
||||||
import * as EmojiPicker from '#/components/EmojiPicker'
|
import * as EmojiPicker from '#/components/EmojiPicker'
|
||||||
@@ -17,7 +17,7 @@ export function EmojiReactionPicker({
|
|||||||
children,
|
children,
|
||||||
onEmojiSelect,
|
onEmojiSelect,
|
||||||
}: {
|
}: {
|
||||||
message: ChatBskyConvoDefs.MessageView
|
message: chat.bsky.convo.defs.MessageView
|
||||||
children?: EmojiPicker.TriggerProps['children']
|
children?: EmojiPicker.TriggerProps['children']
|
||||||
onEmojiSelect: (emoji: string) => void
|
onEmojiSelect: (emoji: string) => void
|
||||||
}) {
|
}) {
|
||||||
@@ -40,7 +40,7 @@ function MenuInner({
|
|||||||
message,
|
message,
|
||||||
onEmojiSelect,
|
onEmojiSelect,
|
||||||
}: {
|
}: {
|
||||||
message: ChatBskyConvoDefs.MessageView
|
message: chat.bsky.convo.defs.MessageView
|
||||||
onEmojiSelect: (emoji: string) => void
|
onEmojiSelect: (emoji: string) => void
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import {memo, useCallback} from 'react'
|
|||||||
import {Platform} from 'react-native'
|
import {Platform} from 'react-native'
|
||||||
import {type GestureType} from 'react-native-gesture-handler'
|
import {type GestureType} from 'react-native-gesture-handler'
|
||||||
import * as Clipboard from 'expo-clipboard'
|
import * as Clipboard from 'expo-clipboard'
|
||||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
|
||||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||||
import {RichText} from '@bsky.app/sdk/richtext'
|
import {RichText} from '@bsky.app/sdk/richtext'
|
||||||
import {plural} from '@lingui/core/macro'
|
import {plural} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {chat} from '#/lexicons'
|
||||||
import {EMOJI_REACTION_LIMIT} from '#/lib/constants'
|
import {EMOJI_REACTION_LIMIT} from '#/lib/constants'
|
||||||
import {useGoogleTranslate} from '#/lib/hooks/useGoogleTranslate'
|
import {useGoogleTranslate} from '#/lib/hooks/useGoogleTranslate'
|
||||||
import {asSdkFacets, richTextToString} from '#/lib/strings/rich-text-helpers'
|
import {asSdkFacets, richTextToString} from '#/lib/strings/rich-text-helpers'
|
||||||
@@ -39,7 +39,7 @@ export let MessageContextMenu = ({
|
|||||||
children,
|
children,
|
||||||
swipeGesture,
|
swipeGesture,
|
||||||
}: {
|
}: {
|
||||||
message: ChatBskyConvoDefs.MessageView
|
message: chat.bsky.convo.defs.MessageView
|
||||||
senderProfile?: bsky.profile.AnyProfileView
|
senderProfile?: bsky.profile.AnyProfileView
|
||||||
moderationOpts: ModerationOpts | undefined
|
moderationOpts: ModerationOpts | undefined
|
||||||
children: TriggerProps['children']
|
children: TriggerProps['children']
|
||||||
|
|||||||
@@ -22,17 +22,13 @@ import Animated, {
|
|||||||
ZoomIn,
|
ZoomIn,
|
||||||
ZoomOut,
|
ZoomOut,
|
||||||
} from 'react-native-reanimated'
|
} from 'react-native-reanimated'
|
||||||
import {
|
|
||||||
AppBskyEmbedRecord,
|
|
||||||
type ChatBskyActorDefs,
|
|
||||||
ChatBskyConvoDefs,
|
|
||||||
ChatBskyEmbedJoinLink,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
import {RichText as RichTextAPI} from '@bsky.app/sdk/richtext'
|
||||||
import {plural} from '@lingui/core/macro'
|
import {plural} from '@lingui/core/macro'
|
||||||
import {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
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 {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
|
||||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||||
import {moderateProfile} from '#/lib/moderation/subjects'
|
import {moderateProfile} from '#/lib/moderation/subjects'
|
||||||
@@ -77,16 +73,19 @@ const SQUARED_BORDER_RADIUS = 4
|
|||||||
const DISPLAY_NAME_INSET = 20
|
const DISPLAY_NAME_INSET = 20
|
||||||
|
|
||||||
export type MessageItemNeighbor =
|
export type MessageItemNeighbor =
|
||||||
| ChatBskyConvoDefs.MessageView
|
| chat.bsky.convo.defs.MessageView
|
||||||
| ChatBskyConvoDefs.DeletedMessageView
|
| chat.bsky.convo.defs.DeletedMessageView
|
||||||
| null
|
| null
|
||||||
|
|
||||||
function messageIsReply(message: MessageItemNeighbor): boolean {
|
function messageIsReply(message: MessageItemNeighbor): boolean {
|
||||||
return (
|
return (
|
||||||
ChatBskyConvoDefs.isMessageView(message) &&
|
bsky.isType(chat.bsky.convo.defs.messageView, message) &&
|
||||||
(ChatBskyConvoDefs.isMessageView(message.replyTo) ||
|
(bsky.isType(chat.bsky.convo.defs.messageView, message.replyTo) ||
|
||||||
ChatBskyConvoDefs.isDeletedMessageView(message.replyTo) ||
|
bsky.isType(chat.bsky.convo.defs.deletedMessageView, message.replyTo) ||
|
||||||
ChatBskyConvoDefs.isMessageBeforeUserJoinedGroupView(message.replyTo))
|
bsky.isType(
|
||||||
|
chat.bsky.convo.defs.messageBeforeUserJoinedGroupView,
|
||||||
|
message.replyTo,
|
||||||
|
))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +97,7 @@ function isWithinClusterBoundary({
|
|||||||
direction,
|
direction,
|
||||||
}: {
|
}: {
|
||||||
isPending: boolean
|
isPending: boolean
|
||||||
message: ChatBskyConvoDefs.MessageView
|
message: chat.bsky.convo.defs.MessageView
|
||||||
adjacentMessage: MessageItemNeighbor
|
adjacentMessage: MessageItemNeighbor
|
||||||
isFromSameSender: boolean
|
isFromSameSender: boolean
|
||||||
direction: 'prev' | 'next'
|
direction: 'prev' | 'next'
|
||||||
@@ -110,7 +109,7 @@ function isWithinClusterBoundary({
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (!isFromSameSender) return true
|
if (!isFromSameSender) return true
|
||||||
if (ChatBskyConvoDefs.isMessageView(adjacentMessage)) {
|
if (bsky.isType(chat.bsky.convo.defs.messageView, adjacentMessage)) {
|
||||||
const currentSentAt = message.sentAt
|
const currentSentAt = message.sentAt
|
||||||
const thisDate = new Date(currentSentAt)
|
const thisDate = new Date(currentSentAt)
|
||||||
const adjDate = new Date(adjacentMessage.sentAt)
|
const adjDate = new Date(adjacentMessage.sentAt)
|
||||||
@@ -137,7 +136,7 @@ let MessageItem = ({
|
|||||||
isGroupChat?: boolean
|
isGroupChat?: boolean
|
||||||
prevMessage: MessageItemNeighbor
|
prevMessage: MessageItemNeighbor
|
||||||
nextMessage: MessageItemNeighbor
|
nextMessage: MessageItemNeighbor
|
||||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||||
}): React.ReactNode => {
|
}): React.ReactNode => {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
@@ -155,13 +154,17 @@ let MessageItem = ({
|
|||||||
// tombstone, or a before-joined placeholder. Narrow away the open-union
|
// tombstone, or a before-joined placeholder. Narrow away the open-union
|
||||||
// fallback so we only render shapes we understand.
|
// fallback so we only render shapes we understand.
|
||||||
const replyTo =
|
const replyTo =
|
||||||
ChatBskyConvoDefs.isMessageView(message.replyTo) ||
|
bsky.isType(chat.bsky.convo.defs.messageView, message.replyTo) ||
|
||||||
ChatBskyConvoDefs.isDeletedMessageView(message.replyTo) ||
|
bsky.isType(chat.bsky.convo.defs.deletedMessageView, message.replyTo) ||
|
||||||
ChatBskyConvoDefs.isMessageBeforeUserJoinedGroupView(message.replyTo)
|
bsky.isType(
|
||||||
|
chat.bsky.convo.defs.messageBeforeUserJoinedGroupView,
|
||||||
|
message.replyTo,
|
||||||
|
)
|
||||||
? message.replyTo
|
? message.replyTo
|
||||||
: undefined
|
: undefined
|
||||||
const replyToMessageId =
|
const replyToMessageId =
|
||||||
replyTo && !ChatBskyConvoDefs.isMessageBeforeUserJoinedGroupView(replyTo)
|
replyTo &&
|
||||||
|
!bsky.isType(chat.bsky.convo.defs.messageBeforeUserJoinedGroupView, replyTo)
|
||||||
? replyTo.id
|
? replyTo.id
|
||||||
: undefined
|
: undefined
|
||||||
const onPressReplyTo = replyToMessageId
|
const onPressReplyTo = replyToMessageId
|
||||||
@@ -175,8 +178,14 @@ let MessageItem = ({
|
|||||||
const isFromSelf =
|
const isFromSelf =
|
||||||
message.sender?.did != null && message.sender.did === currentAccount?.did
|
message.sender?.did != null && message.sender.did === currentAccount?.did
|
||||||
|
|
||||||
const prevIsMessage = ChatBskyConvoDefs.isMessageView(prevMessage)
|
const prevIsMessage = bsky.isType(
|
||||||
const nextIsMessage = ChatBskyConvoDefs.isMessageView(nextMessage)
|
chat.bsky.convo.defs.messageView,
|
||||||
|
prevMessage,
|
||||||
|
)
|
||||||
|
const nextIsMessage = bsky.isType(
|
||||||
|
chat.bsky.convo.defs.messageView,
|
||||||
|
nextMessage,
|
||||||
|
)
|
||||||
|
|
||||||
const isPrevFromSameSender =
|
const isPrevFromSameSender =
|
||||||
prevIsMessage &&
|
prevIsMessage &&
|
||||||
@@ -204,7 +213,7 @@ let MessageItem = ({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const hasLargeGapFromPrev =
|
const hasLargeGapFromPrev =
|
||||||
!ChatBskyConvoDefs.isMessageView(prevMessage) ||
|
!bsky.isType(chat.bsky.convo.defs.messageView, prevMessage) ||
|
||||||
new Date(message.sentAt).getTime() -
|
new Date(message.sentAt).getTime() -
|
||||||
new Date(prevMessage.sentAt).getTime() >
|
new Date(prevMessage.sentAt).getTime() >
|
||||||
MESSAGE_GAP_THRESHOLD_MS
|
MESSAGE_GAP_THRESHOLD_MS
|
||||||
@@ -254,8 +263,8 @@ let MessageItem = ({
|
|||||||
const isEmojiOnly = isOnlyEmoji(message.text)
|
const isEmojiOnly = isOnlyEmoji(message.text)
|
||||||
|
|
||||||
const hasEmbed =
|
const hasEmbed =
|
||||||
AppBskyEmbedRecord.isView(message.embed) ||
|
bsky.isType(app.bsky.embed.record.view, message.embed) ||
|
||||||
ChatBskyEmbedJoinLink.isView(message.embed)
|
bsky.isType(chat.bsky.embed.joinLink.view, message.embed)
|
||||||
const hasEmbedAndText = hasEmbed && rt.text.length > 0
|
const hasEmbedAndText = hasEmbed && rt.text.length > 0
|
||||||
|
|
||||||
const targetBottomRadius = squaredBottomCorner
|
const targetBottomRadius = squaredBottomCorner
|
||||||
@@ -516,7 +525,7 @@ let MessageItem = ({
|
|||||||
message={message}
|
message={message}
|
||||||
senderProfile={profile}
|
senderProfile={profile}
|
||||||
moderationOpts={moderationOpts}>
|
moderationOpts={moderationOpts}>
|
||||||
{AppBskyEmbedRecord.isView(message.embed) && (
|
{bsky.isType(app.bsky.embed.record.view, message.embed) && (
|
||||||
<MessageItemEmbed
|
<MessageItemEmbed
|
||||||
embed={message.embed}
|
embed={message.embed}
|
||||||
isFromSelf={isFromSelf}
|
isFromSelf={isFromSelf}
|
||||||
@@ -528,7 +537,10 @@ let MessageItem = ({
|
|||||||
highlightSV={highlightSV}
|
highlightSV={highlightSV}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{ChatBskyEmbedJoinLink.isView(message.embed) && (
|
{bsky.isType(
|
||||||
|
chat.bsky.embed.joinLink.view,
|
||||||
|
message.embed,
|
||||||
|
) && (
|
||||||
<MessageItemInviteEmbed
|
<MessageItemInviteEmbed
|
||||||
embed={message.embed}
|
embed={message.embed}
|
||||||
isFromSelf={isFromSelf}
|
isFromSelf={isFromSelf}
|
||||||
@@ -666,7 +678,7 @@ function BlockedPlaceholder({
|
|||||||
profile,
|
profile,
|
||||||
style,
|
style,
|
||||||
}: {
|
}: {
|
||||||
profile: Shadow<ChatBskyActorDefs.ProfileViewBasic>
|
profile: Shadow<chat.bsky.actor.defs.ProfileViewBasic>
|
||||||
style?: AnimatedStyle<ViewStyle>
|
style?: AnimatedStyle<ViewStyle>
|
||||||
}) {
|
}) {
|
||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
@@ -776,13 +788,13 @@ function ReplyCaption({
|
|||||||
onPress,
|
onPress,
|
||||||
}: {
|
}: {
|
||||||
replyTo:
|
replyTo:
|
||||||
| ChatBskyConvoDefs.MessageView
|
| chat.bsky.convo.defs.MessageView
|
||||||
| ChatBskyConvoDefs.DeletedMessageView
|
| chat.bsky.convo.defs.DeletedMessageView
|
||||||
| ChatBskyConvoDefs.MessageBeforeUserJoinedGroupView
|
| chat.bsky.convo.defs.MessageBeforeUserJoinedGroupView
|
||||||
isFromSelf: boolean
|
isFromSelf: boolean
|
||||||
isGroupChat: boolean
|
isGroupChat: boolean
|
||||||
replierDisplayName: string | null
|
replierDisplayName: string | null
|
||||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||||
onPress?: () => void
|
onPress?: () => void
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
@@ -791,8 +803,8 @@ function ReplyCaption({
|
|||||||
|
|
||||||
let caption: string = ''
|
let caption: string = ''
|
||||||
if (
|
if (
|
||||||
ChatBskyConvoDefs.isMessageView(replyTo) ||
|
bsky.isType(chat.bsky.convo.defs.messageView, replyTo) ||
|
||||||
ChatBskyConvoDefs.isDeletedMessageView(replyTo)
|
bsky.isType(chat.bsky.convo.defs.deletedMessageView, replyTo)
|
||||||
) {
|
) {
|
||||||
const originalSenderIsSelf = replyTo.sender.did === currentAccount?.did
|
const originalSenderIsSelf = replyTo.sender.did === currentAccount?.did
|
||||||
const originalProfile = relatedProfiles.get(replyTo.sender.did)
|
const originalProfile = relatedProfiles.get(replyTo.sender.did)
|
||||||
@@ -865,11 +877,11 @@ function ReplyQuote({
|
|||||||
onPress,
|
onPress,
|
||||||
}: {
|
}: {
|
||||||
replyTo:
|
replyTo:
|
||||||
| ChatBskyConvoDefs.MessageView
|
| chat.bsky.convo.defs.MessageView
|
||||||
| ChatBskyConvoDefs.DeletedMessageView
|
| chat.bsky.convo.defs.DeletedMessageView
|
||||||
| ChatBskyConvoDefs.MessageBeforeUserJoinedGroupView
|
| chat.bsky.convo.defs.MessageBeforeUserJoinedGroupView
|
||||||
isFromSelf: boolean
|
isFromSelf: boolean
|
||||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||||
onPress?: () => void
|
onPress?: () => void
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
@@ -877,8 +889,8 @@ function ReplyQuote({
|
|||||||
const getReplyPreviewText = useReplyPreviewText()
|
const getReplyPreviewText = useReplyPreviewText()
|
||||||
|
|
||||||
const senderDid =
|
const senderDid =
|
||||||
ChatBskyConvoDefs.isMessageView(replyTo) ||
|
bsky.isType(chat.bsky.convo.defs.messageView, replyTo) ||
|
||||||
ChatBskyConvoDefs.isDeletedMessageView(replyTo)
|
bsky.isType(chat.bsky.convo.defs.deletedMessageView, replyTo)
|
||||||
? replyTo.sender.did
|
? replyTo.sender.did
|
||||||
: undefined
|
: undefined
|
||||||
const senderProfile = useMaybeProfileShadow(
|
const senderProfile = useMaybeProfileShadow(
|
||||||
@@ -908,9 +920,11 @@ function ReplyQuote({
|
|||||||
comment: 'A reply summary in chat',
|
comment: 'A reply summary in chat',
|
||||||
})
|
})
|
||||||
subtle = true
|
subtle = true
|
||||||
} else if (ChatBskyConvoDefs.isMessageView(replyTo)) {
|
} else if (bsky.isType(chat.bsky.convo.defs.messageView, replyTo)) {
|
||||||
;({text, subtle} = getReplyPreviewText(replyTo))
|
;({text, subtle} = getReplyPreviewText(replyTo))
|
||||||
} else if (ChatBskyConvoDefs.isMessageBeforeUserJoinedGroupView(replyTo)) {
|
} else if (
|
||||||
|
bsky.isType(chat.bsky.convo.defs.messageBeforeUserJoinedGroupView, replyTo)
|
||||||
|
) {
|
||||||
text = l({
|
text = l({
|
||||||
message: `(message sent before you joined)`,
|
message: `(message sent before you joined)`,
|
||||||
comment: 'A reply summary in chat',
|
comment: 'A reply summary in chat',
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ import Animated, {
|
|||||||
type SharedValue,
|
type SharedValue,
|
||||||
useAnimatedStyle,
|
useAnimatedStyle,
|
||||||
} from 'react-native-reanimated'
|
} 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 {atoms as a, native, useTheme, web} from '#/alf'
|
||||||
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
|
import {Embed, PostEmbedViewContext} from '#/components/Post/Embed'
|
||||||
import {MessageContextProvider} from './MessageContext'
|
import {MessageContextProvider} from './MessageContext'
|
||||||
@@ -22,7 +23,7 @@ let MessageItemEmbed = ({
|
|||||||
squaredBottomCorner,
|
squaredBottomCorner,
|
||||||
highlightSV,
|
highlightSV,
|
||||||
}: {
|
}: {
|
||||||
embed: $Typed<AppBskyEmbedRecord.View>
|
embed: $Typed<app.bsky.embed.record.View>
|
||||||
isFromSelf: boolean
|
isFromSelf: boolean
|
||||||
isGroupChat: boolean
|
isGroupChat: boolean
|
||||||
squaredTopCorner: boolean
|
squaredTopCorner: boolean
|
||||||
|
|||||||
@@ -5,8 +5,9 @@ import Animated, {
|
|||||||
type SharedValue,
|
type SharedValue,
|
||||||
useAnimatedStyle,
|
useAnimatedStyle,
|
||||||
} from 'react-native-reanimated'
|
} 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 {useConvoActive} from '#/state/messages/convo'
|
||||||
import {isKnownJoinLinkPreview} from '#/state/queries/join-links'
|
import {isKnownJoinLinkPreview} from '#/state/queries/join-links'
|
||||||
import {atoms as a, native, useTheme, web} from '#/alf'
|
import {atoms as a, native, useTheme, web} from '#/alf'
|
||||||
@@ -24,7 +25,7 @@ let MessageItemInviteEmbed = ({
|
|||||||
squaredBottomCorner,
|
squaredBottomCorner,
|
||||||
highlightSV,
|
highlightSV,
|
||||||
}: {
|
}: {
|
||||||
embed: $Typed<ChatBskyEmbedJoinLink.View>
|
embed: $Typed<chat.bsky.embed.joinLink.View>
|
||||||
isFromSelf: boolean
|
isFromSelf: boolean
|
||||||
isGroupChat: boolean
|
isGroupChat: boolean
|
||||||
squaredTopCorner: boolean
|
squaredTopCorner: boolean
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import {
|
|||||||
useState,
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import {LayoutAnimation} from 'react-native'
|
import {LayoutAnimation} from 'react-native'
|
||||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {chat} from '#/lexicons'
|
||||||
import {useConvoActive} from '#/state/messages/convo'
|
import {useConvoActive} from '#/state/messages/convo'
|
||||||
import {unstableCacheProfileView} from '#/state/queries/unstable-profile-cache'
|
import {unstableCacheProfileView} from '#/state/queries/unstable-profile-cache'
|
||||||
import {useDialogControl} from '#/components/Dialog'
|
import {useDialogControl} from '#/components/Dialog'
|
||||||
@@ -23,12 +23,12 @@ import * as Toast from '#/components/Toast'
|
|||||||
import type * as bsky from '#/types/bsky'
|
import type * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
type MessageDialogsContextType = {
|
type MessageDialogsContextType = {
|
||||||
openDeleteMessage: (message: ChatBskyConvoDefs.MessageView) => void
|
openDeleteMessage: (message: chat.bsky.convo.defs.MessageView) => void
|
||||||
openReportMessage: (
|
openReportMessage: (
|
||||||
message: ChatBskyConvoDefs.MessageView,
|
message: chat.bsky.convo.defs.MessageView,
|
||||||
senderProfile: bsky.profile.AnyProfileView | undefined,
|
senderProfile: bsky.profile.AnyProfileView | undefined,
|
||||||
) => void
|
) => void
|
||||||
openReactions: (message: ChatBskyConvoDefs.MessageView) => void
|
openReactions: (message: chat.bsky.convo.defs.MessageView) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const Context = createContext<MessageDialogsContextType | null>(null)
|
const Context = createContext<MessageDialogsContextType | null>(null)
|
||||||
@@ -52,18 +52,18 @@ export function MessageOverlays({children}: {children: React.ReactNode}) {
|
|||||||
const reactionsControl = useDialogControl()
|
const reactionsControl = useDialogControl()
|
||||||
|
|
||||||
const [deleteTarget, setDeleteTarget] =
|
const [deleteTarget, setDeleteTarget] =
|
||||||
useState<ChatBskyConvoDefs.MessageView | null>(null)
|
useState<chat.bsky.convo.defs.MessageView | null>(null)
|
||||||
const [reportTarget, setReportTarget] = useState<{
|
const [reportTarget, setReportTarget] = useState<{
|
||||||
message: ChatBskyConvoDefs.MessageView
|
message: chat.bsky.convo.defs.MessageView
|
||||||
senderProfile: bsky.profile.AnyProfileView | undefined
|
senderProfile: bsky.profile.AnyProfileView | undefined
|
||||||
} | null>(null)
|
} | null>(null)
|
||||||
const [afterReportTarget, setAfterReportTarget] =
|
const [afterReportTarget, setAfterReportTarget] =
|
||||||
useState<ChatBskyConvoDefs.MessageView | null>(null)
|
useState<chat.bsky.convo.defs.MessageView | null>(null)
|
||||||
const [reactionsTarget, setReactionsTarget] =
|
const [reactionsTarget, setReactionsTarget] =
|
||||||
useState<ChatBskyConvoDefs.MessageView | null>(null)
|
useState<chat.bsky.convo.defs.MessageView | null>(null)
|
||||||
|
|
||||||
const openDeleteMessage = useCallback(
|
const openDeleteMessage = useCallback(
|
||||||
(message: ChatBskyConvoDefs.MessageView) => {
|
(message: chat.bsky.convo.defs.MessageView) => {
|
||||||
setDeleteTarget(message)
|
setDeleteTarget(message)
|
||||||
deleteControl.open()
|
deleteControl.open()
|
||||||
},
|
},
|
||||||
@@ -72,7 +72,7 @@ export function MessageOverlays({children}: {children: React.ReactNode}) {
|
|||||||
|
|
||||||
const openReportMessage = useCallback(
|
const openReportMessage = useCallback(
|
||||||
(
|
(
|
||||||
message: ChatBskyConvoDefs.MessageView,
|
message: chat.bsky.convo.defs.MessageView,
|
||||||
senderProfile: bsky.profile.AnyProfileView | undefined,
|
senderProfile: bsky.profile.AnyProfileView | undefined,
|
||||||
) => {
|
) => {
|
||||||
setReportTarget({message, senderProfile})
|
setReportTarget({message, senderProfile})
|
||||||
@@ -82,7 +82,7 @@ export function MessageOverlays({children}: {children: React.ReactNode}) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
const openReactions = useCallback(
|
const openReactions = useCallback(
|
||||||
(message: ChatBskyConvoDefs.MessageView) => {
|
(message: chat.bsky.convo.defs.MessageView) => {
|
||||||
setReactionsTarget(message)
|
setReactionsTarget(message)
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {useCallback} from 'react'
|
import {useCallback} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type AppBskyActorDefs} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
|
import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerification'
|
||||||
import {type NavigationProp} from '#/lib/routes/types'
|
import {type NavigationProp} from '#/lib/routes/types'
|
||||||
import {useGetConvoAvailabilityQuery} from '#/state/queries/messages/get-convo-availability'
|
import {useGetConvoAvailabilityQuery} from '#/state/queries/messages/get-convo-availability'
|
||||||
@@ -20,7 +20,7 @@ import {useAnalytics} from '#/analytics'
|
|||||||
export function MessageProfileButton({
|
export function MessageProfileButton({
|
||||||
profile,
|
profile,
|
||||||
}: {
|
}: {
|
||||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||||
}) {
|
}) {
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import {chat} from '#/lexicons'
|
||||||
import {
|
import {
|
||||||
createContext,
|
createContext,
|
||||||
useCallback,
|
useCallback,
|
||||||
@@ -7,7 +8,6 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import {type ChatBskyConvoDefs} from '@atproto/api'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How long a message stays highlighted after scrolling to it, before the flash
|
* 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.
|
* The message currently staged for reply in the composer, or null.
|
||||||
*/
|
*/
|
||||||
replyTo: ChatBskyConvoDefs.MessageView | null
|
replyTo: chat.bsky.convo.defs.MessageView | null
|
||||||
setReply: (message: ChatBskyConvoDefs.MessageView) => void
|
setReply: (message: chat.bsky.convo.defs.MessageView) => void
|
||||||
clearReply: () => void
|
clearReply: () => void
|
||||||
/**
|
/**
|
||||||
* Scroll the list to a message, if it's currently loaded, and flash it. No-op
|
* 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
|
scrollToMessage: (messageId: string) => boolean
|
||||||
}) {
|
}) {
|
||||||
const [replyTo, setReplyTo] = useState<ChatBskyConvoDefs.MessageView | null>(
|
const [replyTo, setReplyTo] =
|
||||||
null,
|
useState<chat.bsky.convo.defs.MessageView | null>(null)
|
||||||
)
|
|
||||||
const [highlightedMessage, setHighlightedMessage] =
|
const [highlightedMessage, setHighlightedMessage] =
|
||||||
useState<HighlightedMessage | null>(null)
|
useState<HighlightedMessage | null>(null)
|
||||||
const highlightKey = useRef(0)
|
const highlightKey = useRef(0)
|
||||||
@@ -76,7 +75,7 @@ export function MessageRepliesProvider({
|
|||||||
null,
|
null,
|
||||||
)
|
)
|
||||||
|
|
||||||
const setReply = useCallback((message: ChatBskyConvoDefs.MessageView) => {
|
const setReply = useCallback((message: chat.bsky.convo.defs.MessageView) => {
|
||||||
setReplyTo(message)
|
setReplyTo(message)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import {
|
|||||||
useWindowDimensions,
|
useWindowDimensions,
|
||||||
View,
|
View,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {type ChatBskyActorDefs, type ChatBskyConvoDefs} from '@atproto/api'
|
|
||||||
import {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {chat} from '#/lexicons'
|
||||||
import {HITSLOP_10} from '#/lib/constants'
|
import {HITSLOP_10} from '#/lib/constants'
|
||||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||||
@@ -28,7 +28,7 @@ import type * as bsky from '#/types/bsky'
|
|||||||
type Reaction = {
|
type Reaction = {
|
||||||
key: string
|
key: string
|
||||||
value: string
|
value: string
|
||||||
senders: ChatBskyConvoDefs.ReactionViewSender[]
|
senders: chat.bsky.convo.defs.ReactionViewSender[]
|
||||||
count: number
|
count: number
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,8 +41,8 @@ export function ReactionsDialog({
|
|||||||
onClose,
|
onClose,
|
||||||
}: {
|
}: {
|
||||||
control: Dialog.DialogControlProps
|
control: Dialog.DialogControlProps
|
||||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||||
message: ChatBskyConvoDefs.MessageView
|
message: chat.bsky.convo.defs.MessageView
|
||||||
onClose?: () => void
|
onClose?: () => void
|
||||||
}) {
|
}) {
|
||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
@@ -142,10 +142,10 @@ function ReactionRow({
|
|||||||
control: Dialog.DialogControlProps
|
control: Dialog.DialogControlProps
|
||||||
convo: ActiveConvoStates
|
convo: ActiveConvoStates
|
||||||
currentAccount?: SessionAccount
|
currentAccount?: SessionAccount
|
||||||
message: ChatBskyConvoDefs.MessageView
|
message: chat.bsky.convo.defs.MessageView
|
||||||
profile: bsky.profile.AnyProfileView
|
profile: bsky.profile.AnyProfileView
|
||||||
reaction: ChatBskyConvoDefs.ReactionView
|
reaction: chat.bsky.convo.defs.ReactionView
|
||||||
allReactions: ChatBskyConvoDefs.ReactionView[]
|
allReactions: chat.bsky.convo.defs.ReactionView[]
|
||||||
selected: string
|
selected: string
|
||||||
setSelected: React.Dispatch<React.SetStateAction<string>>
|
setSelected: React.Dispatch<React.SetStateAction<string>>
|
||||||
}) {
|
}) {
|
||||||
@@ -398,7 +398,7 @@ function ReactionTab({
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function groupReactions(
|
export function groupReactions(
|
||||||
reactions: ChatBskyConvoDefs.ReactionView[] | undefined,
|
reactions: chat.bsky.convo.defs.ReactionView[] | undefined,
|
||||||
): Reaction[] {
|
): Reaction[] {
|
||||||
const grouped = new Map<string, Reaction>()
|
const grouped = new Map<string, Reaction>()
|
||||||
for (const reaction of reactions ?? []) {
|
for (const reaction of reactions ?? []) {
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ import Animated, {
|
|||||||
useDerivedValue,
|
useDerivedValue,
|
||||||
withTiming,
|
withTiming,
|
||||||
} from 'react-native-reanimated'
|
} from 'react-native-reanimated'
|
||||||
import {type ChatBskyActorDefs} from '@atproto/api'
|
|
||||||
import {plural} from '@lingui/core/macro'
|
import {plural} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {chat} from '#/lexicons'
|
||||||
import {HITSLOP_10} from '#/lib/constants'
|
import {HITSLOP_10} from '#/lib/constants'
|
||||||
import {type SystemMessageGroupItem} from '#/screens/Messages/components/groupSystemMessages'
|
import {type SystemMessageGroupItem} from '#/screens/Messages/components/groupSystemMessages'
|
||||||
import {atoms as a, useTheme} from '#/alf'
|
import {atoms as a, useTheme} from '#/alf'
|
||||||
@@ -29,7 +29,7 @@ export function SystemMessageGroup({
|
|||||||
item: SystemMessageGroupItem
|
item: SystemMessageGroupItem
|
||||||
expanded: boolean
|
expanded: boolean
|
||||||
onToggle: (key: string) => void
|
onToggle: (key: string) => void
|
||||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type ChatBskyActorDefs} from '@atproto/api'
|
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {chat} from '#/lexicons'
|
||||||
import {makeProfileLink} from '#/lib/routes/links'
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
import {type ConvoItem} from '#/state/messages/convo/types'
|
import {type ConvoItem} from '#/state/messages/convo/types'
|
||||||
import {useInviteLinkDialog} from '#/screens/Messages/components/InviteLinkDialogProvider'
|
import {useInviteLinkDialog} from '#/screens/Messages/components/InviteLinkDialogProvider'
|
||||||
@@ -16,7 +16,7 @@ export function SystemMessageItem({
|
|||||||
relatedProfiles,
|
relatedProfiles,
|
||||||
}: {
|
}: {
|
||||||
item: ConvoItem & {type: 'system-message'}
|
item: ConvoItem & {type: 'system-message'}
|
||||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {i18n, t: l} = useLingui()
|
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 {type I18n} from '@lingui/core'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
|
|
||||||
|
import {app, chat} from '#/lexicons'
|
||||||
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
|
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
|
||||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||||
import {
|
import {
|
||||||
@@ -14,12 +9,12 @@ import {
|
|||||||
toBskyAppUrl,
|
toBskyAppUrl,
|
||||||
toShortUrl,
|
toShortUrl,
|
||||||
} from '#/lib/strings/url-helpers'
|
} from '#/lib/strings/url-helpers'
|
||||||
import type * as bsky from '#/types/bsky'
|
import * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
export type UserMessageInfo = {
|
export type UserMessageInfo = {
|
||||||
message: string | null
|
message: string | null
|
||||||
sentAt: string
|
sentAt: string
|
||||||
reportableMessage?: ChatBskyConvoDefs.MessageView
|
reportableMessage?: chat.bsky.convo.defs.MessageView
|
||||||
isBlockedMessage: boolean
|
isBlockedMessage: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +31,7 @@ export function isDidBlockedInConvo({
|
|||||||
primaryProfile,
|
primaryProfile,
|
||||||
}: {
|
}: {
|
||||||
did: string | undefined
|
did: string | undefined
|
||||||
members: ChatBskyActorDefs.ProfileViewBasic[]
|
members: chat.bsky.actor.defs.ProfileViewBasic[]
|
||||||
primaryProfile?: bsky.profile.AnyProfileView
|
primaryProfile?: bsky.profile.AnyProfileView
|
||||||
}): boolean {
|
}): boolean {
|
||||||
if (!did) return false
|
if (!did) return false
|
||||||
@@ -53,12 +48,12 @@ export function getMessageInfo({
|
|||||||
primaryProfile,
|
primaryProfile,
|
||||||
i18n,
|
i18n,
|
||||||
}: {
|
}: {
|
||||||
convo: ChatBskyConvoDefs.ConvoView
|
convo: chat.bsky.convo.defs.ConvoView
|
||||||
currentAccountDid: string | undefined
|
currentAccountDid: string | undefined
|
||||||
primaryProfile?: bsky.profile.AnyProfileView
|
primaryProfile?: bsky.profile.AnyProfileView
|
||||||
i18n: I18n
|
i18n: I18n
|
||||||
}): UserMessageInfo | null {
|
}): UserMessageInfo | null {
|
||||||
if (!ChatBskyConvoDefs.isMessageView(convo.lastMessage)) {
|
if (!bsky.isType(chat.bsky.convo.defs.messageView, convo.lastMessage)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +62,7 @@ export function getMessageInfo({
|
|||||||
const senderDid = lastMessage.sender?.did
|
const senderDid = lastMessage.sender?.did
|
||||||
const sender = convo.members.find(m => m.did === senderDid)
|
const sender = convo.members.find(m => m.did === senderDid)
|
||||||
const name = sender ? createSanitizedDisplayName(sender) : null
|
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 reportableMessage = isFromMe ? undefined : lastMessage
|
||||||
const isBlockedMessage = isDidBlockedInConvo({
|
const isBlockedMessage = isDidBlockedInConvo({
|
||||||
@@ -105,10 +100,10 @@ export function getMessageInfo({
|
|||||||
msg`(contains embedded content)`,
|
msg`(contains embedded content)`,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (AppBskyEmbedRecord.isView(lastMessage.embed)) {
|
if (bsky.isType(app.bsky.embed.record.view, lastMessage.embed)) {
|
||||||
const embed = 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 record = embed.record
|
||||||
const path = postUriToRelativePath(record.uri, {
|
const path = postUriToRelativePath(record.uri, {
|
||||||
handle: record.author.handle,
|
handle: record.author.handle,
|
||||||
@@ -119,7 +114,7 @@ export function getMessageInfo({
|
|||||||
} else {
|
} else {
|
||||||
message = prefix(defaultEmbeddedContentMessage)
|
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)`))
|
message = prefix(i18n._(msg`(chat invite link)`))
|
||||||
} else {
|
} else {
|
||||||
message = prefix(defaultEmbeddedContentMessage)
|
message = prefix(defaultEmbeddedContentMessage)
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {ChatBskyConvoDefs} from '@atproto/api'
|
|
||||||
import {type I18n} from '@lingui/core'
|
import {type I18n} from '@lingui/core'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
|
|
||||||
|
import {chat} from '#/lexicons'
|
||||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||||
import {isDidBlockedInConvo} from '#/components/dms/getMessageInfo'
|
import {isDidBlockedInConvo} from '#/components/dms/getMessageInfo'
|
||||||
import type * as bsky from '#/types/bsky'
|
import * as bsky from '#/types/bsky'
|
||||||
|
|
||||||
export type UserReactionInfo = {
|
export type UserReactionInfo = {
|
||||||
message: string
|
message: string
|
||||||
@@ -18,12 +18,17 @@ export function getReactionInfo({
|
|||||||
primaryProfile,
|
primaryProfile,
|
||||||
i18n,
|
i18n,
|
||||||
}: {
|
}: {
|
||||||
convo: ChatBskyConvoDefs.ConvoView
|
convo: chat.bsky.convo.defs.ConvoView
|
||||||
currentAccountDid: string | undefined
|
currentAccountDid: string | undefined
|
||||||
primaryProfile?: bsky.profile.AnyProfileView
|
primaryProfile?: bsky.profile.AnyProfileView
|
||||||
i18n: I18n
|
i18n: I18n
|
||||||
}): UserReactionInfo | null {
|
}): UserReactionInfo | null {
|
||||||
if (!ChatBskyConvoDefs.isMessageAndReactionView(convo.lastReaction)) {
|
if (
|
||||||
|
!bsky.isType(
|
||||||
|
chat.bsky.convo.defs.messageAndReactionView,
|
||||||
|
convo.lastReaction,
|
||||||
|
)
|
||||||
|
) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import {type ChatBskyActorDefs, ChatBskyConvoDefs} from '@atproto/api'
|
|
||||||
import {type MessageDescriptor} from '@lingui/core'
|
import {type MessageDescriptor} from '@lingui/core'
|
||||||
import {msg} from '@lingui/core/macro'
|
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 {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||||
import {ArrowBoxLeft_Stroke2_Corner0_Rounded as LeaveIcon} from '#/components/icons/ArrowBoxLeft'
|
import {ArrowBoxLeft_Stroke2_Corner0_Rounded as LeaveIcon} from '#/components/icons/ArrowBoxLeft'
|
||||||
import {ArrowBoxRight_Stroke2_Corner3_Rounded as JoinIcon} from '#/components/icons/ArrowBoxRight'
|
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 =
|
export type SystemMessageAction =
|
||||||
| {
|
| {
|
||||||
kind: 'profile'
|
kind: 'profile'
|
||||||
profile: ChatBskyActorDefs.ProfileViewBasic
|
profile: chat.bsky.actor.defs.ProfileViewBasic
|
||||||
displayName: string
|
displayName: string
|
||||||
}
|
}
|
||||||
| {kind: 'inviteLink'}
|
| {kind: 'inviteLink'}
|
||||||
@@ -31,8 +32,8 @@ export type SystemMessageInfo = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getProfileAction(
|
function getProfileAction(
|
||||||
user: ChatBskyConvoDefs.SystemMessageReferredUser,
|
user: chat.bsky.convo.defs.SystemMessageReferredUser,
|
||||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>,
|
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>,
|
||||||
): Extract<SystemMessageAction, {kind: 'profile'}> | null {
|
): Extract<SystemMessageAction, {kind: 'profile'}> | null {
|
||||||
const profile = relatedProfiles.get(user.did)
|
const profile = relatedProfiles.get(user.did)
|
||||||
if (!profile) return null
|
if (!profile) return null
|
||||||
@@ -44,11 +45,11 @@ function getProfileAction(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getSystemMessageInfo(
|
export function getSystemMessageInfo(
|
||||||
data: ChatBskyConvoDefs.SystemMessageView['data'],
|
data: chat.bsky.convo.defs.SystemMessageView['data'],
|
||||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>,
|
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>,
|
||||||
opts = {short: false},
|
opts = {short: false},
|
||||||
): SystemMessageInfo | null {
|
): SystemMessageInfo | null {
|
||||||
if (ChatBskyConvoDefs.isSystemMessageDataAddMember(data)) {
|
if (bsky.isType(chat.bsky.convo.defs.systemMessageDataAddMember, data)) {
|
||||||
const action = getProfileAction(data.member, relatedProfiles)
|
const action = getProfileAction(data.member, relatedProfiles)
|
||||||
return {
|
return {
|
||||||
Icon: JoinIcon,
|
Icon: JoinIcon,
|
||||||
@@ -61,7 +62,9 @@ export function getSystemMessageInfo(
|
|||||||
: msg`Someone was added to the group`,
|
: msg`Someone was added to the group`,
|
||||||
action: action ?? undefined,
|
action: action ?? undefined,
|
||||||
}
|
}
|
||||||
} else if (ChatBskyConvoDefs.isSystemMessageDataRemoveMember(data)) {
|
} else if (
|
||||||
|
bsky.isType(chat.bsky.convo.defs.systemMessageDataRemoveMember, data)
|
||||||
|
) {
|
||||||
const action = getProfileAction(data.member, relatedProfiles)
|
const action = getProfileAction(data.member, relatedProfiles)
|
||||||
return {
|
return {
|
||||||
Icon: LeaveIcon,
|
Icon: LeaveIcon,
|
||||||
@@ -74,7 +77,9 @@ export function getSystemMessageInfo(
|
|||||||
: msg`Someone was removed from the group`,
|
: msg`Someone was removed from the group`,
|
||||||
action: action ?? undefined,
|
action: action ?? undefined,
|
||||||
}
|
}
|
||||||
} else if (ChatBskyConvoDefs.isSystemMessageDataMemberJoin(data)) {
|
} else if (
|
||||||
|
bsky.isType(chat.bsky.convo.defs.systemMessageDataMemberJoin, data)
|
||||||
|
) {
|
||||||
const action = getProfileAction(data.member, relatedProfiles)
|
const action = getProfileAction(data.member, relatedProfiles)
|
||||||
return {
|
return {
|
||||||
Icon: JoinIcon,
|
Icon: JoinIcon,
|
||||||
@@ -87,7 +92,9 @@ export function getSystemMessageInfo(
|
|||||||
: msg`Someone joined the group`,
|
: msg`Someone joined the group`,
|
||||||
action: action ?? undefined,
|
action: action ?? undefined,
|
||||||
}
|
}
|
||||||
} else if (ChatBskyConvoDefs.isSystemMessageDataMemberLeave(data)) {
|
} else if (
|
||||||
|
bsky.isType(chat.bsky.convo.defs.systemMessageDataMemberLeave, data)
|
||||||
|
) {
|
||||||
const action = getProfileAction(data.member, relatedProfiles)
|
const action = getProfileAction(data.member, relatedProfiles)
|
||||||
return {
|
return {
|
||||||
Icon: LeaveIcon,
|
Icon: LeaveIcon,
|
||||||
@@ -100,13 +107,24 @@ export function getSystemMessageInfo(
|
|||||||
: msg`Someone left the group`,
|
: msg`Someone left the group`,
|
||||||
action: action ?? undefined,
|
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`}
|
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`}
|
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`}
|
return {Icon: LockIcon, message: msg`Chat ended`}
|
||||||
} else if (ChatBskyConvoDefs.isSystemMessageDataEditGroup(data)) {
|
} else if (
|
||||||
|
bsky.isType(chat.bsky.convo.defs.systemMessageDataEditGroup, data)
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
Icon: PencilIcon,
|
Icon: PencilIcon,
|
||||||
message:
|
message:
|
||||||
@@ -114,25 +132,33 @@ export function getSystemMessageInfo(
|
|||||||
? msg`Chat title changed to ${data.newName}`
|
? msg`Chat title changed to ${data.newName}`
|
||||||
: msg`Chat title changed`,
|
: msg`Chat title changed`,
|
||||||
}
|
}
|
||||||
} else if (ChatBskyConvoDefs.isSystemMessageDataCreateJoinLink(data)) {
|
} else if (
|
||||||
|
bsky.isType(chat.bsky.convo.defs.systemMessageDataCreateJoinLink, data)
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
Icon: ChainLinkIcon,
|
Icon: ChainLinkIcon,
|
||||||
message: msg`Invite link created`,
|
message: msg`Invite link created`,
|
||||||
action: {kind: 'inviteLink'},
|
action: {kind: 'inviteLink'},
|
||||||
}
|
}
|
||||||
} else if (ChatBskyConvoDefs.isSystemMessageDataEditJoinLink(data)) {
|
} else if (
|
||||||
|
bsky.isType(chat.bsky.convo.defs.systemMessageDataEditJoinLink, data)
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
Icon: ChainLinkIcon,
|
Icon: ChainLinkIcon,
|
||||||
message: msg`Invite link edited`,
|
message: msg`Invite link edited`,
|
||||||
action: {kind: 'inviteLink'},
|
action: {kind: 'inviteLink'},
|
||||||
}
|
}
|
||||||
} else if (ChatBskyConvoDefs.isSystemMessageDataEnableJoinLink(data)) {
|
} else if (
|
||||||
|
bsky.isType(chat.bsky.convo.defs.systemMessageDataEnableJoinLink, data)
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
Icon: ChainLinkIcon,
|
Icon: ChainLinkIcon,
|
||||||
message: msg`Invite link enabled`,
|
message: msg`Invite link enabled`,
|
||||||
action: {kind: 'inviteLink'},
|
action: {kind: 'inviteLink'},
|
||||||
}
|
}
|
||||||
} else if (ChatBskyConvoDefs.isSystemMessageDataDisableJoinLink(data)) {
|
} else if (
|
||||||
|
bsky.isType(chat.bsky.convo.defs.systemMessageDataDisableJoinLink, data)
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
Icon: ChainLinkBrokenIcon,
|
Icon: ChainLinkBrokenIcon,
|
||||||
message: msg`Invite link disabled`,
|
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 {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'
|
import {BSKY_APP_HOST, toShortUrl} from '#/lib/strings/url-helpers'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,13 +16,13 @@ type ReplyEmbedSummary =
|
|||||||
| {type: 'unknown'}
|
| {type: 'unknown'}
|
||||||
|
|
||||||
function summarizeReplyEmbed(
|
function summarizeReplyEmbed(
|
||||||
embed: ChatBskyConvoDefs.MessageView['embed'],
|
embed: chat.bsky.convo.defs.MessageView['embed'],
|
||||||
): ReplyEmbedSummary {
|
): ReplyEmbedSummary {
|
||||||
if (!AppBskyEmbedRecord.isView(embed)) return {type: 'unknown'}
|
if (!bsky.isType(app.bsky.embed.record.view, embed)) return {type: 'unknown'}
|
||||||
const {record} = embed
|
const {record} = embed
|
||||||
if (AppBskyEmbedRecord.isViewRecord(record)) {
|
if (bsky.isType(app.bsky.embed.record.viewRecord, record)) {
|
||||||
const inner = record.embeds?.[0]
|
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: 'external', uri: inner.external.uri}
|
||||||
}
|
}
|
||||||
return {type: 'post'}
|
return {type: 'post'}
|
||||||
@@ -45,25 +40,32 @@ function summarizeReplyEmbed(
|
|||||||
* callers can render it in a muted/italic style.
|
* callers can render it in a muted/italic style.
|
||||||
*/
|
*/
|
||||||
export function useReplyPreviewText(): (
|
export function useReplyPreviewText(): (
|
||||||
message: ChatBskyConvoDefs.MessageView,
|
message: chat.bsky.convo.defs.MessageView,
|
||||||
) => {text: string; subtle: boolean} {
|
) => {text: string; subtle: boolean} {
|
||||||
const {t: l} = useLingui()
|
const {t: l} = useLingui()
|
||||||
|
|
||||||
return (message: ChatBskyConvoDefs.MessageView) => {
|
return (message: chat.bsky.convo.defs.MessageView) => {
|
||||||
const text = message.text
|
const text = message.text
|
||||||
if (text.trim()) {
|
if (text.trim()) {
|
||||||
return {text, subtle: false}
|
return {text, subtle: false}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ChatBskyEmbedJoinLink.isView(message.embed)) {
|
if (bsky.isType(chat.bsky.embed.joinLink.view, message.embed)) {
|
||||||
const {joinLinkPreview} = message.embed
|
const {joinLinkPreview} = message.embed
|
||||||
if (ChatBskyGroupDefs.isJoinLinkPreviewView(joinLinkPreview)) {
|
if (
|
||||||
|
bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, joinLinkPreview)
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
text: `${BSKY_APP_HOST}/chat/${joinLinkPreview.code}`,
|
text: `${BSKY_APP_HOST}/chat/${joinLinkPreview.code}`,
|
||||||
subtle: true,
|
subtle: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ChatBskyGroupDefs.isDisabledJoinLinkPreviewView(joinLinkPreview)) {
|
if (
|
||||||
|
bsky.isType(
|
||||||
|
chat.bsky.group.defs.disabledJoinLinkPreviewView,
|
||||||
|
joinLinkPreview,
|
||||||
|
)
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
text: l({
|
text: l({
|
||||||
message: '(disabled chat invite link)',
|
message: '(disabled chat invite link)',
|
||||||
@@ -72,7 +74,12 @@ export function useReplyPreviewText(): (
|
|||||||
subtle: true,
|
subtle: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ChatBskyGroupDefs.isInvalidJoinLinkPreviewView(joinLinkPreview)) {
|
if (
|
||||||
|
bsky.isType(
|
||||||
|
chat.bsky.group.defs.invalidJoinLinkPreviewView,
|
||||||
|
joinLinkPreview,
|
||||||
|
)
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
text: l({
|
text: l({
|
||||||
message: '(invalid chat invite link)',
|
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 ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||||
|
|
||||||
|
import {type $Typed} from '@atproto/lex'
|
||||||
|
import {chat} from '#/lexicons'
|
||||||
import {EMOJI_REACTION_LIMIT} from '#/lib/constants'
|
import {EMOJI_REACTION_LIMIT} from '#/lib/constants'
|
||||||
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
|
import {isBlockedOrBlocking} from '#/lib/moderation/blocked-and-muted'
|
||||||
import {moderateProfile} from '#/lib/moderation/subjects'
|
import {moderateProfile} from '#/lib/moderation/subjects'
|
||||||
@@ -77,7 +78,7 @@ export function localDateString(date: Date) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function hasAlreadyReacted(
|
export function hasAlreadyReacted(
|
||||||
message: ChatBskyConvoDefs.MessageView,
|
message: chat.bsky.convo.defs.MessageView,
|
||||||
myDid: string | undefined,
|
myDid: string | undefined,
|
||||||
emoji: string,
|
emoji: string,
|
||||||
): boolean {
|
): boolean {
|
||||||
@@ -98,9 +99,9 @@ export function hasAlreadyReacted(
|
|||||||
* already render anonymously ("Someone reacted").
|
* already render anonymously ("Someone reacted").
|
||||||
*/
|
*/
|
||||||
export function filterBlockedReactions(
|
export function filterBlockedReactions(
|
||||||
reactions: ChatBskyConvoDefs.ReactionView[] | undefined,
|
reactions: chat.bsky.convo.defs.ReactionView[] | undefined,
|
||||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>,
|
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>,
|
||||||
): ChatBskyConvoDefs.ReactionView[] {
|
): chat.bsky.convo.defs.ReactionView[] {
|
||||||
if (!reactions) return []
|
if (!reactions) return []
|
||||||
return reactions.filter(reaction => {
|
return reactions.filter(reaction => {
|
||||||
const profile = relatedProfiles.get(reaction.sender.did)
|
const profile = relatedProfiles.get(reaction.sender.did)
|
||||||
@@ -109,7 +110,7 @@ export function filterBlockedReactions(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function hasReachedReactionLimit(
|
export function hasReachedReactionLimit(
|
||||||
message: ChatBskyConvoDefs.MessageView,
|
message: chat.bsky.convo.defs.MessageView,
|
||||||
myDid: string | undefined,
|
myDid: string | undefined,
|
||||||
): boolean {
|
): boolean {
|
||||||
if (!message.reactions) {
|
if (!message.reactions) {
|
||||||
@@ -170,25 +171,25 @@ export function canReact({
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GroupConvoMember = ChatBskyActorDefs.ProfileViewBasic & {
|
export type GroupConvoMember = chat.bsky.actor.defs.ProfileViewBasic & {
|
||||||
// can be missing if account deleted
|
// can be missing if account deleted
|
||||||
kind?: $Typed<ChatBskyActorDefs.GroupConvoMember>
|
kind?: $Typed<chat.bsky.actor.defs.GroupConvoMember>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type DirectConvoMember = ChatBskyActorDefs.ProfileViewBasic & {
|
export type DirectConvoMember = chat.bsky.actor.defs.ProfileViewBasic & {
|
||||||
kind: $Typed<ChatBskyActorDefs.DirectConvoMember>
|
kind: $Typed<chat.bsky.actor.defs.DirectConvoMember>
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ConvoWithDetails = {view: ChatBskyConvoDefs.ConvoView} & (
|
export type ConvoWithDetails = {view: chat.bsky.convo.defs.ConvoView} & (
|
||||||
| {
|
| {
|
||||||
kind: 'group'
|
kind: 'group'
|
||||||
details: $Typed<ChatBskyConvoDefs.GroupConvo>
|
details: $Typed<chat.bsky.convo.defs.GroupConvo>
|
||||||
primaryMember?: GroupConvoMember // the owner - may have left, thus optional
|
primaryMember?: GroupConvoMember // the owner - may have left, thus optional
|
||||||
members: Array<GroupConvoMember>
|
members: Array<GroupConvoMember>
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
kind: 'direct'
|
kind: 'direct'
|
||||||
details: $Typed<ChatBskyConvoDefs.DirectConvo>
|
details: $Typed<chat.bsky.convo.defs.DirectConvo>
|
||||||
primaryMember: DirectConvoMember // the other user
|
primaryMember: DirectConvoMember // the other user
|
||||||
members: Array<DirectConvoMember>
|
members: Array<DirectConvoMember>
|
||||||
}
|
}
|
||||||
@@ -199,24 +200,14 @@ export type ConvoWithDetails = {view: ChatBskyConvoDefs.ConvoView} & (
|
|||||||
* and enforces the correct type for convo members.
|
* and enforces the correct type for convo members.
|
||||||
*/
|
*/
|
||||||
export function parseConvoView(
|
export function parseConvoView(
|
||||||
convoView: ChatBskyConvoDefs.ConvoView,
|
convoView: chat.bsky.convo.defs.ConvoView,
|
||||||
ownDid: string | undefined,
|
ownDid: string | undefined,
|
||||||
): ConvoWithDetails | null {
|
): ConvoWithDetails | null {
|
||||||
if (
|
if (bsky.isType(chat.bsky.convo.defs.groupConvo, convoView.kind)) {
|
||||||
bsky.dangerousIsType<ChatBskyConvoDefs.GroupConvo>(
|
|
||||||
convoView.kind,
|
|
||||||
ChatBskyConvoDefs.isGroupConvo,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
let owner: GroupConvoMember | undefined = undefined
|
let owner: GroupConvoMember | undefined = undefined
|
||||||
|
|
||||||
for (const member of convoView.members) {
|
for (const member of convoView.members) {
|
||||||
if (
|
if (bsky.isType(chat.bsky.actor.defs.groupConvoMember, member.kind)) {
|
||||||
bsky.dangerousIsType<ChatBskyActorDefs.GroupConvoMember>(
|
|
||||||
member.kind,
|
|
||||||
ChatBskyActorDefs.isGroupConvoMember,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
if (member.kind.role === 'owner') {
|
if (member.kind.role === 'owner') {
|
||||||
// have to do a type assertion here
|
// have to do a type assertion here
|
||||||
// this works: {...member, kind: member.kind}
|
// this works: {...member, kind: member.kind}
|
||||||
@@ -238,12 +229,7 @@ export function parseConvoView(
|
|||||||
primaryMember: owner,
|
primaryMember: owner,
|
||||||
members: convoView.members as Array<GroupConvoMember>,
|
members: convoView.members as Array<GroupConvoMember>,
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (bsky.isType(chat.bsky.convo.defs.directConvo, convoView.kind)) {
|
||||||
bsky.dangerousIsType<ChatBskyConvoDefs.DirectConvo>(
|
|
||||||
convoView.kind,
|
|
||||||
ChatBskyConvoDefs.isDirectConvo,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
const otherUser = convoView.members.find(m => m.did !== ownDid)
|
const otherUser = convoView.members.find(m => m.did !== ownDid)
|
||||||
|
|
||||||
if (!otherUser) {
|
if (!otherUser) {
|
||||||
@@ -286,7 +272,7 @@ export function getConvoReportSubject(
|
|||||||
|
|
||||||
const lastMessage = convo.view.lastMessage
|
const lastMessage = convo.view.lastMessage
|
||||||
const reportableMessage =
|
const reportableMessage =
|
||||||
ChatBskyConvoDefs.isMessageView(lastMessage) &&
|
bsky.isType(chat.bsky.convo.defs.messageView, lastMessage) &&
|
||||||
lastMessage.sender?.did !== ownDid
|
lastMessage.sender?.did !== ownDid
|
||||||
? lastMessage
|
? lastMessage
|
||||||
: null
|
: null
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {AppBskyEmbedVideo} from '@atproto/api'
|
|
||||||
|
|
||||||
|
import * as bsky from '#/types/bsky'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type FeedPostSliceItem} from '#/state/queries/post-feed'
|
import {type FeedPostSliceItem} from '#/state/queries/post-feed'
|
||||||
import {type VideoFeedSourceContext} from '#/screens/VideoFeed/types'
|
import {type VideoFeedSourceContext} from '#/screens/VideoFeed/types'
|
||||||
import {atoms as a, useGutters} from '#/alf'
|
import {atoms as a, useGutters} from '#/alf'
|
||||||
@@ -21,7 +22,7 @@ export function PostFeedVideoGridRow({
|
|||||||
const ax = useAnalytics()
|
const ax = useAnalytics()
|
||||||
const gutters = useGutters(['base', 'base', 0, 'base'])
|
const gutters = useGutters(['base', 'base', 0, 'base'])
|
||||||
const posts = slices
|
const posts = slices
|
||||||
.filter(slice => AppBskyEmbedVideo.isView(slice.post.embed))
|
.filter(slice => bsky.isType(app.bsky.embed.video.view, slice.post.embed))
|
||||||
.map(slice => ({
|
.map(slice => ({
|
||||||
post: slice.post,
|
post: slice.post,
|
||||||
moderation: slice.moderation,
|
moderation: slice.moderation,
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import Animated, {
|
|||||||
useAnimatedRef,
|
useAnimatedRef,
|
||||||
} from 'react-native-reanimated'
|
} from 'react-native-reanimated'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {type AppBskyEmbedImages} from '@atproto/api'
|
|
||||||
import {utils} from '@bsky.app/alf'
|
import {utils} from '@bsky.app/alf'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type Dimensions} from '#/lib/media/types'
|
import {type Dimensions} from '#/lib/media/types'
|
||||||
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
|
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
|
||||||
import {atoms as a, useTheme, web} from '#/alf'
|
import {atoms as a, useTheme, web} from '#/alf'
|
||||||
@@ -71,7 +71,7 @@ export function AutoSizedImage({
|
|||||||
onContainerRef,
|
onContainerRef,
|
||||||
onDimsChange,
|
onDimsChange,
|
||||||
}: {
|
}: {
|
||||||
image: AppBskyEmbedImages.ViewImage
|
image: app.bsky.embed.images.ViewImage
|
||||||
crop?: 'none' | 'square' | 'constrained'
|
crop?: 'none' | 'square' | 'constrained'
|
||||||
onPress?: (
|
onPress?: (
|
||||||
containerRef: AnimatedRef<any>,
|
containerRef: AnimatedRef<any>,
|
||||||
|
|||||||
@@ -14,11 +14,11 @@ import Animated, {
|
|||||||
useAnimatedRef,
|
useAnimatedRef,
|
||||||
} from 'react-native-reanimated'
|
} from 'react-native-reanimated'
|
||||||
import {Image} from 'expo-image'
|
import {Image} from 'expo-image'
|
||||||
import {type AppBskyEmbedImages} from '@atproto/api'
|
|
||||||
import {utils} from '@bsky.app/alf'
|
import {utils} from '@bsky.app/alf'
|
||||||
import {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
import debounce from 'lodash.debounce'
|
import debounce from 'lodash.debounce'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type Dimensions} from '#/lib/media/types'
|
import {type Dimensions} from '#/lib/media/types'
|
||||||
import {mergeRefs} from '#/lib/merge-refs'
|
import {mergeRefs} from '#/lib/merge-refs'
|
||||||
import {useA11y} from '#/state/a11y'
|
import {useA11y} from '#/state/a11y'
|
||||||
@@ -46,7 +46,7 @@ export * from './const'
|
|||||||
export * from './maybeApplyGalleryOffsetStyles'
|
export * from './maybeApplyGalleryOffsetStyles'
|
||||||
|
|
||||||
interface GalleryProps {
|
interface GalleryProps {
|
||||||
images: AppBskyEmbedImages.ViewImage[]
|
images: app.bsky.embed.images.ViewImage[]
|
||||||
onPress?: (
|
onPress?: (
|
||||||
index: number,
|
index: number,
|
||||||
containerRefs: AnimatedRef<any>[],
|
containerRefs: AnimatedRef<any>[],
|
||||||
@@ -404,7 +404,7 @@ function GalleryImage({
|
|||||||
onPreviewPress,
|
onPreviewPress,
|
||||||
}: {
|
}: {
|
||||||
contentHeight: number
|
contentHeight: number
|
||||||
image: AppBskyEmbedImages.ViewImage
|
image: app.bsky.embed.images.ViewImage
|
||||||
index: number
|
index: number
|
||||||
imageCount: number
|
imageCount: number
|
||||||
onWidthChange: (index: number, width: number) => void
|
onWidthChange: (index: number, width: number) => void
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
import {
|
|
||||||
AppBskyEmbedGallery,
|
|
||||||
AppBskyEmbedImages,
|
|
||||||
AppBskyEmbedRecordWithMedia,
|
|
||||||
type AppBskyFeedDefs,
|
|
||||||
AppBskyFeedPost,
|
|
||||||
} from '@atproto/api'
|
|
||||||
import {type ModerationCause, type ModerationUI} from '@bsky.app/sdk/moderation'
|
import {type ModerationCause, type ModerationUI} from '@bsky.app/sdk/moderation'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {unique} from '#/lib/moderation'
|
import {unique} from '#/lib/moderation'
|
||||||
import {type AppModerationCause} from '#/components/Pills'
|
import {type AppModerationCause} from '#/components/Pills'
|
||||||
import {Features, features} from '#/analytics/features'
|
import {Features, features} from '#/analytics/features'
|
||||||
@@ -22,17 +16,12 @@ export function maybeApplyGalleryOffsetStyles(
|
|||||||
modui,
|
modui,
|
||||||
additionalCauses,
|
additionalCauses,
|
||||||
}: {
|
}: {
|
||||||
post: AppBskyFeedDefs.PostView
|
post: app.bsky.feed.defs.PostView
|
||||||
modui: ModerationUI
|
modui: ModerationUI
|
||||||
additionalCauses?: ModerationCause[] | AppModerationCause[]
|
additionalCauses?: ModerationCause[] | AppModerationCause[]
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
if (
|
if (!bsky.isType(app.bsky.feed.post, post.record)) {
|
||||||
!bsky.dangerousIsType<AppBskyFeedPost.Record>(
|
|
||||||
post.record,
|
|
||||||
AppBskyFeedPost.isRecord,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,24 +36,11 @@ export function maybeApplyGalleryOffsetStyles(
|
|||||||
* First check if we even have images
|
* First check if we even have images
|
||||||
*/
|
*/
|
||||||
const embed = post.record.embed
|
const embed = post.record.embed
|
||||||
const isImageEmbed =
|
const isImageEmbed = embed && bsky.isType(app.bsky.embed.images.main, embed)
|
||||||
embed &&
|
|
||||||
bsky.dangerousIsType<AppBskyEmbedImages.Main>(
|
|
||||||
embed,
|
|
||||||
AppBskyEmbedImages.isMain,
|
|
||||||
)
|
|
||||||
const isGalleryEmbed =
|
const isGalleryEmbed =
|
||||||
embed &&
|
embed && bsky.isType(app.bsky.embed.gallery.main, embed)
|
||||||
bsky.dangerousIsType<AppBskyEmbedGallery.Main>(
|
|
||||||
embed,
|
|
||||||
AppBskyEmbedGallery.isMain,
|
|
||||||
)
|
|
||||||
const isRecordWithMedia =
|
const isRecordWithMedia =
|
||||||
embed &&
|
embed && bsky.isType(app.bsky.embed.recordWithMedia.main, embed)
|
||||||
bsky.dangerousIsType<AppBskyEmbedRecordWithMedia.Main>(
|
|
||||||
embed,
|
|
||||||
AppBskyEmbedRecordWithMedia.isMain,
|
|
||||||
)
|
|
||||||
let hasImages = false
|
let hasImages = false
|
||||||
if (isImageEmbed) {
|
if (isImageEmbed) {
|
||||||
if (!isPostGalleryEmbedEnabled) return
|
if (!isPostGalleryEmbedEnabled) return
|
||||||
@@ -78,23 +54,13 @@ export function maybeApplyGalleryOffsetStyles(
|
|||||||
hasImages = true
|
hasImages = true
|
||||||
}
|
}
|
||||||
if (isRecordWithMedia) {
|
if (isRecordWithMedia) {
|
||||||
if (
|
if (bsky.isType(app.bsky.embed.images.main, embed.media)) {
|
||||||
bsky.dangerousIsType<AppBskyEmbedImages.Main>(
|
|
||||||
embed.media,
|
|
||||||
AppBskyEmbedImages.isMain,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
if (!isPostGalleryEmbedEnabled) return
|
if (!isPostGalleryEmbedEnabled) return
|
||||||
// one image, not a gallery
|
// one image, not a gallery
|
||||||
if (embed.media.images.length === 1) return
|
if (embed.media.images.length === 1) return
|
||||||
hasImages = true
|
hasImages = true
|
||||||
}
|
}
|
||||||
if (
|
if (bsky.isType(app.bsky.embed.gallery.main, embed.media)) {
|
||||||
bsky.dangerousIsType<AppBskyEmbedGallery.Main>(
|
|
||||||
embed.media,
|
|
||||||
AppBskyEmbedGallery.isMain,
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
// single (or empty) gallery - no offset needed
|
// single (or empty) gallery - no offset needed
|
||||||
if (embed.media.items.length <= 1) return
|
if (embed.media.items.length <= 1) return
|
||||||
hasImages = true
|
hasImages = true
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
import {useRef} from 'react'
|
import {useRef} from 'react'
|
||||||
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
||||||
import {type AnimatedRef, useAnimatedRef} from 'react-native-reanimated'
|
import {type AnimatedRef, useAnimatedRef} from 'react-native-reanimated'
|
||||||
import {type AppBskyEmbedImages} from '@atproto/api'
|
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {atoms as a, useBreakpoints} from '#/alf'
|
import {atoms as a, useBreakpoints} from '#/alf'
|
||||||
import {type Dimensions} from '#/components/Lightbox/types'
|
import {type Dimensions} from '#/components/Lightbox/types'
|
||||||
import {type PostEmbedViewContext} from '#/components/Post/Embed/types'
|
import {type PostEmbedViewContext} from '#/components/Post/Embed/types'
|
||||||
import {GalleryItem} from './ImageLayoutGridItem'
|
import {GalleryItem} from './ImageLayoutGridItem'
|
||||||
|
|
||||||
interface ImageLayoutGridProps {
|
interface ImageLayoutGridProps {
|
||||||
images: AppBskyEmbedImages.ViewImage[]
|
images: app.bsky.embed.images.ViewImage[]
|
||||||
onPress?: (
|
onPress?: (
|
||||||
index: number,
|
index: number,
|
||||||
containerRefs: AnimatedRef<any>[],
|
containerRefs: AnimatedRef<any>[],
|
||||||
@@ -45,7 +45,7 @@ export function ImageLayoutGrid({
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface ImageLayoutGridInnerProps {
|
interface ImageLayoutGridInnerProps {
|
||||||
images: AppBskyEmbedImages.ViewImage[]
|
images: app.bsky.embed.images.ViewImage[]
|
||||||
onPress?: (
|
onPress?: (
|
||||||
index: number,
|
index: number,
|
||||||
containerRefs: AnimatedRef<any>[],
|
containerRefs: AnimatedRef<any>[],
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native'
|
import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native'
|
||||||
import {type AnimatedRef} from 'react-native-reanimated'
|
import {type AnimatedRef} from 'react-native-reanimated'
|
||||||
import {Image, type ImageStyle} from 'expo-image'
|
import {Image, type ImageStyle} from 'expo-image'
|
||||||
import {type AppBskyEmbedImages} from '@atproto/api'
|
|
||||||
import {utils} from '@bsky.app/alf'
|
import {utils} from '@bsky.app/alf'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {type Dimensions} from '#/lib/media/types'
|
import {type Dimensions} from '#/lib/media/types'
|
||||||
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
|
import {useLargeAltBadgeEnabled} from '#/state/preferences/large-alt-badge'
|
||||||
import {atoms as a, tokens, useTheme} from '#/alf'
|
import {atoms as a, tokens, useTheme} from '#/alf'
|
||||||
@@ -18,7 +18,7 @@ import {Text} from '#/components/Typography'
|
|||||||
type EventFunction = (index: number) => void
|
type EventFunction = (index: number) => void
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
images: AppBskyEmbedImages.ViewImage[]
|
images: app.bsky.embed.images.ViewImage[]
|
||||||
index: number
|
index: number
|
||||||
onPress?: (
|
onPress?: (
|
||||||
index: number,
|
index: number,
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {useEffect} from 'react'
|
import {useEffect} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {ChatBskyGroupDefs} from '@atproto/api'
|
|
||||||
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
||||||
import {useNavigation} from '@react-navigation/native'
|
import {useNavigation} from '@react-navigation/native'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import * as bsky from '#/types/bsky'
|
||||||
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
import {createSanitizedDisplayName} from '#/lib/moderation/create-sanitized-display-name'
|
||||||
import {moderateProfile} from '#/lib/moderation/subjects'
|
import {moderateProfile} from '#/lib/moderation/subjects'
|
||||||
import {useCallOnce} from '#/lib/once'
|
import {useCallOnce} from '#/lib/once'
|
||||||
@@ -163,7 +163,10 @@ function GroupChatJoinDialogContent({code}: {code?: string}) {
|
|||||||
errorMessage = l`The member limit has been reached.`
|
errorMessage = l`The member limit has been reached.`
|
||||||
const preview = data?.joinLinkPreviews[0]
|
const preview = data?.joinLinkPreviews[0]
|
||||||
if (
|
if (
|
||||||
ChatBskyGroupDefs.isJoinLinkPreviewView(preview) &&
|
bsky.isType(
|
||||||
|
chat.bsky.group.defs.joinLinkPreviewView,
|
||||||
|
preview,
|
||||||
|
) &&
|
||||||
preview.convo?.id
|
preview.convo?.id
|
||||||
) {
|
) {
|
||||||
ax.metric('groupchat:join:memberLimitReached', {
|
ax.metric('groupchat:join:memberLimitReached', {
|
||||||
@@ -254,7 +257,7 @@ function GroupChatJoinDialogContent({code}: {code?: string}) {
|
|||||||
|
|
||||||
const joinLinkPreview = data.joinLinkPreviews[0]
|
const joinLinkPreview = data.joinLinkPreviews[0]
|
||||||
|
|
||||||
if (!ChatBskyGroupDefs.isJoinLinkPreviewView(joinLinkPreview)) {
|
if (!bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, joinLinkPreview)) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<View style={[a.py_lg, a.align_center]}>
|
<View style={[a.py_lg, a.align_center]}>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import {useMemo} from 'react'
|
import {useMemo} from 'react'
|
||||||
import {Pressable, View} from 'react-native'
|
import {Pressable, View} from 'react-native'
|
||||||
import {type AppBskyUnspeccedDefs} from '@atproto/api'
|
|
||||||
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
import {Plural, Trans, useLingui} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {moderateProfile} from '#/lib/moderation/subjects'
|
import {moderateProfile} from '#/lib/moderation/subjects'
|
||||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||||
import {
|
import {
|
||||||
@@ -183,7 +183,7 @@ function TrendRow({
|
|||||||
recId,
|
recId,
|
||||||
onPress,
|
onPress,
|
||||||
}: ViewStyleProp & {
|
}: ViewStyleProp & {
|
||||||
trend: AppBskyUnspeccedDefs.TrendView
|
trend: app.bsky.unspecced.defs.TrendView
|
||||||
rank: number
|
rank: number
|
||||||
feedSliceIndex: number
|
feedSliceIndex: number
|
||||||
recId?: string
|
recId?: string
|
||||||
@@ -291,7 +291,7 @@ function TrendingTopicRowSkeleton({rank}: {rank: number}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function useModerateTrendingActors(
|
function useModerateTrendingActors(
|
||||||
actors: AppBskyUnspeccedDefs.TrendView['actors'],
|
actors: app.bsky.unspecced.defs.TrendView['actors'],
|
||||||
) {
|
) {
|
||||||
const moderationOpts = useModerationOpts()
|
const moderationOpts = useModerationOpts()
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import {useCallback, useEffect, useMemo} from 'react'
|
import {useCallback, useEffect, useMemo} from 'react'
|
||||||
import {ScrollView, View} from 'react-native'
|
import {ScrollView, View} from 'react-native'
|
||||||
import {AppBskyEmbedVideo, AtUri} from '@atproto/api'
|
|
||||||
import {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {AtUri} from '@atproto/syntax'
|
||||||
|
import * as bsky from '#/types/bsky'
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {VIDEO_FEED_URI} from '#/lib/constants'
|
import {VIDEO_FEED_URI} from '#/lib/constants'
|
||||||
import {makeCustomFeedLink} from '#/lib/routes/links'
|
import {makeCustomFeedLink} from '#/lib/routes/links'
|
||||||
import {useTrendingSettingsApi} from '#/state/preferences/trending'
|
import {useTrendingSettingsApi} from '#/state/preferences/trending'
|
||||||
@@ -153,7 +155,7 @@ function VideoCards({
|
|||||||
.flatMap(page => page.slices)
|
.flatMap(page => page.slices)
|
||||||
.map(slice => slice.items[0])
|
.map(slice => slice.items[0])
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.filter(item => AppBskyEmbedVideo.isView(item.post.embed))
|
.filter(item => bsky.isType(app.bsky.embed.video.view, item.post.embed))
|
||||||
.slice(0, 8)
|
.slice(0, 8)
|
||||||
}, [data])
|
}, [data])
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import {useState} from 'react'
|
import {useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type ComAtprotoLabelDefs, ToolsOzoneReportDefs} from '@atproto/api'
|
|
||||||
import {XrpcResponseError} from '@atproto/lex'
|
import {XrpcResponseError} from '@atproto/lex'
|
||||||
import {type AtUriString, type DidString} from '@atproto/syntax'
|
import {type AtUriString, type DidString} from '@atproto/syntax'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
@@ -23,14 +22,14 @@ import {Loader} from '#/components/Loader'
|
|||||||
import * as Toast from '#/components/Toast'
|
import * as Toast from '#/components/Toast'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
import {IS_ANDROID} from '#/env'
|
import {IS_ANDROID} from '#/env'
|
||||||
import {com} from '#/lexicons'
|
import {com, tools} from '#/lexicons'
|
||||||
|
|
||||||
export function AppealForm({
|
export function AppealForm({
|
||||||
label,
|
label,
|
||||||
control,
|
control,
|
||||||
onPressBack,
|
onPressBack,
|
||||||
}: {
|
}: {
|
||||||
label: ComAtprotoLabelDefs.Label
|
label: com.atproto.label.defs.Label
|
||||||
control: Dialog.DialogOuterProps['control']
|
control: Dialog.DialogOuterProps['control']
|
||||||
onPressBack: () => void
|
onPressBack: () => void
|
||||||
}) {
|
}) {
|
||||||
@@ -51,7 +50,7 @@ export function AppealForm({
|
|||||||
await client.call(
|
await client.call(
|
||||||
com.atproto.moderation.createReport,
|
com.atproto.moderation.createReport,
|
||||||
{
|
{
|
||||||
reasonType: ToolsOzoneReportDefs.REASONAPPEAL,
|
reasonType: tools.ozone.report.defs.reasonAppeal,
|
||||||
/*
|
/*
|
||||||
* `useLabelSubject` derives one shape or the other from the label's
|
* `useLabelSubject` derives one shape or the other from the label's
|
||||||
* `cid`: an at-uri plus cid for a record, or the label's `uri` reused
|
* `cid`: an at-uri plus cid for a record, or the label's `uri` reused
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
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 {Trans, useLingui} from '@lingui/react/macro'
|
import {Trans, useLingui} from '@lingui/react/macro'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
@@ -27,7 +26,7 @@ import {Text} from '#/components/Typography'
|
|||||||
import {chat} from '#/lexicons'
|
import {chat} from '#/lexicons'
|
||||||
import {type AnyProfileView} from '#/types/bsky/profile'
|
import {type AnyProfileView} from '#/types/bsky/profile'
|
||||||
|
|
||||||
type Item = ChatBskyConvoDefs.ConvoView
|
type Item = chat.bsky.convo.defs.ConvoView
|
||||||
|
|
||||||
type BlockDialogProps = {
|
type BlockDialogProps = {
|
||||||
control: DialogControlProps
|
control: DialogControlProps
|
||||||
@@ -252,7 +251,7 @@ function MutualGroupChat({
|
|||||||
onOptimisticallyRemoveConvo,
|
onOptimisticallyRemoveConvo,
|
||||||
onRestoreConvo,
|
onRestoreConvo,
|
||||||
}: {
|
}: {
|
||||||
view: ChatBskyConvoDefs.ConvoView
|
view: chat.bsky.convo.defs.ConvoView
|
||||||
profileDid: string
|
profileDid: string
|
||||||
currentConvoId?: string
|
currentConvoId?: string
|
||||||
onOptimisticallyRemoveConvo: (convoId: string) => void
|
onOptimisticallyRemoveConvo: (convoId: string) => void
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
||||||
import {type ComAtprotoLabelDefs} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Plural} from '@lingui/react/macro'
|
import {Plural} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {com} from '#/lexicons'
|
||||||
import {filterUserFacingLabels} from '#/lib/moderation'
|
import {filterUserFacingLabels} from '#/lib/moderation'
|
||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a} from '#/alf'
|
||||||
@@ -24,7 +24,7 @@ export function LabelsOnMe({
|
|||||||
size,
|
size,
|
||||||
style,
|
style,
|
||||||
}: {
|
}: {
|
||||||
labels: ComAtprotoLabelDefs.Label[] | undefined
|
labels: com.atproto.label.defs.Label[] | undefined
|
||||||
size?: ButtonSize
|
size?: ButtonSize
|
||||||
style?: StyleProp<ViewStyle>
|
style?: StyleProp<ViewStyle>
|
||||||
}) {
|
}) {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {useMemo, useState} from 'react'
|
import {useMemo, useState} from 'react'
|
||||||
import {View} from 'react-native'
|
import {View} from 'react-native'
|
||||||
import {type ComAtprotoLabelDefs} from '@atproto/api'
|
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
|
|
||||||
|
import {com} from '#/lexicons'
|
||||||
import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
|
import {useGetTimeAgo} from '#/lib/hooks/useTimeAgo'
|
||||||
import {useLabelInfo} from '#/lib/moderation/useLabelInfo'
|
import {useLabelInfo} from '#/lib/moderation/useLabelInfo'
|
||||||
import {makeProfileLink} from '#/lib/routes/links'
|
import {makeProfileLink} from '#/lib/routes/links'
|
||||||
@@ -23,7 +23,7 @@ export {useDialogControl as useLabelsOnMeDialogControl} from '#/components/Dialo
|
|||||||
|
|
||||||
export interface LabelsOnMeDialogProps {
|
export interface LabelsOnMeDialogProps {
|
||||||
control: Dialog.DialogOuterProps['control']
|
control: Dialog.DialogOuterProps['control']
|
||||||
labels: ComAtprotoLabelDefs.Label[]
|
labels: com.atproto.label.defs.Label[]
|
||||||
/**
|
/**
|
||||||
* Whether the labels are being shown on the user's account or on a post.
|
* Whether the labels are being shown on the user's account or on a post.
|
||||||
* With `content`, the list may include account-level labels, which get a
|
* With `content`, the list may include account-level labels, which get a
|
||||||
@@ -47,7 +47,7 @@ function LabelsOnMeDialogInner(props: LabelsOnMeDialogProps) {
|
|||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
const {currentAccount} = useSession()
|
const {currentAccount} = useSession()
|
||||||
const [appealingLabel, setAppealingLabel] = useState<
|
const [appealingLabel, setAppealingLabel] = useState<
|
||||||
ComAtprotoLabelDefs.Label | undefined
|
com.atproto.label.defs.Label | undefined
|
||||||
>(undefined)
|
>(undefined)
|
||||||
const {labels} = props
|
const {labels} = props
|
||||||
const isAccount = props.type === 'account'
|
const isAccount = props.type === 'account'
|
||||||
@@ -118,7 +118,7 @@ function Label({
|
|||||||
control,
|
control,
|
||||||
onPressAppeal,
|
onPressAppeal,
|
||||||
}: {
|
}: {
|
||||||
label: ComAtprotoLabelDefs.Label
|
label: com.atproto.label.defs.Label
|
||||||
isSelfLabel: boolean
|
isSelfLabel: boolean
|
||||||
/**
|
/**
|
||||||
* Call out that the label applies to the whole account, for contexts that
|
* Call out that the label applies to the whole account, for contexts that
|
||||||
@@ -126,7 +126,7 @@ function Label({
|
|||||||
*/
|
*/
|
||||||
showAccountCallout?: boolean
|
showAccountCallout?: boolean
|
||||||
control: Dialog.DialogOuterProps['control']
|
control: Dialog.DialogOuterProps['control']
|
||||||
onPressAppeal: (label: ComAtprotoLabelDefs.Label) => void
|
onPressAppeal: (label: com.atproto.label.defs.Label) => void
|
||||||
}) {
|
}) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
const {_} = useLingui()
|
const {_} = useLingui()
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
import {type StyleProp, View, type ViewStyle} from 'react-native'
|
||||||
import {type AppBskyFeedDefs, type ComAtprotoLabelDefs} from '@atproto/api'
|
|
||||||
import {type ModerationCause, type ModerationUI} from '@bsky.app/sdk/moderation'
|
import {type ModerationCause, type ModerationUI} from '@bsky.app/sdk/moderation'
|
||||||
import {plural} from '@lingui/core/macro'
|
import {plural} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react/macro'
|
import {useLingui} from '@lingui/react/macro'
|
||||||
@@ -9,6 +8,7 @@ import {
|
|||||||
getModerationCauseKey,
|
getModerationCauseKey,
|
||||||
unique,
|
unique,
|
||||||
} from '#/lib/moderation'
|
} from '#/lib/moderation'
|
||||||
|
import {app, com} from '#/lexicons'
|
||||||
import {useSession} from '#/state/session'
|
import {useSession} from '#/state/session'
|
||||||
import {atoms as a} from '#/alf'
|
import {atoms as a} from '#/alf'
|
||||||
import {
|
import {
|
||||||
@@ -24,7 +24,7 @@ export function PostAlerts({
|
|||||||
style,
|
style,
|
||||||
additionalCauses,
|
additionalCauses,
|
||||||
}: {
|
}: {
|
||||||
post?: AppBskyFeedDefs.PostView
|
post?: app.bsky.feed.defs.PostView
|
||||||
modui: ModerationUI
|
modui: ModerationUI
|
||||||
/**
|
/**
|
||||||
* Expanded views (e.g. the thread anchor post) render larger pills and
|
* Expanded views (e.g. the thread anchor post) render larger pills and
|
||||||
@@ -48,7 +48,7 @@ export function PostAlerts({
|
|||||||
* author's only entry point to appeal labels on their content.
|
* author's only entry point to appeal labels on their content.
|
||||||
*/
|
*/
|
||||||
const isOwnPost = !!post && post.author.did === currentAccount?.did
|
const isOwnPost = !!post && post.author.did === currentAccount?.did
|
||||||
const allLabels: ComAtprotoLabelDefs.Label[] =
|
const allLabels: com.atproto.label.defs.Label[] =
|
||||||
isOwnPost && view === 'expanded'
|
isOwnPost && view === 'expanded'
|
||||||
? [
|
? [
|
||||||
...(post.labels ?? []),
|
...(post.labels ?? []),
|
||||||
@@ -134,7 +134,7 @@ function AdditionalLabels({
|
|||||||
size,
|
size,
|
||||||
hasPrecedingPills,
|
hasPrecedingPills,
|
||||||
}: {
|
}: {
|
||||||
labels: ComAtprotoLabelDefs.Label[]
|
labels: com.atproto.label.defs.Label[]
|
||||||
size?: Pills.CommonProps['size']
|
size?: Pills.CommonProps['size']
|
||||||
/**
|
/**
|
||||||
* The compact "+n" syntax only makes sense as a continuation of other
|
* The compact "+n" syntax only makes sense as a continuation of other
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ import {
|
|||||||
View,
|
View,
|
||||||
type ViewStyle,
|
type ViewStyle,
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
import {type AppBskyActorDefs} from '@atproto/api'
|
|
||||||
import {type ModerationCause, type ModerationUI} from '@bsky.app/sdk/moderation'
|
import {type ModerationCause, type ModerationUI} from '@bsky.app/sdk/moderation'
|
||||||
import {msg} from '@lingui/core/macro'
|
import {msg} from '@lingui/core/macro'
|
||||||
import {useLingui} from '@lingui/react'
|
import {useLingui} from '@lingui/react'
|
||||||
import {Trans} from '@lingui/react/macro'
|
import {Trans} from '@lingui/react/macro'
|
||||||
import {useQueryClient} from '@tanstack/react-query'
|
import {useQueryClient} from '@tanstack/react-query'
|
||||||
|
|
||||||
|
import {app} from '#/lexicons'
|
||||||
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
|
import {useModerationCauseDescription} from '#/lib/moderation/useModerationCauseDescription'
|
||||||
import {addStyle} from '#/lib/styles'
|
import {addStyle} from '#/lib/styles'
|
||||||
import {unstableCacheProfileView} from '#/state/queries/unstable-profile-cache'
|
import {unstableCacheProfileView} from '#/state/queries/unstable-profile-cache'
|
||||||
@@ -31,7 +31,7 @@ interface Props extends React.ComponentProps<typeof Link> {
|
|||||||
iconSize: number
|
iconSize: number
|
||||||
iconStyles: StyleProp<ViewStyle>
|
iconStyles: StyleProp<ViewStyle>
|
||||||
modui: ModerationUI
|
modui: ModerationUI
|
||||||
profile: AppBskyActorDefs.ProfileViewBasic
|
profile: app.bsky.actor.defs.ProfileViewBasic
|
||||||
interpretFilterAsBlur?: boolean
|
interpretFilterAsBlur?: boolean
|
||||||
hiderStyle?: StyleProp<ViewStyle>
|
hiderStyle?: StyleProp<ViewStyle>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
import {applicationId} from 'expo-application'
|
import {applicationId} from 'expo-application'
|
||||||
import {
|
import {com, tools} from '#/lexicons'
|
||||||
ComAtprotoModerationDefs as RootReportDefs,
|
|
||||||
ToolsOzoneReportDefs as OzoneReportDefs,
|
|
||||||
} from '@atproto/api'
|
|
||||||
|
|
||||||
import {type ParsedReportSubject} from '#/components/moderation/ReportDialog/types'
|
import {type ParsedReportSubject} from '#/components/moderation/ReportDialog/types'
|
||||||
import {IS_ANDROID, IS_IOS, IS_WEB} from '#/env'
|
import {IS_ANDROID, IS_IOS, IS_WEB} from '#/env'
|
||||||
|
|
||||||
@@ -31,59 +27,96 @@ export const NEW_TO_OLD_REASON_MAPPING: Record<string, string> = {}
|
|||||||
* @see https://github.com/bluesky-social/atproto/blob/4c15fb47cec26060bff2e710e95869a90c9d7fdd/packages/ozone/src/mod-service/profile.ts#L16-L64
|
* @see https://github.com/bluesky-social/atproto/blob/4c15fb47cec26060bff2e710e95869a90c9d7fdd/packages/ozone/src/mod-service/profile.ts#L16-L64
|
||||||
*/
|
*/
|
||||||
export const NEW_TO_OLD_REASONS_MAP: Record<
|
export const NEW_TO_OLD_REASONS_MAP: Record<
|
||||||
OzoneReportDefs.ReasonType,
|
tools.ozone.report.defs.ReasonType,
|
||||||
RootReportDefs.ReasonType
|
com.atproto.moderation.defs.ReasonType
|
||||||
> = {
|
> = {
|
||||||
[OzoneReportDefs.REASONAPPEAL]: RootReportDefs.REASONAPPEAL,
|
[tools.ozone.report.defs.reasonAppeal]:
|
||||||
[OzoneReportDefs.REASONOTHER]: RootReportDefs.REASONOTHER,
|
com.atproto.moderation.defs.reasonAppeal,
|
||||||
|
[tools.ozone.report.defs.reasonOther]:
|
||||||
|
com.atproto.moderation.defs.reasonOther,
|
||||||
|
|
||||||
[OzoneReportDefs.REASONVIOLENCEANIMAL]: RootReportDefs.REASONVIOLATION,
|
[tools.ozone.report.defs.reasonViolenceAnimal]:
|
||||||
[OzoneReportDefs.REASONVIOLENCETHREATS]: RootReportDefs.REASONVIOLATION,
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
[OzoneReportDefs.REASONVIOLENCEGRAPHICCONTENT]:
|
[tools.ozone.report.defs.reasonViolenceThreats]:
|
||||||
RootReportDefs.REASONVIOLATION,
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
[OzoneReportDefs.REASONVIOLENCEGLORIFICATION]: RootReportDefs.REASONVIOLATION,
|
[tools.ozone.report.defs.reasonViolenceGraphicContent]:
|
||||||
[OzoneReportDefs.REASONVIOLENCEEXTREMISTCONTENT]:
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
RootReportDefs.REASONVIOLATION,
|
[tools.ozone.report.defs.reasonViolenceGlorification]:
|
||||||
[OzoneReportDefs.REASONVIOLENCETRAFFICKING]: RootReportDefs.REASONVIOLATION,
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
[OzoneReportDefs.REASONVIOLENCEOTHER]: RootReportDefs.REASONVIOLATION,
|
[tools.ozone.report.defs.reasonViolenceExtremistContent]:
|
||||||
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
|
[tools.ozone.report.defs.reasonViolenceTrafficking]:
|
||||||
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
|
[tools.ozone.report.defs.reasonViolenceOther]:
|
||||||
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
|
|
||||||
[OzoneReportDefs.REASONSEXUALABUSECONTENT]: RootReportDefs.REASONSEXUAL,
|
[tools.ozone.report.defs.reasonSexualAbuseContent]:
|
||||||
[OzoneReportDefs.REASONSEXUALNCII]: RootReportDefs.REASONSEXUAL,
|
com.atproto.moderation.defs.reasonSexual,
|
||||||
[OzoneReportDefs.REASONSEXUALDEEPFAKE]: RootReportDefs.REASONSEXUAL,
|
[tools.ozone.report.defs.reasonSexualNCII]:
|
||||||
[OzoneReportDefs.REASONSEXUALANIMAL]: RootReportDefs.REASONSEXUAL,
|
com.atproto.moderation.defs.reasonSexual,
|
||||||
[OzoneReportDefs.REASONSEXUALUNLABELED]: RootReportDefs.REASONSEXUAL,
|
[tools.ozone.report.defs.reasonSexualDeepfake]:
|
||||||
[OzoneReportDefs.REASONSEXUALOTHER]: RootReportDefs.REASONSEXUAL,
|
com.atproto.moderation.defs.reasonSexual,
|
||||||
|
[tools.ozone.report.defs.reasonSexualAnimal]:
|
||||||
|
com.atproto.moderation.defs.reasonSexual,
|
||||||
|
[tools.ozone.report.defs.reasonSexualUnlabeled]:
|
||||||
|
com.atproto.moderation.defs.reasonSexual,
|
||||||
|
[tools.ozone.report.defs.reasonSexualOther]:
|
||||||
|
com.atproto.moderation.defs.reasonSexual,
|
||||||
|
|
||||||
[OzoneReportDefs.REASONCHILDSAFETYCSAM]: RootReportDefs.REASONVIOLATION,
|
[tools.ozone.report.defs.reasonChildSafetyCSAM]:
|
||||||
[OzoneReportDefs.REASONCHILDSAFETYGROOM]: RootReportDefs.REASONVIOLATION,
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
[OzoneReportDefs.REASONCHILDSAFETYPRIVACY]: RootReportDefs.REASONVIOLATION,
|
[tools.ozone.report.defs.reasonChildSafetyGroom]:
|
||||||
[OzoneReportDefs.REASONCHILDSAFETYHARASSMENT]: RootReportDefs.REASONVIOLATION,
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
[OzoneReportDefs.REASONCHILDSAFETYOTHER]: RootReportDefs.REASONVIOLATION,
|
[tools.ozone.report.defs.reasonChildSafetyPrivacy]:
|
||||||
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
|
[tools.ozone.report.defs.reasonChildSafetyHarassment]:
|
||||||
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
|
[tools.ozone.report.defs.reasonChildSafetyOther]:
|
||||||
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
|
|
||||||
[OzoneReportDefs.REASONHARASSMENTTROLL]: RootReportDefs.REASONRUDE,
|
[tools.ozone.report.defs.reasonHarassmentTroll]:
|
||||||
[OzoneReportDefs.REASONHARASSMENTTARGETED]: RootReportDefs.REASONRUDE,
|
com.atproto.moderation.defs.reasonRude,
|
||||||
[OzoneReportDefs.REASONHARASSMENTHATESPEECH]: RootReportDefs.REASONRUDE,
|
[tools.ozone.report.defs.reasonHarassmentTargeted]:
|
||||||
[OzoneReportDefs.REASONHARASSMENTDOXXING]: RootReportDefs.REASONRUDE,
|
com.atproto.moderation.defs.reasonRude,
|
||||||
[OzoneReportDefs.REASONHARASSMENTOTHER]: RootReportDefs.REASONRUDE,
|
[tools.ozone.report.defs.reasonHarassmentHateSpeech]:
|
||||||
|
com.atproto.moderation.defs.reasonRude,
|
||||||
|
[tools.ozone.report.defs.reasonHarassmentDoxxing]:
|
||||||
|
com.atproto.moderation.defs.reasonRude,
|
||||||
|
[tools.ozone.report.defs.reasonHarassmentOther]:
|
||||||
|
com.atproto.moderation.defs.reasonRude,
|
||||||
|
|
||||||
[OzoneReportDefs.REASONMISLEADINGBOT]: RootReportDefs.REASONMISLEADING,
|
[tools.ozone.report.defs.reasonMisleadingBot]:
|
||||||
[OzoneReportDefs.REASONMISLEADINGIMPERSONATION]:
|
com.atproto.moderation.defs.reasonMisleading,
|
||||||
RootReportDefs.REASONMISLEADING,
|
[tools.ozone.report.defs.reasonMisleadingImpersonation]:
|
||||||
[OzoneReportDefs.REASONMISLEADINGSPAM]: RootReportDefs.REASONSPAM,
|
com.atproto.moderation.defs.reasonMisleading,
|
||||||
[OzoneReportDefs.REASONMISLEADINGSCAM]: RootReportDefs.REASONMISLEADING,
|
[tools.ozone.report.defs.reasonMisleadingSpam]:
|
||||||
[OzoneReportDefs.REASONMISLEADINGELECTIONS]: RootReportDefs.REASONMISLEADING,
|
com.atproto.moderation.defs.reasonSpam,
|
||||||
[OzoneReportDefs.REASONMISLEADINGOTHER]: RootReportDefs.REASONMISLEADING,
|
[tools.ozone.report.defs.reasonMisleadingScam]:
|
||||||
|
com.atproto.moderation.defs.reasonMisleading,
|
||||||
|
[tools.ozone.report.defs.reasonMisleadingElections]:
|
||||||
|
com.atproto.moderation.defs.reasonMisleading,
|
||||||
|
[tools.ozone.report.defs.reasonMisleadingOther]:
|
||||||
|
com.atproto.moderation.defs.reasonMisleading,
|
||||||
|
|
||||||
[OzoneReportDefs.REASONRULESITESECURITY]: RootReportDefs.REASONVIOLATION,
|
[tools.ozone.report.defs.reasonRuleSiteSecurity]:
|
||||||
[OzoneReportDefs.REASONRULEPROHIBITEDSALES]: RootReportDefs.REASONVIOLATION,
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
[OzoneReportDefs.REASONRULEBANEVASION]: RootReportDefs.REASONVIOLATION,
|
[tools.ozone.report.defs.reasonRuleProhibitedSales]:
|
||||||
[OzoneReportDefs.REASONRULEOTHER]: RootReportDefs.REASONVIOLATION,
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
|
[tools.ozone.report.defs.reasonRuleBanEvasion]:
|
||||||
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
|
[tools.ozone.report.defs.reasonRuleOther]:
|
||||||
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
|
|
||||||
[OzoneReportDefs.REASONSELFHARMCONTENT]: RootReportDefs.REASONVIOLATION,
|
[tools.ozone.report.defs.reasonSelfHarmContent]:
|
||||||
[OzoneReportDefs.REASONSELFHARMED]: RootReportDefs.REASONVIOLATION,
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
[OzoneReportDefs.REASONSELFHARMSTUNTS]: RootReportDefs.REASONVIOLATION,
|
[tools.ozone.report.defs.reasonSelfHarmED]:
|
||||||
[OzoneReportDefs.REASONSELFHARMSUBSTANCES]: RootReportDefs.REASONVIOLATION,
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
[OzoneReportDefs.REASONSELFHARMOTHER]: RootReportDefs.REASONVIOLATION,
|
[tools.ozone.report.defs.reasonSelfHarmStunts]:
|
||||||
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
|
[tools.ozone.report.defs.reasonSelfHarmSubstances]:
|
||||||
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
|
[tools.ozone.report.defs.reasonSelfHarmOther]:
|
||||||
|
com.atproto.moderation.defs.reasonViolation,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,42 +124,60 @@ export const NEW_TO_OLD_REASONS_MAP: Record<
|
|||||||
* @see https://github.com/bluesky-social/proposals/tree/main/0009-mod-report-granularity#backwards-compatibility
|
* @see https://github.com/bluesky-social/proposals/tree/main/0009-mod-report-granularity#backwards-compatibility
|
||||||
*/
|
*/
|
||||||
export const OLD_TO_NEW_REASONS_MAP: Record<
|
export const OLD_TO_NEW_REASONS_MAP: Record<
|
||||||
Exclude<RootReportDefs.ReasonType, OzoneReportDefs.ReasonType>,
|
Exclude<
|
||||||
OzoneReportDefs.ReasonType
|
com.atproto.moderation.defs.ReasonType,
|
||||||
|
tools.ozone.report.defs.ReasonType
|
||||||
|
>,
|
||||||
|
tools.ozone.report.defs.ReasonType
|
||||||
> = {
|
> = {
|
||||||
[RootReportDefs.REASONSPAM]: [OzoneReportDefs.REASONMISLEADINGSPAM],
|
[com.atproto.moderation.defs.reasonSpam]: [
|
||||||
[RootReportDefs.REASONVIOLATION]: [OzoneReportDefs.REASONRULEOTHER],
|
tools.ozone.report.defs.reasonMisleadingSpam,
|
||||||
[RootReportDefs.REASONMISLEADING]: [OzoneReportDefs.REASONMISLEADINGOTHER],
|
],
|
||||||
[RootReportDefs.REASONSEXUAL]: [OzoneReportDefs.REASONSEXUALUNLABELED],
|
[com.atproto.moderation.defs.reasonViolation]: [
|
||||||
[RootReportDefs.REASONRUDE]: [OzoneReportDefs.REASONHARASSMENTOTHER],
|
tools.ozone.report.defs.reasonRuleOther,
|
||||||
[RootReportDefs.REASONOTHER]: [OzoneReportDefs.REASONOTHER],
|
],
|
||||||
[RootReportDefs.REASONAPPEAL]: [OzoneReportDefs.REASONAPPEAL],
|
[com.atproto.moderation.defs.reasonMisleading]: [
|
||||||
|
tools.ozone.report.defs.reasonMisleadingOther,
|
||||||
|
],
|
||||||
|
[com.atproto.moderation.defs.reasonSexual]: [
|
||||||
|
tools.ozone.report.defs.reasonSexualUnlabeled,
|
||||||
|
],
|
||||||
|
[com.atproto.moderation.defs.reasonRude]: [
|
||||||
|
tools.ozone.report.defs.reasonHarassmentOther,
|
||||||
|
],
|
||||||
|
[com.atproto.moderation.defs.reasonOther]: [
|
||||||
|
tools.ozone.report.defs.reasonOther,
|
||||||
|
],
|
||||||
|
[com.atproto.moderation.defs.reasonAppeal]: [
|
||||||
|
tools.ozone.report.defs.reasonAppeal,
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of report reasons that should optionally include additional details from
|
* Set of report reasons that should optionally include additional details from
|
||||||
* the reporter.
|
* the reporter.
|
||||||
*/
|
*/
|
||||||
export const OTHER_REPORT_REASONS: Set<OzoneReportDefs.ReasonType> = new Set([
|
export const OTHER_REPORT_REASONS: Set<tools.ozone.report.defs.ReasonType> =
|
||||||
OzoneReportDefs.REASONVIOLENCEOTHER,
|
new Set([
|
||||||
OzoneReportDefs.REASONSEXUALOTHER,
|
tools.ozone.report.defs.reasonViolenceOther,
|
||||||
OzoneReportDefs.REASONCHILDSAFETYOTHER,
|
tools.ozone.report.defs.reasonSexualOther,
|
||||||
OzoneReportDefs.REASONHARASSMENTOTHER,
|
tools.ozone.report.defs.reasonChildSafetyOther,
|
||||||
OzoneReportDefs.REASONMISLEADINGOTHER,
|
tools.ozone.report.defs.reasonHarassmentOther,
|
||||||
OzoneReportDefs.REASONRULEOTHER,
|
tools.ozone.report.defs.reasonMisleadingOther,
|
||||||
OzoneReportDefs.REASONSELFHARMOTHER,
|
tools.ozone.report.defs.reasonRuleOther,
|
||||||
OzoneReportDefs.REASONOTHER,
|
tools.ozone.report.defs.reasonSelfHarmOther,
|
||||||
])
|
tools.ozone.report.defs.reasonOther,
|
||||||
|
])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of report reasons that should only be sent to Bluesky's moderation service.
|
* Set of report reasons that should only be sent to Bluesky's moderation service.
|
||||||
*/
|
*/
|
||||||
export const BSKY_LABELER_ONLY_REPORT_REASONS: Set<OzoneReportDefs.ReasonType> =
|
export const BSKY_LABELER_ONLY_REPORT_REASONS: Set<tools.ozone.report.defs.ReasonType> =
|
||||||
new Set([
|
new Set([
|
||||||
OzoneReportDefs.REASONCHILDSAFETYCSAM,
|
tools.ozone.report.defs.reasonChildSafetyCSAM,
|
||||||
OzoneReportDefs.REASONCHILDSAFETYGROOM,
|
tools.ozone.report.defs.reasonChildSafetyGroom,
|
||||||
OzoneReportDefs.REASONCHILDSAFETYOTHER,
|
tools.ozone.report.defs.reasonChildSafetyOther,
|
||||||
OzoneReportDefs.REASONVIOLENCEEXTREMISTCONTENT,
|
tools.ozone.report.defs.reasonViolenceExtremistContent,
|
||||||
])
|
])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user