flip the state layer type imports to the generated lexicons
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Vendored
+17
-17
@@ -1,12 +1,9 @@
|
||||
import {useEffect, useMemo, useState} from 'react'
|
||||
import {
|
||||
AppBskyEmbedRecord,
|
||||
AppBskyEmbedRecordWithMedia,
|
||||
type AppBskyFeedDefs,
|
||||
} from '@atproto/api'
|
||||
import {type QueryClient} from '@tanstack/react-query'
|
||||
import {EventEmitter} from 'eventemitter3'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {app} from '#/lexicons'
|
||||
import {batchedUpdates} from '#/lib/batchedUpdates'
|
||||
import {findAllPostsInQueryData as findAllPostsInBookmarksQueryData} from '#/state/queries/bookmarks/useBookmarksQuery'
|
||||
import {findAllPostsInQueryData as findAllPostsInExploreFeedPreviewsQueryData} from '#/state/queries/explore-feed-previews'
|
||||
@@ -22,7 +19,10 @@ export interface PostShadow {
|
||||
likeUri: string | undefined
|
||||
repostUri: string | undefined
|
||||
isDeleted: boolean
|
||||
embed: AppBskyEmbedRecord.View | AppBskyEmbedRecordWithMedia.View | undefined
|
||||
embed:
|
||||
| app.bsky.embed.record.View
|
||||
| app.bsky.embed.recordWithMedia.View
|
||||
| undefined
|
||||
pinned: boolean
|
||||
optimisticReplyCount: number | undefined
|
||||
bookmarked: boolean | undefined
|
||||
@@ -32,7 +32,7 @@ export const POST_TOMBSTONE = Symbol('PostTombstone')
|
||||
|
||||
const emitter = new EventEmitter()
|
||||
const shadows: WeakMap<
|
||||
AppBskyFeedDefs.PostView,
|
||||
app.bsky.feed.defs.PostView,
|
||||
Partial<PostShadow>
|
||||
> = new WeakMap()
|
||||
|
||||
@@ -40,13 +40,13 @@ const shadows: WeakMap<
|
||||
* Use with caution! This function returns the raw shadow data for a post.
|
||||
* Prefer using `usePostShadow`.
|
||||
*/
|
||||
export function dangerousGetPostShadow(post: AppBskyFeedDefs.PostView) {
|
||||
export function dangerousGetPostShadow(post: app.bsky.feed.defs.PostView) {
|
||||
return shadows.get(post)
|
||||
}
|
||||
|
||||
export function usePostShadow(
|
||||
post: AppBskyFeedDefs.PostView,
|
||||
): Shadow<AppBskyFeedDefs.PostView> | typeof POST_TOMBSTONE {
|
||||
post: app.bsky.feed.defs.PostView,
|
||||
): Shadow<app.bsky.feed.defs.PostView> | typeof POST_TOMBSTONE {
|
||||
const [shadow, setShadow] = useState(() => shadows.get(post))
|
||||
const [prevPost, setPrevPost] = useState(post)
|
||||
if (post !== prevPost) {
|
||||
@@ -74,9 +74,9 @@ export function usePostShadow(
|
||||
}
|
||||
|
||||
function mergeShadow(
|
||||
post: AppBskyFeedDefs.PostView,
|
||||
post: app.bsky.feed.defs.PostView,
|
||||
shadow: Partial<PostShadow>,
|
||||
): Shadow<AppBskyFeedDefs.PostView> | typeof POST_TOMBSTONE {
|
||||
): Shadow<app.bsky.feed.defs.PostView> | typeof POST_TOMBSTONE {
|
||||
if (shadow.isDeleted) {
|
||||
return POST_TOMBSTONE
|
||||
}
|
||||
@@ -125,10 +125,10 @@ function mergeShadow(
|
||||
let embed: typeof post.embed
|
||||
if ('embed' in shadow) {
|
||||
if (
|
||||
(AppBskyEmbedRecord.isView(post.embed) &&
|
||||
AppBskyEmbedRecord.isView(shadow.embed)) ||
|
||||
(AppBskyEmbedRecordWithMedia.isView(post.embed) &&
|
||||
AppBskyEmbedRecordWithMedia.isView(shadow.embed))
|
||||
(bsky.isType(app.bsky.embed.record.view, post.embed) &&
|
||||
bsky.isType(app.bsky.embed.record.view, shadow.embed)) ||
|
||||
(bsky.isType(app.bsky.embed.recordWithMedia.view, post.embed) &&
|
||||
bsky.isType(app.bsky.embed.recordWithMedia.view, shadow.embed))
|
||||
) {
|
||||
embed = shadow.embed
|
||||
}
|
||||
@@ -169,7 +169,7 @@ export function updatePostShadow(
|
||||
function* findPostsInCache(
|
||||
queryClient: QueryClient,
|
||||
uri: string,
|
||||
): Generator<AppBskyFeedDefs.PostView, void> {
|
||||
): Generator<app.bsky.feed.defs.PostView, void> {
|
||||
for (let post of findAllPostsInFeedQueryData(queryClient, uri)) {
|
||||
yield post
|
||||
}
|
||||
|
||||
Vendored
+6
-4
@@ -1,8 +1,8 @@
|
||||
import {useEffect, useMemo, useState} from 'react'
|
||||
import {type AppBskyActorDefs, type AppBskyNotificationDefs} from '@atproto/api'
|
||||
import {type QueryClient} from '@tanstack/react-query'
|
||||
import {EventEmitter} from 'eventemitter3'
|
||||
|
||||
import {app} from '#/lexicons'
|
||||
import {batchedUpdates} from '#/lib/batchedUpdates'
|
||||
import {findAllProfilesInQueryData as findAllProfilesInActivitySubscriptionsQueryData} from '#/state/queries/activity-subscriptions'
|
||||
import {findAllProfilesInQueryData as findAllProfilesInActorSearchQueryData} from '#/state/queries/actor-search'
|
||||
@@ -43,9 +43,11 @@ export interface ProfileShadow {
|
||||
muted: boolean | undefined
|
||||
mutedOnlyReposts: boolean | undefined
|
||||
blockingUri: string | undefined
|
||||
verification: AppBskyActorDefs.VerificationState
|
||||
status: AppBskyActorDefs.StatusView | undefined
|
||||
activitySubscription: AppBskyNotificationDefs.ActivitySubscription | undefined
|
||||
verification: app.bsky.actor.defs.VerificationState
|
||||
status: app.bsky.actor.defs.StatusView | undefined
|
||||
activitySubscription:
|
||||
| app.bsky.notification.defs.ActivitySubscription
|
||||
| undefined
|
||||
}
|
||||
|
||||
const shadows: WeakMap<
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
useRef,
|
||||
} from 'react'
|
||||
import {AppState, type AppStateStatus} from 'react-native'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {type AtUriString, type DidString} from '@atproto/syntax'
|
||||
import throttle from 'lodash.throttle'
|
||||
|
||||
@@ -29,7 +28,7 @@ import {useAppviewClient} from './session'
|
||||
export const FEEDBACK_FEEDS = [...PROD_FEEDS, ...STAGING_FEEDS]
|
||||
|
||||
export const THIRD_PARTY_ALLOWED_INTERACTIONS = new Set<
|
||||
AppBskyFeedDefs.Interaction['event']
|
||||
app.bsky.feed.defs.Interaction['event']
|
||||
>([
|
||||
// These are explicit actions and are therefore fine to send.
|
||||
'app.bsky.feed.defs#requestLess',
|
||||
@@ -47,7 +46,7 @@ export const THIRD_PARTY_ALLOWED_INTERACTIONS = new Set<
|
||||
export type StateContext = {
|
||||
enabled: boolean
|
||||
onItemSeen: (item: any) => void
|
||||
sendInteraction: (interaction: AppBskyFeedDefs.Interaction) => void
|
||||
sendInteraction: (interaction: app.bsky.feed.defs.Interaction) => void
|
||||
feedDescriptor: FeedDescriptor | undefined
|
||||
feedSourceInfo: FeedSourceInfo | undefined
|
||||
}
|
||||
@@ -55,7 +54,7 @@ export type StateContext = {
|
||||
const stateContext = createContext<StateContext>({
|
||||
enabled: false,
|
||||
onItemSeen: (_item: any) => {},
|
||||
sendInteraction: (_interaction: AppBskyFeedDefs.Interaction) => {},
|
||||
sendInteraction: (_interaction: app.bsky.feed.defs.Interaction) => {},
|
||||
feedDescriptor: undefined,
|
||||
feedSourceInfo: undefined,
|
||||
})
|
||||
@@ -84,7 +83,7 @@ export function useFeedFeedback(
|
||||
const history = useRef<
|
||||
// Use a WeakSet so that we don't need to clear it.
|
||||
// This assumes that referential identity of slice items maps 1:1 to feed (re)fetches.
|
||||
WeakSet<FeedPostSliceItem | AppBskyFeedDefs.Interaction>
|
||||
WeakSet<FeedPostSliceItem | app.bsky.feed.defs.Interaction>
|
||||
>(new WeakSet())
|
||||
|
||||
const flushEvents = useCallback(
|
||||
@@ -225,7 +224,7 @@ export function useFeedFeedback(
|
||||
)
|
||||
|
||||
const sendInteraction = useCallback(
|
||||
(interaction: AppBskyFeedDefs.Interaction) => {
|
||||
(interaction: app.bsky.feed.defs.Interaction) => {
|
||||
if (!enabled) {
|
||||
return
|
||||
}
|
||||
@@ -273,7 +272,7 @@ export function isDiscoverFeed(feed?: FeedDescriptor) {
|
||||
function isInteractionAllowed(
|
||||
enabled: boolean,
|
||||
feed: FeedSourceFeedInfo | undefined,
|
||||
interaction: AppBskyFeedDefs.Interaction['event'],
|
||||
interaction: app.bsky.feed.defs.Interaction['event'],
|
||||
) {
|
||||
if (!enabled || !feed) {
|
||||
return false
|
||||
@@ -282,7 +281,7 @@ function isInteractionAllowed(
|
||||
return isDiscover ? true : THIRD_PARTY_ALLOWED_INTERACTIONS.has(interaction)
|
||||
}
|
||||
|
||||
function toString(interaction: AppBskyFeedDefs.Interaction): string {
|
||||
function toString(interaction: app.bsky.feed.defs.Interaction): string {
|
||||
return `${interaction.item}|${interaction.event}|${
|
||||
interaction.feedContext || ''
|
||||
}|${interaction.reqId || ''}`
|
||||
@@ -313,7 +312,7 @@ function createAggregatedStats(): AggregatedStats {
|
||||
|
||||
function sendOrAggregateInteractionsForStats(
|
||||
stats: AggregatedStats,
|
||||
interactions: AppBskyFeedDefs.Interaction[],
|
||||
interactions: app.bsky.feed.defs.Interaction[],
|
||||
) {
|
||||
for (let interaction of interactions) {
|
||||
switch (interaction.event) {
|
||||
|
||||
@@ -1,16 +1,8 @@
|
||||
import {
|
||||
type $Typed,
|
||||
type AppBskyEmbedRecord,
|
||||
type ChatBskyActorDefs,
|
||||
ChatBskyConvoDefs,
|
||||
type ChatBskyConvoGetLog,
|
||||
type ChatBskyEmbedJoinLink,
|
||||
type ChatBskyGroupDefs,
|
||||
} from '@atproto/api'
|
||||
import {type Client, XrpcResponseError} from '@atproto/lex'
|
||||
import {type Client, XrpcResponseError, type $Typed} from '@atproto/lex'
|
||||
import {EventEmitter} from 'eventemitter3'
|
||||
import {nanoid} from 'nanoid/non-secure'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {networkRetry} from '#/lib/async/retry'
|
||||
import {
|
||||
isErrorMaybeAppPasswordPermissions,
|
||||
@@ -49,7 +41,7 @@ import {
|
||||
parseConvoView,
|
||||
} from '#/components/dms/util'
|
||||
import {IS_NATIVE} from '#/env'
|
||||
import {chat} from '#/lexicons'
|
||||
import {app, chat} from '#/lexicons'
|
||||
|
||||
const logger = Logger.create(Logger.Context.ConversationAgent)
|
||||
|
||||
@@ -65,21 +57,21 @@ export function isConvoItemMessage(
|
||||
}
|
||||
|
||||
function toSystemMessageView(
|
||||
ev: ChatBskyConvoGetLog.OutputSchema['logs'][number],
|
||||
): ChatBskyConvoDefs.SystemMessageView | null {
|
||||
ev: chat.bsky.convo.getLog.$OutputBody['logs'][number],
|
||||
): chat.bsky.convo.defs.SystemMessageView | null {
|
||||
const isSystem =
|
||||
ChatBskyConvoDefs.isLogAddMember(ev) ||
|
||||
ChatBskyConvoDefs.isLogRemoveMember(ev) ||
|
||||
ChatBskyConvoDefs.isLogMemberJoin(ev) ||
|
||||
ChatBskyConvoDefs.isLogMemberLeave(ev) ||
|
||||
ChatBskyConvoDefs.isLogLockConvo(ev) ||
|
||||
ChatBskyConvoDefs.isLogUnlockConvo(ev) ||
|
||||
ChatBskyConvoDefs.isLogLockConvoPermanently(ev) ||
|
||||
ChatBskyConvoDefs.isLogEditGroup(ev) ||
|
||||
ChatBskyConvoDefs.isLogCreateJoinLink(ev) ||
|
||||
ChatBskyConvoDefs.isLogEditJoinLink(ev) ||
|
||||
ChatBskyConvoDefs.isLogEnableJoinLink(ev) ||
|
||||
ChatBskyConvoDefs.isLogDisableJoinLink(ev)
|
||||
bsky.isType(chat.bsky.convo.defs.logAddMember, ev) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logRemoveMember, ev) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logMemberJoin, ev) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logMemberLeave, ev) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logLockConvo, ev) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logUnlockConvo, ev) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logLockConvoPermanently, ev) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logEditGroup, ev) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logCreateJoinLink, ev) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logEditJoinLink, ev) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logEnableJoinLink, ev) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logDisableJoinLink, ev)
|
||||
if (!isSystem) return null
|
||||
return ev.message
|
||||
}
|
||||
@@ -89,8 +81,8 @@ function toSystemMessageView(
|
||||
* the fields the deleted view carries so a reply can render it as deleted.
|
||||
*/
|
||||
function toDeletedMessageView(
|
||||
m: ChatBskyConvoDefs.MessageView,
|
||||
): $Typed<ChatBskyConvoDefs.DeletedMessageView> {
|
||||
m: chat.bsky.convo.defs.MessageView,
|
||||
): $Typed<chat.bsky.convo.defs.DeletedMessageView> {
|
||||
return {
|
||||
$type: 'chat.bsky.convo.defs#deletedMessageView',
|
||||
id: m.id,
|
||||
@@ -115,15 +107,15 @@ export class Convo {
|
||||
|
||||
private pastMessages: Map<
|
||||
string,
|
||||
| ChatBskyConvoDefs.MessageView
|
||||
| ChatBskyConvoDefs.DeletedMessageView
|
||||
| ChatBskyConvoDefs.SystemMessageView
|
||||
| chat.bsky.convo.defs.MessageView
|
||||
| chat.bsky.convo.defs.DeletedMessageView
|
||||
| chat.bsky.convo.defs.SystemMessageView
|
||||
> = new Map()
|
||||
private newMessages: Map<
|
||||
string,
|
||||
| ChatBskyConvoDefs.MessageView
|
||||
| ChatBskyConvoDefs.DeletedMessageView
|
||||
| ChatBskyConvoDefs.SystemMessageView
|
||||
| chat.bsky.convo.defs.MessageView
|
||||
| chat.bsky.convo.defs.DeletedMessageView
|
||||
| chat.bsky.convo.defs.SystemMessageView
|
||||
> = new Map()
|
||||
private pendingMessages: Map<
|
||||
string,
|
||||
@@ -131,13 +123,13 @@ export class Convo {
|
||||
id: string
|
||||
message: chat.bsky.convo.defs.MessageInput
|
||||
optimisticEmbedView?:
|
||||
| $Typed<AppBskyEmbedRecord.View>
|
||||
| $Typed<ChatBskyEmbedJoinLink.View>
|
||||
optimisticReplyTo?: $Typed<ChatBskyConvoDefs.MessageView>
|
||||
| $Typed<app.bsky.embed.record.View>
|
||||
| $Typed<chat.bsky.embed.joinLink.View>
|
||||
optimisticReplyTo?: $Typed<chat.bsky.convo.defs.MessageView>
|
||||
}
|
||||
> = new Map()
|
||||
private deletedMessages: Set<string> = new Set()
|
||||
private relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic> =
|
||||
private relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic> =
|
||||
new Map()
|
||||
/**
|
||||
* Accumulated profile shadow state, keyed by did. The profiles this agent
|
||||
@@ -157,8 +149,8 @@ export class Convo {
|
||||
|
||||
convoId: string
|
||||
convo: ConvoWithDetails | undefined
|
||||
sender: ChatBskyActorDefs.ProfileViewBasic | undefined
|
||||
recipients: ChatBskyActorDefs.ProfileViewBasic[] | undefined
|
||||
sender: chat.bsky.actor.defs.ProfileViewBasic | undefined
|
||||
recipients: chat.bsky.actor.defs.ProfileViewBasic[] | undefined
|
||||
snapshot: ConvoState | undefined
|
||||
|
||||
constructor(params: ConvoParams) {
|
||||
@@ -596,7 +588,7 @@ export class Convo {
|
||||
}
|
||||
}
|
||||
|
||||
private setConvo(convo: ChatBskyConvoDefs.ConvoView) {
|
||||
private setConvo(convo: chat.bsky.convo.defs.ConvoView) {
|
||||
this.convo = parseConvoView(convo, this.senderUserDid) ?? this.convo
|
||||
if (this.convo) {
|
||||
for (const member of this.convo.members) {
|
||||
@@ -606,7 +598,7 @@ export class Convo {
|
||||
this.applyProfileShadows()
|
||||
}
|
||||
|
||||
private updateConvo(convo: Partial<ChatBskyConvoDefs.ConvoView>) {
|
||||
private updateConvo(convo: Partial<chat.bsky.convo.defs.ConvoView>) {
|
||||
if (this.convo) {
|
||||
this.convo =
|
||||
parseConvoView({...this.convo.view, ...convo}, this.senderUserDid) ??
|
||||
@@ -716,7 +708,7 @@ export class Convo {
|
||||
}
|
||||
|
||||
private pendingFetchConvo:
|
||||
| Promise<{convo: ChatBskyConvoDefs.ConvoView}>
|
||||
| Promise<{convo: chat.bsky.convo.defs.ConvoView}>
|
||||
| undefined
|
||||
async fetchConvo() {
|
||||
if (this.pendingFetchConvo) return this.pendingFetchConvo
|
||||
@@ -836,9 +828,9 @@ export class Convo {
|
||||
|
||||
for (const message of messages) {
|
||||
if (
|
||||
ChatBskyConvoDefs.isMessageView(message) ||
|
||||
ChatBskyConvoDefs.isDeletedMessageView(message) ||
|
||||
ChatBskyConvoDefs.isSystemMessageView(message)
|
||||
bsky.isType(chat.bsky.convo.defs.messageView, message) ||
|
||||
bsky.isType(chat.bsky.convo.defs.deletedMessageView, message) ||
|
||||
bsky.isType(chat.bsky.convo.defs.systemMessageView, message)
|
||||
) {
|
||||
/*
|
||||
* If this message is already in new messages, it was added by the
|
||||
@@ -913,7 +905,7 @@ export class Convo {
|
||||
this.commit()
|
||||
}
|
||||
|
||||
ingestFirehose(events: ChatBskyConvoGetLog.OutputSchema['logs']) {
|
||||
ingestFirehose(events: chat.bsky.convo.getLog.$OutputBody['logs']) {
|
||||
let needsCommit = false
|
||||
|
||||
for (const ev of events) {
|
||||
@@ -950,8 +942,8 @@ export class Convo {
|
||||
}
|
||||
|
||||
if (
|
||||
ChatBskyConvoDefs.isLogCreateMessage(ev) &&
|
||||
ChatBskyConvoDefs.isMessageView(ev.message)
|
||||
bsky.isType(chat.bsky.convo.defs.logCreateMessage, ev) &&
|
||||
bsky.isType(chat.bsky.convo.defs.messageView, ev.message)
|
||||
) {
|
||||
/*
|
||||
* If this message is already in past messages, the initial
|
||||
@@ -976,8 +968,8 @@ export class Convo {
|
||||
}
|
||||
needsCommit = true
|
||||
} else if (
|
||||
ChatBskyConvoDefs.isLogDeleteMessage(ev) &&
|
||||
ChatBskyConvoDefs.isDeletedMessageView(ev.message)
|
||||
bsky.isType(chat.bsky.convo.defs.logDeleteMessage, ev) &&
|
||||
bsky.isType(chat.bsky.convo.defs.deletedMessageView, ev.message)
|
||||
) {
|
||||
/*
|
||||
* Remove the message itself, and keep its id in `deletedMessages`
|
||||
@@ -992,9 +984,9 @@ export class Convo {
|
||||
this.deletedMessages.add(ev.message.id)
|
||||
needsCommit = true
|
||||
} else if (
|
||||
(ChatBskyConvoDefs.isLogAddReaction(ev) ||
|
||||
ChatBskyConvoDefs.isLogRemoveReaction(ev)) &&
|
||||
ChatBskyConvoDefs.isMessageView(ev.message)
|
||||
(bsky.isType(chat.bsky.convo.defs.logAddReaction, ev) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logRemoveReaction, ev)) &&
|
||||
bsky.isType(chat.bsky.convo.defs.messageView, ev.message)
|
||||
) {
|
||||
/*
|
||||
* Update if we have this in state - replace message wholesale. If we don't, don't worry about it.
|
||||
@@ -1033,9 +1025,9 @@ export class Convo {
|
||||
sendMessage(
|
||||
message: chat.bsky.convo.defs.MessageInput,
|
||||
optimisticEmbedView?:
|
||||
| $Typed<AppBskyEmbedRecord.View>
|
||||
| $Typed<ChatBskyEmbedJoinLink.View>,
|
||||
optimisticReplyTo?: $Typed<ChatBskyConvoDefs.MessageView>,
|
||||
| $Typed<app.bsky.embed.record.View>
|
||||
| $Typed<chat.bsky.embed.joinLink.View>,
|
||||
optimisticReplyTo?: $Typed<chat.bsky.convo.defs.MessageView>,
|
||||
) {
|
||||
// Ignore empty messages for now since they have no other purpose atm
|
||||
if (!message.text.trim() && !message.embed) return
|
||||
@@ -1110,7 +1102,7 @@ export class Convo {
|
||||
this.commit()
|
||||
}
|
||||
|
||||
updateJoinLink(joinLink: ChatBskyGroupDefs.JoinLinkView | undefined) {
|
||||
updateJoinLink(joinLink: chat.bsky.group.defs.JoinLinkView | undefined) {
|
||||
if (this.convo?.kind !== 'group') {
|
||||
throw new Error('updateJoinLink can only be called on group convo')
|
||||
}
|
||||
@@ -1126,7 +1118,7 @@ export class Convo {
|
||||
}
|
||||
|
||||
updateLockStatus(
|
||||
lockStatus: ChatBskyConvoDefs.ConvoLockStatus,
|
||||
lockStatus: chat.bsky.convo.defs.ConvoLockStatus,
|
||||
lockStatusModerationOverride: boolean,
|
||||
) {
|
||||
if (this.convo?.kind !== 'group') {
|
||||
@@ -1340,11 +1332,11 @@ export class Convo {
|
||||
* matching what the server returns on refresh.
|
||||
*/
|
||||
private tombstoneDeletedReplyTo(
|
||||
m: ChatBskyConvoDefs.MessageView,
|
||||
): ChatBskyConvoDefs.MessageView {
|
||||
m: chat.bsky.convo.defs.MessageView,
|
||||
): chat.bsky.convo.defs.MessageView {
|
||||
const {replyTo} = m
|
||||
if (
|
||||
!ChatBskyConvoDefs.isMessageView(replyTo) ||
|
||||
!bsky.isType(chat.bsky.convo.defs.messageView, replyTo) ||
|
||||
!this.deletedMessages.has(replyTo.id)
|
||||
) {
|
||||
return m
|
||||
@@ -1359,19 +1351,19 @@ export class Convo {
|
||||
const items: ConvoItem[] = []
|
||||
|
||||
this.pastMessages.forEach(m => {
|
||||
if (ChatBskyConvoDefs.isMessageView(m)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.messageView, m)) {
|
||||
items.unshift({
|
||||
type: 'message',
|
||||
key: m.id,
|
||||
message: this.tombstoneDeletedReplyTo(m),
|
||||
})
|
||||
} else if (ChatBskyConvoDefs.isDeletedMessageView(m)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.deletedMessageView, m)) {
|
||||
items.unshift({
|
||||
type: 'deleted-message',
|
||||
key: m.id,
|
||||
message: m,
|
||||
})
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageView(m)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.systemMessageView, m)) {
|
||||
items.unshift({
|
||||
type: 'system-message',
|
||||
key: m.id,
|
||||
@@ -1392,19 +1384,19 @@ export class Convo {
|
||||
}
|
||||
|
||||
this.newMessages.forEach(m => {
|
||||
if (ChatBskyConvoDefs.isMessageView(m)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.messageView, m)) {
|
||||
items.push({
|
||||
type: 'message',
|
||||
key: m.id,
|
||||
message: this.tombstoneDeletedReplyTo(m),
|
||||
})
|
||||
} else if (ChatBskyConvoDefs.isDeletedMessageView(m)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.deletedMessageView, m)) {
|
||||
items.push({
|
||||
type: 'deleted-message',
|
||||
key: m.id,
|
||||
message: m,
|
||||
})
|
||||
} else if (ChatBskyConvoDefs.isSystemMessageView(m)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.systemMessageView, m)) {
|
||||
items.push({
|
||||
type: 'system-message',
|
||||
key: m.id,
|
||||
@@ -1479,7 +1471,7 @@ export class Convo {
|
||||
if (this.pastMessages.has(messageId)) {
|
||||
const prevMessage = this.pastMessages.get(messageId)
|
||||
if (
|
||||
ChatBskyConvoDefs.isMessageView(prevMessage) &&
|
||||
bsky.isType(chat.bsky.convo.defs.messageView, prevMessage) &&
|
||||
// skip optimistic update if reaction already exists
|
||||
!prevMessage.reactions?.find(
|
||||
reaction =>
|
||||
@@ -1509,7 +1501,7 @@ export class Convo {
|
||||
} else if (this.newMessages.has(messageId)) {
|
||||
const prevMessage = this.newMessages.get(messageId)
|
||||
if (
|
||||
ChatBskyConvoDefs.isMessageView(prevMessage) &&
|
||||
bsky.isType(chat.bsky.convo.defs.messageView, prevMessage) &&
|
||||
!prevMessage.reactions?.find(reaction => reaction.value === emoji)
|
||||
) {
|
||||
if (prevMessage.reactions && prevMessage.reactions.length >= 5)
|
||||
@@ -1533,7 +1525,7 @@ export class Convo {
|
||||
value: emoji,
|
||||
convoId: this.convoId,
|
||||
})
|
||||
if (ChatBskyConvoDefs.isMessageView(data.message)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.messageView, data.message)) {
|
||||
if (this.pastMessages.has(messageId)) {
|
||||
this.pastMessages.set(messageId, data.message)
|
||||
this.commit()
|
||||
@@ -1558,7 +1550,7 @@ export class Convo {
|
||||
let restore: null | (() => void) = null
|
||||
if (this.pastMessages.has(messageId)) {
|
||||
const prevMessage = this.pastMessages.get(messageId)
|
||||
if (ChatBskyConvoDefs.isMessageView(prevMessage)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.messageView, prevMessage)) {
|
||||
this.pastMessages.set(messageId, {
|
||||
...prevMessage,
|
||||
reactions: prevMessage.reactions?.filter(
|
||||
@@ -1575,7 +1567,7 @@ export class Convo {
|
||||
}
|
||||
} else if (this.newMessages.has(messageId)) {
|
||||
const prevMessage = this.newMessages.get(messageId)
|
||||
if (ChatBskyConvoDefs.isMessageView(prevMessage)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.messageView, prevMessage)) {
|
||||
this.newMessages.set(messageId, {
|
||||
...prevMessage,
|
||||
reactions: prevMessage.reactions?.filter(
|
||||
|
||||
@@ -6,10 +6,11 @@ import {
|
||||
useState,
|
||||
useSyncExternalStore,
|
||||
} from 'react'
|
||||
import {ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {useFocusEffect} from '@react-navigation/native'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {chat} from '#/lexicons'
|
||||
import {useAppState} from '#/lib/appState'
|
||||
import {Convo} from '#/state/messages/convo/agent'
|
||||
import {
|
||||
@@ -34,8 +35,8 @@ import {type GroupConvoMember} from '#/components/dms/util'
|
||||
export * from '#/state/messages/convo/util'
|
||||
|
||||
function membersChanged(
|
||||
a: ChatBskyConvoDefs.ConvoView['members'],
|
||||
b: ChatBskyConvoDefs.ConvoView['members'],
|
||||
a: chat.bsky.convo.defs.ConvoView['members'],
|
||||
b: chat.bsky.convo.defs.ConvoView['members'],
|
||||
) {
|
||||
if (a.length !== b.length) return true
|
||||
const aDids = new Set(a.map(m => m.did))
|
||||
@@ -83,9 +84,10 @@ export function ConvoProvider({
|
||||
const chatClient = useChatClient()
|
||||
const events = useMessagesEventBus()
|
||||
const [convo] = useState(() => {
|
||||
const placeholder = queryClient.getQueryData<ChatBskyConvoDefs.ConvoView>(
|
||||
getConvoKey(convoId),
|
||||
)
|
||||
const placeholder =
|
||||
queryClient.getQueryData<chat.bsky.convo.defs.ConvoView>(
|
||||
getConvoKey(convoId),
|
||||
)
|
||||
return new Convo({
|
||||
convoId,
|
||||
chatClient,
|
||||
@@ -151,14 +153,14 @@ export function ConvoProvider({
|
||||
const queryKey = event.query.queryKey as string[]
|
||||
if (queryKey[0] === root && queryKey[1] === id) {
|
||||
const data = event.query.state.data as
|
||||
| ChatBskyConvoDefs.ConvoView
|
||||
| chat.bsky.convo.defs.ConvoView
|
||||
| undefined
|
||||
if (data && convo.convo && data.muted !== convo.convo.view.muted) {
|
||||
convo.updateMuted(data.muted)
|
||||
}
|
||||
if (
|
||||
data &&
|
||||
ChatBskyConvoDefs.isGroupConvo(data.kind) &&
|
||||
bsky.isType(chat.bsky.convo.defs.groupConvo, data.kind) &&
|
||||
convo.convo?.kind === 'group'
|
||||
) {
|
||||
if (data.kind.name !== convo.convo.details.name) {
|
||||
@@ -180,7 +182,7 @@ export function ConvoProvider({
|
||||
}
|
||||
if (
|
||||
data &&
|
||||
ChatBskyConvoDefs.isGroupConvo(data.kind) &&
|
||||
bsky.isType(chat.bsky.convo.defs.groupConvo, data.kind) &&
|
||||
convo.convo?.kind === 'group' &&
|
||||
(membersChanged(data.members, convo.convo.members) ||
|
||||
data.kind.memberCount !== convo.convo.details.memberCount)
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
import {
|
||||
type $Typed,
|
||||
type AppBskyEmbedRecord,
|
||||
type ChatBskyActorDefs,
|
||||
type ChatBskyConvoDefs,
|
||||
type ChatBskyEmbedJoinLink,
|
||||
} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {type Client, type $Typed} from '@atproto/lex'
|
||||
|
||||
import {type MessagesEventBus} from '#/state/messages/events/agent'
|
||||
import {type ConvoWithDetails} from '#/components/dms/util'
|
||||
import {type chat} from '#/lexicons'
|
||||
import {app, chat} from '#/lexicons'
|
||||
|
||||
export type ConvoParams = {
|
||||
convoId: string
|
||||
@@ -17,7 +10,7 @@ export type ConvoParams = {
|
||||
chatClient: Client
|
||||
events: MessagesEventBus
|
||||
placeholderData?: {
|
||||
convo: ChatBskyConvoDefs.ConvoView
|
||||
convo: chat.bsky.convo.defs.ConvoView
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,12 +68,12 @@ export type ConvoItem =
|
||||
| {
|
||||
type: 'message'
|
||||
key: string
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
message: chat.bsky.convo.defs.MessageView
|
||||
}
|
||||
| {
|
||||
type: 'pending-message'
|
||||
key: string
|
||||
message: ChatBskyConvoDefs.MessageView
|
||||
message: chat.bsky.convo.defs.MessageView
|
||||
failed: boolean
|
||||
/**
|
||||
* Retry sending the message. If present, the message is in a failed state.
|
||||
@@ -90,12 +83,12 @@ export type ConvoItem =
|
||||
| {
|
||||
type: 'deleted-message'
|
||||
key: string
|
||||
message: ChatBskyConvoDefs.DeletedMessageView
|
||||
message: chat.bsky.convo.defs.DeletedMessageView
|
||||
}
|
||||
| {
|
||||
type: 'system-message'
|
||||
key: string
|
||||
message: ChatBskyConvoDefs.SystemMessageView
|
||||
message: chat.bsky.convo.defs.SystemMessageView
|
||||
}
|
||||
| {
|
||||
type: 'error'
|
||||
@@ -111,10 +104,10 @@ type DeleteMessage = (messageId: string) => Promise<void>
|
||||
type SendMessage = (
|
||||
message: chat.bsky.convo.defs.MessageInput,
|
||||
optimisticEmbedView:
|
||||
| $Typed<AppBskyEmbedRecord.View>
|
||||
| $Typed<ChatBskyEmbedJoinLink.View>
|
||||
| $Typed<app.bsky.embed.record.View>
|
||||
| $Typed<chat.bsky.embed.joinLink.View>
|
||||
| undefined,
|
||||
optimisticReplyTo?: $Typed<ChatBskyConvoDefs.MessageView>,
|
||||
optimisticReplyTo?: $Typed<chat.bsky.convo.defs.MessageView>,
|
||||
) => void
|
||||
type FetchMessageHistory = () => Promise<void>
|
||||
type MarkConvoAccepted = () => void
|
||||
@@ -153,7 +146,7 @@ export type ConvoStateReady = {
|
||||
status: ConvoStatus.Ready
|
||||
items: ConvoItem[]
|
||||
convo: ConvoWithDetails
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||
error: undefined
|
||||
isFetchingHistory: boolean
|
||||
hasAllHistory: boolean
|
||||
@@ -168,7 +161,7 @@ export type ConvoStateBackgrounded = {
|
||||
status: ConvoStatus.Backgrounded
|
||||
items: ConvoItem[]
|
||||
convo: ConvoWithDetails
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||
error: undefined
|
||||
isFetchingHistory: boolean
|
||||
hasAllHistory: boolean
|
||||
@@ -183,7 +176,7 @@ export type ConvoStateSuspended = {
|
||||
status: ConvoStatus.Suspended
|
||||
items: ConvoItem[]
|
||||
convo: ConvoWithDetails
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||
error: undefined
|
||||
isFetchingHistory: boolean
|
||||
hasAllHistory: boolean
|
||||
@@ -212,7 +205,7 @@ export type ConvoStateDisabled = {
|
||||
status: ConvoStatus.Disabled
|
||||
items: ConvoItem[]
|
||||
convo: ConvoWithDetails
|
||||
relatedProfiles: Map<string, ChatBskyActorDefs.ProfileViewBasic>
|
||||
relatedProfiles: Map<string, chat.bsky.actor.defs.ProfileViewBasic>
|
||||
error: undefined
|
||||
isFetchingHistory: boolean
|
||||
hasAllHistory: boolean
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type AtIdentifierString} from '@atproto/syntax'
|
||||
import {t} from '@lingui/core/macro'
|
||||
import {
|
||||
@@ -106,7 +105,7 @@ export function useNotificationDeclarationMutation() {
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileView, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileView, void> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.notification.listActivitySubscriptions.$OutputBody>
|
||||
>({
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {useCallback} from 'react'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
import {keepPreviousData, useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
@@ -34,7 +33,7 @@ export function useActorAutocompleteQuery(
|
||||
prefix = prefix.slice(0, -1)
|
||||
}
|
||||
|
||||
return useQuery<AppBskyActorDefs.ProfileViewBasic[]>({
|
||||
return useQuery<app.bsky.actor.defs.ProfileViewBasic[]>({
|
||||
staleTime: STALE.MINUTES.ONE,
|
||||
queryKey: RQKEY(prefix || ''),
|
||||
async queryFn() {
|
||||
@@ -47,7 +46,7 @@ export function useActorAutocompleteQuery(
|
||||
return data?.actors || []
|
||||
},
|
||||
select: useCallback(
|
||||
(data: AppBskyActorDefs.ProfileViewBasic[]) => {
|
||||
(data: app.bsky.actor.defs.ProfileViewBasic[]) => {
|
||||
return computeSuggestions({
|
||||
q: prefix,
|
||||
searched: data,
|
||||
@@ -104,10 +103,10 @@ function computeSuggestions({
|
||||
moderationOpts,
|
||||
}: {
|
||||
q?: string
|
||||
searched?: AppBskyActorDefs.ProfileViewBasic[]
|
||||
searched?: app.bsky.actor.defs.ProfileViewBasic[]
|
||||
moderationOpts: ModerationOpts
|
||||
}) {
|
||||
let items: AppBskyActorDefs.ProfileViewBasic[] = []
|
||||
let items: app.bsky.actor.defs.ProfileViewBasic[] = []
|
||||
for (const item of searched) {
|
||||
if (!items.find(item2 => item2.handle === item.handle)) {
|
||||
items.push(item)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {type AtUriString} from '@atproto/syntax'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
@@ -13,7 +12,7 @@ import {useAppviewClient} from '#/state/session'
|
||||
import {app} from '#/lexicons'
|
||||
|
||||
type MutationArgs =
|
||||
| {action: 'create'; post: AppBskyFeedDefs.PostView}
|
||||
| {action: 'create'; post: app.bsky.feed.defs.PostView}
|
||||
| {
|
||||
action: 'delete'
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type $Typed, AppBskyFeedDefs, AtUri} from '@atproto/api'
|
||||
import {
|
||||
type InfiniteData,
|
||||
type QueryClient,
|
||||
@@ -11,6 +10,8 @@ import {
|
||||
embedViewRecordToPostView,
|
||||
getEmbeddedPost,
|
||||
} from '#/state/queries/util'
|
||||
import {type $Typed} from '@atproto/lex'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {useAppviewClient} from '#/state/session'
|
||||
import {app} from '#/lexicons'
|
||||
import * as bsky from '#/types/bsky'
|
||||
@@ -57,7 +58,7 @@ export async function truncateAndInvalidate(qc: QueryClient) {
|
||||
|
||||
export async function optimisticallySaveBookmark(
|
||||
qc: QueryClient,
|
||||
post: AppBskyFeedDefs.PostView,
|
||||
post: app.bsky.feed.defs.PostView,
|
||||
) {
|
||||
qc.setQueriesData<InfiniteData<app.bsky.bookmark.getBookmarks.$OutputBody>>(
|
||||
{
|
||||
@@ -81,7 +82,7 @@ export async function optimisticallySaveBookmark(
|
||||
uri: post.uri,
|
||||
cid: post.cid,
|
||||
},
|
||||
item: post as $Typed<AppBskyFeedDefs.PostView>,
|
||||
item: post as $Typed<app.bsky.feed.defs.PostView>,
|
||||
} as unknown as app.bsky.bookmark.defs.BookmarkView
|
||||
return {
|
||||
...page,
|
||||
@@ -121,7 +122,7 @@ export async function optimisticallyDeleteBookmark(
|
||||
export function* findAllPostsInQueryData(
|
||||
queryClient: QueryClient,
|
||||
uri: string,
|
||||
): Generator<AppBskyFeedDefs.PostView, undefined> {
|
||||
): Generator<app.bsky.feed.defs.PostView, undefined> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.bookmark.getBookmarks.$OutputBody>
|
||||
>({
|
||||
@@ -135,13 +136,7 @@ export function* findAllPostsInQueryData(
|
||||
}
|
||||
for (const page of queryData?.pages) {
|
||||
for (const bookmark of page.bookmarks) {
|
||||
if (
|
||||
!bsky.dangerousIsType<AppBskyFeedDefs.PostView>(
|
||||
bookmark.item,
|
||||
AppBskyFeedDefs.isPostView,
|
||||
)
|
||||
)
|
||||
continue
|
||||
if (!bsky.isType(app.bsky.feed.defs.postView, bookmark.item)) continue
|
||||
|
||||
if (didOrHandleUriMatches(atUri, bookmark.item)) {
|
||||
yield bookmark.item
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {useMemo, useRef} from 'react'
|
||||
import {type AppBskyActorDefs, AppBskyFeedDefs, AtUri} from '@atproto/api'
|
||||
import {type AtUriString} from '@atproto/syntax'
|
||||
import {type AtUriString, AtUri} from '@atproto/syntax'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {
|
||||
@@ -9,6 +8,8 @@ import {
|
||||
useInfiniteQuery,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {app} from '#/lexicons'
|
||||
import {CustomFeedAPI} from '#/lib/api/feed/custom'
|
||||
import {aggregateUserInterests} from '#/lib/api/feed/utils'
|
||||
import {FeedTuner} from '#/lib/api/feed-manip'
|
||||
@@ -82,7 +83,7 @@ export type FeedPreviewItem =
|
||||
| {
|
||||
type: 'preview:header'
|
||||
key: string
|
||||
feed: AppBskyFeedDefs.GeneratorView
|
||||
feed: app.bsky.feed.defs.GeneratorView
|
||||
}
|
||||
| {
|
||||
type: 'preview:footer'
|
||||
@@ -94,7 +95,7 @@ export type FeedPreviewItem =
|
||||
key: string
|
||||
slice: FeedPostSlice
|
||||
indexInSlice: number
|
||||
feed: AppBskyFeedDefs.GeneratorView
|
||||
feed: app.bsky.feed.defs.GeneratorView
|
||||
showReplyTo: boolean
|
||||
hideTopBorder: boolean
|
||||
}
|
||||
@@ -105,7 +106,7 @@ export type FeedPreviewItem =
|
||||
}
|
||||
|
||||
export function useFeedPreviews(
|
||||
feedsMaybeWithDuplicates: AppBskyFeedDefs.GeneratorView[],
|
||||
feedsMaybeWithDuplicates: app.bsky.feed.defs.GeneratorView[],
|
||||
isEnabled: boolean = true,
|
||||
) {
|
||||
const feeds = useMemo(
|
||||
@@ -127,8 +128,8 @@ export function useFeedPreviews(
|
||||
const processedPageCache = useRef(
|
||||
new Map<
|
||||
{
|
||||
feed: AppBskyFeedDefs.GeneratorView
|
||||
posts: AppBskyFeedDefs.FeedViewPost[]
|
||||
feed: app.bsky.feed.defs.GeneratorView
|
||||
posts: app.bsky.feed.defs.FeedViewPost[]
|
||||
},
|
||||
FeedPreviewItem[]
|
||||
>(),
|
||||
@@ -346,13 +347,13 @@ export function useFeedPreviews(
|
||||
export function* findAllPostsInQueryData(
|
||||
queryClient: QueryClient,
|
||||
uri: string,
|
||||
): Generator<AppBskyFeedDefs.PostView, undefined> {
|
||||
): Generator<app.bsky.feed.defs.PostView, undefined> {
|
||||
const atUri = new AtUri(uri)
|
||||
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<{
|
||||
feed: AppBskyFeedDefs.GeneratorView
|
||||
posts: AppBskyFeedDefs.FeedViewPost[]
|
||||
feed: app.bsky.feed.defs.GeneratorView
|
||||
posts: app.bsky.feed.defs.FeedViewPost[]
|
||||
}>
|
||||
>({
|
||||
queryKey: [RQKEY_ROOT],
|
||||
@@ -372,7 +373,7 @@ export function* findAllPostsInQueryData(
|
||||
yield embedViewRecordToPostView(quotedPost)
|
||||
}
|
||||
|
||||
if (AppBskyFeedDefs.isPostView(item.reply?.parent)) {
|
||||
if (bsky.isType(app.bsky.feed.defs.postView, item.reply?.parent)) {
|
||||
if (didOrHandleUriMatches(atUri, item.reply.parent)) {
|
||||
yield item.reply.parent
|
||||
}
|
||||
@@ -386,7 +387,7 @@ export function* findAllPostsInQueryData(
|
||||
}
|
||||
}
|
||||
|
||||
if (AppBskyFeedDefs.isPostView(item.reply?.root)) {
|
||||
if (bsky.isType(app.bsky.feed.defs.postView, item.reply?.root)) {
|
||||
if (didOrHandleUriMatches(atUri, item.reply.root)) {
|
||||
yield item.reply.root
|
||||
}
|
||||
@@ -404,11 +405,11 @@ export function* findAllPostsInQueryData(
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileViewBasic, undefined> {
|
||||
): Generator<app.bsky.actor.defs.ProfileViewBasic, undefined> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<{
|
||||
feed: AppBskyFeedDefs.GeneratorView
|
||||
posts: AppBskyFeedDefs.FeedViewPost[]
|
||||
feed: app.bsky.feed.defs.GeneratorView
|
||||
posts: app.bsky.feed.defs.FeedViewPost[]
|
||||
}>
|
||||
>({
|
||||
queryKey: [RQKEY_ROOT],
|
||||
@@ -427,13 +428,13 @@ export function* findAllProfilesInQueryData(
|
||||
yield quotedPost.author
|
||||
}
|
||||
if (
|
||||
AppBskyFeedDefs.isPostView(item.reply?.parent) &&
|
||||
bsky.isType(app.bsky.feed.defs.postView, item.reply?.parent) &&
|
||||
item.reply?.parent?.author.did === did
|
||||
) {
|
||||
yield item.reply.parent.author
|
||||
}
|
||||
if (
|
||||
AppBskyFeedDefs.isPostView(item.reply?.root) &&
|
||||
bsky.isType(app.bsky.feed.defs.postView, item.reply?.root) &&
|
||||
item.reply?.root?.author.did === did
|
||||
) {
|
||||
yield item.reply.root.author
|
||||
|
||||
+19
-23
@@ -1,11 +1,5 @@
|
||||
import {useCallback, useEffect, useMemo, useRef} from 'react'
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyGraphDefs,
|
||||
AtUri,
|
||||
} from '@atproto/api'
|
||||
import {type AtUriString} from '@atproto/syntax'
|
||||
import {type AtUriString, AtUri} from '@atproto/syntax'
|
||||
import {RichText} from '@bsky.app/sdk/richtext'
|
||||
import {t} from '@lingui/core/macro'
|
||||
import {
|
||||
@@ -36,7 +30,7 @@ import {precacheResolvedUri} from './resolve-uri'
|
||||
|
||||
export type FeedSourceFeedInfo = {
|
||||
type: 'feed'
|
||||
view?: AppBskyFeedDefs.GeneratorView
|
||||
view?: app.bsky.feed.defs.GeneratorView
|
||||
uri: string
|
||||
feedDescriptor: FeedDescriptor
|
||||
route: {
|
||||
@@ -53,12 +47,12 @@ export type FeedSourceFeedInfo = {
|
||||
likeCount: number | undefined
|
||||
acceptsInteractions?: boolean
|
||||
likeUri: string | undefined
|
||||
contentMode: AppBskyFeedDefs.GeneratorView['contentMode']
|
||||
contentMode: app.bsky.feed.defs.GeneratorView['contentMode']
|
||||
}
|
||||
|
||||
export type FeedSourceListInfo = {
|
||||
type: 'list'
|
||||
view?: AppBskyGraphDefs.ListView
|
||||
view?: app.bsky.graph.defs.ListView
|
||||
uri: string
|
||||
feedDescriptor: FeedDescriptor
|
||||
route: {
|
||||
@@ -95,7 +89,7 @@ const feedSourceNSIDs = {
|
||||
}
|
||||
|
||||
export function hydrateFeedGenerator(
|
||||
view: AppBskyFeedDefs.GeneratorView,
|
||||
view: app.bsky.feed.defs.GeneratorView,
|
||||
): FeedSourceInfo {
|
||||
const urip = new AtUri(view.uri)
|
||||
const collection =
|
||||
@@ -137,7 +131,9 @@ export function hydrateFeedGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
export function hydrateList(view: AppBskyGraphDefs.ListView): FeedSourceInfo {
|
||||
export function hydrateList(
|
||||
view: app.bsky.graph.defs.ListView,
|
||||
): FeedSourceInfo {
|
||||
const urip = new AtUri(view.uri)
|
||||
const collection =
|
||||
urip.collection === 'app.bsky.feed.generator' ? 'feed' : 'lists'
|
||||
@@ -410,7 +406,7 @@ export function usePopularFeedsSearch({
|
||||
}
|
||||
|
||||
export type SavedFeedSourceInfo = FeedSourceInfo & {
|
||||
savedFeed: AppBskyActorDefs.SavedFeed
|
||||
savedFeed: app.bsky.actor.defs.SavedFeed
|
||||
}
|
||||
|
||||
const PWI_DISCOVER_FEED_STUB: SavedFeedSourceInfo = {
|
||||
@@ -549,17 +545,17 @@ export function usePinnedFeedsInfos() {
|
||||
export type SavedFeedItem =
|
||||
| {
|
||||
type: 'feed'
|
||||
config: AppBskyActorDefs.SavedFeed
|
||||
view: AppBskyFeedDefs.GeneratorView
|
||||
config: app.bsky.actor.defs.SavedFeed
|
||||
view: app.bsky.feed.defs.GeneratorView
|
||||
}
|
||||
| {
|
||||
type: 'list'
|
||||
config: AppBskyActorDefs.SavedFeed
|
||||
view: AppBskyGraphDefs.ListView
|
||||
config: app.bsky.actor.defs.SavedFeed
|
||||
view: app.bsky.graph.defs.ListView
|
||||
}
|
||||
| {
|
||||
type: 'timeline'
|
||||
config: AppBskyActorDefs.SavedFeed
|
||||
config: app.bsky.actor.defs.SavedFeed
|
||||
view: undefined
|
||||
}
|
||||
|
||||
@@ -587,8 +583,8 @@ export function useSavedFeeds() {
|
||||
)
|
||||
},
|
||||
queryFn: async () => {
|
||||
const resolvedFeeds = new Map<string, AppBskyFeedDefs.GeneratorView>()
|
||||
const resolvedLists = new Map<string, AppBskyGraphDefs.ListView>()
|
||||
const resolvedFeeds = new Map<string, app.bsky.feed.defs.GeneratorView>()
|
||||
const resolvedLists = new Map<string, app.bsky.graph.defs.ListView>()
|
||||
|
||||
const savedFeeds = savedItems.filter(feed => feed.type === 'feed')
|
||||
const savedLists = savedItems.filter(feed => feed.type === 'list')
|
||||
@@ -703,10 +699,10 @@ function precacheFeed(queryClient: QueryClient, hydratedFeed: FeedSourceInfo) {
|
||||
|
||||
export function precacheList(
|
||||
queryClient: QueryClient,
|
||||
list: AppBskyGraphDefs.ListView,
|
||||
list: app.bsky.graph.defs.ListView,
|
||||
) {
|
||||
precacheResolvedUri(queryClient, list.creator.handle, list.creator.did)
|
||||
queryClient.setQueryData<AppBskyGraphDefs.ListView>(
|
||||
queryClient.setQueryData<app.bsky.graph.defs.ListView>(
|
||||
listQueryKey(list.uri),
|
||||
list,
|
||||
)
|
||||
@@ -714,7 +710,7 @@ export function precacheList(
|
||||
|
||||
export function precacheFeedFromGeneratorView(
|
||||
queryClient: QueryClient,
|
||||
view: AppBskyFeedDefs.GeneratorView,
|
||||
view: app.bsky.feed.defs.GeneratorView,
|
||||
) {
|
||||
const hydratedFeed = hydrateFeedGenerator(view)
|
||||
precacheFeed(queryClient, hydratedFeed)
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import {useCallback} from 'react'
|
||||
import {
|
||||
type $Typed,
|
||||
ChatBskyGroupDefs,
|
||||
type ChatBskyGroupGetJoinLinkPreviews,
|
||||
} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {type Client, type $Typed} from '@atproto/lex'
|
||||
import {type QueryClient, useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {CHAT_SERVICE} from '#/lib/constants'
|
||||
import {createLexClient} from '#/lib/lexClient'
|
||||
import {logger} from '#/logger'
|
||||
@@ -21,9 +17,9 @@ import {chat} from '#/lexicons'
|
||||
* `ChatInvitePreview` for that.
|
||||
*/
|
||||
export type KnownChatInvitePreview =
|
||||
| $Typed<ChatBskyGroupDefs.JoinLinkPreviewView>
|
||||
| $Typed<ChatBskyGroupDefs.DisabledJoinLinkPreviewView>
|
||||
| $Typed<ChatBskyGroupDefs.InvalidJoinLinkPreviewView>
|
||||
| $Typed<chat.bsky.group.defs.JoinLinkPreviewView>
|
||||
| $Typed<chat.bsky.group.defs.DisabledJoinLinkPreviewView>
|
||||
| $Typed<chat.bsky.group.defs.InvalidJoinLinkPreviewView>
|
||||
|
||||
/**
|
||||
* The full open-union shape, including the `{$type: string}` fallback for
|
||||
@@ -39,9 +35,9 @@ export function isKnownJoinLinkPreview(
|
||||
preview: unknown,
|
||||
): preview is KnownChatInvitePreview {
|
||||
return (
|
||||
ChatBskyGroupDefs.isJoinLinkPreviewView(preview) ||
|
||||
ChatBskyGroupDefs.isDisabledJoinLinkPreviewView(preview) ||
|
||||
ChatBskyGroupDefs.isInvalidJoinLinkPreviewView(preview)
|
||||
bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview) ||
|
||||
bsky.isType(chat.bsky.group.defs.disabledJoinLinkPreviewView, preview) ||
|
||||
bsky.isType(chat.bsky.group.defs.invalidJoinLinkPreviewView, preview)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -90,7 +86,7 @@ export function setJoinLinkPreviewRequestedForCode(
|
||||
code: string,
|
||||
requested: boolean,
|
||||
) {
|
||||
queryClient.setQueriesData<ChatBskyGroupGetJoinLinkPreviews.OutputSchema>(
|
||||
queryClient.setQueriesData<chat.bsky.group.getJoinLinkPreviews.$OutputBody>(
|
||||
{
|
||||
predicate: query => {
|
||||
const [root, args] = query.queryKey as Partial<
|
||||
@@ -109,7 +105,7 @@ export function setJoinLinkPreviewRequestedForCode(
|
||||
...old,
|
||||
joinLinkPreviews: old.joinLinkPreviews.map(preview => {
|
||||
if (
|
||||
ChatBskyGroupDefs.isJoinLinkPreviewView(preview) &&
|
||||
bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview) &&
|
||||
preview.code === code
|
||||
) {
|
||||
return {
|
||||
@@ -143,12 +139,12 @@ export function invalidateJoinLinkPreviewsForConvo(
|
||||
const [root] = query.queryKey
|
||||
if (root !== joinLinkPreviewQueryKeyRoot) return false
|
||||
const data = query.state.data as
|
||||
| ChatBskyGroupGetJoinLinkPreviews.OutputSchema
|
||||
| chat.bsky.group.getJoinLinkPreviews.$OutputBody
|
||||
| undefined
|
||||
return (
|
||||
data?.joinLinkPreviews.some(
|
||||
preview =>
|
||||
ChatBskyGroupDefs.isJoinLinkPreviewView(preview) &&
|
||||
bsky.isType(chat.bsky.group.defs.joinLinkPreviewView, preview) &&
|
||||
preview.convoId === convoId,
|
||||
) ?? false
|
||||
)
|
||||
@@ -204,7 +200,7 @@ export function useJoinLinkPreviewsQuery({
|
||||
* Seed the query with an already-known preview (e.g. a DM message embed
|
||||
* already carries the resolved view), avoiding a duplicate fetch.
|
||||
*/
|
||||
initialData?: ChatBskyGroupGetJoinLinkPreviews.OutputSchema
|
||||
initialData?: chat.bsky.group.getJoinLinkPreviews.$OutputBody
|
||||
}) {
|
||||
const client = useChatClient()
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
@@ -43,7 +42,7 @@ export function useProfileKnownFollowersQuery(did: string | undefined) {
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileView, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileView, void> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.graph.getKnownFollowers.$OutputBody>
|
||||
>({
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs, type AppBskyGraphDefs} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {type AtUriString} from '@atproto/syntax'
|
||||
import {
|
||||
@@ -91,7 +90,7 @@ export async function invalidateListMembersQuery({
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileView, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileView, void> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.graph.getList.$OutputBody>
|
||||
>({
|
||||
@@ -114,7 +113,7 @@ export function* findAllProfilesInQueryData(
|
||||
}
|
||||
|
||||
const allQueryData = queryClient.getQueriesData<
|
||||
AppBskyGraphDefs.ListItemView[]
|
||||
app.bsky.graph.defs.ListItemView[]
|
||||
>({
|
||||
queryKey: [RQKEY_ROOT_ALL],
|
||||
})
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
type AppBskyGraphGetStarterPacksWithMembership,
|
||||
} from '@atproto/api'
|
||||
import {
|
||||
AtUri,
|
||||
type AtUriString,
|
||||
@@ -73,7 +69,7 @@ export function useListMembershipAddMutation({
|
||||
// update WITH_MEMBERSHIPS query for starter packs
|
||||
if (subject) {
|
||||
queryClient.setQueryData<
|
||||
InfiniteData<AppBskyGraphGetStarterPacksWithMembership.OutputSchema>
|
||||
InfiniteData<app.bsky.graph.getStarterPacksWithMembership.$OutputBody>
|
||||
>(STARTER_PACKS_WITH_MEMBERSHIPS_RKEY(variables.actorDid), old => {
|
||||
if (!old) return old
|
||||
|
||||
@@ -94,7 +90,7 @@ export function useListMembershipAddMutation({
|
||||
listItemsSample: [
|
||||
{
|
||||
uri: data.uri,
|
||||
subject: subject as AppBskyActorDefs.ProfileView,
|
||||
subject: subject as app.bsky.actor.defs.ProfileView,
|
||||
},
|
||||
...(spWithMembership.starterPack.listItemsSample?.filter(
|
||||
item => item.subject.did !== variables.actorDid,
|
||||
@@ -109,7 +105,7 @@ export function useListMembershipAddMutation({
|
||||
},
|
||||
listItem: {
|
||||
uri: data.uri,
|
||||
subject: subject as AppBskyActorDefs.ProfileView,
|
||||
subject: subject as app.bsky.actor.defs.ProfileView,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -167,7 +163,7 @@ export function useListMembershipRemoveMutation({
|
||||
|
||||
// update WITH_MEMBERSHIPS query for starter packs
|
||||
queryClient.setQueryData<
|
||||
InfiniteData<AppBskyGraphGetStarterPacksWithMembership.OutputSchema>
|
||||
InfiniteData<app.bsky.graph.getStarterPacksWithMembership.$OutputBody>
|
||||
>(STARTER_PACKS_WITH_MEMBERSHIPS_RKEY(variables.actorDid), old => {
|
||||
if (!old) return old
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyGraphDefs} from '@atproto/api'
|
||||
import {type $Typed, type Client} from '@atproto/lex'
|
||||
import {
|
||||
type AtIdentifierString,
|
||||
@@ -30,7 +29,7 @@ export const RQKEY = (uri: string) => [RQKEY_ROOT, uri]
|
||||
|
||||
export function useListQuery(uri?: string) {
|
||||
const client = useAppviewClient()
|
||||
return useQuery<AppBskyGraphDefs.ListView, Error>({
|
||||
return useQuery<app.bsky.graph.defs.ListView, Error>({
|
||||
staleTime: STALE.MINUTES.ONE,
|
||||
queryKey: RQKEY(uri || ''),
|
||||
async queryFn() {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type AtIdentifierString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
@@ -60,7 +59,7 @@ export function updateListMembershipOptimistically({
|
||||
actor: string
|
||||
listUri: string
|
||||
membershipUri: string
|
||||
subject: AppBskyActorDefs.ProfileView
|
||||
subject: app.bsky.actor.defs.ProfileView
|
||||
}) {
|
||||
queryClient.setQueryData<
|
||||
InfiniteData<app.bsky.graph.getListsWithMembership.$OutputBody>
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import {
|
||||
type ChatBskyConvoAcceptConvo,
|
||||
type ChatBskyConvoDefs,
|
||||
} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
@@ -29,7 +25,7 @@ export function useAcceptConversation(
|
||||
onError,
|
||||
}: {
|
||||
onMutate?: () => void
|
||||
onSuccess?: (data: ChatBskyConvoAcceptConvo.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.convo.acceptConvo.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
},
|
||||
) {
|
||||
@@ -47,7 +43,7 @@ export function useAcceptConversation(
|
||||
queryClient.getQueriesData<ConvoListQueryData>({
|
||||
queryKey: [CONVO_LIST_ROOT_KEY],
|
||||
})
|
||||
let convoBeingAccepted: ChatBskyConvoDefs.ConvoView | null = null
|
||||
let convoBeingAccepted: chat.bsky.convo.defs.ConvoView | null = null
|
||||
for (const [_key, data] of queryClient.getQueriesData<ConvoListQueryData>(
|
||||
{queryKey: CONVO_LIST_PARTIAL_KEY('request')},
|
||||
)) {
|
||||
@@ -60,7 +56,7 @@ export function useAcceptConversation(
|
||||
(old?: ConvoListQueryData) => optimisticDelete(convoId, old),
|
||||
)
|
||||
if (convoBeingAccepted) {
|
||||
const acceptedConvo: ChatBskyConvoDefs.ConvoView = {
|
||||
const acceptedConvo: chat.bsky.convo.defs.ConvoView = {
|
||||
...convoBeingAccepted,
|
||||
status: 'accepted',
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
@@ -6,7 +5,7 @@ import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
import {logger} from '#/logger'
|
||||
import {usePdsClient, useSession} from '#/state/session'
|
||||
import {resolveAllowGroupInvites} from '#/components/dms/util'
|
||||
import {chat, com} from '#/lexicons'
|
||||
import {app, chat, com} from '#/lexicons'
|
||||
import {RQKEY as PROFILE_RKEY} from '../profile'
|
||||
|
||||
export function useUpdateActorDeclaration({
|
||||
@@ -27,7 +26,7 @@ export function useUpdateActorDeclaration({
|
||||
}) => {
|
||||
if (!currentAccount) throw new Error('Not signed in')
|
||||
const current =
|
||||
queryClient.getQueryData<AppBskyActorDefs.ProfileViewDetailed>(
|
||||
queryClient.getQueryData<app.bsky.actor.defs.ProfileViewDetailed>(
|
||||
PROFILE_RKEY(currentAccount.did),
|
||||
)
|
||||
const allowIncoming =
|
||||
@@ -57,7 +56,7 @@ export function useUpdateActorDeclaration({
|
||||
if (!currentAccount) return
|
||||
queryClient.setQueryData(
|
||||
PROFILE_RKEY(currentAccount?.did),
|
||||
(old?: AppBskyActorDefs.ProfileViewDetailed) => {
|
||||
(old?: app.bsky.actor.defs.ProfileViewDetailed) => {
|
||||
if (!old) return old
|
||||
const allowIncoming =
|
||||
update.allowIncoming ??
|
||||
@@ -81,7 +80,7 @@ export function useUpdateActorDeclaration({
|
||||
allowGroupInvites,
|
||||
},
|
||||
},
|
||||
} satisfies AppBskyActorDefs.ProfileViewDetailed
|
||||
} satisfies app.bsky.actor.defs.ProfileViewDetailed
|
||||
},
|
||||
)
|
||||
},
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
import {
|
||||
type ChatBskyActorDefs,
|
||||
ChatBskyConvoDefs,
|
||||
type ChatBskyConvoListConvos,
|
||||
type ChatBskyGroupAddMembers,
|
||||
} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
@@ -15,7 +9,7 @@ import {logger} from '#/logger'
|
||||
import {useProfileQuery} from '#/state/queries/profile'
|
||||
import {useChatClient, useSession} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {RQKEY as CONVO_KEY} from './conversation'
|
||||
import {RQKEY_ROOT as CONVO_LIST_KEY} from './list-conversations'
|
||||
import {listConvoMembersQueryKey} from './list-convo-members'
|
||||
@@ -26,7 +20,7 @@ export function useAddGroupMembers(
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (data: ChatBskyGroupAddMembers.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.group.addMembers.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
},
|
||||
) {
|
||||
@@ -52,24 +46,26 @@ export function useAddGroupMembers(
|
||||
onMutate: ({profiles}) => {
|
||||
if (!convoId) return
|
||||
|
||||
const prevConvo = queryClient.getQueryData<ChatBskyConvoDefs.ConvoView>(
|
||||
CONVO_KEY(convoId),
|
||||
)
|
||||
const prevConvo =
|
||||
queryClient.getQueryData<chat.bsky.convo.defs.ConvoView>(
|
||||
CONVO_KEY(convoId),
|
||||
)
|
||||
const prevListEntries = queryClient.getQueriesData<
|
||||
InfiniteData<ChatBskyConvoListConvos.OutputSchema>
|
||||
InfiniteData<chat.bsky.convo.listConvos.$OutputBody>
|
||||
>({queryKey: [CONVO_LIST_KEY]})
|
||||
const prevMemberList = queryClient.getQueryData<
|
||||
ChatBskyActorDefs.ProfileViewBasic[]
|
||||
chat.bsky.actor.defs.ProfileViewBasic[]
|
||||
>(listConvoMembersQueryKey(convoId))
|
||||
|
||||
const addedBy: ChatBskyActorDefs.ProfileViewBasic | undefined = myProfile
|
||||
? {
|
||||
...myProfile,
|
||||
$type: 'chat.bsky.actor.defs#profileViewBasic',
|
||||
}
|
||||
: undefined
|
||||
const addedBy: chat.bsky.actor.defs.ProfileViewBasic | undefined =
|
||||
myProfile
|
||||
? {
|
||||
...myProfile,
|
||||
$type: 'chat.bsky.actor.defs#profileViewBasic',
|
||||
}
|
||||
: undefined
|
||||
|
||||
const optimisticMembers: ChatBskyActorDefs.ProfileViewBasic[] =
|
||||
const optimisticMembers: chat.bsky.actor.defs.ProfileViewBasic[] =
|
||||
profiles.map(profile => ({
|
||||
...profile,
|
||||
$type: 'chat.bsky.actor.defs#profileViewBasic',
|
||||
@@ -80,11 +76,12 @@ export function useAddGroupMembers(
|
||||
},
|
||||
}))
|
||||
|
||||
queryClient.setQueryData<ChatBskyConvoDefs.ConvoView>(
|
||||
queryClient.setQueryData<chat.bsky.convo.defs.ConvoView>(
|
||||
CONVO_KEY(convoId),
|
||||
prev => {
|
||||
if (!prev) return
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(prev.kind)) return prev
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind))
|
||||
return prev
|
||||
return {
|
||||
...prev,
|
||||
members: [...prev.members, ...optimisticMembers],
|
||||
@@ -97,7 +94,7 @@ export function useAddGroupMembers(
|
||||
)
|
||||
|
||||
queryClient.setQueriesData<
|
||||
InfiniteData<ChatBskyConvoListConvos.OutputSchema>
|
||||
InfiniteData<chat.bsky.convo.listConvos.$OutputBody>
|
||||
>({queryKey: [CONVO_LIST_KEY]}, prev => {
|
||||
if (!prev?.pages) return
|
||||
return {
|
||||
@@ -106,7 +103,8 @@ export function useAddGroupMembers(
|
||||
...page,
|
||||
convos: page.convos.map(convo => {
|
||||
if (convo.id !== convoId) return convo
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(convo.kind)) return convo
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind))
|
||||
return convo
|
||||
return {
|
||||
...convo,
|
||||
members: [...convo.members, ...optimisticMembers],
|
||||
@@ -121,7 +119,7 @@ export function useAddGroupMembers(
|
||||
}
|
||||
})
|
||||
|
||||
queryClient.setQueryData<ChatBskyActorDefs.ProfileViewBasic[]>(
|
||||
queryClient.setQueryData<chat.bsky.actor.defs.ProfileViewBasic[]>(
|
||||
listConvoMembersQueryKey(convoId),
|
||||
prev => {
|
||||
if (!prev) return
|
||||
@@ -133,13 +131,13 @@ export function useAddGroupMembers(
|
||||
},
|
||||
onSuccess: data => {
|
||||
if (convoId) {
|
||||
queryClient.setQueryData<ChatBskyConvoDefs.ConvoView>(
|
||||
queryClient.setQueryData<chat.bsky.convo.defs.ConvoView>(
|
||||
CONVO_KEY(convoId),
|
||||
data.convo,
|
||||
)
|
||||
|
||||
queryClient.setQueriesData<
|
||||
InfiniteData<ChatBskyConvoListConvos.OutputSchema>
|
||||
InfiniteData<chat.bsky.convo.listConvos.$OutputBody>
|
||||
>({queryKey: [CONVO_LIST_KEY]}, prev => {
|
||||
if (!prev?.pages) return
|
||||
return {
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
import {
|
||||
type ChatBskyActorDefs,
|
||||
type ChatBskyConvoDefs,
|
||||
type ChatBskyConvoGetConvo,
|
||||
type ChatBskyConvoGetUnreadCounts,
|
||||
} from '@atproto/api'
|
||||
import {
|
||||
type QueryClient,
|
||||
useMutation,
|
||||
@@ -44,7 +38,7 @@ export function useConvoQuery({convoId}: {convoId: string}) {
|
||||
|
||||
export function precacheConvoQuery(
|
||||
queryClient: QueryClient,
|
||||
convo: ChatBskyConvoDefs.ConvoView,
|
||||
convo: chat.bsky.convo.defs.ConvoView,
|
||||
) {
|
||||
queryClient.setQueryData(RQKEY(convo.id), convo)
|
||||
}
|
||||
@@ -81,7 +75,7 @@ export function useMarkAsReadMutation() {
|
||||
// find the convo so we know which badge counter (if any) to decrement.
|
||||
// keep scanning past a stale unreadCount === 0 cache so another cache
|
||||
// holding the true unread state still drives the decrement
|
||||
let unreadStatus: ChatBskyConvoDefs.ConvoView['status'] | undefined
|
||||
let unreadStatus: chat.bsky.convo.defs.ConvoView['status'] | undefined
|
||||
for (const [, data] of prevListQueries) {
|
||||
if (!data) continue
|
||||
const convo = getConvoFromQueryData(convoId, data)
|
||||
@@ -96,11 +90,13 @@ export function useMarkAsReadMutation() {
|
||||
// the badge count query is a separate server query that the list caches
|
||||
// don't feed, so decrement it here to keep the badge in sync
|
||||
const prevUnreadCountsQueries =
|
||||
queryClient.getQueriesData<ChatBskyConvoGetUnreadCounts.OutputSchema>({
|
||||
queryKey: UNREAD_COUNTS_PARTIAL_KEY,
|
||||
})
|
||||
queryClient.getQueriesData<chat.bsky.convo.getUnreadCounts.$OutputBody>(
|
||||
{
|
||||
queryKey: UNREAD_COUNTS_PARTIAL_KEY,
|
||||
},
|
||||
)
|
||||
if (unreadStatus) {
|
||||
queryClient.setQueriesData<ChatBskyConvoGetUnreadCounts.OutputSchema>(
|
||||
queryClient.setQueriesData<chat.bsky.convo.getUnreadCounts.$OutputBody>(
|
||||
{queryKey: UNREAD_COUNTS_PARTIAL_KEY},
|
||||
old => {
|
||||
if (!old) return old
|
||||
@@ -184,9 +180,9 @@ export function useMarkAsReadMutation() {
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<ChatBskyActorDefs.ProfileViewBasic, void> {
|
||||
): Generator<chat.bsky.actor.defs.ProfileViewBasic, void> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
ChatBskyConvoGetConvo.OutputSchema['convo']
|
||||
chat.bsky.convo.getConvo.$OutputBody['convo']
|
||||
>({
|
||||
queryKey: [RQKEY_ROOT],
|
||||
})
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type ChatBskyGroupCreateGroup} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
@@ -11,7 +10,7 @@ export function useCreateGroupChat({
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (data: ChatBskyGroupCreateGroup.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.group.createGroup.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
}) {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import {
|
||||
ChatBskyConvoDefs,
|
||||
type ChatBskyGroupCreateJoinLink,
|
||||
type ChatBskyGroupDefs,
|
||||
} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {logger} from '#/logger'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
@@ -19,7 +15,7 @@ export function useCreateJoinLink(
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (data: ChatBskyGroupCreateJoinLink.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.group.createJoinLink.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
},
|
||||
) {
|
||||
@@ -31,7 +27,7 @@ export function useCreateJoinLink(
|
||||
joinRule,
|
||||
requireApproval,
|
||||
}: {
|
||||
joinRule: ChatBskyGroupDefs.JoinRule
|
||||
joinRule: chat.bsky.group.defs.JoinRule
|
||||
requireApproval: boolean
|
||||
}) => {
|
||||
if (!convoId) throw new Error('No convoId provided')
|
||||
@@ -44,7 +40,8 @@ export function useCreateJoinLink(
|
||||
onMutate: ({joinRule, requireApproval}) => {
|
||||
if (!convoId) return
|
||||
return updateConvoOptimistic(queryClient, convoId, prev => {
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(prev.kind)) return undefined
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind))
|
||||
return undefined
|
||||
return {
|
||||
...prev,
|
||||
kind: {
|
||||
@@ -64,7 +61,8 @@ export function useCreateJoinLink(
|
||||
onSuccess: data => {
|
||||
if (convoId) {
|
||||
updateConvoOptimistic(queryClient, convoId, prev => {
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(prev.kind)) return undefined
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind))
|
||||
return undefined
|
||||
return {
|
||||
...prev,
|
||||
kind: {...prev.kind, joinLink: data.joinLink},
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import {
|
||||
ChatBskyConvoDefs,
|
||||
type ChatBskyGroupDisableJoinLink,
|
||||
} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {logger} from '#/logger'
|
||||
import {invalidateJoinLinkPreviewsForCode} from '#/state/queries/join-links'
|
||||
import {useChatClient} from '#/state/session'
|
||||
@@ -19,7 +16,7 @@ export function useDisableJoinLink(
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (data: ChatBskyGroupDisableJoinLink.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.group.disableJoinLink.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
},
|
||||
) {
|
||||
@@ -34,7 +31,10 @@ export function useDisableJoinLink(
|
||||
onMutate: () => {
|
||||
if (!convoId) return
|
||||
return updateConvoOptimistic(queryClient, convoId, prev => {
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(prev.kind) || !prev.kind.joinLink) {
|
||||
if (
|
||||
!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind) ||
|
||||
!prev.kind.joinLink
|
||||
) {
|
||||
return undefined
|
||||
}
|
||||
return {
|
||||
@@ -49,7 +49,8 @@ export function useDisableJoinLink(
|
||||
onSuccess: data => {
|
||||
if (convoId) {
|
||||
updateConvoOptimistic(queryClient, convoId, prev => {
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(prev.kind)) return undefined
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind))
|
||||
return undefined
|
||||
return {
|
||||
...prev,
|
||||
kind: {...prev.kind, joinLink: data.joinLink},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {ChatBskyConvoDefs, type ChatBskyGroupEditGroup} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {logger} from '#/logger'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
@@ -15,7 +15,7 @@ export function useEditGroupChatName(
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (data: ChatBskyGroupEditGroup.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.group.editGroup.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
},
|
||||
) {
|
||||
@@ -33,7 +33,8 @@ export function useEditGroupChatName(
|
||||
onMutate: ({name: groupName}) => {
|
||||
if (!convoId) return
|
||||
return updateConvoOptimistic(queryClient, convoId, prev => {
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(prev.kind)) return undefined
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind))
|
||||
return undefined
|
||||
return {
|
||||
...prev,
|
||||
kind: {...prev.kind, name: groupName},
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
import {
|
||||
ChatBskyConvoDefs,
|
||||
type ChatBskyGroupDefs,
|
||||
type ChatBskyGroupEditJoinLink,
|
||||
} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {logger} from '#/logger'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
@@ -19,7 +15,7 @@ export function useEditJoinLink(
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (data: ChatBskyGroupEditJoinLink.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.group.editJoinLink.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
},
|
||||
) {
|
||||
@@ -31,7 +27,7 @@ export function useEditJoinLink(
|
||||
joinRule,
|
||||
requireApproval,
|
||||
}: {
|
||||
joinRule: ChatBskyGroupDefs.JoinRule
|
||||
joinRule: chat.bsky.group.defs.JoinRule
|
||||
requireApproval: boolean
|
||||
}) => {
|
||||
if (!convoId) throw new Error('No convoId provided')
|
||||
@@ -44,7 +40,10 @@ export function useEditJoinLink(
|
||||
onMutate: ({joinRule, requireApproval}) => {
|
||||
if (!convoId) return
|
||||
return updateConvoOptimistic(queryClient, convoId, prev => {
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(prev.kind) || !prev.kind.joinLink) {
|
||||
if (
|
||||
!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind) ||
|
||||
!prev.kind.joinLink
|
||||
) {
|
||||
return undefined
|
||||
}
|
||||
return {
|
||||
@@ -59,7 +58,8 @@ export function useEditJoinLink(
|
||||
onSuccess: data => {
|
||||
if (convoId) {
|
||||
updateConvoOptimistic(queryClient, convoId, prev => {
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(prev.kind)) return undefined
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind))
|
||||
return undefined
|
||||
return {
|
||||
...prev,
|
||||
kind: {...prev.kind, joinLink: data.joinLink},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {ChatBskyConvoDefs, type ChatBskyGroupEnableJoinLink} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {logger} from '#/logger'
|
||||
import {invalidateJoinLinkPreviewsForCode} from '#/state/queries/join-links'
|
||||
import {useChatClient} from '#/state/session'
|
||||
@@ -16,7 +16,7 @@ export function useEnableJoinLink(
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (data: ChatBskyGroupEnableJoinLink.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.group.enableJoinLink.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
},
|
||||
) {
|
||||
@@ -31,7 +31,10 @@ export function useEnableJoinLink(
|
||||
onMutate: () => {
|
||||
if (!convoId) return
|
||||
return updateConvoOptimistic(queryClient, convoId, prev => {
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(prev.kind) || !prev.kind.joinLink) {
|
||||
if (
|
||||
!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind) ||
|
||||
!prev.kind.joinLink
|
||||
) {
|
||||
return undefined
|
||||
}
|
||||
return {
|
||||
@@ -46,7 +49,8 @@ export function useEnableJoinLink(
|
||||
onSuccess: data => {
|
||||
if (convoId) {
|
||||
updateConvoOptimistic(queryClient, convoId, prev => {
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(prev.kind)) return undefined
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind))
|
||||
return undefined
|
||||
return {
|
||||
...prev,
|
||||
kind: {...prev.kind, joinLink: data.joinLink},
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type ChatBskyConvoGetConvoForMembers} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
@@ -11,7 +10,7 @@ export function useGetConvoForMembers({
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (data: ChatBskyConvoGetConvoForMembers.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.convo.getConvoForMembers.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
}) {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
import {
|
||||
type ChatBskyActorDefs,
|
||||
type ChatBskyGroupApproveJoinRequest,
|
||||
type ChatBskyGroupListJoinRequests,
|
||||
type ChatBskyGroupRejectJoinRequest,
|
||||
} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
@@ -20,8 +14,8 @@ import {createListJoinRequestsQueryKey} from './list-join-requests'
|
||||
type JoinRequestAction = 'approve' | 'reject'
|
||||
|
||||
type JoinRequestOutput<A extends JoinRequestAction> = A extends 'approve'
|
||||
? ChatBskyGroupApproveJoinRequest.OutputSchema
|
||||
: ChatBskyGroupRejectJoinRequest.OutputSchema
|
||||
? chat.bsky.group.approveJoinRequest.$OutputBody
|
||||
: chat.bsky.group.rejectJoinRequest.$OutputBody
|
||||
|
||||
export function useJoinRequestMutation<A extends JoinRequestAction>(
|
||||
action: A,
|
||||
@@ -65,7 +59,7 @@ export function useJoinRequestMutation<A extends JoinRequestAction>(
|
||||
const requestsKey = createListJoinRequestsQueryKey({convoId})
|
||||
const prevRequests =
|
||||
queryClient.getQueryData<
|
||||
InfiniteData<ChatBskyGroupListJoinRequests.OutputSchema>
|
||||
InfiniteData<chat.bsky.group.listJoinRequests.$OutputBody>
|
||||
>(requestsKey)
|
||||
|
||||
const requestedByProfile = prevRequests?.pages
|
||||
@@ -73,7 +67,7 @@ export function useJoinRequestMutation<A extends JoinRequestAction>(
|
||||
.find(request => request.requestedBy.did === member)?.requestedBy
|
||||
|
||||
queryClient.setQueryData<
|
||||
InfiniteData<ChatBskyGroupListJoinRequests.OutputSchema>
|
||||
InfiniteData<chat.bsky.group.listJoinRequests.$OutputBody>
|
||||
>(requestsKey, prev => {
|
||||
if (!prev?.pages) return prev
|
||||
return {
|
||||
@@ -87,14 +81,14 @@ export function useJoinRequestMutation<A extends JoinRequestAction>(
|
||||
}
|
||||
})
|
||||
|
||||
let prevMembers: ChatBskyActorDefs.ProfileViewBasic[] | undefined
|
||||
let prevMembers: chat.bsky.actor.defs.ProfileViewBasic[] | undefined
|
||||
if (action === 'approve' && requestedByProfile) {
|
||||
const membersKey = listConvoMembersQueryKey(convoId)
|
||||
prevMembers =
|
||||
queryClient.getQueryData<ChatBskyActorDefs.ProfileViewBasic[]>(
|
||||
queryClient.getQueryData<chat.bsky.actor.defs.ProfileViewBasic[]>(
|
||||
membersKey,
|
||||
)
|
||||
queryClient.setQueryData<ChatBskyActorDefs.ProfileViewBasic[]>(
|
||||
queryClient.setQueryData<chat.bsky.actor.defs.ProfileViewBasic[]>(
|
||||
membersKey,
|
||||
prev => {
|
||||
if (!prev) return prev
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import {
|
||||
type ChatBskyConvoLeaveConvo,
|
||||
type ChatBskyConvoListConvos,
|
||||
} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
@@ -22,7 +18,7 @@ export function RQKEY(convoId: string | undefined) {
|
||||
|
||||
type ConvoListQueryData = {
|
||||
pageParams: Array<string | undefined>
|
||||
pages: Array<ChatBskyConvoListConvos.OutputSchema>
|
||||
pages: Array<chat.bsky.convo.listConvos.$OutputBody>
|
||||
}
|
||||
|
||||
export function useLeaveConvo(
|
||||
@@ -33,7 +29,7 @@ export function useLeaveConvo(
|
||||
onError,
|
||||
}: {
|
||||
onMutate?: () => void
|
||||
onSuccess?: (data: ChatBskyConvoLeaveConvo.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.convo.leaveConvo.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
},
|
||||
) {
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
import {
|
||||
ChatBskyConvoDefs,
|
||||
type ChatBskyConvoListConvoRequests,
|
||||
ChatBskyGroupDefs,
|
||||
} from '@atproto/api'
|
||||
import {
|
||||
type InfiniteData,
|
||||
type QueryClient,
|
||||
useInfiniteQuery,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
|
||||
@@ -44,16 +40,18 @@ export function useListConvoRequests({
|
||||
|
||||
export type ConvoRequestListQueryData = {
|
||||
pageParams: Array<string | undefined>
|
||||
pages: Array<ChatBskyConvoListConvoRequests.OutputSchema>
|
||||
pages: Array<chat.bsky.convo.listConvoRequests.$OutputBody>
|
||||
}
|
||||
|
||||
export type ConvoRequestItem =
|
||||
ChatBskyConvoListConvoRequests.OutputSchema['requests'][number]
|
||||
chat.bsky.convo.listConvoRequests.$OutputBody['requests'][number]
|
||||
|
||||
export function optimisticUpdate(
|
||||
chatId: string,
|
||||
old: ConvoRequestListQueryData | undefined,
|
||||
updateFn: (convo: ChatBskyConvoDefs.ConvoView) => ChatBskyConvoDefs.ConvoView,
|
||||
updateFn: (
|
||||
convo: chat.bsky.convo.defs.ConvoView,
|
||||
) => chat.bsky.convo.defs.ConvoView,
|
||||
): ConvoRequestListQueryData | undefined {
|
||||
if (!old) return old
|
||||
|
||||
@@ -62,7 +60,10 @@ export function optimisticUpdate(
|
||||
pages: old.pages.map(page => ({
|
||||
...page,
|
||||
requests: page.requests.map((item): ConvoRequestItem => {
|
||||
if (ChatBskyConvoDefs.isConvoView(item) && item.id === chatId) {
|
||||
if (
|
||||
bsky.isType(chat.bsky.convo.defs.convoView, item) &&
|
||||
item.id === chatId
|
||||
) {
|
||||
return {
|
||||
...updateFn(item),
|
||||
$type: 'chat.bsky.convo.defs#convoView',
|
||||
@@ -85,7 +86,9 @@ export function optimisticDelete(
|
||||
pages: old.pages.map(page => ({
|
||||
...page,
|
||||
requests: page.requests.filter(
|
||||
item => !ChatBskyConvoDefs.isConvoView(item) || item.id !== chatId,
|
||||
item =>
|
||||
!bsky.isType(chat.bsky.convo.defs.convoView, item) ||
|
||||
item.id !== chatId,
|
||||
),
|
||||
})),
|
||||
}
|
||||
@@ -101,7 +104,7 @@ export function markAllRead(
|
||||
pages: old.pages.map(page => ({
|
||||
...page,
|
||||
requests: page.requests.map((item): ConvoRequestItem => {
|
||||
if (ChatBskyConvoDefs.isConvoView(item)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.convoView, item)) {
|
||||
return {
|
||||
...item,
|
||||
$type: 'chat.bsky.convo.defs#convoView',
|
||||
@@ -126,7 +129,7 @@ export function optimisticDeleteJoinRequest(
|
||||
...page,
|
||||
requests: page.requests.filter(
|
||||
item =>
|
||||
!ChatBskyGroupDefs.isJoinRequestConvoView(item) ||
|
||||
!bsky.isType(chat.bsky.group.defs.joinRequestConvoView, item) ||
|
||||
item.convoId !== convoId,
|
||||
),
|
||||
})),
|
||||
@@ -138,7 +141,7 @@ export function* findAllProfilesInQueryData(
|
||||
did: string,
|
||||
) {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<ChatBskyConvoListConvoRequests.OutputSchema>
|
||||
InfiniteData<chat.bsky.convo.listConvoRequests.$OutputBody>
|
||||
>({
|
||||
queryKey: [RQKEY_ROOT],
|
||||
})
|
||||
@@ -147,13 +150,15 @@ export function* findAllProfilesInQueryData(
|
||||
|
||||
for (const page of queryData.pages) {
|
||||
for (const item of page.requests) {
|
||||
if (ChatBskyConvoDefs.isConvoView(item)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.convoView, item)) {
|
||||
for (const member of item.members) {
|
||||
if (member.did === did) {
|
||||
yield member
|
||||
}
|
||||
}
|
||||
} else if (ChatBskyGroupDefs.isJoinRequestConvoView(item)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.group.defs.joinRequestConvoView, item)
|
||||
) {
|
||||
if (item.owner.did === did) {
|
||||
yield item.owner
|
||||
}
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
import {useCallback, useEffect, useMemo} from 'react'
|
||||
import {
|
||||
type ChatBskyActorDefs,
|
||||
ChatBskyConvoDefs,
|
||||
type ChatBskyConvoListConvos,
|
||||
} from '@atproto/api'
|
||||
import {
|
||||
type InfiniteData,
|
||||
type Query,
|
||||
@@ -68,7 +63,7 @@ export const RQKEY_PARTIAL = (
|
||||
* filters client-side or convos leak into lists that should exclude them.
|
||||
*/
|
||||
export function convoMatchesQueryKey(
|
||||
convo: ChatBskyConvoDefs.ConvoView,
|
||||
convo: chat.bsky.convo.defs.ConvoView,
|
||||
queryKey: QueryKey,
|
||||
): boolean {
|
||||
const [, status, readState, kind, lockStatus] = queryKey as ReturnType<
|
||||
@@ -76,7 +71,7 @@ export function convoMatchesQueryKey(
|
||||
>
|
||||
if (status !== 'all' && status !== convo.status) return false
|
||||
if (readState === 'unread' && convo.unreadCount === 0) return false
|
||||
if (ChatBskyConvoDefs.isGroupConvo(convo.kind)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) {
|
||||
if (kind === 'direct') return false
|
||||
if (lockStatus && convo.kind.lockStatus !== lockStatus) return false
|
||||
} else {
|
||||
@@ -94,7 +89,7 @@ export function convoMatchesQueryKey(
|
||||
* longer matches (e.g. unreadCount dropped to 0), mirroring how read/mute
|
||||
* log events update convos in place everywhere.
|
||||
*/
|
||||
export function convoListQueryPredicate(convo: ChatBskyConvoDefs.ConvoView) {
|
||||
export function convoListQueryPredicate(convo: chat.bsky.convo.defs.ConvoView) {
|
||||
return (query: Query): boolean => {
|
||||
const data = query.state.data as ConvoListQueryData | undefined
|
||||
if (data && getConvoFromQueryData(convo.id, data)) return true
|
||||
@@ -196,10 +191,10 @@ export function ListConvosProviderInner({
|
||||
function mutateMembers(
|
||||
convoId: string,
|
||||
fn: (
|
||||
members: ChatBskyActorDefs.ProfileViewBasic[],
|
||||
) => ChatBskyActorDefs.ProfileViewBasic[],
|
||||
members: chat.bsky.actor.defs.ProfileViewBasic[],
|
||||
) => chat.bsky.actor.defs.ProfileViewBasic[],
|
||||
) {
|
||||
queryClient.setQueryData<ChatBskyActorDefs.ProfileViewBasic[]>(
|
||||
queryClient.setQueryData<chat.bsky.actor.defs.ProfileViewBasic[]>(
|
||||
listConvoMembersQueryKey(convoId),
|
||||
old => {
|
||||
if (!old) return // query doesn't exist yet, skip
|
||||
@@ -211,8 +206,8 @@ export function ListConvosProviderInner({
|
||||
function updateConvoInAllLists(
|
||||
convoId: string,
|
||||
fn: (
|
||||
convo: ChatBskyConvoDefs.ConvoView,
|
||||
) => ChatBskyConvoDefs.ConvoView,
|
||||
convo: chat.bsky.convo.defs.ConvoView,
|
||||
) => chat.bsky.convo.defs.ConvoView,
|
||||
) {
|
||||
queryClient.setQueriesData<ConvoListQueryData>(
|
||||
{queryKey: [RQKEY_ROOT]},
|
||||
@@ -227,10 +222,10 @@ export function ListConvosProviderInner({
|
||||
function mutateConvoView(
|
||||
convoId: string,
|
||||
fn: (
|
||||
convo: ChatBskyConvoDefs.ConvoView,
|
||||
) => ChatBskyConvoDefs.ConvoView,
|
||||
convo: chat.bsky.convo.defs.ConvoView,
|
||||
) => chat.bsky.convo.defs.ConvoView,
|
||||
) {
|
||||
queryClient.setQueryData<ChatBskyConvoDefs.ConvoView>(
|
||||
queryClient.setQueryData<chat.bsky.convo.defs.ConvoView>(
|
||||
CONVO_KEY(convoId),
|
||||
old => (old ? fn(old) : old),
|
||||
)
|
||||
@@ -251,7 +246,7 @@ export function ListConvosProviderInner({
|
||||
function handleMemberAdded(
|
||||
convoId: string,
|
||||
did: string,
|
||||
relatedProfiles: ChatBskyActorDefs.ProfileViewBasic[],
|
||||
relatedProfiles: chat.bsky.actor.defs.ProfileViewBasic[],
|
||||
rev: string,
|
||||
) {
|
||||
const newMember = relatedProfiles.find(r => r.did === did)
|
||||
@@ -261,7 +256,7 @@ export function ListConvosProviderInner({
|
||||
const alreadyKnownMember =
|
||||
queryClient
|
||||
.getQueryData<
|
||||
ChatBskyActorDefs.ProfileViewBasic[]
|
||||
chat.bsky.actor.defs.ProfileViewBasic[]
|
||||
>(listConvoMembersQueryKey(convoId))
|
||||
?.some(m => m.did === did) ?? false
|
||||
mutateMembers(convoId, list =>
|
||||
@@ -285,7 +280,7 @@ export function ListConvosProviderInner({
|
||||
const alreadyRemovedMember =
|
||||
queryClient
|
||||
.getQueryData<
|
||||
ChatBskyActorDefs.ProfileViewBasic[]
|
||||
chat.bsky.actor.defs.ProfileViewBasic[]
|
||||
>(listConvoMembersQueryKey(convoId))
|
||||
?.some(m => m.did === did) === false
|
||||
mutateMembers(convoId, list => list.filter(m => m.did !== did))
|
||||
@@ -298,24 +293,36 @@ export function ListConvosProviderInner({
|
||||
}
|
||||
|
||||
for (const log of events.logs) {
|
||||
if (ChatBskyConvoDefs.isLogBeginConvo(log)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.logBeginConvo, log)) {
|
||||
debouncedRefetch()
|
||||
} else if (ChatBskyConvoDefs.isLogLeaveConvo(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logLeaveConvo, log)) {
|
||||
deleteConvoFromAllLists(log.convoId)
|
||||
// The viewer is no longer in this convo (they left on another
|
||||
// device, or were removed - removed members receive a
|
||||
// logLeaveConvo, not a logRemoveMember). Refetch any cached join
|
||||
// link preview so its viewer state reflects the lost membership.
|
||||
void invalidateJoinLinkPreviewsForConvo(queryClient, log.convoId)
|
||||
} else if (ChatBskyConvoDefs.isLogDeleteMessage(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logDeleteMessage, log)) {
|
||||
updateConvoInAllLists(
|
||||
log.convoId,
|
||||
withRevGuard(log.rev, convo => {
|
||||
if (
|
||||
(ChatBskyConvoDefs.isDeletedMessageView(log.message) ||
|
||||
ChatBskyConvoDefs.isMessageView(log.message)) &&
|
||||
(ChatBskyConvoDefs.isDeletedMessageView(convo.lastMessage) ||
|
||||
ChatBskyConvoDefs.isMessageView(convo.lastMessage))
|
||||
(bsky.isType(
|
||||
chat.bsky.convo.defs.deletedMessageView,
|
||||
log.message,
|
||||
) ||
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.messageView,
|
||||
log.message,
|
||||
)) &&
|
||||
(bsky.isType(
|
||||
chat.bsky.convo.defs.deletedMessageView,
|
||||
convo.lastMessage,
|
||||
) ||
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.messageView,
|
||||
convo.lastMessage,
|
||||
))
|
||||
) {
|
||||
return log.message.id === convo.lastMessage.id
|
||||
? {
|
||||
@@ -329,9 +336,9 @@ export function ListConvosProviderInner({
|
||||
}
|
||||
}),
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogCreateMessage(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logCreateMessage, log)) {
|
||||
// Store in a new var to avoid TS errors due to closures.
|
||||
const logRef: ChatBskyConvoDefs.LogCreateMessage = log
|
||||
const logRef: chat.bsky.convo.defs.LogCreateMessage = log
|
||||
|
||||
// Get all matching queries
|
||||
const queries = queryClient.getQueriesData<ConvoListQueryData>({
|
||||
@@ -339,7 +346,7 @@ export function ListConvosProviderInner({
|
||||
})
|
||||
|
||||
// Check if convo exists in any query
|
||||
let foundConvo: ChatBskyConvoDefs.ConvoView | null = null
|
||||
let foundConvo: chat.bsky.convo.defs.ConvoView | null = null
|
||||
for (const [_key, query] of queries) {
|
||||
if (!query) continue
|
||||
const convo = getConvoFromQueryData(logRef.convoId, query)
|
||||
@@ -382,15 +389,23 @@ export function ListConvosProviderInner({
|
||||
lastMessage: logRef.message,
|
||||
unreadCount:
|
||||
foundConvo.id !== currentConvoId
|
||||
? (ChatBskyConvoDefs.isMessageView(logRef.message) ||
|
||||
ChatBskyConvoDefs.isDeletedMessageView(logRef.message)) &&
|
||||
? (bsky.isType(
|
||||
chat.bsky.convo.defs.messageView,
|
||||
logRef.message,
|
||||
) ||
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.deletedMessageView,
|
||||
logRef.message,
|
||||
)) &&
|
||||
logRef.message.sender.did !== currentAccount?.did
|
||||
? foundConvo.unreadCount + 1
|
||||
: foundConvo.unreadCount
|
||||
: 0,
|
||||
}
|
||||
|
||||
function filterConvoFromPage(convo: ChatBskyConvoDefs.ConvoView[]) {
|
||||
function filterConvoFromPage(
|
||||
convo: chat.bsky.convo.defs.ConvoView[],
|
||||
) {
|
||||
return convo.filter(c => c.id !== logRef.convoId)
|
||||
}
|
||||
|
||||
@@ -453,7 +468,7 @@ export function ListConvosProviderInner({
|
||||
old => moveConvoToTopInRequests(updatedConvo, old),
|
||||
)
|
||||
}
|
||||
} else if (ChatBskyConvoDefs.isLogReadMessage(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logReadMessage, log)) {
|
||||
updateConvoInAllLists(
|
||||
log.convoId,
|
||||
withRevGuard(log.rev, convo => ({
|
||||
@@ -462,7 +477,7 @@ export function ListConvosProviderInner({
|
||||
rev: log.rev,
|
||||
})),
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogReadConvo(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logReadConvo, log)) {
|
||||
updateConvoInAllLists(
|
||||
log.convoId,
|
||||
withRevGuard(log.rev, convo => ({
|
||||
@@ -471,12 +486,12 @@ export function ListConvosProviderInner({
|
||||
rev: log.rev,
|
||||
})),
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogAcceptConvo(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logAcceptConvo, log)) {
|
||||
const requestQueries =
|
||||
queryClient.getQueriesData<ConvoListQueryData>({
|
||||
queryKey: RQKEY_PARTIAL('request'),
|
||||
})
|
||||
let foundConvo: ChatBskyConvoDefs.ConvoView | null = null
|
||||
let foundConvo: chat.bsky.convo.defs.ConvoView | null = null
|
||||
for (const [_key, data] of requestQueries) {
|
||||
if (!data) continue
|
||||
foundConvo = getConvoFromQueryData(log.convoId, data)
|
||||
@@ -492,7 +507,7 @@ export function ListConvosProviderInner({
|
||||
if (log.rev <= foundConvo.rev) {
|
||||
continue
|
||||
}
|
||||
const acceptedConvo: ChatBskyConvoDefs.ConvoView = {
|
||||
const acceptedConvo: chat.bsky.convo.defs.ConvoView = {
|
||||
...foundConvo,
|
||||
status: 'accepted',
|
||||
rev: log.rev,
|
||||
@@ -553,7 +568,7 @@ export function ListConvosProviderInner({
|
||||
}
|
||||
},
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogMuteConvo(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logMuteConvo, log)) {
|
||||
mutateConvoView(
|
||||
log.convoId,
|
||||
withRevGuard(log.rev, convo => ({
|
||||
@@ -562,7 +577,7 @@ export function ListConvosProviderInner({
|
||||
rev: log.rev,
|
||||
})),
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogUnmuteConvo(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logUnmuteConvo, log)) {
|
||||
mutateConvoView(
|
||||
log.convoId,
|
||||
withRevGuard(log.rev, convo => ({
|
||||
@@ -571,11 +586,11 @@ export function ListConvosProviderInner({
|
||||
rev: log.rev,
|
||||
})),
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogLockConvo(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logLockConvo, log)) {
|
||||
mutateConvoView(
|
||||
log.convoId,
|
||||
withRevGuard(log.rev, convo => {
|
||||
if (ChatBskyConvoDefs.isGroupConvo(convo.kind)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) {
|
||||
return {
|
||||
...convo,
|
||||
kind: {...convo.kind, lockStatus: 'locked'},
|
||||
@@ -590,11 +605,11 @@ export function ListConvosProviderInner({
|
||||
void queryClient.invalidateQueries({
|
||||
queryKey: CONVO_KEY(log.convoId),
|
||||
})
|
||||
} else if (ChatBskyConvoDefs.isLogUnlockConvo(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logUnlockConvo, log)) {
|
||||
mutateConvoView(
|
||||
log.convoId,
|
||||
withRevGuard(log.rev, convo => {
|
||||
if (ChatBskyConvoDefs.isGroupConvo(convo.kind)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) {
|
||||
return {
|
||||
...convo,
|
||||
kind: {
|
||||
@@ -609,11 +624,13 @@ export function ListConvosProviderInner({
|
||||
return {...convo, rev: log.rev}
|
||||
}),
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogLockConvoPermanently(log)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.logLockConvoPermanently, log)
|
||||
) {
|
||||
mutateConvoView(
|
||||
log.convoId,
|
||||
withRevGuard(log.rev, convo => {
|
||||
if (ChatBskyConvoDefs.isGroupConvo(convo.kind)) {
|
||||
if (bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) {
|
||||
return {
|
||||
...convo,
|
||||
kind: {...convo.kind, lockStatus: 'locked-permanently'},
|
||||
@@ -624,20 +641,20 @@ export function ListConvosProviderInner({
|
||||
}),
|
||||
)
|
||||
} else if (
|
||||
ChatBskyConvoDefs.isLogCreateJoinLink(log) ||
|
||||
ChatBskyConvoDefs.isLogEditJoinLink(log) ||
|
||||
ChatBskyConvoDefs.isLogEnableJoinLink(log) ||
|
||||
ChatBskyConvoDefs.isLogDisableJoinLink(log)
|
||||
bsky.isType(chat.bsky.convo.defs.logCreateJoinLink, log) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logEditJoinLink, log) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logEnableJoinLink, log) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logDisableJoinLink, log)
|
||||
) {
|
||||
// Join link data not included in the log event, trigger refetch to get it
|
||||
debouncedRefetch()
|
||||
} else if (ChatBskyConvoDefs.isLogEditGroup(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logEditGroup, log)) {
|
||||
// Updated group details (name etc.) aren't included in the log
|
||||
// event, so refetch to pick them up.
|
||||
debouncedRefetch()
|
||||
} else if (
|
||||
ChatBskyConvoDefs.isLogApproveJoinRequest(log) ||
|
||||
ChatBskyConvoDefs.isLogRejectJoinRequest(log)
|
||||
bsky.isType(chat.bsky.convo.defs.logApproveJoinRequest, log) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logRejectJoinRequest, log)
|
||||
) {
|
||||
// Route through mutateConvoView (not updateConvoInAllLists) so the
|
||||
// single-convo cache updates too, keeping the in-convo requests
|
||||
@@ -648,7 +665,9 @@ export function ListConvosProviderInner({
|
||||
applyJoinRequestCountDelta(convo, log.rev, -1),
|
||||
),
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogIncomingJoinRequest(log)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.logIncomingJoinRequest, log)
|
||||
) {
|
||||
// Route through mutateConvoView (not updateConvoInAllLists) so the
|
||||
// single-convo cache updates too, letting the in-convo requests
|
||||
// banner appear live.
|
||||
@@ -658,14 +677,16 @@ export function ListConvosProviderInner({
|
||||
applyJoinRequestCountDelta(convo, log.rev, 1),
|
||||
),
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogReadJoinRequests(log)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.logReadJoinRequests, log)
|
||||
) {
|
||||
// The owner marked join requests as read (possibly on another
|
||||
// device). Zero the unread count but keep the total, mirroring the
|
||||
// useMarkJoinRequestsRead mutation.
|
||||
mutateConvoView(
|
||||
log.convoId,
|
||||
withRevGuard(log.rev, convo => {
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(convo.kind)) {
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) {
|
||||
return {...convo, rev: log.rev}
|
||||
}
|
||||
return {
|
||||
@@ -675,11 +696,18 @@ export function ListConvosProviderInner({
|
||||
}
|
||||
}),
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogOutgoingJoinRequest(log)) {
|
||||
} else if (
|
||||
bsky.isType(chat.bsky.convo.defs.logOutgoingJoinRequest, log)
|
||||
) {
|
||||
// Viewer isn't in the chat yet, but the inbox surfaces outgoing
|
||||
// requests, so refetch to pick up the new entry.
|
||||
debouncedRefetch()
|
||||
} else if (ChatBskyConvoDefs.isLogWithdrawIncomingJoinRequest(log)) {
|
||||
} else if (
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.logWithdrawIncomingJoinRequest,
|
||||
log,
|
||||
)
|
||||
) {
|
||||
// A requester rescinded their request to a group the viewer owns.
|
||||
// Mirror of isLogIncomingJoinRequest: decrement the counts.
|
||||
mutateConvoView(
|
||||
@@ -688,14 +716,19 @@ export function ListConvosProviderInner({
|
||||
applyJoinRequestCountDelta(convo, log.rev, -1),
|
||||
),
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogWithdrawOutgoingJoinRequest(log)) {
|
||||
} else if (
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.logWithdrawOutgoingJoinRequest,
|
||||
log,
|
||||
)
|
||||
) {
|
||||
// The viewer rescinded their own outgoing join request (possibly on
|
||||
// another device). Remove it from the requests inbox cache.
|
||||
queryClient.setQueriesData<ConvoRequestListQueryData>(
|
||||
{queryKey: [REQUESTS_RQKEY_ROOT]},
|
||||
old => optimisticDeleteJoinRequest(log.convoId, old),
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogAddReaction(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logAddReaction, log)) {
|
||||
updateConvoInAllLists(
|
||||
log.convoId,
|
||||
withRevGuard(log.rev, convo => {
|
||||
@@ -718,13 +751,10 @@ export function ListConvosProviderInner({
|
||||
}
|
||||
}),
|
||||
)
|
||||
} else if (ChatBskyConvoDefs.isLogAddMember(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logAddMember, log)) {
|
||||
const data = log.message.data
|
||||
if (
|
||||
bsky.dangerousIsType<ChatBskyConvoDefs.SystemMessageDataAddMember>(
|
||||
data,
|
||||
ChatBskyConvoDefs.isSystemMessageDataAddMember,
|
||||
)
|
||||
bsky.isType(chat.bsky.convo.defs.systemMessageDataAddMember, data)
|
||||
) {
|
||||
handleMemberAdded(
|
||||
log.convoId,
|
||||
@@ -738,12 +768,12 @@ export function ListConvosProviderInner({
|
||||
queryKey: CONVO_KEY(log.convoId),
|
||||
})
|
||||
debouncedRefetch()
|
||||
} else if (ChatBskyConvoDefs.isLogRemoveMember(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logRemoveMember, log)) {
|
||||
const data = log.message.data
|
||||
if (
|
||||
bsky.dangerousIsType<ChatBskyConvoDefs.SystemMessageDataRemoveMember>(
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.systemMessageDataRemoveMember,
|
||||
data,
|
||||
ChatBskyConvoDefs.isSystemMessageDataRemoveMember,
|
||||
)
|
||||
) {
|
||||
handleMemberRemoved(log.convoId, data.member.did, log.rev)
|
||||
@@ -753,12 +783,12 @@ export function ListConvosProviderInner({
|
||||
queryKey: CONVO_KEY(log.convoId),
|
||||
})
|
||||
debouncedRefetch()
|
||||
} else if (ChatBskyConvoDefs.isLogMemberJoin(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logMemberJoin, log)) {
|
||||
const data = log.message.data
|
||||
if (
|
||||
bsky.dangerousIsType<ChatBskyConvoDefs.SystemMessageDataMemberJoin>(
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.systemMessageDataMemberJoin,
|
||||
data,
|
||||
ChatBskyConvoDefs.isSystemMessageDataMemberJoin,
|
||||
)
|
||||
) {
|
||||
handleMemberAdded(
|
||||
@@ -772,12 +802,12 @@ export function ListConvosProviderInner({
|
||||
queryKey: CONVO_KEY(log.convoId),
|
||||
})
|
||||
debouncedRefetch()
|
||||
} else if (ChatBskyConvoDefs.isLogMemberLeave(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logMemberLeave, log)) {
|
||||
const data = log.message.data
|
||||
if (
|
||||
bsky.dangerousIsType<ChatBskyConvoDefs.SystemMessageDataMemberLeave>(
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.systemMessageDataMemberLeave,
|
||||
data,
|
||||
ChatBskyConvoDefs.isSystemMessageDataMemberLeave,
|
||||
)
|
||||
) {
|
||||
handleMemberRemoved(log.convoId, data.member.did, log.rev)
|
||||
@@ -786,7 +816,7 @@ export function ListConvosProviderInner({
|
||||
queryKey: CONVO_KEY(log.convoId),
|
||||
})
|
||||
debouncedRefetch()
|
||||
} else if (ChatBskyConvoDefs.isLogRemoveReaction(log)) {
|
||||
} else if (bsky.isType(chat.bsky.convo.defs.logRemoveReaction, log)) {
|
||||
queryClient.setQueriesData(
|
||||
{queryKey: [RQKEY_ROOT]},
|
||||
(old?: ConvoListQueryData) =>
|
||||
@@ -797,10 +827,14 @@ export function ListConvosProviderInner({
|
||||
if (
|
||||
// if the convo is the same
|
||||
log.convoId === convo.id &&
|
||||
ChatBskyConvoDefs.isMessageAndReactionView(
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.messageAndReactionView,
|
||||
convo.lastReaction,
|
||||
) &&
|
||||
ChatBskyConvoDefs.isMessageView(log.message) &&
|
||||
bsky.isType(
|
||||
chat.bsky.convo.defs.messageView,
|
||||
log.message,
|
||||
) &&
|
||||
// ...and the message is the same
|
||||
convo.lastReaction.message.id === log.message.id &&
|
||||
// ...and the reaction is the same
|
||||
@@ -882,7 +916,7 @@ export function useUnreadMessageCount(): {
|
||||
|
||||
export type ConvoListQueryData = {
|
||||
pageParams: Array<string | undefined>
|
||||
pages: Array<ChatBskyConvoListConvos.OutputSchema>
|
||||
pages: Array<chat.bsky.convo.listConvos.$OutputBody>
|
||||
}
|
||||
|
||||
export function useOnMarkAsRead() {
|
||||
@@ -919,8 +953,8 @@ export function useOnMarkAsRead() {
|
||||
*/
|
||||
function withRevGuard(
|
||||
rev: string,
|
||||
fn: (convo: ChatBskyConvoDefs.ConvoView) => ChatBskyConvoDefs.ConvoView,
|
||||
): (convo: ChatBskyConvoDefs.ConvoView) => ChatBskyConvoDefs.ConvoView {
|
||||
fn: (convo: chat.bsky.convo.defs.ConvoView) => chat.bsky.convo.defs.ConvoView,
|
||||
): (convo: chat.bsky.convo.defs.ConvoView) => chat.bsky.convo.defs.ConvoView {
|
||||
return convo => (rev <= convo.rev ? convo : fn(convo))
|
||||
}
|
||||
|
||||
@@ -928,8 +962,8 @@ function optimisticUpdate(
|
||||
chatId: string,
|
||||
old?: ConvoListQueryData,
|
||||
updateFn?: (
|
||||
convo: ChatBskyConvoDefs.ConvoView,
|
||||
) => ChatBskyConvoDefs.ConvoView,
|
||||
convo: chat.bsky.convo.defs.ConvoView,
|
||||
) => chat.bsky.convo.defs.ConvoView,
|
||||
) {
|
||||
if (!old || !updateFn) return old
|
||||
|
||||
@@ -945,12 +979,12 @@ function optimisticUpdate(
|
||||
}
|
||||
|
||||
function applyJoinRequestCountDelta(
|
||||
convo: ChatBskyConvoDefs.ConvoView,
|
||||
convo: chat.bsky.convo.defs.ConvoView,
|
||||
rev: string,
|
||||
delta: 1 | -1,
|
||||
): ChatBskyConvoDefs.ConvoView {
|
||||
): chat.bsky.convo.defs.ConvoView {
|
||||
// Join requests are only meaningful for group convos.
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(convo.kind)) {
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) {
|
||||
return {...convo, rev}
|
||||
}
|
||||
// Bump the total and unread counts together. Both are clamped at 0 and
|
||||
@@ -971,7 +1005,7 @@ function applyJoinRequestCountDelta(
|
||||
}
|
||||
|
||||
function moveConvoToTopInRequests(
|
||||
updatedConvo: ChatBskyConvoDefs.ConvoView,
|
||||
updatedConvo: chat.bsky.convo.defs.ConvoView,
|
||||
old: ConvoRequestListQueryData | undefined,
|
||||
): ConvoRequestListQueryData | undefined {
|
||||
if (!old) return old
|
||||
@@ -985,7 +1019,8 @@ function moveConvoToTopInRequests(
|
||||
pages: old.pages.map((page, i) => {
|
||||
const filtered = page.requests.filter(
|
||||
item =>
|
||||
!ChatBskyConvoDefs.isConvoView(item) || item.id !== updatedConvo.id,
|
||||
!bsky.isType(chat.bsky.convo.defs.convoView, item) ||
|
||||
item.id !== updatedConvo.id,
|
||||
)
|
||||
if (i === 0) {
|
||||
return {
|
||||
@@ -999,13 +1034,13 @@ function moveConvoToTopInRequests(
|
||||
}
|
||||
|
||||
function removeMemberFromConvoView(
|
||||
convo: ChatBskyConvoDefs.ConvoView,
|
||||
convo: chat.bsky.convo.defs.ConvoView,
|
||||
did: string,
|
||||
rev: string,
|
||||
alreadyRemovedMember: boolean,
|
||||
): ChatBskyConvoDefs.ConvoView {
|
||||
): chat.bsky.convo.defs.ConvoView {
|
||||
// Member add/remove/join/leave events are only meaningful for group convos.
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(convo.kind)) return convo
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) return convo
|
||||
const nextMembers = convo.members.filter(m => m.did !== did)
|
||||
return {
|
||||
...convo,
|
||||
@@ -1021,13 +1056,13 @@ function removeMemberFromConvoView(
|
||||
}
|
||||
|
||||
function addMemberToConvoView(
|
||||
convo: ChatBskyConvoDefs.ConvoView,
|
||||
member: ChatBskyActorDefs.ProfileViewBasic,
|
||||
convo: chat.bsky.convo.defs.ConvoView,
|
||||
member: chat.bsky.actor.defs.ProfileViewBasic,
|
||||
rev: string,
|
||||
alreadyKnownMember: boolean,
|
||||
): ChatBskyConvoDefs.ConvoView {
|
||||
): chat.bsky.convo.defs.ConvoView {
|
||||
// Member add/remove/join/leave events are only meaningful for group convos.
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(convo.kind)) return convo
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) return convo
|
||||
const alreadyInCuratedList = convo.members.some(m => m.did === member.did)
|
||||
const nextMembers = alreadyInCuratedList
|
||||
? convo.members
|
||||
@@ -1073,7 +1108,7 @@ export function* findAllProfilesInQueryData(
|
||||
did: string,
|
||||
) {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<ChatBskyConvoListConvos.OutputSchema>
|
||||
InfiniteData<chat.bsky.convo.listConvos.$OutputBody>
|
||||
>({
|
||||
queryKey: [RQKEY_ROOT],
|
||||
})
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type ChatBskyActorDefs} from '@atproto/api'
|
||||
import {type QueryClient, useQuery} from '@tanstack/react-query'
|
||||
|
||||
import {STALE} from '#/state/queries'
|
||||
@@ -18,7 +17,7 @@ export function useListConvoMembersQuery({
|
||||
placeholderData,
|
||||
}: {
|
||||
convoId: string
|
||||
placeholderData?: ChatBskyActorDefs.ProfileViewBasic[]
|
||||
placeholderData?: chat.bsky.actor.defs.ProfileViewBasic[]
|
||||
}) {
|
||||
const client = useChatClient()
|
||||
|
||||
@@ -32,7 +31,7 @@ export function useListConvoMembersQuery({
|
||||
* `members` with the exported profile type also keeps the hook's result
|
||||
* type unchanged for consumers.
|
||||
*/
|
||||
const members: ChatBskyActorDefs.ProfileViewBasic[] = []
|
||||
const members: chat.bsky.actor.defs.ProfileViewBasic[] = []
|
||||
let cursor: string | undefined
|
||||
|
||||
do {
|
||||
@@ -55,9 +54,9 @@ export function useListConvoMembersQuery({
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<ChatBskyActorDefs.ProfileViewBasic, void> {
|
||||
): Generator<chat.bsky.actor.defs.ProfileViewBasic, void> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
ChatBskyActorDefs.ProfileViewBasic[]
|
||||
chat.bsky.actor.defs.ProfileViewBasic[]
|
||||
>({
|
||||
queryKey: [RQKEY_ROOT],
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {useEffect} from 'react'
|
||||
import {ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {useInfiniteQuery, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {useMessagesEventBus} from '#/state/messages/events'
|
||||
import {createQueryKey} from '#/state/queries/util'
|
||||
import {useChatClient} from '#/state/session'
|
||||
@@ -35,9 +35,9 @@ export function useListJoinRequestsQuery({
|
||||
if (event.type !== 'logs') return
|
||||
for (const log of event.logs) {
|
||||
if (
|
||||
ChatBskyConvoDefs.isLogIncomingJoinRequest(log) ||
|
||||
ChatBskyConvoDefs.isLogApproveJoinRequest(log) ||
|
||||
ChatBskyConvoDefs.isLogRejectJoinRequest(log)
|
||||
bsky.isType(chat.bsky.convo.defs.logIncomingJoinRequest, log) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logApproveJoinRequest, log) ||
|
||||
bsky.isType(chat.bsky.convo.defs.logRejectJoinRequest, log)
|
||||
) {
|
||||
void queryClient.invalidateQueries({
|
||||
queryKey: createListJoinRequestsQueryKey({convoId}),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {ChatBskyConvoDefs, type ChatBskyConvoLockConvo} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
import {
|
||||
@@ -15,7 +15,7 @@ export function useLockConvo(
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (
|
||||
data: ChatBskyConvoLockConvo.OutputSchema,
|
||||
data: chat.bsky.convo.lockConvo.$OutputBody,
|
||||
variables: {lock: boolean; silent?: boolean},
|
||||
) => void
|
||||
onError?: (
|
||||
@@ -39,7 +39,8 @@ export function useLockConvo(
|
||||
onMutate: ({lock}) => {
|
||||
if (!convoId) return
|
||||
return updateConvoOptimistic(queryClient, convoId, prev => {
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(prev.kind)) return undefined
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind))
|
||||
return undefined
|
||||
return {
|
||||
...prev,
|
||||
kind: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {ChatBskyConvoDefs} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {logger} from '#/logger'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
@@ -22,13 +22,15 @@ export function useMarkJoinRequestsRead(convoId: string | undefined) {
|
||||
onMutate: () => {
|
||||
if (!convoId) return
|
||||
|
||||
const prevConvo = queryClient.getQueryData<ChatBskyConvoDefs.ConvoView>(
|
||||
CONVO_KEY(convoId),
|
||||
)
|
||||
queryClient.setQueryData<ChatBskyConvoDefs.ConvoView | undefined>(
|
||||
const prevConvo =
|
||||
queryClient.getQueryData<chat.bsky.convo.defs.ConvoView>(
|
||||
CONVO_KEY(convoId),
|
||||
)
|
||||
queryClient.setQueryData<chat.bsky.convo.defs.ConvoView | undefined>(
|
||||
CONVO_KEY(convoId),
|
||||
old => {
|
||||
if (!old || !ChatBskyConvoDefs.isGroupConvo(old.kind)) return old
|
||||
if (!old || !bsky.isType(chat.bsky.convo.defs.groupConvo, old.kind))
|
||||
return old
|
||||
return {
|
||||
...old,
|
||||
kind: {...old.kind, unreadJoinRequestCount: 0},
|
||||
@@ -50,7 +52,7 @@ export function useMarkJoinRequestsRead(convoId: string | undefined) {
|
||||
convos: page.convos.map(convo => {
|
||||
if (
|
||||
convo.id !== convoId ||
|
||||
!ChatBskyConvoDefs.isGroupConvo(convo.kind)
|
||||
!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)
|
||||
) {
|
||||
return convo
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type ChatBskyConvoMuteConvo} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {useChatClient} from '#/state/session'
|
||||
@@ -14,7 +13,7 @@ export function useMuteConvo(
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (data: ChatBskyConvoMuteConvo.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.convo.muteConvo.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
},
|
||||
) {
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
import {
|
||||
type ChatBskyActorDefs,
|
||||
ChatBskyConvoDefs,
|
||||
type ChatBskyConvoListConvos,
|
||||
type ChatBskyGroupRemoveMembers,
|
||||
} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
@@ -11,6 +5,7 @@ import {
|
||||
useQueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {logger} from '#/logger'
|
||||
import {useChatClient} from '#/state/session'
|
||||
import {chat} from '#/lexicons'
|
||||
@@ -24,7 +19,7 @@ export function useRemoveFromGroupChat(
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (data: ChatBskyGroupRemoveMembers.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.group.removeMembers.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
},
|
||||
) {
|
||||
@@ -43,23 +38,24 @@ export function useRemoveFromGroupChat(
|
||||
onMutate: ({members}) => {
|
||||
if (!convoId) return
|
||||
|
||||
const prevConvo = queryClient.getQueryData<ChatBskyConvoDefs.ConvoView>(
|
||||
CONVO_KEY(convoId),
|
||||
)
|
||||
const prevConvo =
|
||||
queryClient.getQueryData<chat.bsky.convo.defs.ConvoView>(
|
||||
CONVO_KEY(convoId),
|
||||
)
|
||||
const prevListEntries = queryClient.getQueriesData<
|
||||
InfiniteData<ChatBskyConvoListConvos.OutputSchema>
|
||||
InfiniteData<chat.bsky.convo.listConvos.$OutputBody>
|
||||
>({queryKey: [CONVO_LIST_KEY]})
|
||||
const prevMemberList = queryClient.getQueryData<
|
||||
ChatBskyActorDefs.ProfileViewBasic[]
|
||||
chat.bsky.actor.defs.ProfileViewBasic[]
|
||||
>(listConvoMembersQueryKey(convoId))
|
||||
|
||||
queryClient.setQueryData<ChatBskyConvoDefs.ConvoView>(
|
||||
queryClient.setQueryData<chat.bsky.convo.defs.ConvoView>(
|
||||
CONVO_KEY(convoId),
|
||||
prev => {
|
||||
if (!prev) return
|
||||
const nextMembers = prev.members.filter(m => !members.includes(m.did))
|
||||
const removed = prev.members.length - nextMembers.length
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(prev.kind)) {
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, prev.kind)) {
|
||||
return {...prev, members: nextMembers}
|
||||
}
|
||||
return {
|
||||
@@ -74,7 +70,7 @@ export function useRemoveFromGroupChat(
|
||||
)
|
||||
|
||||
queryClient.setQueriesData<
|
||||
InfiniteData<ChatBskyConvoListConvos.OutputSchema>
|
||||
InfiniteData<chat.bsky.convo.listConvos.$OutputBody>
|
||||
>({queryKey: [CONVO_LIST_KEY]}, prev => {
|
||||
if (!prev?.pages) return
|
||||
return {
|
||||
@@ -87,7 +83,7 @@ export function useRemoveFromGroupChat(
|
||||
m => !members.includes(m.did),
|
||||
)
|
||||
const removed = convo.members.length - nextMembers.length
|
||||
if (!ChatBskyConvoDefs.isGroupConvo(convo.kind)) {
|
||||
if (!bsky.isType(chat.bsky.convo.defs.groupConvo, convo.kind)) {
|
||||
return {...convo, members: nextMembers}
|
||||
}
|
||||
return {
|
||||
@@ -103,7 +99,7 @@ export function useRemoveFromGroupChat(
|
||||
}
|
||||
})
|
||||
|
||||
queryClient.setQueryData<ChatBskyActorDefs.ProfileViewBasic[]>(
|
||||
queryClient.setQueryData<chat.bsky.actor.defs.ProfileViewBasic[]>(
|
||||
listConvoMembersQueryKey(convoId),
|
||||
prev => {
|
||||
if (!prev) return
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type ChatBskyGroupRequestJoin} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
@@ -10,7 +9,7 @@ export function useRequestJoinGroupChat({
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (data: ChatBskyGroupRequestJoin.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.group.requestJoin.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
} = {}) {
|
||||
const client = useChatClient()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type ChatBskyConvoGetUnreadCounts} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
@@ -94,10 +93,12 @@ export function useUpdateAllRead(
|
||||
// zero out the badge count query that actually drives the unread badge,
|
||||
// since it's a separate server query that the list caches don't feed
|
||||
const prevUnreadCountsQueries =
|
||||
queryClient.getQueriesData<ChatBskyConvoGetUnreadCounts.OutputSchema>({
|
||||
queryKey: UNREAD_COUNTS_PARTIAL_KEY,
|
||||
})
|
||||
queryClient.setQueriesData<ChatBskyConvoGetUnreadCounts.OutputSchema>(
|
||||
queryClient.getQueriesData<chat.bsky.convo.getUnreadCounts.$OutputBody>(
|
||||
{
|
||||
queryKey: UNREAD_COUNTS_PARTIAL_KEY,
|
||||
},
|
||||
)
|
||||
queryClient.setQueriesData<chat.bsky.convo.getUnreadCounts.$OutputBody>(
|
||||
{queryKey: UNREAD_COUNTS_PARTIAL_KEY},
|
||||
old => {
|
||||
if (!old) return old
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import {
|
||||
type ChatBskyConvoDefs,
|
||||
type ChatBskyConvoListConvos,
|
||||
} from '@atproto/api'
|
||||
import {
|
||||
type InfiniteData,
|
||||
type QueryClient,
|
||||
@@ -10,15 +6,16 @@ import {
|
||||
|
||||
import {RQKEY as CONVO_KEY} from '../conversation'
|
||||
import {RQKEY_ROOT as CONVO_LIST_KEY} from '../list-conversations'
|
||||
import {chat} from '#/lexicons'
|
||||
|
||||
type ConvoUpdater = (
|
||||
prev: ChatBskyConvoDefs.ConvoView,
|
||||
) => ChatBskyConvoDefs.ConvoView | undefined
|
||||
prev: chat.bsky.convo.defs.ConvoView,
|
||||
) => chat.bsky.convo.defs.ConvoView | undefined
|
||||
|
||||
export type ConvoCacheSnapshot = {
|
||||
prevConvo: ChatBskyConvoDefs.ConvoView | undefined
|
||||
prevConvo: chat.bsky.convo.defs.ConvoView | undefined
|
||||
prevListEntries: Array<
|
||||
[QueryKey, InfiniteData<ChatBskyConvoListConvos.OutputSchema> | undefined]
|
||||
[QueryKey, InfiniteData<chat.bsky.convo.listConvos.$OutputBody> | undefined]
|
||||
>
|
||||
}
|
||||
|
||||
@@ -34,14 +31,14 @@ export function updateConvoOptimistic(
|
||||
convoId: string,
|
||||
updater: ConvoUpdater,
|
||||
): ConvoCacheSnapshot {
|
||||
const prevConvo = queryClient.getQueryData<ChatBskyConvoDefs.ConvoView>(
|
||||
const prevConvo = queryClient.getQueryData<chat.bsky.convo.defs.ConvoView>(
|
||||
CONVO_KEY(convoId),
|
||||
)
|
||||
const prevListEntries = queryClient.getQueriesData<
|
||||
InfiniteData<ChatBskyConvoListConvos.OutputSchema>
|
||||
InfiniteData<chat.bsky.convo.listConvos.$OutputBody>
|
||||
>({queryKey: [CONVO_LIST_KEY]})
|
||||
|
||||
queryClient.setQueryData<ChatBskyConvoDefs.ConvoView>(
|
||||
queryClient.setQueryData<chat.bsky.convo.defs.ConvoView>(
|
||||
CONVO_KEY(convoId),
|
||||
prev => {
|
||||
if (!prev) return
|
||||
@@ -51,7 +48,7 @@ export function updateConvoOptimistic(
|
||||
)
|
||||
|
||||
queryClient.setQueriesData<
|
||||
InfiniteData<ChatBskyConvoListConvos.OutputSchema>
|
||||
InfiniteData<chat.bsky.convo.listConvos.$OutputBody>
|
||||
>({queryKey: [CONVO_LIST_KEY]}, prev => {
|
||||
if (!prev?.pages) return
|
||||
return {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type ChatBskyGroupWithdrawJoinRequest} from '@atproto/api'
|
||||
import {useMutation, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {logger} from '#/logger'
|
||||
@@ -14,7 +13,7 @@ export function useWithdrawJoinGroupChatRequest({
|
||||
onSuccess,
|
||||
onError,
|
||||
}: {
|
||||
onSuccess?: (data: ChatBskyGroupWithdrawJoinRequest.OutputSchema) => void
|
||||
onSuccess?: (data: chat.bsky.group.withdrawJoinRequest.$OutputBody) => void
|
||||
onError?: (error: Error) => void
|
||||
} = {}) {
|
||||
const client = useChatClient()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {
|
||||
type InfiniteData,
|
||||
type QueryClient,
|
||||
@@ -37,7 +36,7 @@ export function useMyBlockedAccountsQuery() {
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileView, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileView, void> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.graph.getBlocks.$OutputBody>
|
||||
>({
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyGraphDefs} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {type QueryClient, useQuery} from '@tanstack/react-query'
|
||||
|
||||
@@ -19,11 +18,11 @@ export const RQKEY = (filter: MyListsFilter) => [RQKEY_ROOT, filter]
|
||||
export function useMyListsQuery(filter: MyListsFilter) {
|
||||
const {currentAccount} = useSession()
|
||||
const client = useAppviewClient()
|
||||
return useQuery<AppBskyGraphDefs.ListView[]>({
|
||||
return useQuery<app.bsky.graph.defs.ListView[]>({
|
||||
staleTime: STALE.MINUTES.ONE,
|
||||
queryKey: RQKEY(filter),
|
||||
async queryFn() {
|
||||
let lists: AppBskyGraphDefs.ListView[] = []
|
||||
let lists: app.bsky.graph.defs.ListView[] = []
|
||||
const promises = [
|
||||
accumulate(cursor =>
|
||||
client
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {
|
||||
type InfiniteData,
|
||||
type QueryClient,
|
||||
@@ -37,7 +36,7 @@ export function useMyMutedAccountsQuery() {
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileView, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileView, void> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.graph.getMutes.$OutputBody>
|
||||
>({
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import {type AppBskyNotificationListNotifications} from '@atproto/api'
|
||||
import {describe, expect, it, jest} from '@jest/globals'
|
||||
|
||||
import {groupNotifications} from '../util'
|
||||
import {app} from '#/lexicons'
|
||||
|
||||
jest.mock('#/state/queries/profile', () => ({precacheProfile: jest.fn()}))
|
||||
|
||||
type Notification = AppBskyNotificationListNotifications.Notification
|
||||
type Notification = app.bsky.notification.listNotifications.Notification
|
||||
|
||||
function makeFollowNotification(
|
||||
did: string,
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
|
||||
import {useCallback, useEffect, useMemo, useRef} from 'react'
|
||||
import {AppBskyFeedDefs, AppBskyFeedPost, AtUri} from '@atproto/api'
|
||||
import {
|
||||
type InfiniteData,
|
||||
type QueryClient,
|
||||
@@ -26,12 +25,14 @@ import {
|
||||
useQueryClient,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {app} from '#/lexicons'
|
||||
import {moderatePost} from '#/lib/moderation/subjects'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {STALE} from '#/state/queries'
|
||||
import {useAppviewClient} from '#/state/session'
|
||||
import {useThreadgateHiddenReplyUris} from '#/state/threadgate-hidden-replies'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {
|
||||
didOrHandleUriMatches,
|
||||
embedViewRecordToPostView,
|
||||
@@ -195,7 +196,9 @@ export function useNotificationFeedQuery(opts: {
|
||||
* a `$type` field on the `subject`. But if the nested
|
||||
* `record` is a post, we know it's a post view.
|
||||
*/
|
||||
if (AppBskyFeedPost.isRecord(item.subject?.record)) {
|
||||
if (
|
||||
bsky.isType(app.bsky.feed.post, item.subject?.record)
|
||||
) {
|
||||
const mod = moderatePost(item.subject, moderationOpts!)
|
||||
if (mod.ui('contentList').filter) {
|
||||
return false
|
||||
@@ -272,7 +275,7 @@ export function useNotificationFeedQuery(opts: {
|
||||
export function* findAllPostsInQueryData(
|
||||
queryClient: QueryClient,
|
||||
uri: string,
|
||||
): Generator<AppBskyFeedDefs.PostView, void> {
|
||||
): Generator<app.bsky.feed.defs.PostView, void> {
|
||||
const atUri = new AtUri(uri)
|
||||
|
||||
const queryDatas = queryClient.getQueriesData<InfiniteData<FeedPage>>({
|
||||
@@ -291,7 +294,7 @@ export function* findAllPostsInQueryData(
|
||||
}
|
||||
}
|
||||
|
||||
if (AppBskyFeedDefs.isPostView(item.subject)) {
|
||||
if (bsky.isType(app.bsky.feed.defs.postView, item.subject)) {
|
||||
const quotedPost = getEmbeddedPost(item.subject?.embed)
|
||||
if (quotedPost && didOrHandleUriMatches(atUri, quotedPost)) {
|
||||
yield embedViewRecordToPostView(quotedPost)
|
||||
@@ -329,7 +332,7 @@ export function* findAllProfilesInQueryData(
|
||||
) {
|
||||
yield item.subject.author
|
||||
}
|
||||
if (AppBskyFeedDefs.isPostView(item.subject)) {
|
||||
if (bsky.isType(app.bsky.feed.defs.postView, item.subject)) {
|
||||
const quotedPost = getEmbeddedPost(item.subject?.embed)
|
||||
if (quotedPost?.author.did === did) {
|
||||
yield quotedPost.author
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
import {
|
||||
type AppBskyNotificationDefs,
|
||||
type ChatBskyNotificationDefs,
|
||||
} from '@atproto/api'
|
||||
import {t} from '@lingui/core/macro'
|
||||
import {
|
||||
type QueryClient,
|
||||
@@ -24,18 +20,18 @@ const RQKEY_CHAT = [RQKEY_ROOT, 'chat']
|
||||
// fetched and cached separately. This combined type names every preference for
|
||||
// the generic settings dialog, but it is never the shape of a query response.
|
||||
export type NotificationSettingsPreferences = Omit<
|
||||
AppBskyNotificationDefs.Preferences,
|
||||
app.bsky.notification.defs.Preferences,
|
||||
'chat'
|
||||
> &
|
||||
Partial<Pick<ChatBskyNotificationDefs.Preferences, 'chat' | 'chatRequest'>>
|
||||
Partial<Pick<chat.bsky.notification.defs.Preferences, 'chat' | 'chatRequest'>>
|
||||
|
||||
export type AppNotificationSettingsPreferences = Omit<
|
||||
AppBskyNotificationDefs.Preferences,
|
||||
app.bsky.notification.defs.Preferences,
|
||||
'chat'
|
||||
>
|
||||
|
||||
export type ChatNotificationSettingsPreferences = Pick<
|
||||
ChatBskyNotificationDefs.Preferences,
|
||||
chat.bsky.notification.defs.Preferences,
|
||||
'chat' | 'chatRequest'
|
||||
>
|
||||
|
||||
@@ -45,9 +41,9 @@ export type NotificationSettingsPreferenceName = Exclude<
|
||||
>
|
||||
|
||||
export type NotificationSettingsPreference =
|
||||
| AppBskyNotificationDefs.Preference
|
||||
| AppBskyNotificationDefs.FilterablePreference
|
||||
| ChatBskyNotificationDefs.ChatPreference
|
||||
| app.bsky.notification.defs.Preference
|
||||
| app.bsky.notification.defs.FilterablePreference
|
||||
| chat.bsky.notification.defs.ChatPreference
|
||||
|
||||
export function isChatPreferenceName(
|
||||
name: NotificationSettingsPreferenceName,
|
||||
@@ -58,7 +54,7 @@ export function isChatPreferenceName(
|
||||
type NotificationSettingsUpdate = Partial<NotificationSettingsPreferences>
|
||||
|
||||
type AppNotificationSettingsUpdate = Partial<
|
||||
Omit<AppBskyNotificationDefs.Preferences, '$type' | 'chat'>
|
||||
Omit<app.bsky.notification.defs.Preferences, '$type' | 'chat'>
|
||||
>
|
||||
|
||||
type ChatNotificationSettingsUpdate =
|
||||
@@ -159,15 +155,15 @@ function optimisticUpdateNotificationSettings(
|
||||
}
|
||||
|
||||
function appPreferencesWithoutChat(
|
||||
preferences: AppBskyNotificationDefs.Preferences,
|
||||
): Omit<AppBskyNotificationDefs.Preferences, 'chat'> {
|
||||
preferences: app.bsky.notification.defs.Preferences,
|
||||
): Omit<app.bsky.notification.defs.Preferences, 'chat'> {
|
||||
const {chat: _ignoredChat, ...appPreferences} = preferences
|
||||
return appPreferences
|
||||
}
|
||||
|
||||
function chatPreferencesForSettings(
|
||||
preferences: ChatBskyNotificationDefs.Preferences,
|
||||
): Pick<ChatBskyNotificationDefs.Preferences, 'chat' | 'chatRequest'> {
|
||||
preferences: chat.bsky.notification.defs.Preferences,
|
||||
): Pick<chat.bsky.notification.defs.Preferences, 'chat' | 'chatRequest'> {
|
||||
return {
|
||||
chat: preferences.chat,
|
||||
chatRequest: preferences.chatRequest,
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import {
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyGraphDefs,
|
||||
type AppBskyNotificationListNotifications,
|
||||
} from '@atproto/api'
|
||||
import {app} from '#/lexicons'
|
||||
|
||||
export type NotificationType =
|
||||
| StarterPackNotificationType
|
||||
@@ -11,11 +7,11 @@ export type NotificationType =
|
||||
export type FeedNotification =
|
||||
| (FeedNotificationBase & {
|
||||
type: StarterPackNotificationType
|
||||
subject?: AppBskyGraphDefs.StarterPackViewBasic
|
||||
subject?: app.bsky.graph.defs.StarterPackViewBasic
|
||||
})
|
||||
| (FeedNotificationBase & {
|
||||
type: OtherNotificationType
|
||||
subject?: AppBskyFeedDefs.PostView
|
||||
subject?: app.bsky.feed.defs.PostView
|
||||
})
|
||||
|
||||
export interface FeedPage {
|
||||
@@ -54,8 +50,10 @@ type OtherNotificationType =
|
||||
|
||||
type FeedNotificationBase = {
|
||||
_reactKey: string
|
||||
notification: AppBskyNotificationListNotifications.Notification
|
||||
additional?: AppBskyNotificationListNotifications.Notification[]
|
||||
notification: app.bsky.notification.listNotifications.Notification
|
||||
additional?: app.bsky.notification.listNotifications.Notification[]
|
||||
subjectUri?: string
|
||||
subject?: AppBskyFeedDefs.PostView | AppBskyGraphDefs.StarterPackViewBasic
|
||||
subject?:
|
||||
| app.bsky.feed.defs.PostView
|
||||
| app.bsky.graph.defs.StarterPackViewBasic
|
||||
}
|
||||
|
||||
@@ -1,12 +1,3 @@
|
||||
import {
|
||||
type AppBskyFeedDefs,
|
||||
AppBskyFeedLike,
|
||||
AppBskyFeedPost,
|
||||
AppBskyFeedRepost,
|
||||
type AppBskyGraphDefs,
|
||||
AppBskyGraphStarterpack,
|
||||
type AppBskyNotificationListNotifications,
|
||||
} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {type AtUriString} from '@atproto/syntax'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
@@ -117,7 +108,7 @@ export async function fetchPage({
|
||||
// =
|
||||
|
||||
export function shouldFilterNotif(
|
||||
notif: AppBskyNotificationListNotifications.Notification,
|
||||
notif: app.bsky.notification.listNotifications.Notification,
|
||||
moderationOpts: ModerationOpts | undefined,
|
||||
): boolean {
|
||||
const containsImperative = !!notif.author.labels?.some(labelIsHideableOffense)
|
||||
@@ -129,10 +120,7 @@ export function shouldFilterNotif(
|
||||
}
|
||||
if (
|
||||
notif.reason === 'subscribed-post' &&
|
||||
bsky.dangerousIsType<AppBskyFeedPost.Record>(
|
||||
notif.record,
|
||||
AppBskyFeedPost.isRecord,
|
||||
) &&
|
||||
bsky.isType(app.bsky.feed.post, notif.record) &&
|
||||
hasMutedWord({
|
||||
mutedWords: moderationOpts.prefs.mutedWords,
|
||||
text: notif.record.text,
|
||||
@@ -151,7 +139,7 @@ export function shouldFilterNotif(
|
||||
}
|
||||
|
||||
export function groupNotifications(
|
||||
notifs: AppBskyNotificationListNotifications.Notification[],
|
||||
notifs: app.bsky.notification.listNotifications.Notification[],
|
||||
): FeedNotification[] {
|
||||
const groupedNotifs: FeedNotification[] = []
|
||||
for (const notif of notifs) {
|
||||
@@ -211,8 +199,8 @@ async function fetchSubjects(
|
||||
client: Client,
|
||||
groupedNotifs: FeedNotification[],
|
||||
): Promise<{
|
||||
posts: Map<string, AppBskyFeedDefs.PostView>
|
||||
starterPacks: Map<string, AppBskyGraphDefs.StarterPackViewBasic>
|
||||
posts: Map<string, app.bsky.feed.defs.PostView>
|
||||
starterPacks: Map<string, app.bsky.graph.defs.StarterPackViewBasic>
|
||||
}> {
|
||||
const postUris = new Set<string>()
|
||||
const packUris = new Set<string>()
|
||||
@@ -243,15 +231,15 @@ async function fetchSubjects(
|
||||
.then(data => data.starterPacks),
|
||||
),
|
||||
)
|
||||
const postsMap = new Map<string, AppBskyFeedDefs.PostView>()
|
||||
const packsMap = new Map<string, AppBskyGraphDefs.StarterPackViewBasic>()
|
||||
const postsMap = new Map<string, app.bsky.feed.defs.PostView>()
|
||||
const packsMap = new Map<string, app.bsky.graph.defs.StarterPackViewBasic>()
|
||||
for (const post of postsChunks.flat()) {
|
||||
if (AppBskyFeedPost.isRecord(post.record)) {
|
||||
if (bsky.isType(app.bsky.feed.post, post.record)) {
|
||||
postsMap.set(post.uri, post)
|
||||
}
|
||||
}
|
||||
for (const pack of packsChunks.flat()) {
|
||||
if (AppBskyGraphStarterpack.isRecord(pack.record)) {
|
||||
if (bsky.isType(app.bsky.graph.starterpack, pack.record)) {
|
||||
packsMap.set(pack.uri, pack)
|
||||
}
|
||||
}
|
||||
@@ -262,7 +250,7 @@ async function fetchSubjects(
|
||||
}
|
||||
|
||||
function toKnownType(
|
||||
notif: AppBskyNotificationListNotifications.Notification,
|
||||
notif: app.bsky.notification.listNotifications.Notification,
|
||||
): NotificationType {
|
||||
if (notif.reason === 'like') {
|
||||
if (notif.reasonSubject?.includes('feed.generator')) {
|
||||
@@ -291,7 +279,7 @@ function toKnownType(
|
||||
|
||||
function getSubjectUri(
|
||||
type: NotificationType,
|
||||
notif: AppBskyNotificationListNotifications.Notification,
|
||||
notif: app.bsky.notification.listNotifications.Notification,
|
||||
): string | undefined {
|
||||
if (
|
||||
type === 'reply' ||
|
||||
@@ -307,14 +295,8 @@ function getSubjectUri(
|
||||
type === 'repost-via-repost'
|
||||
) {
|
||||
if (
|
||||
bsky.dangerousIsType<AppBskyFeedRepost.Record>(
|
||||
notif.record,
|
||||
AppBskyFeedRepost.isRecord,
|
||||
) ||
|
||||
bsky.dangerousIsType<AppBskyFeedLike.Record>(
|
||||
notif.record,
|
||||
AppBskyFeedLike.isRecord,
|
||||
)
|
||||
bsky.isType(app.bsky.feed.repost, notif.record) ||
|
||||
bsky.isType(app.bsky.feed.like, notif.record)
|
||||
) {
|
||||
return typeof notif.record.subject?.uri === 'string'
|
||||
? notif.record.subject?.uri
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {app} from '#/lexicons'
|
||||
|
||||
export type Data = Record<string, unknown> | undefined
|
||||
|
||||
export type BaseNux<
|
||||
T extends Pick<AppBskyActorDefs.Nux, 'id' | 'expiresAt'> & {data: Data},
|
||||
> = Pick<AppBskyActorDefs.Nux, 'id' | 'completed' | 'expiresAt'> & T
|
||||
T extends Pick<app.bsky.actor.defs.Nux, 'id' | 'expiresAt'> & {data: Data},
|
||||
> = Pick<app.bsky.actor.defs.Nux, 'id' | 'completed' | 'expiresAt'> & T
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {type AppBskyActorDefs, nuxSchema} from '@atproto/api'
|
||||
import {nuxSchema} from '@bsky.app/sdk/utils'
|
||||
|
||||
import {
|
||||
type AppNux,
|
||||
@@ -6,8 +6,9 @@ import {
|
||||
nuxNames,
|
||||
NuxSchemas,
|
||||
} from '#/state/queries/nuxs/definitions'
|
||||
import {type app} from '#/lexicons'
|
||||
|
||||
export function parseAppNux(nux: AppBskyActorDefs.Nux): AppNux | undefined {
|
||||
export function parseAppNux(nux: app.bsky.actor.defs.Nux): AppNux | undefined {
|
||||
if (!nuxNames.has(nux.id as Nux)) return
|
||||
if (!nuxSchema.safeParse(nux).success) return
|
||||
|
||||
@@ -32,11 +33,11 @@ export function parseAppNux(nux: AppBskyActorDefs.Nux): AppNux | undefined {
|
||||
} as AppNux
|
||||
}
|
||||
|
||||
export function serializeAppNux(nux: AppNux): AppBskyActorDefs.Nux {
|
||||
export function serializeAppNux(nux: AppNux): app.bsky.actor.defs.Nux {
|
||||
const {data, ...rest} = nux
|
||||
const schema = NuxSchemas[nux.id]
|
||||
|
||||
const result: AppBskyActorDefs.Nux = {
|
||||
const result: app.bsky.actor.defs.Nux = {
|
||||
...rest,
|
||||
data: undefined,
|
||||
}
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
import {useCallback, useEffect, useMemo, useRef} from 'react'
|
||||
import {AppState} from 'react-native'
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
AppBskyFeedDefs,
|
||||
type AppBskyFeedPost,
|
||||
AtUri,
|
||||
} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {type AtIdentifierString, type AtUriString} from '@atproto/syntax'
|
||||
import {type AtIdentifierString, type AtUriString, AtUri} from '@atproto/syntax'
|
||||
import {
|
||||
type ModerationDecision,
|
||||
type ModerationPrefs,
|
||||
@@ -19,6 +13,8 @@ import {
|
||||
useInfiniteQuery,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {app} from '#/lexicons'
|
||||
import {AuthorFeedAPI} from '#/lib/api/feed/author'
|
||||
import {CustomFeedAPI} from '#/lib/api/feed/custom'
|
||||
import {DemoFeedAPI} from '#/lib/api/feed/demo'
|
||||
@@ -83,10 +79,10 @@ export function RQKEY(feedDesc: FeedDescriptor, params?: FeedParams) {
|
||||
export interface FeedPostSliceItem {
|
||||
_reactKey: string
|
||||
uri: string
|
||||
post: AppBskyFeedDefs.PostView
|
||||
record: AppBskyFeedPost.Record
|
||||
post: app.bsky.feed.defs.PostView
|
||||
record: app.bsky.feed.post.Main
|
||||
moderation: ModerationDecision
|
||||
parentAuthor?: AppBskyActorDefs.ProfileViewBasic
|
||||
parentAuthor?: app.bsky.actor.defs.ProfileViewBasic
|
||||
isParentBlocked?: boolean
|
||||
isParentNotFound?: boolean
|
||||
}
|
||||
@@ -101,8 +97,8 @@ export interface FeedPostSlice {
|
||||
reqId: string | undefined
|
||||
feedPostUri: string
|
||||
reason?:
|
||||
| AppBskyFeedDefs.ReasonRepost
|
||||
| AppBskyFeedDefs.ReasonPin
|
||||
| app.bsky.feed.defs.ReasonRepost
|
||||
| app.bsky.feed.defs.ReasonPin
|
||||
| ReasonFeedSource
|
||||
| {[k: string]: unknown; $type: string}
|
||||
}
|
||||
@@ -110,7 +106,7 @@ export interface FeedPostSlice {
|
||||
export interface FeedPageUnselected {
|
||||
api: FeedAPI
|
||||
cursor: string | undefined
|
||||
feed: AppBskyFeedDefs.FeedViewPost[]
|
||||
feed: app.bsky.feed.defs.FeedViewPost[]
|
||||
fetchedAt: number
|
||||
}
|
||||
|
||||
@@ -515,7 +511,7 @@ function createApi({
|
||||
export function* findAllPostsInQueryData(
|
||||
queryClient: QueryClient,
|
||||
uri: string,
|
||||
): Generator<AppBskyFeedDefs.PostView, undefined> {
|
||||
): Generator<app.bsky.feed.defs.PostView, undefined> {
|
||||
const atUri = new AtUri(uri)
|
||||
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
@@ -538,7 +534,7 @@ export function* findAllPostsInQueryData(
|
||||
yield embedViewRecordToPostView(quotedPost)
|
||||
}
|
||||
|
||||
if (AppBskyFeedDefs.isPostView(item.reply?.parent)) {
|
||||
if (bsky.isType(app.bsky.feed.defs.postView, item.reply?.parent)) {
|
||||
if (didOrHandleUriMatches(atUri, item.reply.parent)) {
|
||||
yield item.reply.parent
|
||||
}
|
||||
@@ -552,7 +548,7 @@ export function* findAllPostsInQueryData(
|
||||
}
|
||||
}
|
||||
|
||||
if (AppBskyFeedDefs.isPostView(item.reply?.root)) {
|
||||
if (bsky.isType(app.bsky.feed.defs.postView, item.reply?.root)) {
|
||||
if (didOrHandleUriMatches(atUri, item.reply.root)) {
|
||||
yield item.reply.root
|
||||
}
|
||||
@@ -570,7 +566,7 @@ export function* findAllPostsInQueryData(
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileViewBasic, undefined> {
|
||||
): Generator<app.bsky.actor.defs.ProfileViewBasic, undefined> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<FeedPageUnselected>
|
||||
>({
|
||||
@@ -590,13 +586,13 @@ export function* findAllProfilesInQueryData(
|
||||
yield quotedPost.author
|
||||
}
|
||||
if (
|
||||
AppBskyFeedDefs.isPostView(item.reply?.parent) &&
|
||||
bsky.isType(app.bsky.feed.defs.postView, item.reply?.parent) &&
|
||||
item.reply?.parent?.author.did === did
|
||||
) {
|
||||
yield item.reply.parent.author
|
||||
}
|
||||
if (
|
||||
AppBskyFeedDefs.isPostView(item.reply?.root) &&
|
||||
bsky.isType(app.bsky.feed.defs.postView, item.reply?.root) &&
|
||||
item.reply?.root?.author.did === did
|
||||
) {
|
||||
yield item.reply.root.author
|
||||
@@ -607,7 +603,7 @@ export function* findAllProfilesInQueryData(
|
||||
}
|
||||
|
||||
function assertSomePostsPassModeration(
|
||||
feed: AppBskyFeedDefs.FeedViewPost[],
|
||||
feed: app.bsky.feed.defs.FeedViewPost[],
|
||||
moderationPrefs: ModerationPrefs,
|
||||
) {
|
||||
// no posts in this feed
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type AtUriString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
@@ -83,7 +82,7 @@ export function useLikedBySampleQuery({uri}: {uri: string | undefined}) {
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileView, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileView, void> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.feed.getLikes.$OutputBody>
|
||||
>({
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
AppBskyEmbedRecord,
|
||||
type AppBskyFeedDefs,
|
||||
AtUri,
|
||||
} from '@atproto/api'
|
||||
import {type AtUriString} from '@atproto/syntax'
|
||||
import {type AtUriString, AtUri} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
type QueryClient,
|
||||
@@ -12,6 +6,7 @@ import {
|
||||
useInfiniteQuery,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {useAppviewClient} from '#/state/session'
|
||||
import {app} from '#/lexicons'
|
||||
import {
|
||||
@@ -54,8 +49,16 @@ export function usePostQuotesQuery(resolvedUri: string | undefined) {
|
||||
return {
|
||||
...page,
|
||||
posts: page.posts.filter(post => {
|
||||
if (post.embed && AppBskyEmbedRecord.isView(post.embed)) {
|
||||
if (AppBskyEmbedRecord.isViewDetached(post.embed.record)) {
|
||||
if (
|
||||
post.embed &&
|
||||
bsky.isType(app.bsky.embed.record.view, post.embed)
|
||||
) {
|
||||
if (
|
||||
bsky.isType(
|
||||
app.bsky.embed.record.viewDetached,
|
||||
post.embed.record,
|
||||
)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -71,7 +74,7 @@ export function usePostQuotesQuery(resolvedUri: string | undefined) {
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileViewBasic, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileViewBasic, void> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.feed.getQuotes.$OutputBody>
|
||||
>({
|
||||
@@ -98,7 +101,7 @@ export function* findAllProfilesInQueryData(
|
||||
export function* findAllPostsInQueryData(
|
||||
queryClient: QueryClient,
|
||||
uri: string,
|
||||
): Generator<AppBskyFeedDefs.PostView, undefined> {
|
||||
): Generator<app.bsky.feed.defs.PostView, undefined> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.feed.getQuotes.$OutputBody>
|
||||
>({
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type AtUriString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
@@ -44,7 +43,7 @@ export function usePostRepostedByQuery(resolvedUri: string | undefined) {
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileView, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileView, void> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.feed.getRepostedBy.$OutputBody>
|
||||
>({
|
||||
|
||||
+13
-14
@@ -1,7 +1,6 @@
|
||||
import {useCallback} from 'react'
|
||||
import {type AppBskyActorDefs, type AppBskyFeedDefs, AtUri} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {type AtUriString, type HandleString} from '@atproto/syntax'
|
||||
import {type AtUriString, type HandleString, AtUri} from '@atproto/syntax'
|
||||
import {deleteLike, deletePost, deleteRepost, like, repost} from '@bsky.app/sdk'
|
||||
import {
|
||||
type QueryClient,
|
||||
@@ -26,7 +25,7 @@ export const RQKEY = (postUri: string) => [RQKEY_ROOT, postUri]
|
||||
|
||||
export function usePostQuery(uri: string | undefined) {
|
||||
const client = useAppviewClient()
|
||||
return useQuery<AppBskyFeedDefs.PostView>({
|
||||
return useQuery<app.bsky.feed.defs.PostView>({
|
||||
queryKey: RQKEY(uri || ''),
|
||||
queryFn: async () => {
|
||||
if (!uri) throw new Error('[unreachable] No URI provided')
|
||||
@@ -53,7 +52,7 @@ export function usePostQuery(uri: string | undefined) {
|
||||
async function fetchPost(
|
||||
client: Client,
|
||||
uri: string,
|
||||
): Promise<AppBskyFeedDefs.PostView | undefined> {
|
||||
): Promise<app.bsky.feed.defs.PostView | undefined> {
|
||||
const urip = new AtUri(uri)
|
||||
|
||||
if (!urip.host.startsWith('did:')) {
|
||||
@@ -72,7 +71,7 @@ async function fetchPost(
|
||||
export function precachePost(
|
||||
queryClient: QueryClient,
|
||||
uri: string,
|
||||
post: AppBskyFeedDefs.PostView,
|
||||
post: app.bsky.feed.defs.PostView,
|
||||
) {
|
||||
queryClient.setQueryData(RQKEY(uri), post)
|
||||
}
|
||||
@@ -110,7 +109,7 @@ export function useGetPosts() {
|
||||
uris: uris as AtUriString[],
|
||||
})
|
||||
// See the note on `fetchPost` about the view shapes.
|
||||
return data.posts as AppBskyFeedDefs.PostView[]
|
||||
return data.posts as app.bsky.feed.defs.PostView[]
|
||||
},
|
||||
})
|
||||
},
|
||||
@@ -119,7 +118,7 @@ export function useGetPosts() {
|
||||
}
|
||||
|
||||
export function usePostLikeMutationQueue(
|
||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||
post: Shadow<app.bsky.feed.defs.PostView>,
|
||||
viaRepost: {uri: string; cid: string} | undefined,
|
||||
feedDescriptor: string | undefined,
|
||||
logContext: Metrics['post:like']['logContext'],
|
||||
@@ -183,7 +182,7 @@ export function usePostLikeMutationQueue(
|
||||
function usePostLikeMutation(
|
||||
feedDescriptor: string | undefined,
|
||||
logContext: Metrics['post:like']['logContext'],
|
||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||
post: Shadow<app.bsky.feed.defs.PostView>,
|
||||
) {
|
||||
const {currentAccount} = useSession()
|
||||
const queryClient = useQueryClient()
|
||||
@@ -196,7 +195,7 @@ function usePostLikeMutation(
|
||||
{uri: string; cid: string; via?: {uri: string; cid: string}} // the post's uri and cid, and the repost uri/cid if present
|
||||
>({
|
||||
mutationFn: ({uri, cid, via}) => {
|
||||
let ownProfile: AppBskyActorDefs.ProfileViewDetailed | undefined
|
||||
let ownProfile: app.bsky.actor.defs.ProfileViewDetailed | undefined
|
||||
if (currentAccount) {
|
||||
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
|
||||
}
|
||||
@@ -231,7 +230,7 @@ function usePostLikeMutation(
|
||||
function usePostUnlikeMutation(
|
||||
feedDescriptor: string | undefined,
|
||||
logContext: Metrics['post:unlike']['logContext'],
|
||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||
post: Shadow<app.bsky.feed.defs.PostView>,
|
||||
) {
|
||||
const pdsClient = usePdsClient()
|
||||
const ax = useAnalytics()
|
||||
@@ -249,7 +248,7 @@ function usePostUnlikeMutation(
|
||||
}
|
||||
|
||||
export function usePostRepostMutationQueue(
|
||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||
post: Shadow<app.bsky.feed.defs.PostView>,
|
||||
viaRepost: {uri: string; cid: string} | undefined,
|
||||
feedDescriptor: string | undefined,
|
||||
logContext: Metrics['post:repost']['logContext'],
|
||||
@@ -315,7 +314,7 @@ export function usePostRepostMutationQueue(
|
||||
function usePostRepostMutation(
|
||||
feedDescriptor: string | undefined,
|
||||
logContext: Metrics['post:repost']['logContext'],
|
||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||
post: Shadow<app.bsky.feed.defs.PostView>,
|
||||
) {
|
||||
const pdsClient = usePdsClient()
|
||||
const ax = useAnalytics()
|
||||
@@ -343,7 +342,7 @@ function usePostRepostMutation(
|
||||
function usePostUnrepostMutation(
|
||||
feedDescriptor: string | undefined,
|
||||
logContext: Metrics['post:unrepost']['logContext'],
|
||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||
post: Shadow<app.bsky.feed.defs.PostView>,
|
||||
) {
|
||||
const pdsClient = usePdsClient()
|
||||
const ax = useAnalytics()
|
||||
@@ -374,7 +373,7 @@ export function usePostDeleteMutation() {
|
||||
}
|
||||
|
||||
export function useThreadMuteMutationQueue(
|
||||
post: Shadow<AppBskyFeedDefs.PostView>,
|
||||
post: Shadow<app.bsky.feed.defs.PostView>,
|
||||
rootUri: string,
|
||||
) {
|
||||
const threadMuteMutation = useThreadMuteMutation()
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
import {useRef} from 'react'
|
||||
import {
|
||||
AppBskyEmbedRecord,
|
||||
AppBskyEmbedRecordWithMedia,
|
||||
type AppBskyFeedDefs,
|
||||
} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {AtUri, type HandleString} from '@atproto/syntax'
|
||||
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
@@ -173,7 +168,7 @@ export function useToggleQuoteDetachmentMutation() {
|
||||
const pdsClient = usePdsClient()
|
||||
const queryClient = useQueryClient()
|
||||
const getPosts = useGetPosts()
|
||||
const prevEmbed = useRef<AppBskyFeedDefs.PostView['embed']>(undefined)
|
||||
const prevEmbed = useRef<app.bsky.feed.defs.PostView['embed']>(undefined)
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async ({
|
||||
@@ -181,7 +176,7 @@ export function useToggleQuoteDetachmentMutation() {
|
||||
quoteUri,
|
||||
action,
|
||||
}: {
|
||||
post: AppBskyFeedDefs.PostView
|
||||
post: app.bsky.feed.defs.PostView
|
||||
quoteUri: string
|
||||
action: 'detach' | 'reattach'
|
||||
}) => {
|
||||
@@ -247,8 +242,8 @@ export function useToggleQuoteDetachmentMutation() {
|
||||
if (action === 'detach' && prevEmbed.current) {
|
||||
// detach failed, add the embed back
|
||||
if (
|
||||
AppBskyEmbedRecord.isView(prevEmbed.current) ||
|
||||
AppBskyEmbedRecordWithMedia.isView(prevEmbed.current)
|
||||
bsky.isType(app.bsky.embed.record.view, prevEmbed.current) ||
|
||||
bsky.isType(app.bsky.embed.recordWithMedia.view, prevEmbed.current)
|
||||
) {
|
||||
updatePostShadow(queryClient, post.uri, {
|
||||
embed: prevEmbed.current,
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import {
|
||||
type $Typed,
|
||||
AppBskyEmbedRecord,
|
||||
AppBskyEmbedRecordWithMedia,
|
||||
type AppBskyFeedDefs,
|
||||
AtUri,
|
||||
} from '@atproto/api'
|
||||
import {type AtUriString, toDatetimeString} from '@atproto/syntax'
|
||||
import {type AtUriString, toDatetimeString, AtUri} from '@atproto/syntax'
|
||||
|
||||
import {type app} from '#/lexicons'
|
||||
import {type $Typed} from '@atproto/lex'
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {app} from '#/lexicons'
|
||||
|
||||
export const POSTGATE_COLLECTION = 'app.bsky.feed.postgate'
|
||||
|
||||
@@ -64,8 +59,8 @@ export function createEmbedViewDetachedRecord({
|
||||
uri,
|
||||
}: {
|
||||
uri: string
|
||||
}): $Typed<AppBskyEmbedRecord.View> {
|
||||
const record: $Typed<AppBskyEmbedRecord.ViewDetached> = {
|
||||
}): $Typed<app.bsky.embed.record.View> {
|
||||
const record: $Typed<app.bsky.embed.record.ViewDetached> = {
|
||||
$type: 'app.bsky.embed.record#viewDetached',
|
||||
uri,
|
||||
detached: true,
|
||||
@@ -83,24 +78,27 @@ export function createMaybeDetachedQuoteEmbed({
|
||||
detached,
|
||||
}:
|
||||
| {
|
||||
post: AppBskyFeedDefs.PostView
|
||||
quote: AppBskyFeedDefs.PostView
|
||||
post: app.bsky.feed.defs.PostView
|
||||
quote: app.bsky.feed.defs.PostView
|
||||
quoteUri: undefined
|
||||
detached: false
|
||||
}
|
||||
| {
|
||||
post: AppBskyFeedDefs.PostView
|
||||
post: app.bsky.feed.defs.PostView
|
||||
quote: undefined
|
||||
quoteUri: string
|
||||
detached: true
|
||||
}): AppBskyEmbedRecord.View | AppBskyEmbedRecordWithMedia.View | undefined {
|
||||
if (AppBskyEmbedRecord.isView(post.embed)) {
|
||||
}):
|
||||
| app.bsky.embed.record.View
|
||||
| app.bsky.embed.recordWithMedia.View
|
||||
| undefined {
|
||||
if (bsky.isType(app.bsky.embed.record.view, post.embed)) {
|
||||
if (detached) {
|
||||
return createEmbedViewDetachedRecord({uri: quoteUri})
|
||||
} else {
|
||||
return createEmbedRecordView({post: quote})
|
||||
}
|
||||
} else if (AppBskyEmbedRecordWithMedia.isView(post.embed)) {
|
||||
} else if (bsky.isType(app.bsky.embed.recordWithMedia.view, post.embed)) {
|
||||
if (detached) {
|
||||
return {
|
||||
...post.embed,
|
||||
@@ -113,8 +111,8 @@ export function createMaybeDetachedQuoteEmbed({
|
||||
}
|
||||
|
||||
export function createEmbedViewRecordFromPost(
|
||||
post: AppBskyFeedDefs.PostView,
|
||||
): $Typed<AppBskyEmbedRecord.ViewRecord> {
|
||||
post: app.bsky.feed.defs.PostView,
|
||||
): $Typed<app.bsky.embed.record.ViewRecord> {
|
||||
return {
|
||||
$type: 'app.bsky.embed.record#viewRecord',
|
||||
uri: post.uri,
|
||||
@@ -134,8 +132,8 @@ export function createEmbedViewRecordFromPost(
|
||||
export function createEmbedRecordView({
|
||||
post,
|
||||
}: {
|
||||
post: AppBskyFeedDefs.PostView
|
||||
}): AppBskyEmbedRecord.View {
|
||||
post: app.bsky.feed.defs.PostView
|
||||
}): app.bsky.embed.record.View {
|
||||
return {
|
||||
$type: 'app.bsky.embed.record#view',
|
||||
record: createEmbedViewRecordFromPost(post),
|
||||
@@ -146,10 +144,10 @@ export function createEmbedRecordWithMediaView({
|
||||
post,
|
||||
quote,
|
||||
}: {
|
||||
post: AppBskyFeedDefs.PostView
|
||||
quote: AppBskyFeedDefs.PostView
|
||||
}): AppBskyEmbedRecordWithMedia.View | undefined {
|
||||
if (!AppBskyEmbedRecordWithMedia.isView(post.embed)) return
|
||||
post: app.bsky.feed.defs.PostView
|
||||
quote: app.bsky.feed.defs.PostView
|
||||
}): app.bsky.embed.recordWithMedia.View | undefined {
|
||||
if (!bsky.isType(app.bsky.embed.recordWithMedia.view, post.embed)) return
|
||||
return {
|
||||
...(post.embed || {}),
|
||||
record: {
|
||||
@@ -163,11 +161,11 @@ export function getMaybeDetachedQuoteEmbed({
|
||||
post,
|
||||
}: {
|
||||
viewerDid: string
|
||||
post: AppBskyFeedDefs.PostView
|
||||
post: app.bsky.feed.defs.PostView
|
||||
}) {
|
||||
if (AppBskyEmbedRecord.isView(post.embed)) {
|
||||
if (bsky.isType(app.bsky.embed.record.view, post.embed)) {
|
||||
// detached
|
||||
if (AppBskyEmbedRecord.isViewDetached(post.embed.record)) {
|
||||
if (bsky.isType(app.bsky.embed.record.viewDetached, post.embed.record)) {
|
||||
const urip = new AtUri(post.embed.record.uri)
|
||||
return {
|
||||
embed: post.embed,
|
||||
@@ -178,7 +176,7 @@ export function getMaybeDetachedQuoteEmbed({
|
||||
}
|
||||
|
||||
// post
|
||||
if (AppBskyEmbedRecord.isViewRecord(post.embed.record)) {
|
||||
if (bsky.isType(app.bsky.embed.record.viewRecord, post.embed.record)) {
|
||||
const urip = new AtUri(post.embed.record.uri)
|
||||
return {
|
||||
embed: post.embed,
|
||||
@@ -187,9 +185,11 @@ export function getMaybeDetachedQuoteEmbed({
|
||||
isDetached: false,
|
||||
}
|
||||
}
|
||||
} else if (AppBskyEmbedRecordWithMedia.isView(post.embed)) {
|
||||
} else if (bsky.isType(app.bsky.embed.recordWithMedia.view, post.embed)) {
|
||||
// detached
|
||||
if (AppBskyEmbedRecord.isViewDetached(post.embed.record.record)) {
|
||||
if (
|
||||
bsky.isType(app.bsky.embed.record.viewDetached, post.embed.record.record)
|
||||
) {
|
||||
const urip = new AtUri(post.embed.record.record.uri)
|
||||
return {
|
||||
embed: post.embed,
|
||||
@@ -200,7 +200,9 @@ export function getMaybeDetachedQuoteEmbed({
|
||||
}
|
||||
|
||||
// post
|
||||
if (AppBskyEmbedRecord.isViewRecord(post.embed.record.record)) {
|
||||
if (
|
||||
bsky.isType(app.bsky.embed.record.viewRecord, post.embed.record.record)
|
||||
) {
|
||||
const urip = new AtUri(post.embed.record.record.uri)
|
||||
return {
|
||||
embed: post.embed,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {useCallback} from 'react'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {
|
||||
addSavedFeeds,
|
||||
@@ -278,7 +277,7 @@ export function useOverwriteSavedFeedsMutation() {
|
||||
const queryClient = useQueryClient()
|
||||
const client = usePdsClient()
|
||||
|
||||
return useMutation<void, unknown, AppBskyActorDefs.SavedFeed[]>({
|
||||
return useMutation<void, unknown, app.bsky.actor.defs.SavedFeed[]>({
|
||||
mutationFn: async savedFeeds => {
|
||||
await client.call(overwriteSavedFeeds, savedFeeds)
|
||||
// triggers a refetch
|
||||
@@ -296,7 +295,7 @@ export function useAddSavedFeedsMutation() {
|
||||
return useMutation<
|
||||
void,
|
||||
unknown,
|
||||
Pick<AppBskyActorDefs.SavedFeed, 'type' | 'value' | 'pinned'>[]
|
||||
Pick<app.bsky.actor.defs.SavedFeed, 'type' | 'value' | 'pinned'>[]
|
||||
>({
|
||||
mutationFn: async savedFeeds => {
|
||||
await client.call(addSavedFeeds, savedFeeds)
|
||||
@@ -312,7 +311,7 @@ export function useRemoveFeedMutation() {
|
||||
const queryClient = useQueryClient()
|
||||
const client = usePdsClient()
|
||||
|
||||
return useMutation<void, unknown, Pick<AppBskyActorDefs.SavedFeed, 'id'>>({
|
||||
return useMutation<void, unknown, Pick<app.bsky.actor.defs.SavedFeed, 'id'>>({
|
||||
mutationFn: async savedFeed => {
|
||||
await client.call(removeSavedFeeds, [savedFeed.id])
|
||||
// triggers a refetch
|
||||
@@ -332,8 +331,8 @@ export function useReplaceForYouWithDiscoverFeedMutation() {
|
||||
forYouFeedConfig,
|
||||
discoverFeedConfig,
|
||||
}: {
|
||||
forYouFeedConfig: AppBskyActorDefs.SavedFeed | undefined
|
||||
discoverFeedConfig: AppBskyActorDefs.SavedFeed | undefined
|
||||
forYouFeedConfig: app.bsky.actor.defs.SavedFeed | undefined
|
||||
discoverFeedConfig: app.bsky.actor.defs.SavedFeed | undefined
|
||||
}) => {
|
||||
if (forYouFeedConfig) {
|
||||
await client.call(removeSavedFeeds, [forYouFeedConfig.id])
|
||||
@@ -366,7 +365,7 @@ export function useUpdateSavedFeedsMutation() {
|
||||
const queryClient = useQueryClient()
|
||||
const client = usePdsClient()
|
||||
|
||||
return useMutation<void, unknown, AppBskyActorDefs.SavedFeed[]>({
|
||||
return useMutation<void, unknown, app.bsky.actor.defs.SavedFeed[]>({
|
||||
mutationFn: async feeds => {
|
||||
await client.call(updateSavedFeeds, feeds)
|
||||
|
||||
@@ -477,7 +476,7 @@ export function useSetActiveProgressGuideMutation() {
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (
|
||||
guide: AppBskyActorDefs.BskyAppProgressGuide | undefined,
|
||||
guide: app.bsky.actor.defs.BskyAppProgressGuide | undefined,
|
||||
) => {
|
||||
await client.call(setActiveProgressGuide, guide)
|
||||
// triggers a refetch
|
||||
@@ -508,7 +507,7 @@ export function useSetVerificationPrefsMutation() {
|
||||
const queryClient = useQueryClient()
|
||||
const client = usePdsClient()
|
||||
|
||||
return useMutation<void, unknown, AppBskyActorDefs.VerificationPrefs>({
|
||||
return useMutation<void, unknown, app.bsky.actor.defs.VerificationPrefs>({
|
||||
mutationFn: async prefs => {
|
||||
await client.call(setVerificationPrefs, prefs)
|
||||
if (prefs.hideBadges) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {useCallback, useMemo, useRef, useState} from 'react'
|
||||
import {type AppBskyUnspeccedGetPostThreadV2} from '@atproto/api'
|
||||
import {useFocusEffect} from '@react-navigation/native'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
import {app} from '#/lexicons'
|
||||
import {useCallOnce} from '#/lib/once'
|
||||
import {
|
||||
usePreferencesQuery,
|
||||
@@ -13,7 +13,7 @@ import {useAnalytics} from '#/analytics'
|
||||
import {type Literal} from '#/types/utils'
|
||||
|
||||
export type ThreadSortOption = Literal<
|
||||
AppBskyUnspeccedGetPostThreadV2.QueryParams['sort'],
|
||||
app.bsky.unspecced.getPostThreadV2.$Params['sort'],
|
||||
string
|
||||
>
|
||||
export type ThreadViewOption = 'linear' | 'tree'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
@@ -67,7 +66,7 @@ export function useProfileFollowersQuery(
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileView, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileView, void> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.graph.getFollowers.$OutputBody>
|
||||
>({
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
@@ -72,7 +71,7 @@ export function useProfileFollowsQuery(
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileView, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileView, void> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.graph.getFollows.$OutputBody>
|
||||
>({
|
||||
|
||||
@@ -1,18 +1,11 @@
|
||||
import {useCallback} from 'react'
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
type AppBskyActorGetProfile,
|
||||
type AppBskyActorGetProfiles,
|
||||
type AppBskyGraphGetFollows,
|
||||
AtUri,
|
||||
type Un$Typed,
|
||||
} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {type Client, type Un$Typed} from '@atproto/lex'
|
||||
import {
|
||||
type AtIdentifierString,
|
||||
type AtUriString,
|
||||
type DidString,
|
||||
toDatetimeString,
|
||||
AtUri,
|
||||
} from '@atproto/syntax'
|
||||
import {
|
||||
deleteFollow,
|
||||
@@ -82,7 +75,7 @@ export function useProfileQuery({
|
||||
}) {
|
||||
const client = useAppviewClient()
|
||||
const {getUnstableProfile} = useUnstableProfileViewCache()
|
||||
return useQuery<AppBskyActorDefs.ProfileViewDetailed>({
|
||||
return useQuery<app.bsky.actor.defs.ProfileViewDetailed>({
|
||||
// WARNING
|
||||
// this staleTime is load-bearing
|
||||
// if you remove it, the UI infinite-loops
|
||||
@@ -97,7 +90,7 @@ export function useProfileQuery({
|
||||
},
|
||||
placeholderData: () => {
|
||||
if (!did) return
|
||||
return getUnstableProfile(did) as AppBskyActorDefs.ProfileViewDetailed
|
||||
return getUnstableProfile(did) as app.bsky.actor.defs.ProfileViewDetailed
|
||||
},
|
||||
enabled: !!did,
|
||||
})
|
||||
@@ -145,7 +138,7 @@ export function usePrefetchProfileQuery() {
|
||||
}
|
||||
|
||||
interface ProfileUpdateParams {
|
||||
profile: AppBskyActorDefs.ProfileViewDetailed
|
||||
profile: app.bsky.actor.defs.ProfileViewDetailed
|
||||
updates:
|
||||
| Un$Typed<app.bsky.actor.profile.Main>
|
||||
| ((
|
||||
@@ -153,7 +146,7 @@ interface ProfileUpdateParams {
|
||||
) => Un$Typed<app.bsky.actor.profile.Main>)
|
||||
newUserAvatar?: ImageMeta | undefined | null
|
||||
newUserBanner?: ImageMeta | undefined | null
|
||||
checkCommitted?: (res: AppBskyActorGetProfile.Response) => boolean
|
||||
checkCommitted?: (res: app.bsky.actor.getProfile.Response) => boolean
|
||||
}
|
||||
export function useProfileUpdateMutation() {
|
||||
const queryClient = useQueryClient()
|
||||
@@ -303,7 +296,7 @@ export function useProfileFollowMutationQueue(
|
||||
// Optimistically update profile follows cache for avatar displays
|
||||
if (currentAccount?.did) {
|
||||
type FollowsQueryData =
|
||||
InfiniteData<AppBskyGraphGetFollows.OutputSchema>
|
||||
InfiniteData<app.bsky.graph.getFollows.$OutputBody>
|
||||
queryClient.setQueryData<FollowsQueryData>(
|
||||
PROFILE_FOLLOWS_RQKEY(currentAccount.did),
|
||||
old => {
|
||||
@@ -320,7 +313,7 @@ export function useProfileFollowMutationQueue(
|
||||
{
|
||||
...old.pages[0],
|
||||
follows: [
|
||||
profile as AppBskyActorDefs.ProfileView,
|
||||
profile as app.bsky.actor.defs.ProfileView,
|
||||
...old.pages[0].follows,
|
||||
],
|
||||
},
|
||||
@@ -390,7 +383,7 @@ function useProfileFollowMutation(
|
||||
|
||||
return useMutation<{uri: string; cid: string}, Error, {did: string}>({
|
||||
mutationFn: async ({did}) => {
|
||||
let ownProfile: AppBskyActorDefs.ProfileViewDetailed | undefined
|
||||
let ownProfile: app.bsky.actor.defs.ProfileViewDetailed | undefined
|
||||
if (currentAccount) {
|
||||
ownProfile = findProfileQueryData(queryClient, currentAccount.did)
|
||||
}
|
||||
@@ -686,7 +679,7 @@ function useProfileUnblockMutation() {
|
||||
async function whenAppViewReady(
|
||||
client: Client,
|
||||
actor: string,
|
||||
fn: (res: AppBskyActorGetProfile.Response) => boolean,
|
||||
fn: (res: app.bsky.actor.getProfile.Response) => boolean,
|
||||
) {
|
||||
await until(
|
||||
5, // 5 tries
|
||||
@@ -709,9 +702,9 @@ async function whenAppViewReady(
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileViewDetailed, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileViewDetailed, void> {
|
||||
const profileQueryDatas =
|
||||
queryClient.getQueriesData<AppBskyActorDefs.ProfileViewDetailed>({
|
||||
queryClient.getQueriesData<app.bsky.actor.defs.ProfileViewDetailed>({
|
||||
queryKey: [RQKEY_ROOT],
|
||||
})
|
||||
for (const [_queryKey, queryData] of profileQueryDatas) {
|
||||
@@ -723,7 +716,7 @@ export function* findAllProfilesInQueryData(
|
||||
}
|
||||
}
|
||||
const profilesQueryDatas =
|
||||
queryClient.getQueriesData<AppBskyActorGetProfiles.OutputSchema>({
|
||||
queryClient.getQueriesData<app.bsky.actor.getProfiles.$OutputBody>({
|
||||
queryKey: [profilesQueryKeyRoot],
|
||||
})
|
||||
for (const [_queryKey, queryData] of profilesQueryDatas) {
|
||||
@@ -741,8 +734,8 @@ export function* findAllProfilesInQueryData(
|
||||
export function findProfileQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): AppBskyActorDefs.ProfileViewDetailed | undefined {
|
||||
return queryClient.getQueryData<AppBskyActorDefs.ProfileViewDetailed>(
|
||||
): app.bsky.actor.defs.ProfileViewDetailed | undefined {
|
||||
return queryClient.getQueryData<app.bsky.actor.defs.ProfileViewDetailed>(
|
||||
RQKEY(did),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import {AtUri} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {type HandleString} from '@atproto/syntax'
|
||||
import {type HandleString, AtUri} from '@atproto/syntax'
|
||||
import {type QueryClient, queryOptions, useQuery} from '@tanstack/react-query'
|
||||
|
||||
import {STALE} from '#/state/queries'
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import {app} from '#/lexicons'
|
||||
/*
|
||||
* Pure helpers for lifting structured `app.bsky.feed.searchPosts` params out of
|
||||
* a free-text query. Kept free of React Native imports so it can be unit
|
||||
* tested in isolation (the search-posts query hook re-exports these).
|
||||
*/
|
||||
|
||||
import {type AppBskyFeedSearchPostsV2} from '@atproto/api'
|
||||
|
||||
import {
|
||||
filtersToApiParams,
|
||||
type SearchFilters,
|
||||
@@ -204,9 +203,9 @@ function mergeList(a?: string[], b?: string[]): string[] | undefined {
|
||||
export function buildSearchPostsV2Filters(
|
||||
embedded: Omit<ExtractedSearchParams, 'q'>,
|
||||
filters?: SearchFilters,
|
||||
): AppBskyFeedSearchPostsV2.QueryParams {
|
||||
): app.bsky.feed.searchPostsV2.$Params {
|
||||
const apiFilters = filters ? filtersToApiParams(filters) : {}
|
||||
const params: AppBskyFeedSearchPostsV2.QueryParams = {}
|
||||
const params: app.bsky.feed.searchPostsV2.$Params = {}
|
||||
|
||||
const authors = mergeList(
|
||||
embedded.author ? [embedded.author] : undefined,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {useCallback, useMemo, useRef} from 'react'
|
||||
import {type AppBskyFeedDefs, AtUri} from '@atproto/api'
|
||||
import {
|
||||
type InfiniteData,
|
||||
type QueryClient,
|
||||
@@ -7,6 +6,7 @@ import {
|
||||
useInfiniteQuery,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {moderatePost} from '#/lib/moderation/subjects'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {useAppviewClient} from '#/state/session'
|
||||
@@ -180,7 +180,7 @@ export function useSearchPostsV2Query({
|
||||
export function* findAllPostsInQueryData(
|
||||
queryClient: QueryClient,
|
||||
uri: string,
|
||||
): Generator<AppBskyFeedDefs.PostView, undefined> {
|
||||
): Generator<app.bsky.feed.defs.PostView, undefined> {
|
||||
const queryDatas = queryClient.getQueriesData<
|
||||
InfiniteData<app.bsky.feed.searchPostsV2.$OutputBody>
|
||||
>({
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
import {
|
||||
AppBskyFeedDefs,
|
||||
AppBskyGraphDefs,
|
||||
AppBskyGraphStarterpack,
|
||||
} from '@atproto/api'
|
||||
import {type Client, type LexValue} from '@atproto/lex'
|
||||
import {AtUri, type AtUriString, toDatetimeString} from '@atproto/syntax'
|
||||
import {RichText} from '@bsky.app/sdk/richtext'
|
||||
@@ -57,7 +52,7 @@ export function useStarterPackQuery({
|
||||
}) {
|
||||
const client = useAppviewClient()
|
||||
|
||||
return useQuery<AppBskyGraphDefs.StarterPackView>({
|
||||
return useQuery<app.bsky.graph.defs.StarterPackView>({
|
||||
queryKey: RQKEY(uri ? {uri} : {did, rkey}),
|
||||
queryFn: async () => {
|
||||
if (!uri) {
|
||||
@@ -92,7 +87,7 @@ interface UseCreateStarterPackMutationParams {
|
||||
name: string
|
||||
description?: string
|
||||
profiles: bsky.profile.AnyProfileView[]
|
||||
feeds?: AppBskyFeedDefs.GeneratorView[]
|
||||
feeds?: app.bsky.feed.defs.GeneratorView[]
|
||||
}
|
||||
|
||||
export function useCreateStarterPackMutation({
|
||||
@@ -173,8 +168,8 @@ export function useEditStarterPackMutation({
|
||||
void,
|
||||
Error,
|
||||
UseCreateStarterPackMutationParams & {
|
||||
currentStarterPack: AppBskyGraphDefs.StarterPackView
|
||||
currentListItems: AppBskyGraphDefs.ListItemView[]
|
||||
currentStarterPack: app.bsky.graph.defs.StarterPackView
|
||||
currentListItems: app.bsky.graph.defs.ListItemView[]
|
||||
}
|
||||
>({
|
||||
mutationFn: async ({
|
||||
@@ -373,33 +368,33 @@ async function whenAppViewReady(
|
||||
export function precacheStarterPack(
|
||||
queryClient: QueryClient,
|
||||
starterPack:
|
||||
| AppBskyGraphDefs.StarterPackViewBasic
|
||||
| AppBskyGraphDefs.StarterPackView,
|
||||
| app.bsky.graph.defs.StarterPackViewBasic
|
||||
| app.bsky.graph.defs.StarterPackView,
|
||||
) {
|
||||
if (!AppBskyGraphStarterpack.isRecord(starterPack.record)) {
|
||||
if (!bsky.isType(app.bsky.graph.starterpack, starterPack.record)) {
|
||||
return
|
||||
}
|
||||
|
||||
let starterPackView: AppBskyGraphDefs.StarterPackView | undefined
|
||||
if (AppBskyGraphDefs.isStarterPackView(starterPack)) {
|
||||
let starterPackView: app.bsky.graph.defs.StarterPackView | undefined
|
||||
if (bsky.isType(app.bsky.graph.defs.starterPackView, starterPack)) {
|
||||
starterPackView = starterPack
|
||||
} else if (
|
||||
AppBskyGraphDefs.isStarterPackViewBasic(starterPack) &&
|
||||
bsky.validate(starterPack.record, AppBskyGraphStarterpack.validateRecord)
|
||||
bsky.isType(app.bsky.graph.defs.starterPackViewBasic, starterPack) &&
|
||||
bsky.matches(app.bsky.graph.starterpack, starterPack.record)
|
||||
) {
|
||||
let feeds: AppBskyFeedDefs.GeneratorView[] | undefined
|
||||
let feeds: app.bsky.feed.defs.GeneratorView[] | undefined
|
||||
if (starterPack.record.feeds) {
|
||||
feeds = []
|
||||
for (const feed of starterPack.record.feeds) {
|
||||
// note: types are wrong? claims to be `FeedItem`, but we actually
|
||||
// get un$typed `GeneratorView` objects here -sfn
|
||||
if (bsky.validate(feed, AppBskyFeedDefs.validateGeneratorView)) {
|
||||
if (bsky.matches(app.bsky.feed.defs.generatorView, feed)) {
|
||||
feeds.push(feed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const listView: AppBskyGraphDefs.ListViewBasic = {
|
||||
const listView: app.bsky.graph.defs.ListViewBasic = {
|
||||
uri: starterPack.record.list,
|
||||
// This will be populated once the data from server is fetched
|
||||
cid: '',
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {useCallback, useMemo} from 'react'
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type DidString} from '@atproto/syntax'
|
||||
import {
|
||||
type InfiniteData,
|
||||
@@ -103,7 +102,7 @@ export function useSuggestedFollowsByActorWithDismiss({
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileView, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileView, void> {
|
||||
yield* findAllProfilesInSuggestedFollowsQueryData(queryClient, did)
|
||||
yield* findAllProfilesInSuggestedFollowsByActorQueryData(queryClient, did)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {type Client} from '@atproto/lex'
|
||||
import {AtUri, type HandleString} from '@atproto/syntax'
|
||||
import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'
|
||||
@@ -67,7 +66,7 @@ export function useThreadgateViewQuery({
|
||||
initialData,
|
||||
}: {
|
||||
postUri?: string
|
||||
initialData?: AppBskyFeedDefs.ThreadgateView
|
||||
initialData?: app.bsky.feed.defs.ThreadgateView
|
||||
} = {}) {
|
||||
const getPost = useGetPost()
|
||||
|
||||
@@ -248,7 +247,7 @@ export function useSetThreadgateAllowMutation() {
|
||||
})
|
||||
},
|
||||
async onSuccess(_, {postUri, allow}) {
|
||||
const data = await retry<AppBskyFeedDefs.ThreadgateView | undefined>(
|
||||
const data = await retry<app.bsky.feed.defs.ThreadgateView | undefined>(
|
||||
5, // 5 tries
|
||||
_e => true,
|
||||
async () => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
import {type AtUriString, toDatetimeString} from '@atproto/syntax'
|
||||
|
||||
import {type ThreadgateAllowUISetting} from '#/state/queries/threadgate/types'
|
||||
@@ -12,7 +11,7 @@ import * as bsky from '#/types/bsky'
|
||||
* through `com.atproto.repo.putRecord`, whose body is typed as a lex `LexMap`.
|
||||
*/
|
||||
export function threadgateViewToAllowUISetting(
|
||||
threadgateView: AppBskyFeedDefs.ThreadgateView | undefined,
|
||||
threadgateView: app.bsky.feed.defs.ThreadgateView | undefined,
|
||||
): ThreadgateAllowUISetting[] {
|
||||
// Validate the record for clarity, since backwards compat code is a little confusing
|
||||
const threadgate =
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
import {app} from '#/lexicons'
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
import {type AppBskyUnspeccedGetPostThreadV2} from '@atproto/api'
|
||||
|
||||
/**
|
||||
* See the `below` param on {@link AppBskyUnspeccedGetPostThreadV2.QueryParams}
|
||||
* See the `below` param on {@link app.bsky.unspecced.getPostThreadV2.$Params}
|
||||
*/
|
||||
export const LINEAR_VIEW_BELOW = 10
|
||||
|
||||
/**
|
||||
* See the `branchingFactor` param on {@link AppBskyUnspeccedGetPostThreadV2.QueryParams}
|
||||
* See the `branchingFactor` param on {@link app.bsky.unspecced.getPostThreadV2.$Params}
|
||||
*/
|
||||
export const LINEAR_VIEW_BF = 1
|
||||
|
||||
/**
|
||||
* See the `below` param on {@link AppBskyUnspeccedGetPostThreadV2.QueryParams}
|
||||
* See the `below` param on {@link app.bsky.unspecced.getPostThreadV2.$Params}
|
||||
*/
|
||||
export const TREE_VIEW_BELOW = 4
|
||||
|
||||
/**
|
||||
* See the `branchingFactor` param on {@link AppBskyUnspeccedGetPostThreadV2.QueryParams}
|
||||
* See the `branchingFactor` param on {@link app.bsky.unspecced.getPostThreadV2.$Params}
|
||||
*/
|
||||
export const TREE_VIEW_BF = undefined
|
||||
|
||||
/**
|
||||
* See the `below` param on {@link AppBskyUnspeccedGetPostThreadV2.QueryParams}
|
||||
* See the `below` param on {@link app.bsky.unspecced.getPostThreadV2.$Params}
|
||||
*/
|
||||
export const TREE_VIEW_BELOW_DESKTOP = 6
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
import {useCallback} from 'react'
|
||||
import {
|
||||
type $Typed,
|
||||
type AppBskyActorDefs,
|
||||
type AppBskyFeedDefs,
|
||||
AppBskyUnspeccedDefs,
|
||||
type AppBskyUnspeccedGetPostThreadOtherV2,
|
||||
type AppBskyUnspeccedGetPostThreadV2,
|
||||
AtUri,
|
||||
} from '@atproto/api'
|
||||
import {type QueryClient, useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {
|
||||
dangerousGetPostShadow,
|
||||
updatePostShadow,
|
||||
} from '#/state/cache/post-shadow'
|
||||
import {type $Typed} from '@atproto/lex'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {app} from '#/lexicons'
|
||||
import {findAllPostsInQueryData as findAllPostsInBookmarksQueryData} from '#/state/queries/bookmarks/useBookmarksQuery'
|
||||
import {findAllPostsInQueryData as findAllPostsInExploreFeedPreviewsQueryData} from '#/state/queries/explore-feed-previews'
|
||||
import {findAllPostsInQueryData as findAllPostsInNotifsQueryData} from '#/state/queries/notifications/feed'
|
||||
@@ -51,18 +46,18 @@ export function createCacheMutator({
|
||||
return {
|
||||
insertReplies(
|
||||
parentUri: string,
|
||||
replies: AppBskyUnspeccedGetPostThreadV2.ThreadItem[],
|
||||
replies: app.bsky.unspecced.getPostThreadV2.ThreadItem[],
|
||||
) {
|
||||
/*
|
||||
* Main thread query mutator.
|
||||
*/
|
||||
queryClient.setQueryData<AppBskyUnspeccedGetPostThreadV2.OutputSchema>(
|
||||
queryClient.setQueryData<app.bsky.unspecced.getPostThreadV2.$OutputBody>(
|
||||
postThreadQueryKey,
|
||||
data => {
|
||||
if (!data) return
|
||||
return {
|
||||
...data,
|
||||
thread: mutator<AppBskyUnspeccedGetPostThreadV2.ThreadItem>([
|
||||
thread: mutator<app.bsky.unspecced.getPostThreadV2.ThreadItem>([
|
||||
...data.thread,
|
||||
]),
|
||||
}
|
||||
@@ -72,15 +67,15 @@ export function createCacheMutator({
|
||||
/*
|
||||
* Additional replies query mutator.
|
||||
*/
|
||||
queryClient.setQueryData<AppBskyUnspeccedGetPostThreadOtherV2.OutputSchema>(
|
||||
queryClient.setQueryData<app.bsky.unspecced.getPostThreadOtherV2.$OutputBody>(
|
||||
postThreadOtherQueryKey,
|
||||
data => {
|
||||
if (!data) return
|
||||
return {
|
||||
...data,
|
||||
thread: mutator<AppBskyUnspeccedGetPostThreadOtherV2.ThreadItem>([
|
||||
...data.thread,
|
||||
]),
|
||||
thread: mutator<app.bsky.unspecced.getPostThreadOtherV2.ThreadItem>(
|
||||
[...data.thread],
|
||||
),
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -89,7 +84,10 @@ export function createCacheMutator({
|
||||
for (let i = 0; i < thread.length; i++) {
|
||||
const parent = thread[i]
|
||||
|
||||
if (!AppBskyUnspeccedDefs.isThreadItemPost(parent.value)) continue
|
||||
if (
|
||||
!bsky.isType(app.bsky.unspecced.defs.threadItemPost, parent.value)
|
||||
)
|
||||
continue
|
||||
if (parent.uri !== parentUri) continue
|
||||
|
||||
/*
|
||||
@@ -124,7 +122,8 @@ export function createCacheMutator({
|
||||
const isParentRoot = parent.depth === 0
|
||||
const isParentBelowRoot = parent.depth > 0
|
||||
const optimisticReply = replies.at(0)
|
||||
const opIsReplier = AppBskyUnspeccedDefs.isThreadItemPost(
|
||||
const opIsReplier = bsky.isType(
|
||||
app.bsky.unspecced.defs.threadItemPost,
|
||||
optimisticReply?.value,
|
||||
)
|
||||
? opDid === optimisticReply.value.post.author.did
|
||||
@@ -172,8 +171,8 @@ export function createCacheMutator({
|
||||
* Unused atm, post shadow does the trick, but it would be nice to clean up
|
||||
* the whole sub-tree on deletes.
|
||||
*/
|
||||
deletePost(post: AppBskyUnspeccedGetPostThreadV2.ThreadItem) {
|
||||
queryClient.setQueryData<AppBskyUnspeccedGetPostThreadV2.OutputSchema>(
|
||||
deletePost(post: app.bsky.unspecced.getPostThreadV2.ThreadItem) {
|
||||
queryClient.setQueryData<app.bsky.unspecced.getPostThreadV2.$OutputBody>(
|
||||
postThreadQueryKey,
|
||||
queryData => {
|
||||
if (!queryData) return
|
||||
@@ -182,7 +181,10 @@ export function createCacheMutator({
|
||||
|
||||
for (let i = 0; i < thread.length; i++) {
|
||||
const existingPost = thread[i]
|
||||
if (!AppBskyUnspeccedDefs.isThreadItemPost(post.value)) continue
|
||||
if (
|
||||
!bsky.isType(app.bsky.unspecced.defs.threadItemPost, post.value)
|
||||
)
|
||||
continue
|
||||
|
||||
if (existingPost.uri === post.uri) {
|
||||
const branch = getBranch(thread, i, existingPost.depth)
|
||||
@@ -204,7 +206,7 @@ export function createCacheMutator({
|
||||
export function getThreadPlaceholder(
|
||||
queryClient: QueryClient,
|
||||
uri: string,
|
||||
): $Typed<AppBskyUnspeccedGetPostThreadV2.ThreadItem> | void {
|
||||
): $Typed<app.bsky.unspecced.getPostThreadV2.ThreadItem> | void {
|
||||
let partial
|
||||
for (let item of getThreadPlaceholderCandidates(queryClient, uri)) {
|
||||
/*
|
||||
@@ -231,8 +233,8 @@ export function* getThreadPlaceholderCandidates(
|
||||
uri: string,
|
||||
): Generator<
|
||||
$Typed<
|
||||
Omit<AppBskyUnspeccedGetPostThreadV2.ThreadItem, 'value'> & {
|
||||
value: $Typed<AppBskyUnspeccedDefs.ThreadItemPost>
|
||||
Omit<app.bsky.unspecced.getPostThreadV2.ThreadItem, 'value'> & {
|
||||
value: $Typed<app.bsky.unspecced.defs.ThreadItemPost>
|
||||
}
|
||||
>,
|
||||
void
|
||||
@@ -276,10 +278,10 @@ export function* getThreadPlaceholderCandidates(
|
||||
export function* findAllPostsInQueryData(
|
||||
queryClient: QueryClient,
|
||||
uri: string,
|
||||
): Generator<AppBskyFeedDefs.PostView, void> {
|
||||
): Generator<app.bsky.feed.defs.PostView, void> {
|
||||
const atUri = new AtUri(uri)
|
||||
const queryDatas =
|
||||
queryClient.getQueriesData<AppBskyUnspeccedGetPostThreadV2.OutputSchema>({
|
||||
queryClient.getQueriesData<app.bsky.unspecced.getPostThreadV2.$OutputBody>({
|
||||
queryKey: [postThreadQueryKeyRoot],
|
||||
})
|
||||
|
||||
@@ -289,7 +291,7 @@ export function* findAllPostsInQueryData(
|
||||
const {thread} = queryData
|
||||
|
||||
for (const item of thread) {
|
||||
if (AppBskyUnspeccedDefs.isThreadItemPost(item.value)) {
|
||||
if (bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value)) {
|
||||
if (didOrHandleUriMatches(atUri, item.value.post)) {
|
||||
yield item.value.post
|
||||
}
|
||||
@@ -306,9 +308,9 @@ export function* findAllPostsInQueryData(
|
||||
export function* findAllProfilesInQueryData(
|
||||
queryClient: QueryClient,
|
||||
did: string,
|
||||
): Generator<AppBskyActorDefs.ProfileViewBasic, void> {
|
||||
): Generator<app.bsky.actor.defs.ProfileViewBasic, void> {
|
||||
const queryDatas =
|
||||
queryClient.getQueriesData<AppBskyUnspeccedGetPostThreadV2.OutputSchema>({
|
||||
queryClient.getQueriesData<app.bsky.unspecced.getPostThreadV2.$OutputBody>({
|
||||
queryKey: [postThreadQueryKeyRoot],
|
||||
})
|
||||
|
||||
@@ -318,7 +320,7 @@ export function* findAllProfilesInQueryData(
|
||||
const {thread} = queryData
|
||||
|
||||
for (const item of thread) {
|
||||
if (AppBskyUnspeccedDefs.isThreadItemPost(item.value)) {
|
||||
if (bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value)) {
|
||||
if (item.value.post.author.did === did) {
|
||||
yield item.value.post.author
|
||||
}
|
||||
@@ -337,14 +339,15 @@ export function useUpdatePostThreadThreadgateQueryCache() {
|
||||
const context = usePostThreadContext()
|
||||
|
||||
return useCallback(
|
||||
(threadgate: AppBskyFeedDefs.ThreadgateView) => {
|
||||
(threadgate: app.bsky.feed.defs.ThreadgateView) => {
|
||||
if (!context) return
|
||||
|
||||
function mutator<T>(thread: ApiThreadItem[]): T[] {
|
||||
for (let i = 0; i < thread.length; i++) {
|
||||
const item = thread[i]
|
||||
|
||||
if (!AppBskyUnspeccedDefs.isThreadItemPost(item.value)) continue
|
||||
if (!bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value))
|
||||
continue
|
||||
|
||||
if (item.depth === 0) {
|
||||
thread.splice(i, 1, {
|
||||
@@ -363,13 +366,13 @@ export function useUpdatePostThreadThreadgateQueryCache() {
|
||||
return thread as T[]
|
||||
}
|
||||
|
||||
qc.setQueryData<AppBskyUnspeccedGetPostThreadV2.OutputSchema>(
|
||||
qc.setQueryData<app.bsky.unspecced.getPostThreadV2.$OutputBody>(
|
||||
context.postThreadQueryKey,
|
||||
data => {
|
||||
if (!data) return
|
||||
return {
|
||||
...data,
|
||||
thread: mutator<AppBskyUnspeccedGetPostThreadV2.ThreadItem>([
|
||||
thread: mutator<app.bsky.unspecced.getPostThreadV2.ThreadItem>([
|
||||
...data.thread,
|
||||
]),
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {AppBskyUnspeccedDefs} from '@atproto/api'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
|
||||
import {
|
||||
@@ -14,6 +13,8 @@ import {
|
||||
getTraversalMetadata,
|
||||
storeTraversalMetadata,
|
||||
} from '#/state/queries/usePostThread/utils'
|
||||
import * as bsky from '#/types/bsky'
|
||||
import {app} from '#/lexicons'
|
||||
import * as views from '#/state/queries/usePostThread/views'
|
||||
|
||||
export function sortAndAnnotateThreadItems(
|
||||
@@ -46,7 +47,7 @@ export function sortAndAnnotateThreadItems(
|
||||
let parentMetadata: TraversalMetadata | undefined
|
||||
let metadata: TraversalMetadata | undefined
|
||||
|
||||
if (AppBskyUnspeccedDefs.isThreadItemPost(item.value)) {
|
||||
if (bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value)) {
|
||||
parentMetadata = metadatas.get(
|
||||
getPostRecord(item.value.post).reply?.parent?.uri || '',
|
||||
)
|
||||
@@ -65,13 +66,24 @@ export function sortAndAnnotateThreadItems(
|
||||
* _up_ from there.
|
||||
*/
|
||||
} else if (item.depth === 0) {
|
||||
if (AppBskyUnspeccedDefs.isThreadItemNoUnauthenticated(item.value)) {
|
||||
if (
|
||||
bsky.isType(
|
||||
app.bsky.unspecced.defs.threadItemNoUnauthenticated,
|
||||
item.value,
|
||||
)
|
||||
) {
|
||||
threadItems.push(views.threadPostNoUnauthenticated(item))
|
||||
} else if (AppBskyUnspeccedDefs.isThreadItemNotFound(item.value)) {
|
||||
} else if (
|
||||
bsky.isType(app.bsky.unspecced.defs.threadItemNotFound, item.value)
|
||||
) {
|
||||
threadItems.push(views.threadPostNotFound(item))
|
||||
} else if (AppBskyUnspeccedDefs.isThreadItemBlocked(item.value)) {
|
||||
} else if (
|
||||
bsky.isType(app.bsky.unspecced.defs.threadItemBlocked, item.value)
|
||||
) {
|
||||
threadItems.push(views.threadPostBlocked(item))
|
||||
} else if (AppBskyUnspeccedDefs.isThreadItemPost(item.value)) {
|
||||
} else if (
|
||||
bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value)
|
||||
) {
|
||||
const post = views.threadPost({
|
||||
uri: item.uri,
|
||||
depth: item.depth,
|
||||
@@ -85,7 +97,10 @@ export function sortAndAnnotateThreadItems(
|
||||
const parent = thread[pi]
|
||||
|
||||
if (
|
||||
AppBskyUnspeccedDefs.isThreadItemNoUnauthenticated(parent.value)
|
||||
bsky.isType(
|
||||
app.bsky.unspecced.defs.threadItemNoUnauthenticated,
|
||||
parent.value,
|
||||
)
|
||||
) {
|
||||
const post = views.threadPostNoUnauthenticated(parent)
|
||||
post.ui = getThreadPostNoUnauthenticatedUI({
|
||||
@@ -97,13 +112,22 @@ export function sortAndAnnotateThreadItems(
|
||||
threadItems.unshift(post)
|
||||
// for now, break parent traversal at first no-unauthed
|
||||
break parentTraversal
|
||||
} else if (AppBskyUnspeccedDefs.isThreadItemNotFound(parent.value)) {
|
||||
} else if (
|
||||
bsky.isType(
|
||||
app.bsky.unspecced.defs.threadItemNotFound,
|
||||
parent.value,
|
||||
)
|
||||
) {
|
||||
threadItems.unshift(views.threadPostNotFound(parent))
|
||||
break parentTraversal
|
||||
} else if (AppBskyUnspeccedDefs.isThreadItemBlocked(parent.value)) {
|
||||
} else if (
|
||||
bsky.isType(app.bsky.unspecced.defs.threadItemBlocked, parent.value)
|
||||
) {
|
||||
threadItems.unshift(views.threadPostBlocked(parent))
|
||||
break parentTraversal
|
||||
} else if (AppBskyUnspeccedDefs.isThreadItemPost(parent.value)) {
|
||||
} else if (
|
||||
bsky.isType(app.bsky.unspecced.defs.threadItemPost, parent.value)
|
||||
) {
|
||||
threadItems.unshift(
|
||||
views.threadPost({
|
||||
uri: parent.uri,
|
||||
@@ -123,16 +147,21 @@ export function sortAndAnnotateThreadItems(
|
||||
* we could.
|
||||
*/
|
||||
const shouldBreak =
|
||||
AppBskyUnspeccedDefs.isThreadItemNoUnauthenticated(item.value) ||
|
||||
AppBskyUnspeccedDefs.isThreadItemNotFound(item.value) ||
|
||||
AppBskyUnspeccedDefs.isThreadItemBlocked(item.value)
|
||||
bsky.isType(
|
||||
app.bsky.unspecced.defs.threadItemNoUnauthenticated,
|
||||
item.value,
|
||||
) ||
|
||||
bsky.isType(app.bsky.unspecced.defs.threadItemNotFound, item.value) ||
|
||||
bsky.isType(app.bsky.unspecced.defs.threadItemBlocked, item.value)
|
||||
|
||||
if (shouldBreak) {
|
||||
const branch = getBranch(thread, i, item.depth)
|
||||
// could insert tombstone
|
||||
i = branch.end
|
||||
continue traversal
|
||||
} else if (AppBskyUnspeccedDefs.isThreadItemPost(item.value)) {
|
||||
} else if (
|
||||
bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value)
|
||||
) {
|
||||
if (parentMetadata) {
|
||||
/*
|
||||
* Set this value before incrementing the `repliesSeenCounter` later
|
||||
@@ -180,7 +209,9 @@ export function sortAndAnnotateThreadItems(
|
||||
for (let ci = startIndex; ci <= branch.end; ci++) {
|
||||
const child = thread[ci]
|
||||
|
||||
if (AppBskyUnspeccedDefs.isThreadItemPost(child.value)) {
|
||||
if (
|
||||
bsky.isType(app.bsky.unspecced.defs.threadItemPost, child.value)
|
||||
) {
|
||||
const childParentMetadata = metadatas.get(
|
||||
getPostRecord(child.value.post).reply?.parent?.uri || '',
|
||||
)
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
import {
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyFeedPost,
|
||||
type AppBskyFeedThreadgate,
|
||||
type AppBskyUnspeccedDefs,
|
||||
type AppBskyUnspeccedGetPostThreadOtherV2,
|
||||
type AppBskyUnspeccedGetPostThreadV2,
|
||||
} from '@atproto/api'
|
||||
import {type ModerationDecision} from '@bsky.app/sdk/moderation'
|
||||
import {app} from '#/lexicons'
|
||||
|
||||
export type ApiThreadItem =
|
||||
| AppBskyUnspeccedGetPostThreadV2.ThreadItem
|
||||
| AppBskyUnspeccedGetPostThreadOtherV2.ThreadItem
|
||||
| app.bsky.unspecced.getPostThreadV2.ThreadItem
|
||||
| app.bsky.unspecced.getPostThreadOtherV2.ThreadItem
|
||||
|
||||
export const postThreadQueryKeyRoot = 'post-thread-v2' as const
|
||||
|
||||
@@ -18,13 +11,13 @@ export const createPostThreadQueryKey = (props: PostThreadParams) =>
|
||||
[postThreadQueryKeyRoot, props] as const
|
||||
|
||||
export const createPostThreadOtherQueryKey = (
|
||||
props: Omit<AppBskyUnspeccedGetPostThreadOtherV2.QueryParams, 'anchor'> & {
|
||||
props: Omit<app.bsky.unspecced.getPostThreadOtherV2.$Params, 'anchor'> & {
|
||||
anchor?: string
|
||||
},
|
||||
) => [postThreadQueryKeyRoot, 'other', props] as const
|
||||
|
||||
export type PostThreadParams = Pick<
|
||||
AppBskyUnspeccedGetPostThreadV2.QueryParams,
|
||||
app.bsky.unspecced.getPostThreadV2.$Params,
|
||||
'sort'
|
||||
> & {
|
||||
anchor?: string
|
||||
@@ -33,9 +26,9 @@ export type PostThreadParams = Pick<
|
||||
|
||||
export type UsePostThreadQueryResult = {
|
||||
hasOtherReplies: boolean
|
||||
thread: AppBskyUnspeccedGetPostThreadV2.ThreadItem[]
|
||||
threadgate?: Omit<AppBskyFeedDefs.ThreadgateView, 'record'> & {
|
||||
record: AppBskyFeedThreadgate.Record
|
||||
thread: app.bsky.unspecced.getPostThreadV2.ThreadItem[]
|
||||
threadgate?: Omit<app.bsky.feed.defs.ThreadgateView, 'record'> & {
|
||||
record: app.bsky.feed.threadgate.Main
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,9 +38,9 @@ export type ThreadItem =
|
||||
key: string
|
||||
uri: string
|
||||
depth: number
|
||||
value: Omit<AppBskyUnspeccedDefs.ThreadItemPost, 'post'> & {
|
||||
post: Omit<AppBskyFeedDefs.PostView, 'record'> & {
|
||||
record: AppBskyFeedPost.Record
|
||||
value: Omit<app.bsky.unspecced.defs.ThreadItemPost, 'post'> & {
|
||||
post: Omit<app.bsky.feed.defs.PostView, 'record'> & {
|
||||
record: app.bsky.feed.post.Main
|
||||
}
|
||||
}
|
||||
isBlurred: boolean
|
||||
@@ -67,7 +60,7 @@ export type ThreadItem =
|
||||
key: string
|
||||
uri: string
|
||||
depth: number
|
||||
value: AppBskyUnspeccedDefs.ThreadItemNoUnauthenticated
|
||||
value: app.bsky.unspecced.defs.ThreadItemNoUnauthenticated
|
||||
ui: {
|
||||
showParentReplyLine: boolean
|
||||
showChildReplyLine: boolean
|
||||
@@ -78,14 +71,14 @@ export type ThreadItem =
|
||||
key: string
|
||||
uri: string
|
||||
depth: number
|
||||
value: AppBskyUnspeccedDefs.ThreadItemNotFound
|
||||
value: app.bsky.unspecced.defs.ThreadItemNotFound
|
||||
}
|
||||
| {
|
||||
type: 'threadPostBlocked'
|
||||
key: string
|
||||
uri: string
|
||||
depth: number
|
||||
value: AppBskyUnspeccedDefs.ThreadItemBlocked
|
||||
value: app.bsky.unspecced.defs.ThreadItemBlocked
|
||||
}
|
||||
| {
|
||||
type: 'replyComposer'
|
||||
|
||||
@@ -1,38 +1,23 @@
|
||||
import {
|
||||
type AppBskyFeedDefs,
|
||||
AppBskyFeedPost,
|
||||
AppBskyFeedThreadgate,
|
||||
AppBskyUnspeccedDefs,
|
||||
type AppBskyUnspeccedGetPostThreadV2,
|
||||
AtUri,
|
||||
} from '@atproto/api'
|
||||
|
||||
import {
|
||||
type ApiThreadItem,
|
||||
type ThreadItem,
|
||||
type TraversalMetadata,
|
||||
} from '#/state/queries/usePostThread/types'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {app} from '#/lexicons'
|
||||
import {isDevMode} from '#/storage/hooks/dev-mode'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
export function getThreadgateRecord(
|
||||
view: AppBskyUnspeccedGetPostThreadV2.OutputSchema['threadgate'],
|
||||
view: app.bsky.unspecced.getPostThreadV2.$OutputBody['threadgate'],
|
||||
) {
|
||||
return bsky.dangerousIsType<AppBskyFeedThreadgate.Record>(
|
||||
view?.record,
|
||||
AppBskyFeedThreadgate.isRecord,
|
||||
)
|
||||
return bsky.isType(app.bsky.feed.threadgate, view?.record)
|
||||
? view?.record
|
||||
: undefined
|
||||
}
|
||||
|
||||
export function getRootPostAtUri(post: AppBskyFeedDefs.PostView) {
|
||||
if (
|
||||
bsky.dangerousIsType<AppBskyFeedPost.Record>(
|
||||
post.record,
|
||||
AppBskyFeedPost.isRecord,
|
||||
)
|
||||
) {
|
||||
export function getRootPostAtUri(post: app.bsky.feed.defs.PostView) {
|
||||
if (bsky.isType(app.bsky.feed.post, post.record)) {
|
||||
/**
|
||||
* If the record has no `reply` field, it is a root post.
|
||||
*/
|
||||
@@ -45,8 +30,8 @@ export function getRootPostAtUri(post: AppBskyFeedDefs.PostView) {
|
||||
}
|
||||
}
|
||||
|
||||
export function getPostRecord(post: AppBskyFeedDefs.PostView) {
|
||||
return post.record as AppBskyFeedPost.Record
|
||||
export function getPostRecord(post: app.bsky.feed.defs.PostView) {
|
||||
return post.record as app.bsky.feed.post.Main
|
||||
}
|
||||
|
||||
export function getTraversalMetadata({
|
||||
@@ -60,7 +45,7 @@ export function getTraversalMetadata({
|
||||
nextItem?: ApiThreadItem
|
||||
parentMetadata?: TraversalMetadata
|
||||
}): TraversalMetadata {
|
||||
if (!AppBskyUnspeccedDefs.isThreadItemPost(item.value)) {
|
||||
if (!bsky.isType(app.bsky.unspecced.defs.threadItemPost, item.value)) {
|
||||
throw new Error(`Expected thread item to be a post`)
|
||||
}
|
||||
const repliesCount = item.value.post.replyCount || 0
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
import {
|
||||
type $Typed,
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyFeedPost,
|
||||
type AppBskyUnspeccedDefs,
|
||||
type AppBskyUnspeccedGetPostThreadV2,
|
||||
AtUri,
|
||||
} from '@atproto/api'
|
||||
import {type ModerationOpts} from '@bsky.app/sdk/moderation'
|
||||
|
||||
import {type $Typed} from '@atproto/lex'
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {app} from '#/lexicons'
|
||||
import {moderatePost} from '#/lib/moderation/subjects'
|
||||
import {makeProfileLink} from '#/lib/routes/links'
|
||||
import {
|
||||
@@ -26,7 +21,7 @@ export function threadPostNoUnauthenticated({
|
||||
key: uri,
|
||||
uri,
|
||||
depth,
|
||||
value: value as AppBskyUnspeccedDefs.ThreadItemNoUnauthenticated,
|
||||
value: value as app.bsky.unspecced.defs.ThreadItemNoUnauthenticated,
|
||||
// @ts-ignore populated by the traversal
|
||||
ui: {},
|
||||
}
|
||||
@@ -42,7 +37,7 @@ export function threadPostNotFound({
|
||||
key: uri,
|
||||
uri,
|
||||
depth,
|
||||
value: value as AppBskyUnspeccedDefs.ThreadItemNotFound,
|
||||
value: value as app.bsky.unspecced.defs.ThreadItemNotFound,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +51,7 @@ export function threadPostBlocked({
|
||||
key: uri,
|
||||
uri,
|
||||
depth,
|
||||
value: value as AppBskyUnspeccedDefs.ThreadItemBlocked,
|
||||
value: value as app.bsky.unspecced.defs.ThreadItemBlocked,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +64,7 @@ export function threadPost({
|
||||
}: {
|
||||
uri: string
|
||||
depth: number
|
||||
value: $Typed<AppBskyUnspeccedDefs.ThreadItemPost>
|
||||
value: $Typed<app.bsky.unspecced.defs.ThreadItemPost>
|
||||
moderationOpts: ModerationOpts
|
||||
threadgateHiddenReplies: Set<string>
|
||||
}): Extract<ThreadItem, {type: 'threadPost'}> {
|
||||
@@ -91,8 +86,8 @@ export function threadPost({
|
||||
* Do not spread anything here, load bearing for post shadow strict
|
||||
* equality reference checks.
|
||||
*/
|
||||
post: value.post as Omit<AppBskyFeedDefs.PostView, 'record'> & {
|
||||
record: AppBskyFeedPost.Record
|
||||
post: value.post as Omit<app.bsky.feed.defs.PostView, 'record'> & {
|
||||
record: app.bsky.feed.post.Main
|
||||
},
|
||||
},
|
||||
isBlurred,
|
||||
@@ -161,10 +156,10 @@ export function skeleton({
|
||||
}
|
||||
|
||||
export function postViewToThreadPlaceholder(
|
||||
post: AppBskyFeedDefs.PostView,
|
||||
post: app.bsky.feed.defs.PostView,
|
||||
): $Typed<
|
||||
Omit<AppBskyUnspeccedGetPostThreadV2.ThreadItem, 'value'> & {
|
||||
value: $Typed<AppBskyUnspeccedDefs.ThreadItemPost>
|
||||
Omit<app.bsky.unspecced.getPostThreadV2.ThreadItem, 'value'> & {
|
||||
value: $Typed<app.bsky.unspecced.defs.ThreadItemPost>
|
||||
}
|
||||
> {
|
||||
return {
|
||||
|
||||
+12
-25
@@ -1,17 +1,11 @@
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
AppBskyEmbedRecord,
|
||||
AppBskyEmbedRecordWithMedia,
|
||||
type AppBskyFeedDefs,
|
||||
AppBskyFeedPost,
|
||||
type AtUri,
|
||||
} from '@atproto/api'
|
||||
import {
|
||||
type InfiniteData,
|
||||
type QueryClient,
|
||||
type QueryKey,
|
||||
} from '@tanstack/react-query'
|
||||
|
||||
import {type AtUri} from '@atproto/syntax'
|
||||
import {app} from '#/lexicons'
|
||||
import * as bsky from '#/types/bsky'
|
||||
|
||||
export type StructuredQueryKey<T extends Record<string, unknown>> = readonly [
|
||||
@@ -93,7 +87,7 @@ export async function truncateAndInvalidate<T = any>(
|
||||
// of the currentUri that is being checked.
|
||||
export function didOrHandleUriMatches(
|
||||
atUri: AtUri,
|
||||
record: {uri: string; author: AppBskyActorDefs.ProfileViewBasic},
|
||||
record: {uri: string; author: app.bsky.actor.defs.ProfileViewBasic},
|
||||
) {
|
||||
if (atUri.host.startsWith('did:')) {
|
||||
return atUri.href === record.uri
|
||||
@@ -104,26 +98,19 @@ export function didOrHandleUriMatches(
|
||||
|
||||
export function getEmbeddedPost(
|
||||
v: unknown,
|
||||
): AppBskyEmbedRecord.ViewRecord | undefined {
|
||||
if (
|
||||
bsky.dangerousIsType<AppBskyEmbedRecord.View>(v, AppBskyEmbedRecord.isView)
|
||||
) {
|
||||
): app.bsky.embed.record.ViewRecord | undefined {
|
||||
if (bsky.isType(app.bsky.embed.record.view, v)) {
|
||||
if (
|
||||
AppBskyEmbedRecord.isViewRecord(v.record) &&
|
||||
AppBskyFeedPost.isRecord(v.record.value)
|
||||
bsky.isType(app.bsky.embed.record.viewRecord, v.record) &&
|
||||
bsky.isType(app.bsky.feed.post, v.record.value)
|
||||
) {
|
||||
return v.record
|
||||
}
|
||||
}
|
||||
if (
|
||||
bsky.dangerousIsType<AppBskyEmbedRecordWithMedia.View>(
|
||||
v,
|
||||
AppBskyEmbedRecordWithMedia.isView,
|
||||
)
|
||||
) {
|
||||
if (bsky.isType(app.bsky.embed.recordWithMedia.view, v)) {
|
||||
if (
|
||||
AppBskyEmbedRecord.isViewRecord(v.record.record) &&
|
||||
AppBskyFeedPost.isRecord(v.record.record.value)
|
||||
bsky.isType(app.bsky.embed.record.viewRecord, v.record.record) &&
|
||||
bsky.isType(app.bsky.feed.post, v.record.record.value)
|
||||
) {
|
||||
return v.record.record
|
||||
}
|
||||
@@ -131,8 +118,8 @@ export function getEmbeddedPost(
|
||||
}
|
||||
|
||||
export function embedViewRecordToPostView(
|
||||
v: AppBskyEmbedRecord.ViewRecord,
|
||||
): AppBskyFeedDefs.PostView {
|
||||
v: app.bsky.embed.record.ViewRecord,
|
||||
): app.bsky.feed.defs.PostView {
|
||||
return {
|
||||
uri: v.uri,
|
||||
cid: v.cid,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import {type AppBskyActorDefs} from '@atproto/api'
|
||||
import {type AtIdentifierString, AtUri} from '@atproto/syntax'
|
||||
import {useMutation} from '@tanstack/react-query'
|
||||
|
||||
@@ -22,7 +21,7 @@ export function useVerificationsRemoveMutation() {
|
||||
verifications,
|
||||
}: {
|
||||
profile: bsky.profile.AnyProfileView
|
||||
verifications: AppBskyActorDefs.VerificationView[]
|
||||
verifications: app.bsky.actor.defs.VerificationView[]
|
||||
}) {
|
||||
if (!currentAccount) {
|
||||
throw new Error('User not logged in')
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
import {createContext, useContext, useMemo, useState} from 'react'
|
||||
import {
|
||||
type AppBskyActorDefs,
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyUnspeccedGetPostThreadV2,
|
||||
} from '@atproto/api'
|
||||
import {type ModerationDecision} from '@bsky.app/sdk/moderation'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {useLingui} from '@lingui/react'
|
||||
import {useQueryClient} from '@tanstack/react-query'
|
||||
|
||||
import {app} from '#/lexicons'
|
||||
import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback'
|
||||
import {postUriToRelativePath, toBskyAppUrl} from '#/lib/strings/url-helpers'
|
||||
import {purgeTemporaryImageFiles} from '#/state/gallery'
|
||||
@@ -24,15 +20,15 @@ export interface ComposerOptsPostRef {
|
||||
cid: string
|
||||
text: string
|
||||
langs?: string[]
|
||||
author: AppBskyActorDefs.ProfileViewBasic
|
||||
embed?: AppBskyFeedDefs.PostView['embed']
|
||||
author: app.bsky.actor.defs.ProfileViewBasic
|
||||
embed?: app.bsky.feed.defs.PostView['embed']
|
||||
moderation?: ModerationDecision
|
||||
}
|
||||
|
||||
export type OnPostSuccessData =
|
||||
| {
|
||||
replyToUri?: string
|
||||
posts: AppBskyUnspeccedGetPostThreadV2.ThreadItem[]
|
||||
posts: app.bsky.unspecced.getPostThreadV2.ThreadItem[]
|
||||
}
|
||||
| undefined
|
||||
|
||||
@@ -48,7 +44,7 @@ export interface ComposerOpts {
|
||||
replyTo?: ComposerOptsPostRef
|
||||
onPost?: (postUri: string | undefined) => void
|
||||
onPostSuccess?: (data: OnPostSuccessData) => void
|
||||
quote?: AppBskyFeedDefs.PostView
|
||||
quote?: app.bsky.feed.defs.PostView
|
||||
mention?: string // handle of user to mention
|
||||
text?: string
|
||||
imageUris?: {uri: string; width: number; height: number; altText?: string}[]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {createContext, useCallback, useContext, useMemo, useState} from 'react'
|
||||
import {type AppBskyFeedThreadgate} from '@atproto/api'
|
||||
import {app} from '#/lexicons'
|
||||
|
||||
type StateContext = {
|
||||
uris: Set<string>
|
||||
@@ -74,7 +74,7 @@ export function useThreadgateHiddenReplyUrisAPI() {
|
||||
export function useMergedThreadgateHiddenReplies({
|
||||
threadgateRecord,
|
||||
}: {
|
||||
threadgateRecord?: AppBskyFeedThreadgate.Record
|
||||
threadgateRecord?: app.bsky.feed.threadgate.Main
|
||||
}) {
|
||||
const {uris, recentlyUnhiddenUris} = useThreadgateHiddenReplyUris()
|
||||
return useMemo(() => {
|
||||
@@ -89,7 +89,7 @@ export function useMergedThreadgateHiddenReplies({
|
||||
export function useMergeThreadgateHiddenReplies() {
|
||||
const {uris, recentlyUnhiddenUris} = useThreadgateHiddenReplyUris()
|
||||
return useCallback(
|
||||
(threadgate?: AppBskyFeedThreadgate.Record) => {
|
||||
(threadgate?: app.bsky.feed.threadgate.Main) => {
|
||||
const set = new Set([...(threadgate?.hiddenReplies || []), ...uris])
|
||||
for (const uri of recentlyUnhiddenUris) {
|
||||
set.delete(uri)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {useEffect, useId, useState} from 'react'
|
||||
import {type AppBskyFeedDefs, AtUri} from '@atproto/api'
|
||||
|
||||
import {AtUri} from '@atproto/syntax'
|
||||
import {app} from '#/lexicons'
|
||||
import {Logger} from '#/logger'
|
||||
import {type FeedSourceInfo} from '#/state/queries/feed'
|
||||
|
||||
@@ -10,7 +11,7 @@ import {type FeedSourceInfo} from '#/state/queries/feed'
|
||||
const logger = Logger.create(Logger.Context.PostSource)
|
||||
|
||||
export type PostSource = {
|
||||
post: AppBskyFeedDefs.FeedViewPost
|
||||
post: app.bsky.feed.defs.FeedViewPost
|
||||
feedSourceInfo?: FeedSourceInfo
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user