From 46909a3a25ee8dbc1ebb19f01e2cf00a679a38e8 Mon Sep 17 00:00:00 2001 From: Mattias Granlund Date: Wed, 29 Nov 2023 22:07:00 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=80=20feat:=20add=20state=20management?= =?UTF-8?q?=20for=20PR=20service=20and=20update=20createPullRequest=20meth?= =?UTF-8?q?od?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/ui/src/lib/github/pullrequest.ts | 76 +++++++++++++------ .../[projectId]/components/CommitList.svelte | 16 ++-- 2 files changed, 62 insertions(+), 30 deletions(-) diff --git a/packages/ui/src/lib/github/pullrequest.ts b/packages/ui/src/lib/github/pullrequest.ts index ef5526235..636cd4861 100644 --- a/packages/ui/src/lib/github/pullrequest.ts +++ b/packages/ui/src/lib/github/pullrequest.ts @@ -9,9 +9,14 @@ import { } from '$lib/github/types'; import { newClient } from '$lib/github/client'; +export type PrAction = 'creating_pr'; +export type PrServiceState = { busy: boolean; branchId: string; action?: PrAction }; + export class PrService { prs$: Observable; error$ = new BehaviorSubject(undefined); + + private stateMap = new Map>(); private reload$ = new BehaviorSubject<{ skipCache: boolean } | undefined>(undefined); private fresh$ = new Subject(); @@ -27,6 +32,7 @@ export class PrService { }), shareReplay(1), catchError((err) => { + console.log(err); this.error$.next(err); return of([]); }) @@ -42,6 +48,53 @@ export class PrService { if (!branch) return; return this.prs$.pipe(map((prs) => prs.find((pr) => pr.targetBranch == branch))); } + + /* TODO: Figure out a way to cleanup old behavior subjects */ + getState(branchId: string) { + let state$ = this.stateMap.get(branchId); + if (!state$) { + state$ = new BehaviorSubject({ busy: false, branchId }); + this.stateMap.set(branchId, state$); + } + return state$; + } + + private setBusy(action: PrAction, branchId: string) { + const state$ = this.getState(branchId); + state$.next({ busy: true, action, branchId }); + } + + private setIdle(branchId: string) { + const state$ = this.getState(branchId); + state$.next({ busy: false, branchId }); + } + + async createPullRequest( + ctx: GitHubIntegrationContext, + head: string, + base: string, + title: string, + body: string, + branchId: string + ): Promise { + const octokit = newClient(ctx); + this.setBusy('creating_pr', branchId); + try { + const rsp = await octokit.rest.pulls.create({ + owner: ctx.owner, + repo: ctx.repo, + head, + base, + title, + body + }); + return ghResponseToInstance(rsp.data); + } catch (e) { + console.log(e); + } finally { + this.setIdle(branchId); + } + } } function loadPrs(ctx: GitHubIntegrationContext, skipCache: boolean): Observable { @@ -90,26 +143,3 @@ export async function getPullRequestByBranch( console.log(e); } } - -export async function createPullRequest( - ctx: GitHubIntegrationContext, - head: string, - base: string, - title: string, - body: string -): Promise { - const octokit = newClient(ctx); - try { - const rsp = await octokit.rest.pulls.create({ - owner: ctx.owner, - repo: ctx.repo, - head, - base, - title, - body - }); - return ghResponseToInstance(rsp.data); - } catch (e) { - console.log(e); - } -} diff --git a/packages/ui/src/routes/[projectId]/components/CommitList.svelte b/packages/ui/src/routes/[projectId]/components/CommitList.svelte index 2578508ac..f9d390146 100644 --- a/packages/ui/src/routes/[projectId]/components/CommitList.svelte +++ b/packages/ui/src/routes/[projectId]/components/CommitList.svelte @@ -16,7 +16,7 @@ import { open } from '@tauri-apps/api/shell'; import toast from 'svelte-french-toast'; import { sleep } from '$lib/utils/sleep'; - import { createPullRequest, type PrService } from '$lib/github/pullrequest'; + import type { PrService } from '$lib/github/pullrequest'; export let branch: Branch; export let githubContext: GitHubIntegrationContext | undefined; @@ -48,6 +48,7 @@ } }); $: pr$ = prService.get(branchName); + $: prServiceState$ = prService.getState(branch.id); async function push(opts?: { createPr: boolean }) { isPushing = true; @@ -69,17 +70,20 @@ async function createPr(): Promise { if (githubContext && base?.branchName && branchName) { - const pr = await createPullRequest( + const pr = await prService.createPullRequest( githubContext, branchName, base.branchName.split('/').slice(-1)[0], branch.name, - branch.notes + branch.notes, + branch.id ); if (pr) { await prService.reload(); } return; + } else { + console.log('Unable to create pull request'); } } @@ -152,7 +156,7 @@ {#if githubContext && !$pr$ && type == 'local'} { @@ -168,8 +172,7 @@ wide kind="outlined" color="primary" - id="push-commits" - loading={isPushing} + loading={isPushing || $prServiceState$?.busy} on:click={async () => { try { await push({ createPr: true }); @@ -184,7 +187,6 @@