chore: split app to commons and web (squash commit)

This commit is contained in:
Andrew Bastin
2022-12-02 02:57:46 -05:00
parent fb827e3586
commit 3d004f2322
535 changed files with 1487 additions and 501 deletions

View File

@@ -0,0 +1,8 @@
/**
* Defines how a Shortcode is represented in the ShortcodeListAdapter
*/
export interface Shortcode {
id: string
request: string
createdOn: Date
}

View File

@@ -0,0 +1,170 @@
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 myShortcodesCreated: Subscription | null
private myShortcodesRevoked: Subscription | null
private myShortcodesCreatedSub: WSubscription | null
private myShortcodesRevokedSub: 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.myShortcodesCreated = null
this.myShortcodesRevoked = null
this.myShortcodesCreatedSub = null
this.myShortcodesRevokedSub = null
if (!deferInit) this.initialize()
}
unsubscribeSubscriptions() {
this.myShortcodesCreated?.unsubscribe()
this.myShortcodesRevoked?.unsubscribe()
this.myShortcodesCreatedSub?.unsubscribe()
this.myShortcodesRevokedSub?.unsubscribe()
}
initialize() {
if (!this.isDispose) throw new Error(`Adapter is already initialized`)
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.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 short codes list: ${result.left}`)
}
const fetchedResult = result.right.myShortcodes
this.pushNewShortcodes(fetchedResult)
if (fetchedResult.length !== BACKEND_PAGE_SIZE) {
this.hasMoreShortcodes$.next(false)
}
this.loading$.next(false)
}
private pushNewShortcodes(results: Shortcode[]) {
const userShortcodes = this.shortcodes$.value
userShortcodes.push(...results)
this.shortcodes$.next(userShortcodes)
}
private createShortcode(shortcode: Shortcode) {
const userShortcodes = this.shortcodes$.value
userShortcodes.unshift(shortcode)
this.shortcodes$.next(userShortcodes)
}
private deleteShortcode(codeId: string) {
const newShortcodes = this.shortcodes$.value.filter(
({ id }) => id !== codeId
)
this.shortcodes$.next(newShortcodes)
}
private registerSubscriptions() {
const [myShortcodeCreated$, myShortcodeCreatedSub] =
runAuthOnlyGQLSubscription({
query: ShortcodeCreatedDocument,
})
this.myShortcodesCreatedSub = myShortcodeCreatedSub
this.myShortcodesCreated = myShortcodeCreated$.subscribe((result) => {
if (E.isLeft(result)) {
console.error(result.left)
throw new Error(`Shortcode Create Error ${result.left}`)
}
this.createShortcode(result.right.myShortcodesCreated)
})
const [myShortcodesRevoked$, myShortcodeRevokedSub] =
runAuthOnlyGQLSubscription({
query: ShortcodeDeletedDocument,
})
this.myShortcodesRevokedSub = myShortcodeRevokedSub
this.myShortcodesRevoked = myShortcodesRevoked$.subscribe((result) => {
if (E.isLeft(result)) {
console.error(result.left)
throw new Error(`Shortcode Delete Error ${result.left}`)
}
this.deleteShortcode(result.right.myShortcodesRevoked.id)
})
}
}