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