Merged origin/master into Update new branch styling

This commit is contained in:
Pavel Laptev 2024-01-05 14:34:17 +01:00 committed by GitButler
commit 8d762f88d0
10 changed files with 94 additions and 73 deletions

View File

@ -1,6 +1,9 @@
import { subscribeToFetches } from '$lib/backend/fetches';
import { Observable } from 'rxjs';
import { Observable, shareReplay, startWith } from 'rxjs';
export function getFetchNotifications(projectId: string): Observable<void> {
return new Observable((observer) => subscribeToFetches(projectId, () => observer.next()));
export function getFetchNotifications(projectId: string): Observable<unknown> {
return new Observable((observer) => subscribeToFetches(projectId, () => observer.next())).pipe(
startWith(undefined),
shareReplay(1)
);
}

View File

@ -1,10 +1,10 @@
import { getHead, subscribeToHead } from '$lib/backend/heads';
import { Observable, concat, from } from 'rxjs';
import { Observable, concat, from, shareReplay } from 'rxjs';
export function getHeads(projectId: string): Observable<string> {
const head$ = from(getHead(projectId));
const stream$ = new Observable<string>((subscriber) =>
subscribeToHead(projectId, (head) => subscriber.next(head))
);
return concat(head$, stream$);
return concat(head$, stream$).pipe(shareReplay(1));
}

View File

@ -5,9 +5,8 @@ import {
BehaviorSubject,
Observable,
catchError,
combineLatestWith,
combineLatest,
map,
merge,
of,
shareReplay,
switchMap
@ -24,8 +23,7 @@ export class RemoteBranchService {
head$: Observable<any>,
baseBranch$: Observable<any>
) {
this.branches$ = merge(fetches$, head$, baseBranch$).pipe(
combineLatestWith(this.reload$),
this.branches$ = combineLatest([baseBranch$, this.reload$, head$, fetches$]).pipe(
switchMap(() => getRemoteBranchesData({ projectId })),
map((branches) => branches.filter((b) => b.ahead != 0)),
shareReplay(1),

View File

@ -2,7 +2,6 @@ import { BaseBranch, Branch } from './types';
import { plainToInstance } from 'class-transformer';
import { UserError, invoke, listen } from '$lib/backend/ipc';
import {
merge,
switchMap,
Observable,
shareReplay,
@ -14,7 +13,8 @@ import {
tap,
map,
firstValueFrom,
timeout
timeout,
combineLatest
} from 'rxjs';
export class VirtualBranchService {
@ -83,8 +83,8 @@ export class BaseBranchService {
error$ = new BehaviorSubject<any>(undefined);
private reload$ = new BehaviorSubject<void>(undefined);
constructor(projectId: string, fetches$: Observable<void>, head$: Observable<string>) {
this.base$ = merge(fetches$, head$, this.reload$).pipe(
constructor(projectId: string, fetches$: Observable<unknown>, head$: Observable<string>) {
this.base$ = combineLatest([fetches$, head$, this.reload$]).pipe(
debounceTime(100),
switchMap(() => getBaseBranch({ projectId })),
catchError((e) => {

View File

@ -145,6 +145,8 @@
{readonly}
{branchController}
{branch}
{base}
{githubService}
projectId={project.id}
on:action={(e) => {
if (e.detail == 'generate-branch-name') {

View File

@ -2,17 +2,27 @@
import IconButton from '$lib/components/IconButton.svelte';
import Icon from '$lib/icons/Icon.svelte';
import type { BranchController } from '$lib/vbranches/branchController';
import type { Branch } from '$lib/vbranches/types';
import type { BaseBranch, Branch } from '$lib/vbranches/types';
import { fade } from 'svelte/transition';
import BranchLabel from './BranchLabel.svelte';
import BranchLanePopupMenu from './BranchLanePopupMenu.svelte';
import { clickOutside } from '$lib/clickOutside';
import Tag from './Tag.svelte';
import { branchUrl } from './commitList';
import type { GitHubService } from '$lib/github/service';
import BranchIcon from '../navigation/BranchIcon.svelte';
import { open } from '@tauri-apps/api/shell';
export let readonly = false;
export let branch: Branch;
export let base: BaseBranch | undefined | null;
export let branchController: BranchController;
export let projectId: string;
export let githubService: GitHubService;
$: pr$ = githubService.get(branch.upstreamName);
// $: prStatus$ = githubService.getStatus($pr$?.targetBranch);
let meatballButton: HTMLDivElement;
let visible = false;
@ -24,7 +34,7 @@
</script>
<div class="card__header relative" data-drag-handle>
<div class="card__row" data-drag-handle>
<div class="header__row" data-drag-handle>
<div class="header__left">
{#if !readonly}
<div class="draggable" data-drag-handle>
@ -48,17 +58,51 @@
</div>
</div>
{#if branch.upstreamName}
<div class="card__row text-base-11" data-drag-handle>
<div class="card__remote">
{#if !branch.upstream}
{#if hasIntegratedCommits}
<div class="status-tag deleted">deleted</div>
{:else}
<div class="status-tag pending">pending</div>
{/if}
<div class="header__remote-branch text-base-body-11" data-drag-handle>
{#if !branch.upstream}
{#if hasIntegratedCommits}
<div class="status-tag deleted">deleted</div>
{:else}
<div class="status-tag pending">pending</div>
{/if}
<div>origin/{branch.upstreamName}</div>
</div>
{/if}
<div>origin/{branch.upstreamName}</div>
</div>
{/if}
{#if branch.upstream}
<div class="header__links">
<BranchIcon name="remote-branch" color="neutral" />
<Tag
icon="open-link"
color="ghost"
border
clickable
on:click={(e) => {
const url = branchUrl(base, branch.upstream?.name);
if (url) open(url);
e.preventDefault();
e.stopPropagation();
}}
>
View remote branch
</Tag>
{#if $pr$?.htmlUrl}
<Tag
icon="pr-small"
color="ghost"
border
clickable
on:click={(e) => {
const url = $pr$?.htmlUrl;
if (url) open(url);
e.preventDefault();
e.stopPropagation();
}}
>
View PR
</Tag>
{/if}
</div>
{/if}
</div>
@ -72,12 +116,11 @@
.card__header:hover .draggable {
color: var(--clr-theme-scale-ntrl-40);
}
.card__row {
.header__row {
width: 100%;
display: flex;
justify-content: space-between;
gap: var(--space-8);
align-items: center;
overflow-x: hidden;
}
.header__left {
@ -89,6 +132,15 @@
gap: var(--space-4);
}
.header__links {
display: flex;
gap: var(--space-6);
align-items: center;
padding-left: var(--space-28);
margin-top: var(--space-10);
fill: var(--clr-core-ntrl-50);
}
.draggable {
display: flex;
cursor: grab;
@ -103,14 +155,14 @@
z-index: 10;
}
.card__remote {
.header__remote-branch {
color: var(--clr-theme-scale-ntrl-50);
padding-left: var(--space-28);
display: flex;
gap: var(--space-4);
text-overflow: ellipsis;
overflow-x: hidden;
white-space: nowrap;
color: var(--clr-theme-scale-ntrl-50);
align-items: center;
}
@ -118,10 +170,12 @@
padding: var(--space-2) var(--space-4);
border-radius: var(--radius-s);
}
.pending {
color: var(--clr-theme-scale-ntrl-40);
background: var(--clr-theme-container-sub);
}
.deleted {
color: var(--clr-theme-scale-warn-30);
background: var(--clr-theme-warn-container-dim);

View File

@ -29,15 +29,12 @@
return c.isIntegrated;
}
});
$: pr$ = githubService.get(branch.upstreamName);
// $: prStatus$ = githubService.getStatus($pr$?.targetBranch);
let expanded = true;
</script>
{#if commits.length > 0}
<div class="commit-list" style:min-height={expanded ? `${2 * headerHeight}px` : undefined}>
<CommitListHeader bind:expanded {branch} {pr$} {type} {base} bind:height={headerHeight} />
<CommitListHeader bind:expanded {type} bind:height={headerHeight} />
{#if expanded}
<div class="commit-list__content">
<div class="commits">

View File

@ -1,20 +1,10 @@
<script lang="ts">
import type { PullRequest } from '$lib/github/types';
import type { BaseBranch, Branch } from '$lib/vbranches/types';
import type { Observable } from 'rxjs';
import { branchUrl, type CommitType } from './commitList';
import { open } from '@tauri-apps/api/shell';
import Link from '$lib/components/Link.svelte';
import Icon from '$lib/icons/Icon.svelte';
import Tag from './Tag.svelte';
import { onMount } from 'svelte';
import type { CommitType } from './commitList';
export let branch: Branch;
export let expanded: boolean;
export let pr$: Observable<PullRequest | undefined> | undefined;
// export let prStatus$: Observable<PrStatus | undefined> | undefined;
export let type: CommitType;
export let base: BaseBranch | undefined | null;
export let height: number | undefined;
let element: HTMLButtonElement | undefined = undefined;
@ -38,32 +28,7 @@
{#if type == 'local'}
Local
{:else if type == 'remote'}
{#if branch.upstream}
<Link
target="_blank"
rel="noreferrer"
href={branchUrl(base, branch.upstream?.name)}
class="inline-block max-w-full truncate"
>
Remote
</Link>
{#if $pr$?.htmlUrl}
<Tag
icon="pr-small"
color="ghost"
border
clickable
on:click={(e) => {
const url = $pr$?.htmlUrl;
if (url) open(url);
e.preventDefault();
e.stopPropagation();
}}
>
View PR
</Tag>
{/if}
{/if}
Remote branch
{:else if type == 'integrated'}
Integrated
{/if}

View File

@ -2,8 +2,11 @@ import type { BaseBranch } from '$lib/vbranches/types';
export type CommitType = 'local' | 'remote' | 'integrated';
export function branchUrl(target: BaseBranch | undefined | null, upstreamBranchName: string) {
if (!target) return undefined;
export function branchUrl(
target: BaseBranch | undefined | null,
upstreamBranchName: string | undefined
) {
if (!target || !upstreamBranchName) return undefined;
const baseBranchName = target.branchName.split('/')[1];
const parts = upstreamBranchName.split('/');
const branchName = parts[parts.length - 1];

View File

@ -12,7 +12,6 @@
justify-content: space-between;
padding: var(--space-12);
gap: var(--space-8);
align-items: center;
border-bottom: 1px solid var(--clr-theme-container-outline-light);
}