rework session layer on PasswordSession + three-client pattern
- PasswordSession (@atproto/lex-password-session) is now the single auth
core; SessionAgent bridges it to the base Agent from @atproto/api so
the ~148 useAgent() consumer files keep working unchanged
- SessionBundle carries {session, agent, accountClient, appviewClient};
useLexClient() now returns the authed appview client, new
useAppviewClient()/usePdsClient() hooks
- reducer: OpaqueSessionBundle, new replaced-current-bundle action for
network-free cross-tab same-did sync (PasswordSession is immutable, so
the bundle is rebuilt instead of mutated in place)
- moderation: AtpAgent.configure -> Client.configure + Agent.configure,
per-account labelers on both the bridge and the appview client
- push-token unregistration uses temporary PasswordSessions
- hard-tail migrations: SignupQueued refresh via resumeSession shim,
useBeginAgeAssurance scoped-token raw Client, useAccountEmailState
reads currentAccount
- PDS routing preserved on the no-network resume fast path by
synthesizing a minimal didDoc from the persisted pdsUrl
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,20 +1,20 @@
|
||||
import {
|
||||
AppBskyFeedDefs,
|
||||
type AppBskyFeedGetAuthorFeed as GetAuthorFeed,
|
||||
type AtpAgent,
|
||||
} from '@atproto/api'
|
||||
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
|
||||
export class AuthorFeedAPI implements FeedAPI {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
_params: GetAuthorFeed.QueryParams
|
||||
|
||||
constructor({
|
||||
agent,
|
||||
feedParams,
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
feedParams: GetAuthorFeed.QueryParams
|
||||
}) {
|
||||
this.agent = agent
|
||||
|
||||
@@ -9,11 +9,12 @@ import {
|
||||
getAppLanguageAsContentLanguage,
|
||||
getContentLanguages,
|
||||
} from '#/state/preferences/languages'
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
import {createBskyTopicsHeader, isBlueskyOwnedFeed} from './utils'
|
||||
|
||||
export class CustomFeedAPI implements FeedAPI {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
params: GetCustomFeed.QueryParams
|
||||
userInterests?: string
|
||||
|
||||
@@ -22,7 +23,7 @@ export class CustomFeedAPI implements FeedAPI {
|
||||
feedParams,
|
||||
userInterests,
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
feedParams: GetCustomFeed.QueryParams
|
||||
userInterests?: string
|
||||
}) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import {type AppBskyFeedDefs, type AtpAgent} from '@atproto/api'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
|
||||
import {DEMO_FEED} from '#/lib/demo'
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
|
||||
export class DemoFeedAPI implements FeedAPI {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
|
||||
constructor({agent}: {agent: AtpAgent}) {
|
||||
constructor({agent}: {agent: SessionAgent}) {
|
||||
this.agent = agent
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import {type AppBskyFeedDefs, type AtpAgent} from '@atproto/api'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
|
||||
export class FollowingFeedAPI implements FeedAPI {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
|
||||
constructor({agent}: {agent: AtpAgent}) {
|
||||
constructor({agent}: {agent: SessionAgent}) {
|
||||
this.agent = agent
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {type AppBskyFeedDefs, type AtpAgent} from '@atproto/api'
|
||||
import {type AppBskyFeedDefs} from '@atproto/api'
|
||||
|
||||
import {PROD_DEFAULT_FEED} from '#/lib/constants'
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {CustomFeedAPI} from './custom'
|
||||
import {FollowingFeedAPI} from './following'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
@@ -27,7 +28,7 @@ export const FALLBACK_MARKER_POST: AppBskyFeedDefs.FeedViewPost = {
|
||||
}
|
||||
|
||||
export class HomeFeedAPI implements FeedAPI {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
following: FollowingFeedAPI
|
||||
discover: CustomFeedAPI
|
||||
usingDiscover = false
|
||||
@@ -39,7 +40,7 @@ export class HomeFeedAPI implements FeedAPI {
|
||||
agent,
|
||||
}: {
|
||||
userInterests?: string
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
}) {
|
||||
this.agent = agent
|
||||
this.following = new FollowingFeedAPI({agent})
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import {
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyFeedGetActorLikes as GetActorLikes,
|
||||
type AtpAgent,
|
||||
} from '@atproto/api'
|
||||
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {type FeedAPI, type FeedAPIResponse} from './types'
|
||||
|
||||
export class LikesFeedAPI implements FeedAPI {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
params: GetActorLikes.QueryParams
|
||||
|
||||
constructor({
|
||||
agent,
|
||||
feedParams,
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
feedParams: GetActorLikes.QueryParams
|
||||
}) {
|
||||
this.agent = agent
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
import {
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyFeedGetTimeline,
|
||||
type AtpAgent,
|
||||
} from '@atproto/api'
|
||||
import {type AppBskyFeedDefs, type AppBskyFeedGetTimeline} from '@atproto/api'
|
||||
import shuffle from 'lodash.shuffle'
|
||||
|
||||
import {bundleAsync} from '#/lib/async/bundle'
|
||||
@@ -10,6 +6,7 @@ import {timeout} from '#/lib/async/timeout'
|
||||
import {feedUriToHref} from '#/lib/strings/url-helpers'
|
||||
import {getContentLanguages} from '#/state/preferences/languages'
|
||||
import {type FeedParams} from '#/state/queries/post-feed'
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {FeedTuner} from '../feed-manip'
|
||||
import {type FeedTunerFn} from '../feed-manip'
|
||||
import {
|
||||
@@ -24,7 +21,7 @@ const POST_AGE_CUTOFF = 60e3 * 60 * 24 // 24hours
|
||||
|
||||
export class MergeFeedAPI implements FeedAPI {
|
||||
userInterests?: string
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
params: FeedParams
|
||||
feedTuners: FeedTunerFn[]
|
||||
following: MergeFeedSource_Following
|
||||
@@ -39,7 +36,7 @@ export class MergeFeedAPI implements FeedAPI {
|
||||
feedTuners,
|
||||
userInterests,
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
feedParams: FeedParams
|
||||
feedTuners: FeedTunerFn[]
|
||||
userInterests?: string
|
||||
@@ -175,7 +172,7 @@ export class MergeFeedAPI implements FeedAPI {
|
||||
}
|
||||
|
||||
class MergeFeedSource {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
feedTuners: FeedTunerFn[]
|
||||
sourceInfo: ReasonFeedSource | undefined
|
||||
cursor: string | undefined = undefined
|
||||
@@ -186,7 +183,7 @@ class MergeFeedSource {
|
||||
agent,
|
||||
feedTuners,
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
feedTuners: FeedTunerFn[]
|
||||
}) {
|
||||
this.agent = agent
|
||||
@@ -253,7 +250,7 @@ class MergeFeedSource_Following extends MergeFeedSource {
|
||||
}
|
||||
|
||||
class MergeFeedSource_Custom extends MergeFeedSource {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
minDate: Date
|
||||
feedUri: string
|
||||
userInterests?: string
|
||||
@@ -264,7 +261,7 @@ class MergeFeedSource_Custom extends MergeFeedSource {
|
||||
feedTuners,
|
||||
userInterests,
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
feedUri: string
|
||||
feedTuners: FeedTunerFn[]
|
||||
userInterests?: string
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
type AppBskyEmbedRecordWithMedia,
|
||||
type AppBskyEmbedVideo,
|
||||
AppBskyFeedPost,
|
||||
type AtpAgent,
|
||||
BlobRef,
|
||||
ChatBskyGroupDefs,
|
||||
type ComAtprotoLabelDefs,
|
||||
@@ -35,6 +34,7 @@ import {
|
||||
createThreadgateRecord,
|
||||
threadgateAllowUISettingToAllowRecordValue,
|
||||
} from '#/state/queries/threadgate'
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {
|
||||
type EmbedDraft,
|
||||
type PostDraft,
|
||||
@@ -54,7 +54,7 @@ interface PostOpts {
|
||||
}
|
||||
|
||||
export async function post(
|
||||
agent: AtpAgent,
|
||||
agent: SessionAgent,
|
||||
queryClient: QueryClient,
|
||||
opts: PostOpts,
|
||||
) {
|
||||
@@ -196,7 +196,7 @@ export async function post(
|
||||
return {uris}
|
||||
}
|
||||
|
||||
async function resolveRT(agent: AtpAgent, richtext: RichText) {
|
||||
async function resolveRT(agent: SessionAgent, richtext: RichText) {
|
||||
const trimmedText = richtext.text
|
||||
// Trim leading whitespace-only lines (but don't break ASCII art).
|
||||
.replace(/^(\s*\n)+/, '')
|
||||
@@ -216,7 +216,7 @@ export class ReplyDeletedError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveReply(agent: AtpAgent, replyTo: string) {
|
||||
async function resolveReply(agent: SessionAgent, replyTo: string) {
|
||||
const {data} = await agent.app.bsky.feed.getPosts({
|
||||
uris: [replyTo],
|
||||
})
|
||||
@@ -249,7 +249,7 @@ async function resolveReply(agent: AtpAgent, replyTo: string) {
|
||||
}
|
||||
|
||||
async function resolveEmbed(
|
||||
agent: AtpAgent,
|
||||
agent: SessionAgent,
|
||||
queryClient: QueryClient,
|
||||
draft: PostDraft,
|
||||
onStateChange: ((state: string) => void) | undefined,
|
||||
@@ -308,7 +308,7 @@ async function resolveEmbed(
|
||||
}
|
||||
|
||||
async function resolveMedia(
|
||||
agent: AtpAgent,
|
||||
agent: SessionAgent,
|
||||
queryClient: QueryClient,
|
||||
embedDraft: EmbedDraft,
|
||||
onStateChange: ((state: string) => void) | undefined,
|
||||
@@ -481,7 +481,7 @@ async function resolveMedia(
|
||||
}
|
||||
|
||||
async function resolveRecord(
|
||||
agent: AtpAgent,
|
||||
agent: SessionAgent,
|
||||
queryClient: QueryClient,
|
||||
uri: string,
|
||||
): Promise<ComAtprotoRepoStrongRef.Main> {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import {
|
||||
type AppBskyFeedDefs,
|
||||
type AppBskyGraphDefs,
|
||||
type AtpAgent,
|
||||
type ComAtprotoRepoStrongRef,
|
||||
} from '@atproto/api'
|
||||
import {AtUri} from '@atproto/api'
|
||||
@@ -28,6 +27,7 @@ import {
|
||||
import {type ComposerImage} from '#/state/gallery'
|
||||
import {createComposerImage} from '#/state/gallery'
|
||||
import {type ChatInvitePreview} from '#/state/queries/join-links'
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {type Gif} from '#/features/gifPicker/types'
|
||||
import {createGIFDescription} from '../gif-alt-text'
|
||||
|
||||
@@ -95,7 +95,7 @@ export class EmbeddingDisabledError extends Error {
|
||||
}
|
||||
|
||||
export async function resolveLink(
|
||||
agent: AtpAgent,
|
||||
agent: SessionAgent,
|
||||
uri: string,
|
||||
): Promise<ResolvedLink> {
|
||||
if (isShortLink(uri)) {
|
||||
@@ -217,7 +217,7 @@ export async function resolveLink(
|
||||
}
|
||||
|
||||
export async function resolveGif(
|
||||
agent: AtpAgent,
|
||||
agent: SessionAgent,
|
||||
gif: Gif,
|
||||
): Promise<ResolvedExternalLink> {
|
||||
const gifUrl = gif.media_formats.gif.url
|
||||
@@ -259,7 +259,7 @@ function getFileSlug(url: string | undefined): string | undefined {
|
||||
}
|
||||
|
||||
async function resolveExternal(
|
||||
agent: AtpAgent,
|
||||
agent: SessionAgent,
|
||||
uri: string,
|
||||
): Promise<ResolvedExternalLink> {
|
||||
const result = await getLinkMeta(agent, uri)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {copyAsync} from 'expo-file-system/legacy'
|
||||
import {type AtpAgent, type ComAtprotoRepoUploadBlob} from '@atproto/api'
|
||||
import {type Agent, type ComAtprotoRepoUploadBlob} from '@atproto/api'
|
||||
|
||||
import {safeDeleteAsync} from '#/lib/media/manip'
|
||||
|
||||
@@ -7,7 +7,7 @@ import {safeDeleteAsync} from '#/lib/media/manip'
|
||||
* @param encoding Allows overriding the blob's type
|
||||
*/
|
||||
export async function uploadBlob(
|
||||
agent: AtpAgent,
|
||||
agent: Agent,
|
||||
input: string | Blob,
|
||||
encoding?: string,
|
||||
): Promise<ComAtprotoRepoUploadBlob.Response> {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {type AtpAgent, type ComAtprotoRepoUploadBlob} from '@atproto/api'
|
||||
import {type Agent, type ComAtprotoRepoUploadBlob} from '@atproto/api'
|
||||
|
||||
/**
|
||||
* @note It is recommended, on web, to use the `file` instance of the file
|
||||
@@ -7,7 +7,7 @@ import {type AtpAgent, type ComAtprotoRepoUploadBlob} from '@atproto/api'
|
||||
* be passed directly to this function.
|
||||
*/
|
||||
export async function uploadBlob(
|
||||
agent: AtpAgent,
|
||||
agent: Agent,
|
||||
input: string | Blob,
|
||||
encoding?: string,
|
||||
): Promise<ComAtprotoRepoUploadBlob.Response> {
|
||||
|
||||
@@ -2,7 +2,6 @@ import {
|
||||
type $Typed,
|
||||
type AppBskyActorDefs,
|
||||
type AppBskyGraphGetStarterPack,
|
||||
type AtpAgent,
|
||||
type ComAtprotoRepoApplyWrites,
|
||||
type Facet,
|
||||
} from '@atproto/api'
|
||||
@@ -14,7 +13,7 @@ import {until} from '#/lib/async/until'
|
||||
import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {enforceLen} from '#/lib/strings/helpers'
|
||||
import {useAgent} from '#/state/session'
|
||||
import {type SessionAgent, useAgent} from '#/state/session'
|
||||
import type * as bsky from '#/types/bsky'
|
||||
|
||||
export const createStarterPackList = async ({
|
||||
@@ -28,7 +27,7 @@ export const createStarterPackList = async ({
|
||||
description?: string
|
||||
descriptionFacets?: Facet[]
|
||||
profiles: bsky.profile.AnyProfileView[]
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
}): Promise<{uri: string; cid: string}> => {
|
||||
if (profiles.length === 0) throw new Error('No profiles given')
|
||||
|
||||
@@ -152,7 +151,7 @@ function createListItem({
|
||||
}
|
||||
|
||||
async function whenAppViewReady(
|
||||
agent: AtpAgent,
|
||||
agent: SessionAgent,
|
||||
uri: string,
|
||||
fn: (res?: AppBskyGraphGetStarterPack.Response) => boolean,
|
||||
) {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import {type AppBskyEmbedExternal, type AtpAgent} from '@atproto/api'
|
||||
import {type AppBskyEmbedExternal} from '@atproto/api'
|
||||
|
||||
import {LINK_META_PROXY} from '#/lib/constants'
|
||||
import {getGiphyMetaUri} from '#/lib/strings/embed-player'
|
||||
import {parseStarterPackUri} from '#/lib/strings/starter-pack'
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {isBskyAppUrl} from '../strings/url-helpers'
|
||||
|
||||
export enum LikelyType {
|
||||
@@ -31,7 +32,7 @@ export interface LinkMeta {
|
||||
}
|
||||
|
||||
export async function getLinkMeta(
|
||||
agent: AtpAgent,
|
||||
agent: SessionAgent,
|
||||
url: string,
|
||||
timeout = 15e3,
|
||||
): Promise<LinkMeta> {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import {type AtpAgent} from '@atproto/api'
|
||||
import {type I18n} from '@lingui/core'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
|
||||
import {VIDEO_SERVICE_DID} from '#/lib/constants'
|
||||
import {UploadLimitError} from '#/lib/media/video/errors'
|
||||
import {getServiceAuthAudFromUrl} from '#/lib/strings/url-helpers'
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {createVideoAgent} from './util'
|
||||
|
||||
export async function getServiceAuthToken({
|
||||
@@ -13,7 +13,7 @@ export async function getServiceAuthToken({
|
||||
lxm,
|
||||
exp,
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
aud?: string
|
||||
lxm: string
|
||||
exp?: number
|
||||
@@ -30,7 +30,7 @@ export async function getServiceAuthToken({
|
||||
return serviceAuth.token
|
||||
}
|
||||
|
||||
export async function getVideoUploadLimits(agent: AtpAgent, i18n: I18n) {
|
||||
export async function getVideoUploadLimits(agent: SessionAgent, i18n: I18n) {
|
||||
const token = await getServiceAuthToken({
|
||||
agent,
|
||||
lxm: 'app.bsky.video.getUploadLimits',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {createUploadTask, FileSystemUploadType} from 'expo-file-system/legacy'
|
||||
import {type AppBskyVideoDefs, type AtpAgent} from '@atproto/api'
|
||||
import {type AppBskyVideoDefs} from '@atproto/api'
|
||||
import {type I18n} from '@lingui/core'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {nanoid} from 'nanoid/non-secure'
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
type CompressedVideo,
|
||||
type VideoUploadTransport,
|
||||
} from '#/lib/media/video/types'
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {Features, features} from '#/analytics/features'
|
||||
import {MultipartFallbackError, uploadVideoMultipart} from './multipart/upload'
|
||||
import {getServiceAuthToken, getVideoUploadLimits} from './upload.shared'
|
||||
@@ -25,7 +26,7 @@ export async function uploadVideo({
|
||||
onTransport,
|
||||
}: {
|
||||
video: CompressedVideo
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
did: string
|
||||
setProgress: (progress: number) => void
|
||||
signal: AbortSignal
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {type AppBskyVideoDefs, type AtpAgent} from '@atproto/api'
|
||||
import {type AppBskyVideoDefs} from '@atproto/api'
|
||||
import {type I18n} from '@lingui/core'
|
||||
import {msg} from '@lingui/core/macro'
|
||||
import {nanoid} from 'nanoid/non-secure'
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
type CompressedVideo,
|
||||
type VideoUploadTransport,
|
||||
} from '#/lib/media/video/types'
|
||||
import {type SessionAgent} from '#/state/session'
|
||||
import {Features, features} from '#/analytics/features'
|
||||
import {MultipartFallbackError, uploadVideoMultipart} from './multipart/upload'
|
||||
import {getServiceAuthToken, getVideoUploadLimits} from './upload.shared'
|
||||
@@ -24,7 +25,7 @@ export async function uploadVideo({
|
||||
onTransport,
|
||||
}: {
|
||||
video: CompressedVideo
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
did: string
|
||||
setProgress: (progress: number) => void
|
||||
signal: AbortSignal
|
||||
|
||||
@@ -2,7 +2,7 @@ import {useCallback, useEffect} from 'react'
|
||||
import {Platform} from 'react-native'
|
||||
import * as Notifications from 'expo-notifications'
|
||||
import {getBadgeCountAsync, setBadgeCountAsync} from 'expo-notifications'
|
||||
import {type AppBskyNotificationRegisterPush, type AtpAgent} from '@atproto/api'
|
||||
import {type AppBskyNotificationRegisterPush} from '@atproto/api'
|
||||
import debounce from 'lodash.debounce'
|
||||
|
||||
import {
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
import {logger as notyLogger} from '#/lib/notifications/util'
|
||||
import {isNetworkError} from '#/lib/strings/errors'
|
||||
import {type SessionAccount, useAgent, useSession} from '#/state/session'
|
||||
import {type SessionAgent} from '#/state/session/session-core'
|
||||
import BackgroundNotificationHandler from '#/../modules/expo-background-notification-handler'
|
||||
import {useAgeAssurance} from '#/ageAssurance'
|
||||
import {useAnalytics} from '#/analytics'
|
||||
@@ -28,7 +29,7 @@ async function _registerPushToken({
|
||||
token,
|
||||
extra = {},
|
||||
}: {
|
||||
agent: AtpAgent
|
||||
agent: SessionAgent
|
||||
currentAccount: SessionAccount
|
||||
token: Notifications.DevicePushToken
|
||||
extra?: {
|
||||
@@ -326,7 +327,7 @@ export async function resetBadgeCount() {
|
||||
await setBadgeCountAsync(0)
|
||||
}
|
||||
|
||||
export async function unregisterPushToken(agents: AtpAgent[]) {
|
||||
export async function unregisterPushToken(agents: SessionAgent[]) {
|
||||
if (!IS_NATIVE) return
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user