feat: shared request (#3486)

Co-authored-by: jamesgeorge007 <jamesgeorge998001@gmail.com>
This commit is contained in:
Nivedin
2023-12-04 22:51:18 +05:30
committed by GitHub
parent 259cd48dbb
commit 2528bbb92f
35 changed files with 1525 additions and 517 deletions

View File

@@ -0,0 +1,9 @@
/**
* Defines how a Shortcode is represented in the ShortcodeListAdapter
*/
export interface Shortcode {
id: string
request: string
properties?: string | null | undefined
createdOn: Date
}

View File

@@ -0,0 +1,173 @@
import * as E from "fp-ts/Either"
import { BehaviorSubject, Subscription } from "rxjs"
import { Subscription as WSubscription } from "wonka"
import {
GQLError,
runAuthOnlyGQLSubscription,
runGQLQuery,
} from "../backend/GQLClient"
import {
GetUserShortcodesQuery,
GetUserShortcodesDocument,
ShortcodeCreatedDocument,
ShortcodeDeletedDocument,
} from "../backend/graphql"
import { BACKEND_PAGE_SIZE } from "../backend/helpers"
import { Shortcode } from "./Shortcode"
export default class ShortcodeListAdapter {
error$: BehaviorSubject<GQLError<string> | null>
loading$: BehaviorSubject<boolean>
shortcodes$: BehaviorSubject<GetUserShortcodesQuery["myShortcodes"]>
hasMoreShortcodes$: BehaviorSubject<boolean>
private isDispose: boolean
private shortcodeCreated: Subscription | null
private shortcodeRevoked: Subscription | null
private shortcodeCreatedSub: WSubscription | null
private shortcodeRevokedSub: WSubscription | null
constructor(deferInit = false) {
this.error$ = new BehaviorSubject<GQLError<string> | null>(null)
this.loading$ = new BehaviorSubject<boolean>(false)
this.shortcodes$ = new BehaviorSubject<
GetUserShortcodesQuery["myShortcodes"]
>([])
this.hasMoreShortcodes$ = new BehaviorSubject<boolean>(true)
this.isDispose = true
this.shortcodeCreated = null
this.shortcodeRevoked = null
this.shortcodeCreatedSub = null
this.shortcodeRevokedSub = null
if (!deferInit) this.initialize()
}
unsubscribeSubscriptions() {
this.shortcodeCreated?.unsubscribe()
this.shortcodeRevoked?.unsubscribe()
this.shortcodeCreatedSub?.unsubscribe()
this.shortcodeRevokedSub?.unsubscribe()
}
initialize() {
if (!this.isDispose) throw new Error(`Adapter is already initialized`)
this.isDispose = false
this.fetchList()
this.registerSubscriptions()
}
/**
* Returns whether the shortcode adapter is active and initialized
*/
public isInitialized() {
return !this.isDispose
}
public dispose() {
if (this.isDispose) throw new Error(`Adapter has been disposed`)
this.isDispose = true
this.shortcodes$.next([])
this.unsubscribeSubscriptions()
}
fetchList() {
this.loadMore(true)
}
async loadMore(forcedAttempt = false) {
if (!this.hasMoreShortcodes$.value && !forcedAttempt) return
this.loading$.next(true)
const lastCodeID =
this.shortcodes$.value.length > 0
? this.shortcodes$.value[this.shortcodes$.value.length - 1].id
: undefined
const result = await runGQLQuery({
query: GetUserShortcodesDocument,
variables: {
cursor: lastCodeID,
},
})
if (E.isLeft(result)) {
this.error$.next(result.left)
console.error(result.left)
this.loading$.next(false)
throw new Error(`Failed fetching shortcodes list: ${result.left}`)
}
const fetchedResult = result.right.myShortcodes
this.pushNewShortcode(fetchedResult)
if (fetchedResult.length !== BACKEND_PAGE_SIZE) {
this.hasMoreShortcodes$.next(false)
}
this.loading$.next(false)
}
private pushNewShortcode(results: Shortcode[]) {
const userShortcodes = this.shortcodes$.value
userShortcodes.push(...results)
this.shortcodes$.next(userShortcodes)
}
private createShortcode(shortcode: Shortcode) {
const userShortcode = this.shortcodes$.value
userShortcode.unshift(shortcode)
this.shortcodes$.next(userShortcode)
}
private deleteSharedRequest(codeId: string) {
const newShortcode = this.shortcodes$.value.filter(
({ id }) => id !== codeId
)
this.shortcodes$.next(newShortcode)
}
private registerSubscriptions() {
const [shortcodeCreated$, shortcodeCreatedSub] = runAuthOnlyGQLSubscription(
{
query: ShortcodeCreatedDocument,
}
)
this.shortcodeCreatedSub = shortcodeCreatedSub
this.shortcodeCreated = shortcodeCreated$.subscribe((result) => {
if (E.isLeft(result)) {
console.error(result.left)
throw new Error(`Shortcode Create Error ${result.left}`)
}
this.createShortcode(result.right.myShortcodesCreated)
})
const [shortcodeRevoked$, shortcodeRevokedSub] = runAuthOnlyGQLSubscription(
{
query: ShortcodeDeletedDocument,
}
)
this.shortcodeRevokedSub = shortcodeRevokedSub
this.shortcodeRevoked = shortcodeRevoked$.subscribe((result) => {
if (E.isLeft(result)) {
console.error(result.left)
throw new Error(`Shortcode Delete Error ${result.left}`)
}
this.deleteSharedRequest(result.right.myShortcodesRevoked.id)
})
}
}