Handle pending invites correctly
parent
72fad215df
commit
486ce26a91
|
@ -0,0 +1,121 @@
|
|||
import {makeAutoObservable} from 'mobx'
|
||||
import * as GetAssertions from '../../third-party/api/src/client/types/app/bsky/graph/getAssertions'
|
||||
import {RootStoreModel} from './root-store'
|
||||
|
||||
type ResponseAssertion = GetAssertions.OutputSchema['assertions'][number]
|
||||
export type Assertion = ResponseAssertion & {
|
||||
_reactKey: string
|
||||
}
|
||||
|
||||
export class GetAssertionsView {
|
||||
// state
|
||||
isLoading = false
|
||||
isRefreshing = false
|
||||
hasLoaded = false
|
||||
error = ''
|
||||
params: GetAssertions.QueryParams
|
||||
|
||||
// data
|
||||
assertions: Assertion[] = []
|
||||
|
||||
constructor(
|
||||
public rootStore: RootStoreModel,
|
||||
params: GetAssertions.QueryParams,
|
||||
) {
|
||||
makeAutoObservable(
|
||||
this,
|
||||
{
|
||||
rootStore: false,
|
||||
params: false,
|
||||
},
|
||||
{autoBind: true},
|
||||
)
|
||||
this.params = params
|
||||
}
|
||||
|
||||
get hasContent() {
|
||||
return this.assertions.length > 0
|
||||
}
|
||||
|
||||
get hasError() {
|
||||
return this.error !== ''
|
||||
}
|
||||
|
||||
get isEmpty() {
|
||||
return this.hasLoaded && !this.hasContent
|
||||
}
|
||||
|
||||
getBySubject(did: string) {
|
||||
return this.assertions.find(assertion => assertion.subject.did === did)
|
||||
}
|
||||
|
||||
get confirmed() {
|
||||
return this.assertions.filter(assertion => !!assertion.confirmation)
|
||||
}
|
||||
|
||||
get unconfirmed() {
|
||||
return this.assertions.filter(assertion => !assertion.confirmation)
|
||||
}
|
||||
|
||||
// public api
|
||||
// =
|
||||
|
||||
async setup() {
|
||||
await this._fetch()
|
||||
}
|
||||
|
||||
async refresh() {
|
||||
await this._fetch(true)
|
||||
}
|
||||
|
||||
async loadMore() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
// state transitions
|
||||
// =
|
||||
|
||||
private _xLoading(isRefreshing = false) {
|
||||
this.isLoading = true
|
||||
this.isRefreshing = isRefreshing
|
||||
this.error = ''
|
||||
}
|
||||
|
||||
private _xIdle(err: string = '') {
|
||||
this.isLoading = false
|
||||
this.isRefreshing = false
|
||||
this.hasLoaded = true
|
||||
this.error = err
|
||||
}
|
||||
|
||||
// loader functions
|
||||
// =
|
||||
|
||||
private async _fetch(isRefreshing = false) {
|
||||
this._xLoading(isRefreshing)
|
||||
try {
|
||||
const res = await this.rootStore.api.app.bsky.graph.getAssertions(
|
||||
this.params,
|
||||
)
|
||||
this._replaceAll(res)
|
||||
this._xIdle()
|
||||
} catch (e: any) {
|
||||
this._xIdle(e.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private _replaceAll(res: GetAssertions.Response) {
|
||||
this.assertions.length = 0
|
||||
let counter = 0
|
||||
for (const item of res.data.assertions) {
|
||||
this._append({
|
||||
_reactKey: `item-${counter++}`,
|
||||
...item,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private _append(item: Assertion) {
|
||||
this.assertions.push(item)
|
||||
}
|
||||
}
|
|
@ -46,6 +46,10 @@ export class MembersViewModel {
|
|||
return this.hasLoaded && !this.hasContent
|
||||
}
|
||||
|
||||
isMember(did: string) {
|
||||
return this.members.find(member => member.did === did)
|
||||
}
|
||||
|
||||
// public api
|
||||
// =
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import {makeAutoObservable} from 'mobx'
|
||||
import * as GetSuggestions from '../../third-party/api/src/client/types/app/bsky/actor/getSuggestions'
|
||||
import {RootStoreModel} from './root-store'
|
||||
import {Declaration} from './_common'
|
||||
|
||||
type ResponseSuggestedActor = GetSuggestions.OutputSchema['actors'][number]
|
||||
export type SuggestedActor = ResponseSuggestedActor & {
|
||||
|
|
|
@ -1,27 +1,30 @@
|
|||
import {makeAutoObservable, runInAction} from 'mobx'
|
||||
import {RootStoreModel} from './root-store'
|
||||
import {MembersViewModel} from './members-view'
|
||||
import {UserFollowsViewModel, FollowItem} from './user-follows-view'
|
||||
import {APP_BSKY_SYSTEM} from '../../third-party/api'
|
||||
import {GetAssertionsView} from './get-assertions-view'
|
||||
import {APP_BSKY_SYSTEM, APP_BSKY_GRAPH} from '../../third-party/api'
|
||||
|
||||
export interface SuggestedInvites {
|
||||
export interface SuggestedInvitesViewParams {
|
||||
sceneDid: string
|
||||
}
|
||||
|
||||
export class SuggestedInvites {
|
||||
export class SuggestedInvitesView {
|
||||
// state
|
||||
isLoading = false
|
||||
isRefreshing = false
|
||||
hasLoaded = false
|
||||
error = ''
|
||||
params: SuggestedInvites
|
||||
sceneMembersView: MembersViewModel
|
||||
params: SuggestedInvitesViewParams
|
||||
sceneAssertionsView: GetAssertionsView
|
||||
myFollowsView: UserFollowsViewModel
|
||||
|
||||
// data
|
||||
suggestions: FollowItem[] = []
|
||||
|
||||
constructor(public rootStore: RootStoreModel, params: SuggestedInvites) {
|
||||
constructor(
|
||||
public rootStore: RootStoreModel,
|
||||
params: SuggestedInvitesViewParams,
|
||||
) {
|
||||
makeAutoObservable(
|
||||
this,
|
||||
{
|
||||
|
@ -31,8 +34,9 @@ export class SuggestedInvites {
|
|||
{autoBind: true},
|
||||
)
|
||||
this.params = params
|
||||
this.sceneMembersView = new MembersViewModel(rootStore, {
|
||||
actor: params.sceneDid,
|
||||
this.sceneAssertionsView = new GetAssertionsView(rootStore, {
|
||||
author: params.sceneDid,
|
||||
assertion: APP_BSKY_GRAPH.AssertMember,
|
||||
})
|
||||
this.myFollowsView = new UserFollowsViewModel(rootStore, {
|
||||
user: rootStore.me.did || '',
|
||||
|
@ -51,6 +55,10 @@ export class SuggestedInvites {
|
|||
return this.hasLoaded && !this.hasContent
|
||||
}
|
||||
|
||||
get unconfirmed() {
|
||||
return this.sceneAssertionsView.unconfirmed
|
||||
}
|
||||
|
||||
// public api
|
||||
// =
|
||||
|
||||
|
@ -88,7 +96,8 @@ export class SuggestedInvites {
|
|||
private async _fetch(isRefreshing = false) {
|
||||
this._xLoading(isRefreshing)
|
||||
try {
|
||||
await this.sceneMembersView.setup()
|
||||
// TODO need to fetch all!
|
||||
await this.sceneAssertionsView.setup()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
this._xIdle(
|
||||
|
@ -112,9 +121,7 @@ export class SuggestedInvites {
|
|||
if (follow.declaration.actorType !== APP_BSKY_SYSTEM.ActorUser) {
|
||||
continue
|
||||
}
|
||||
if (
|
||||
!this.sceneMembersView.members.find(member => member.did === follow.did)
|
||||
) {
|
||||
if (!this.sceneAssertionsView.getBySubject(follow.did)) {
|
||||
newSuggestions.push(follow)
|
||||
}
|
||||
}
|
|
@ -6960,6 +6960,7 @@ __export(src_exports, {
|
|||
AppBskyGraphAssertion: () => assertion_exports,
|
||||
AppBskyGraphConfirmation: () => confirmation_exports,
|
||||
AppBskyGraphFollow: () => follow_exports,
|
||||
AppBskyGraphGetAssertions: () => getAssertions_exports,
|
||||
AppBskyGraphGetFollowers: () => getFollowers_exports,
|
||||
AppBskyGraphGetFollows: () => getFollows_exports,
|
||||
AppBskyGraphGetMembers: () => getMembers_exports,
|
||||
|
@ -13340,6 +13341,231 @@ var methodSchemaDict = {
|
|||
}
|
||||
}
|
||||
},
|
||||
"app.bsky.graph.getAssertions": {
|
||||
lexicon: 1,
|
||||
id: "app.bsky.graph.getAssertions",
|
||||
type: "query",
|
||||
description: "General-purpose query for assertions.",
|
||||
parameters: {
|
||||
type: "object",
|
||||
properties: {
|
||||
author: {
|
||||
type: "string"
|
||||
},
|
||||
subject: {
|
||||
type: "string"
|
||||
},
|
||||
assertion: {
|
||||
type: "string"
|
||||
},
|
||||
confirmed: {
|
||||
type: "boolean"
|
||||
},
|
||||
limit: {
|
||||
type: "number",
|
||||
maximum: 100
|
||||
},
|
||||
before: {
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
output: {
|
||||
encoding: "application/json",
|
||||
schema: {
|
||||
type: "object",
|
||||
required: ["assertions"],
|
||||
properties: {
|
||||
cursor: {
|
||||
type: "string"
|
||||
},
|
||||
assertions: {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
required: [
|
||||
"uri",
|
||||
"cid",
|
||||
"assertion",
|
||||
"author",
|
||||
"subject",
|
||||
"indexedAt",
|
||||
"createdAt"
|
||||
],
|
||||
properties: {
|
||||
uri: {
|
||||
type: "string"
|
||||
},
|
||||
cid: {
|
||||
type: "string"
|
||||
},
|
||||
assertion: {
|
||||
type: "string"
|
||||
},
|
||||
confirmation: {
|
||||
$ref: "#/$defs/confirmation"
|
||||
},
|
||||
author: {
|
||||
$ref: "#/$defs/actor"
|
||||
},
|
||||
subject: {
|
||||
$ref: "#/$defs/actor"
|
||||
},
|
||||
indexedAt: {
|
||||
type: "string",
|
||||
format: "date-time"
|
||||
},
|
||||
createdAt: {
|
||||
type: "string",
|
||||
format: "date-time"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
$defs: {
|
||||
confirmation: {
|
||||
type: "object",
|
||||
required: ["uri", "cid", "indexedAt", "createdAt"],
|
||||
properties: {
|
||||
uri: {
|
||||
type: "string"
|
||||
},
|
||||
cid: {
|
||||
type: "string"
|
||||
},
|
||||
indexedAt: {
|
||||
type: "string",
|
||||
format: "date-time"
|
||||
},
|
||||
createdAt: {
|
||||
type: "string",
|
||||
format: "date-time"
|
||||
}
|
||||
}
|
||||
},
|
||||
actor: {
|
||||
type: "object",
|
||||
required: ["did", "declaration", "handle"],
|
||||
properties: {
|
||||
did: {
|
||||
type: "string"
|
||||
},
|
||||
declaration: {
|
||||
$ref: "#/$defs/declaration"
|
||||
},
|
||||
handle: {
|
||||
type: "string"
|
||||
},
|
||||
displayName: {
|
||||
type: "string",
|
||||
maxLength: 64
|
||||
}
|
||||
}
|
||||
},
|
||||
declaration: {
|
||||
type: "object",
|
||||
required: ["cid", "actorType"],
|
||||
properties: {
|
||||
cid: {
|
||||
type: "string"
|
||||
},
|
||||
actorType: {
|
||||
oneOf: [
|
||||
{
|
||||
$ref: "#/$defs/actorKnown"
|
||||
},
|
||||
{
|
||||
$ref: "#/$defs/actorUnknown"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
actorKnown: {
|
||||
type: "string",
|
||||
enum: ["app.bsky.system.actorUser", "app.bsky.system.actorScene"]
|
||||
},
|
||||
actorUnknown: {
|
||||
type: "string",
|
||||
not: {
|
||||
enum: ["app.bsky.system.actorUser", "app.bsky.system.actorScene"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
defs: {
|
||||
confirmation: {
|
||||
type: "object",
|
||||
required: ["uri", "cid", "indexedAt", "createdAt"],
|
||||
properties: {
|
||||
uri: {
|
||||
type: "string"
|
||||
},
|
||||
cid: {
|
||||
type: "string"
|
||||
},
|
||||
indexedAt: {
|
||||
type: "string",
|
||||
format: "date-time"
|
||||
},
|
||||
createdAt: {
|
||||
type: "string",
|
||||
format: "date-time"
|
||||
}
|
||||
}
|
||||
},
|
||||
actor: {
|
||||
type: "object",
|
||||
required: ["did", "declaration", "handle"],
|
||||
properties: {
|
||||
did: {
|
||||
type: "string"
|
||||
},
|
||||
declaration: {
|
||||
$ref: "#/$defs/declaration"
|
||||
},
|
||||
handle: {
|
||||
type: "string"
|
||||
},
|
||||
displayName: {
|
||||
type: "string",
|
||||
maxLength: 64
|
||||
}
|
||||
}
|
||||
},
|
||||
declaration: {
|
||||
type: "object",
|
||||
required: ["cid", "actorType"],
|
||||
properties: {
|
||||
cid: {
|
||||
type: "string"
|
||||
},
|
||||
actorType: {
|
||||
oneOf: [
|
||||
{
|
||||
$ref: "#/$defs/actorKnown"
|
||||
},
|
||||
{
|
||||
$ref: "#/$defs/actorUnknown"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
actorKnown: {
|
||||
type: "string",
|
||||
enum: ["app.bsky.system.actorUser", "app.bsky.system.actorScene"]
|
||||
},
|
||||
actorUnknown: {
|
||||
type: "string",
|
||||
not: {
|
||||
enum: ["app.bsky.system.actorUser", "app.bsky.system.actorScene"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"app.bsky.graph.getFollowers": {
|
||||
lexicon: 1,
|
||||
id: "app.bsky.graph.getFollowers",
|
||||
|
@ -15138,9 +15364,9 @@ function toKnownErr34(e) {
|
|||
return e;
|
||||
}
|
||||
|
||||
// src/client/types/app/bsky/graph/getFollowers.ts
|
||||
var getFollowers_exports = {};
|
||||
__export(getFollowers_exports, {
|
||||
// src/client/types/app/bsky/graph/getAssertions.ts
|
||||
var getAssertions_exports = {};
|
||||
__export(getAssertions_exports, {
|
||||
toKnownErr: () => toKnownErr35
|
||||
});
|
||||
function toKnownErr35(e) {
|
||||
|
@ -15149,9 +15375,9 @@ function toKnownErr35(e) {
|
|||
return e;
|
||||
}
|
||||
|
||||
// src/client/types/app/bsky/graph/getFollows.ts
|
||||
var getFollows_exports = {};
|
||||
__export(getFollows_exports, {
|
||||
// src/client/types/app/bsky/graph/getFollowers.ts
|
||||
var getFollowers_exports = {};
|
||||
__export(getFollowers_exports, {
|
||||
toKnownErr: () => toKnownErr36
|
||||
});
|
||||
function toKnownErr36(e) {
|
||||
|
@ -15160,9 +15386,9 @@ function toKnownErr36(e) {
|
|||
return e;
|
||||
}
|
||||
|
||||
// src/client/types/app/bsky/graph/getMembers.ts
|
||||
var getMembers_exports = {};
|
||||
__export(getMembers_exports, {
|
||||
// src/client/types/app/bsky/graph/getFollows.ts
|
||||
var getFollows_exports = {};
|
||||
__export(getFollows_exports, {
|
||||
toKnownErr: () => toKnownErr37
|
||||
});
|
||||
function toKnownErr37(e) {
|
||||
|
@ -15171,9 +15397,9 @@ function toKnownErr37(e) {
|
|||
return e;
|
||||
}
|
||||
|
||||
// src/client/types/app/bsky/graph/getMemberships.ts
|
||||
var getMemberships_exports = {};
|
||||
__export(getMemberships_exports, {
|
||||
// src/client/types/app/bsky/graph/getMembers.ts
|
||||
var getMembers_exports = {};
|
||||
__export(getMembers_exports, {
|
||||
toKnownErr: () => toKnownErr38
|
||||
});
|
||||
function toKnownErr38(e) {
|
||||
|
@ -15182,9 +15408,9 @@ function toKnownErr38(e) {
|
|||
return e;
|
||||
}
|
||||
|
||||
// src/client/types/app/bsky/notification/getCount.ts
|
||||
var getCount_exports = {};
|
||||
__export(getCount_exports, {
|
||||
// src/client/types/app/bsky/graph/getMemberships.ts
|
||||
var getMemberships_exports = {};
|
||||
__export(getMemberships_exports, {
|
||||
toKnownErr: () => toKnownErr39
|
||||
});
|
||||
function toKnownErr39(e) {
|
||||
|
@ -15193,9 +15419,9 @@ function toKnownErr39(e) {
|
|||
return e;
|
||||
}
|
||||
|
||||
// src/client/types/app/bsky/notification/list.ts
|
||||
var list_exports = {};
|
||||
__export(list_exports, {
|
||||
// src/client/types/app/bsky/notification/getCount.ts
|
||||
var getCount_exports = {};
|
||||
__export(getCount_exports, {
|
||||
toKnownErr: () => toKnownErr40
|
||||
});
|
||||
function toKnownErr40(e) {
|
||||
|
@ -15204,9 +15430,9 @@ function toKnownErr40(e) {
|
|||
return e;
|
||||
}
|
||||
|
||||
// src/client/types/app/bsky/notification/updateSeen.ts
|
||||
var updateSeen_exports = {};
|
||||
__export(updateSeen_exports, {
|
||||
// src/client/types/app/bsky/notification/list.ts
|
||||
var list_exports = {};
|
||||
__export(list_exports, {
|
||||
toKnownErr: () => toKnownErr41
|
||||
});
|
||||
function toKnownErr41(e) {
|
||||
|
@ -15215,6 +15441,17 @@ function toKnownErr41(e) {
|
|||
return e;
|
||||
}
|
||||
|
||||
// src/client/types/app/bsky/notification/updateSeen.ts
|
||||
var updateSeen_exports = {};
|
||||
__export(updateSeen_exports, {
|
||||
toKnownErr: () => toKnownErr42
|
||||
});
|
||||
function toKnownErr42(e) {
|
||||
if (e instanceof XRPCError) {
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
// src/client/types/app/bsky/actor/profile.ts
|
||||
var profile_exports = {};
|
||||
|
||||
|
@ -15754,24 +15991,29 @@ var GraphNS = class {
|
|||
this.confirmation = new ConfirmationRecord(service);
|
||||
this.follow = new FollowRecord(service);
|
||||
}
|
||||
getAssertions(params, opts) {
|
||||
return this._service.xrpc.call("app.bsky.graph.getAssertions", params, void 0, opts).catch((e) => {
|
||||
throw toKnownErr35(e);
|
||||
});
|
||||
}
|
||||
getFollowers(params, opts) {
|
||||
return this._service.xrpc.call("app.bsky.graph.getFollowers", params, void 0, opts).catch((e) => {
|
||||
throw toKnownErr35(e);
|
||||
throw toKnownErr36(e);
|
||||
});
|
||||
}
|
||||
getFollows(params, opts) {
|
||||
return this._service.xrpc.call("app.bsky.graph.getFollows", params, void 0, opts).catch((e) => {
|
||||
throw toKnownErr36(e);
|
||||
throw toKnownErr37(e);
|
||||
});
|
||||
}
|
||||
getMembers(params, opts) {
|
||||
return this._service.xrpc.call("app.bsky.graph.getMembers", params, void 0, opts).catch((e) => {
|
||||
throw toKnownErr37(e);
|
||||
throw toKnownErr38(e);
|
||||
});
|
||||
}
|
||||
getMemberships(params, opts) {
|
||||
return this._service.xrpc.call("app.bsky.graph.getMemberships", params, void 0, opts).catch((e) => {
|
||||
throw toKnownErr38(e);
|
||||
throw toKnownErr39(e);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -15892,17 +16134,17 @@ var NotificationNS = class {
|
|||
}
|
||||
getCount(params, opts) {
|
||||
return this._service.xrpc.call("app.bsky.notification.getCount", params, void 0, opts).catch((e) => {
|
||||
throw toKnownErr39(e);
|
||||
throw toKnownErr40(e);
|
||||
});
|
||||
}
|
||||
list(params, opts) {
|
||||
return this._service.xrpc.call("app.bsky.notification.list", params, void 0, opts).catch((e) => {
|
||||
throw toKnownErr40(e);
|
||||
throw toKnownErr41(e);
|
||||
});
|
||||
}
|
||||
updateSeen(data, opts) {
|
||||
return this._service.xrpc.call("app.bsky.notification.updateSeen", opts?.qp, data, opts).catch((e) => {
|
||||
throw toKnownErr41(e);
|
||||
throw toKnownErr42(e);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -16100,6 +16342,7 @@ var SessionManager = class extends import_events.default {
|
|||
AppBskyGraphAssertion,
|
||||
AppBskyGraphConfirmation,
|
||||
AppBskyGraphFollow,
|
||||
AppBskyGraphGetAssertions,
|
||||
AppBskyGraphGetFollowers,
|
||||
AppBskyGraphGetFollows,
|
||||
AppBskyGraphGetMembers,
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -42,6 +42,7 @@ import * as AppBskyFeedVote from './types/app/bsky/feed/vote';
|
|||
import * as AppBskyGraphAssertion from './types/app/bsky/graph/assertion';
|
||||
import * as AppBskyGraphConfirmation from './types/app/bsky/graph/confirmation';
|
||||
import * as AppBskyGraphFollow from './types/app/bsky/graph/follow';
|
||||
import * as AppBskyGraphGetAssertions from './types/app/bsky/graph/getAssertions';
|
||||
import * as AppBskyGraphGetFollowers from './types/app/bsky/graph/getFollowers';
|
||||
import * as AppBskyGraphGetFollows from './types/app/bsky/graph/getFollows';
|
||||
import * as AppBskyGraphGetMembers from './types/app/bsky/graph/getMembers';
|
||||
|
@ -93,6 +94,7 @@ export * as AppBskyFeedVote from './types/app/bsky/feed/vote';
|
|||
export * as AppBskyGraphAssertion from './types/app/bsky/graph/assertion';
|
||||
export * as AppBskyGraphConfirmation from './types/app/bsky/graph/confirmation';
|
||||
export * as AppBskyGraphFollow from './types/app/bsky/graph/follow';
|
||||
export * as AppBskyGraphGetAssertions from './types/app/bsky/graph/getAssertions';
|
||||
export * as AppBskyGraphGetFollowers from './types/app/bsky/graph/getFollowers';
|
||||
export * as AppBskyGraphGetFollows from './types/app/bsky/graph/getFollows';
|
||||
export * as AppBskyGraphGetMembers from './types/app/bsky/graph/getMembers';
|
||||
|
@ -357,6 +359,7 @@ export declare class GraphNS {
|
|||
confirmation: ConfirmationRecord;
|
||||
follow: FollowRecord;
|
||||
constructor(service: ServiceClient);
|
||||
getAssertions(params?: AppBskyGraphGetAssertions.QueryParams, opts?: AppBskyGraphGetAssertions.CallOptions): Promise<AppBskyGraphGetAssertions.Response>;
|
||||
getFollowers(params?: AppBskyGraphGetFollowers.QueryParams, opts?: AppBskyGraphGetFollowers.CallOptions): Promise<AppBskyGraphGetFollowers.Response>;
|
||||
getFollows(params?: AppBskyGraphGetFollows.QueryParams, opts?: AppBskyGraphGetFollows.CallOptions): Promise<AppBskyGraphGetFollows.Response>;
|
||||
getMembers(params?: AppBskyGraphGetMembers.QueryParams, opts?: AppBskyGraphGetMembers.CallOptions): Promise<AppBskyGraphGetMembers.Response>;
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
import { Headers } from '@atproto/xrpc';
|
||||
export interface QueryParams {
|
||||
author?: string;
|
||||
subject?: string;
|
||||
assertion?: string;
|
||||
confirmed?: boolean;
|
||||
limit?: number;
|
||||
before?: string;
|
||||
}
|
||||
export interface CallOptions {
|
||||
headers?: Headers;
|
||||
}
|
||||
export declare type InputSchema = undefined;
|
||||
export declare type ActorKnown = 'app.bsky.system.actorUser' | 'app.bsky.system.actorScene';
|
||||
export declare type ActorUnknown = string;
|
||||
export interface OutputSchema {
|
||||
cursor?: string;
|
||||
assertions: {
|
||||
uri: string;
|
||||
cid: string;
|
||||
assertion: string;
|
||||
confirmation?: Confirmation;
|
||||
author: Actor;
|
||||
subject: Actor;
|
||||
indexedAt: string;
|
||||
createdAt: string;
|
||||
}[];
|
||||
}
|
||||
export interface Confirmation {
|
||||
uri: string;
|
||||
cid: string;
|
||||
indexedAt: string;
|
||||
createdAt: string;
|
||||
}
|
||||
export interface Actor {
|
||||
did: string;
|
||||
declaration: Declaration;
|
||||
handle: string;
|
||||
displayName?: string;
|
||||
}
|
||||
export interface Declaration {
|
||||
cid: string;
|
||||
actorType: ActorKnown | ActorUnknown;
|
||||
}
|
||||
export interface Response {
|
||||
success: boolean;
|
||||
headers: Headers;
|
||||
data: OutputSchema;
|
||||
}
|
||||
export declare function toKnownErr(e: any): any;
|
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,5 @@
|
|||
import React, {useState, useEffect, useMemo} from 'react'
|
||||
import {observer} from 'mobx-react-lite'
|
||||
import Toast from '../util/Toast'
|
||||
import {
|
||||
ActivityIndicator,
|
||||
|
@ -23,13 +24,18 @@ import {ErrorMessage} from '../util/ErrorMessage'
|
|||
import {useStores} from '../../../state'
|
||||
import * as apilib from '../../../state/lib/api'
|
||||
import {ProfileViewModel} from '../../../state/models/profile-view'
|
||||
import {SuggestedInvites} from '../../../state/models/suggested-invites'
|
||||
import {SuggestedInvitesView} from '../../../state/models/suggested-invites-view'
|
||||
import {Assertion} from '../../../state/models/get-assertions-view'
|
||||
import {FollowItem} from '../../../state/models/user-follows-view'
|
||||
import {s, colors} from '../../lib/styles'
|
||||
|
||||
export const snapPoints = ['70%']
|
||||
|
||||
export function Component({profileView}: {profileView: ProfileViewModel}) {
|
||||
export const Component = observer(function Component({
|
||||
profileView,
|
||||
}: {
|
||||
profileView: ProfileViewModel
|
||||
}) {
|
||||
const store = useStores()
|
||||
const layout = useWindowDimensions()
|
||||
const [index, setIndex] = useState(0)
|
||||
|
@ -40,12 +46,18 @@ export function Component({profileView}: {profileView: ProfileViewModel}) {
|
|||
const [hasSetup, setHasSetup] = useState<boolean>(false)
|
||||
const [error, setError] = useState<string>('')
|
||||
const suggestions = useMemo(
|
||||
() => new SuggestedInvites(store, {sceneDid: profileView.did}),
|
||||
() => new SuggestedInvitesView(store, {sceneDid: profileView.did}),
|
||||
[profileView.did],
|
||||
)
|
||||
const [createdInvites, setCreatedInvites] = useState<Record<string, string>>(
|
||||
{},
|
||||
)
|
||||
// TODO: it would be much better if we just used the suggestions view for the deleted pending invites
|
||||
// but mobx isnt picking up on the state change in suggestions.unconfirmed and I dont have
|
||||
// time to debug that right now -prf
|
||||
const [deletedPendingInvites, setDeletedPendingInvites] = useState<
|
||||
Record<string, boolean>
|
||||
>({})
|
||||
|
||||
useEffect(() => {
|
||||
let aborted = false
|
||||
|
@ -95,6 +107,28 @@ export function Component({profileView}: {profileView: ProfileViewModel}) {
|
|||
}
|
||||
}
|
||||
|
||||
const onPressDeleteInvite = async (assertion: Assertion) => {
|
||||
setError('')
|
||||
const urip = new AtUri(assertion.uri)
|
||||
try {
|
||||
await store.api.app.bsky.graph.assertion.delete({
|
||||
did: profileView.did,
|
||||
rkey: urip.rkey,
|
||||
})
|
||||
setDeletedPendingInvites({
|
||||
[assertion.uri]: true,
|
||||
...deletedPendingInvites,
|
||||
})
|
||||
Toast.show('Invite removed', {
|
||||
duration: Toast.durations.LONG,
|
||||
position: Toast.positions.TOP,
|
||||
})
|
||||
} catch (e) {
|
||||
setError('There was an issue with the invite. Please try again.')
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const renderSuggestionItem = ({item}: {item: FollowItem}) => {
|
||||
const createdInvite = createdInvites[item.did]
|
||||
return (
|
||||
|
@ -124,6 +158,27 @@ export function Component({profileView}: {profileView: ProfileViewModel}) {
|
|||
)
|
||||
}
|
||||
|
||||
const renderPendingInviteItem = ({item}: {item: Assertion}) => {
|
||||
const wasDeleted = deletedPendingInvites[item.uri]
|
||||
if (wasDeleted) {
|
||||
return <View />
|
||||
}
|
||||
return (
|
||||
<ProfileCard
|
||||
did={item.subject.did}
|
||||
handle={item.subject.handle}
|
||||
displayName={item.subject.displayName}
|
||||
renderButton={() => (
|
||||
<>
|
||||
<FontAwesomeIcon icon="x" style={[s.mr5]} size={14} />
|
||||
<Text style={[s.fw400, s.f14]}>Undo invite</Text>
|
||||
</>
|
||||
)}
|
||||
onPressButton={() => onPressDeleteInvite(item)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const Suggestions = () => (
|
||||
<View style={s.flex1}>
|
||||
{hasSetup ? (
|
||||
|
@ -163,11 +218,30 @@ export function Component({profileView}: {profileView: ProfileViewModel}) {
|
|||
)
|
||||
|
||||
const PendingInvites = () => (
|
||||
<View>
|
||||
<View style={styles.todoContainer}>
|
||||
<Text style={styles.todoLabel}>
|
||||
Pending invites are still being implemented. Check back soon!
|
||||
<View style={s.flex1}>
|
||||
{suggestions.sceneAssertionsView.isLoading ? (
|
||||
<ActivityIndicator />
|
||||
) : undefined}
|
||||
<View style={s.flex1}>
|
||||
{!suggestions.unconfirmed.length ? (
|
||||
<Text
|
||||
style={{
|
||||
textAlign: 'center',
|
||||
paddingTop: 10,
|
||||
paddingHorizontal: 40,
|
||||
fontWeight: 'bold',
|
||||
color: colors.gray5,
|
||||
}}>
|
||||
No pending invites.
|
||||
</Text>
|
||||
) : (
|
||||
<FlatList
|
||||
data={suggestions.unconfirmed}
|
||||
keyExtractor={item => item._reactKey}
|
||||
renderItem={renderPendingInviteItem}
|
||||
style={s.flex1}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
|
@ -207,7 +281,7 @@ export function Component({profileView}: {profileView: ProfileViewModel}) {
|
|||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
title: {
|
||||
|
|
Loading…
Reference in New Issue