get rid of virtual / remote confusion

This commit is contained in:
Nikita Galaiko 2023-09-15 12:46:25 +02:00 committed by GitButler
parent 797942fedd
commit edbbe1f0a8
13 changed files with 189 additions and 116 deletions

View File

@ -366,6 +366,7 @@ impl App {
let diff = Self::diff_hunks_to_string(diff); let diff = Self::diff_hunks_to_string(diff);
Ok(diff) Ok(diff)
} }
pub fn git_commit_diff( pub fn git_commit_diff(
&self, &self,
project_id: &str, project_id: &str,

View File

@ -1,12 +1,13 @@
use std::{collections::HashMap, path}; use std::{collections::HashMap, path};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use serde::Serialize;
use crate::git; use crate::git;
use super::Repository; use super::Repository;
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone, Serialize)]
pub struct Hunk { pub struct Hunk {
pub old_start: usize, pub old_start: usize,
pub old_lines: usize, pub old_lines: usize,

View File

@ -8,7 +8,7 @@ use futures::future::join_all;
use tauri::{generate_context, Manager}; use tauri::{generate_context, Manager};
use tracing::instrument; use tracing::instrument;
use gitbutler::{virtual_branches::VirtualBranchCommit, *}; use gitbutler::*;
use crate::{error::Error, git, project_repository::activity}; use crate::{error::Error, git, project_repository::activity};
@ -366,7 +366,7 @@ async fn git_remote_branches_data(
.map(|commit| { .map(|commit| {
let proxy = proxy.clone(); let proxy = proxy.clone();
async move { async move {
VirtualBranchCommit { virtual_branches::RemoteCommit {
author: virtual_branches::Author { author: virtual_branches::Author {
gravatar_url: proxy gravatar_url: proxy
.proxy(&commit.author.gravatar_url) .proxy(&commit.author.gravatar_url)

View File

@ -451,7 +451,7 @@ pub fn target_to_base_branch(
.log(oid, project_repository::LogUntil::Commit(target.sha)) .log(oid, project_repository::LogUntil::Commit(target.sha))
.context("failed to get upstream commits")? .context("failed to get upstream commits")?
.iter() .iter()
.map(|c| super::commit_to_vbranch_commit(project_repository, target, c, None)) .map(|commit| super::commit_to_remote_commit(&project_repository.git_repository, commit))
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
// get some recent commits // get some recent commits
@ -459,7 +459,7 @@ pub fn target_to_base_branch(
.log(target.sha, LogUntil::Take(20)) .log(target.sha, LogUntil::Take(20))
.context("failed to get recent commits")? .context("failed to get recent commits")?
.iter() .iter()
.map(|c| super::commit_to_vbranch_commit(project_repository, target, c, None)) .map(|commit| super::commit_to_remote_commit(&project_repository.git_repository, commit))
.collect::<Result<Vec<_>>>()?; .collect::<Result<Vec<_>>>()?;
let base = super::BaseBranch { let base = super::BaseBranch {
@ -576,7 +576,8 @@ pub fn create_virtual_branch_from_branch(
// do a diff between the head of this branch and the target base // do a diff between the head of this branch and the target base
let diff = diff::trees(&project_repository.git_repository, &merge_tree, &tree) let diff = diff::trees(&project_repository.git_repository, &merge_tree, &tree)
.context("failed to diff trees")?; .context("failed to diff trees")?;
let hunks_by_filepath = super::hunks_by_filepath(project_repository, &diff); let hunks_by_filepath =
super::virtual_hunks_by_filepath(&project_repository.git_repository, &diff);
// assign ownership to the branch // assign ownership to the branch
for hunk in hunks_by_filepath.values().flatten() { for hunk in hunks_by_filepath.values().flatten() {

View File

@ -349,7 +349,7 @@ impl Controller {
.recent_commits .recent_commits
.into_iter() .into_iter()
.map(|commit| async move { .map(|commit| async move {
super::VirtualBranchCommit { super::RemoteCommit {
author: super::Author { author: super::Author {
gravatar_url: self gravatar_url: self
.assets_proxy .assets_proxy
@ -373,7 +373,7 @@ impl Controller {
.upstream_commits .upstream_commits
.into_iter() .into_iter()
.map(|commit| async move { .map(|commit| async move {
super::VirtualBranchCommit { super::RemoteCommit {
author: super::Author { author: super::Author {
gravatar_url: self gravatar_url: self
.assets_proxy .assets_proxy

View File

@ -64,7 +64,6 @@ pub struct VirtualBranchCommit {
pub created_at: u128, pub created_at: u128,
pub author: Author, pub author: Author,
pub is_remote: bool, pub is_remote: bool,
// only present if is_remote is false
pub files: Vec<VirtualBranchFile>, pub files: Vec<VirtualBranchFile>,
pub is_integrated: bool, pub is_integrated: bool,
} }
@ -88,6 +87,14 @@ pub struct VirtualBranchFile {
pub binary: bool, pub binary: bool,
} }
#[derive(Debug, PartialEq, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RemoteBranchFile {
pub path: path::PathBuf,
pub hunks: Vec<git::diff::Hunk>,
pub binary: bool,
}
// this struct is a mapping to the view `Hunk` type in Typescript // this struct is a mapping to the view `Hunk` type in Typescript
// found in src-tauri/src/routes/repo/[project_id]/types.ts // found in src-tauri/src/routes/repo/[project_id]/types.ts
// it holds a materialized view for presentation purposes of one entry of the // it holds a materialized view for presentation purposes of one entry of the
@ -110,6 +117,19 @@ pub struct VirtualBranchHunk {
pub locked: bool, pub locked: bool,
} }
#[derive(Debug, PartialEq, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RemoteBranchHunk {
pub id: String,
pub diff: String,
pub modified_at: u128,
pub file_path: path::PathBuf,
pub hash: String,
pub start: usize,
pub end: usize,
pub binary: bool,
}
// this struct is a mapping to the view `RemoteBranch` type in Typescript // this struct is a mapping to the view `RemoteBranch` type in Typescript
// found in src-tauri/src/routes/repo/[project_id]/types.ts // found in src-tauri/src/routes/repo/[project_id]/types.ts
// //
@ -127,7 +147,17 @@ pub struct RemoteBranch {
pub behind: u32, pub behind: u32,
pub upstream: Option<git::RemoteBranchName>, pub upstream: Option<git::RemoteBranchName>,
pub mergeable: bool, pub mergeable: bool,
pub commits: Vec<VirtualBranchCommit>, pub commits: Vec<RemoteCommit>,
}
#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct RemoteCommit {
pub id: String,
pub description: String,
pub created_at: u128,
pub author: Author,
pub files: Vec<RemoteBranchFile>,
} }
#[derive(Debug, Serialize, PartialEq, Clone)] #[derive(Debug, Serialize, PartialEq, Clone)]
@ -139,8 +169,8 @@ pub struct BaseBranch {
pub base_sha: String, pub base_sha: String,
pub current_sha: String, pub current_sha: String,
pub behind: u32, pub behind: u32,
pub upstream_commits: Vec<VirtualBranchCommit>, pub upstream_commits: Vec<RemoteCommit>,
pub recent_commits: Vec<VirtualBranchCommit>, pub recent_commits: Vec<RemoteCommit>,
} }
#[derive(Debug, Serialize, Hash, Clone, PartialEq, Eq)] #[derive(Debug, Serialize, Hash, Clone, PartialEq, Eq)]
@ -572,74 +602,91 @@ pub fn list_remote_branches(
let mut branches: Vec<RemoteBranch> = Vec::new(); let mut branches: Vec<RemoteBranch> = Vec::new();
for branch in &top_branches { for branch in &top_branches {
let branch_name = branch.refname().context("could not get branch name")?; if let Some(branch_oid) = branch.target() {
match branch.target() { let ahead = project_repository
Some(branch_oid) => { .log(branch_oid, LogUntil::Commit(main_oid))
// get the branch ref .context("failed to get ahead commits")?;
let branch_commit = repo
.find_commit(branch_oid)
.context("failed to find branch commit")?;
let count_behind = project_repository if ahead.is_empty() {
.distance(main_oid, branch_oid) continue;
.context("failed to get behind count")?;
let ahead = project_repository
.log(branch_oid, LogUntil::Commit(main_oid))
.context("failed to get ahead commits")?;
let count_ahead = ahead.len();
let upstream = branch
.upstream()
.ok()
.map(|upstream_branch| git::RemoteBranchName::try_from(&upstream_branch))
.transpose()?;
if count_ahead > 0 {
if let Ok(base_tree) = find_base_tree(repo, &branch_commit, &target_commit) {
// determine if this tree is mergeable
let branch_tree = branch_commit.tree()?;
let mergeable = !repo
.merge_trees(&base_tree, &branch_tree, &wd_tree)?
.has_conflicts();
branches.push(RemoteBranch {
sha: branch_oid.to_string(),
name: branch_name.to_string(),
upstream,
behind: count_behind,
mergeable,
commits: ahead
.into_iter()
.map(|commit| {
commit_to_vbranch_commit(
project_repository,
&default_target,
&commit,
None,
)
})
.collect::<Result<Vec<_>>>()?,
});
};
}
}
None => {
// this is a detached head
branches.push(RemoteBranch {
sha: "".to_string(),
name: branch_name.to_string(),
behind: 0,
upstream: None,
mergeable: false,
commits: vec![],
});
} }
let branch_name = branch.refname().context("could not get branch name")?;
// get the branch ref
let branch_commit = repo
.find_commit(branch_oid)
.context("failed to find branch commit")?;
let count_behind = project_repository
.distance(main_oid, branch_oid)
.context("failed to get behind count")?;
let upstream = branch
.upstream()
.ok()
.map(|upstream_branch| git::RemoteBranchName::try_from(&upstream_branch))
.transpose()?;
let base_tree = find_base_tree(repo, &branch_commit, &target_commit)?;
// determine if this tree is mergeable
let branch_tree = branch_commit.tree()?;
let mergeable = !repo
.merge_trees(&base_tree, &branch_tree, &wd_tree)?
.has_conflicts();
branches.push(RemoteBranch {
sha: branch_oid.to_string(),
name: branch_name.to_string(),
upstream,
behind: count_behind,
mergeable,
commits: ahead
.into_iter()
.map(|commit| commit_to_remote_commit(repo, &commit))
.collect::<Result<Vec<_>>>()?,
});
} }
} }
Ok(branches) Ok(branches)
} }
pub fn commit_to_remote_commit(
repository: &git::Repository,
commit: &git::Commit,
) -> Result<RemoteCommit> {
Ok(RemoteCommit {
id: commit.id().to_string(),
description: commit.message().unwrap_or_default().to_string(),
created_at: commit.time().seconds().try_into().unwrap(),
author: commit.author().into(),
files: list_remote_commit_files(repository, commit)?,
})
}
fn list_remote_commit_files(
repository: &git::Repository,
commit: &git::Commit,
) -> Result<Vec<RemoteBranchFile>> {
if commit.parent_count() == 0 {
return Ok(vec![]);
}
let parent = commit.parent(0).context("failed to get parent commit")?;
let commit_tree = commit.tree().context("failed to get commit tree")?;
let parent_tree = parent.tree().context("failed to get parent tree")?;
let diff = diff::trees(repository, &parent_tree, &commit_tree)?;
let files = diff
.into_iter()
.map(|(file_path, hunks)| RemoteBranchFile {
path: file_path.clone(),
hunks: hunks.clone(),
binary: hunks.iter().any(|h| h.binary),
})
.collect::<Vec<_>>();
Ok(files)
}
pub fn get_wd_tree(repo: &git::Repository) -> Result<git::Tree> { pub fn get_wd_tree(repo: &git::Repository) -> Result<git::Tree> {
let mut index = repo.index()?; let mut index = repo.index()?;
index.add_all(["*"], git2::IndexAddOption::DEFAULT, None)?; index.add_all(["*"], git2::IndexAddOption::DEFAULT, None)?;
@ -819,7 +866,8 @@ fn calculate_non_commited_files(
) )
.context("failed to diff trees")?; .context("failed to diff trees")?;
let non_commited_hunks_by_filepath = super::hunks_by_filepath(project_repository, &diff); let non_commited_hunks_by_filepath =
super::virtual_hunks_by_filepath(&project_repository.git_repository, &diff);
let file_hunks = files let file_hunks = files
.iter() .iter()
@ -910,7 +958,7 @@ fn calculate_non_commited_files(
Ok(vfiles) Ok(vfiles)
} }
fn list_commit_files( fn list_virtual_commit_files(
project_repository: &project_repository::Repository, project_repository: &project_repository::Repository,
commit: &git::Commit, commit: &git::Commit,
) -> Result<Vec<VirtualBranchFile>> { ) -> Result<Vec<VirtualBranchFile>> {
@ -925,8 +973,8 @@ fn list_commit_files(
&parent_tree, &parent_tree,
&commit_tree, &commit_tree,
)?; )?;
let hunks_by_filepath = hunks_by_filepath(project_repository, &diff); let hunks_by_filepath = virtual_hunks_by_filepath(&project_repository.git_repository, &diff);
Ok(hunks_to_files( Ok(virtual_hunks_to_virtual_files(
project_repository, project_repository,
&hunks_by_filepath &hunks_by_filepath
.values() .values()
@ -952,11 +1000,8 @@ pub fn commit_to_vbranch_commit(
None => true, None => true,
}; };
let files = if is_remote { let files =
vec![] list_virtual_commit_files(repository, commit).context("failed to list commit files")?;
} else {
list_commit_files(repository, commit).context("failed to list commit files")?
};
let is_integrated = is_commit_integrated(repository, target, commit)?; let is_integrated = is_commit_integrated(repository, target, commit)?;
@ -1242,8 +1287,8 @@ fn diff_hash(diff: &str) -> String {
format!("{:x}", md5::compute(addition)) format!("{:x}", md5::compute(addition))
} }
pub fn hunks_by_filepath( pub fn virtual_hunks_by_filepath(
project_repository: &project_repository::Repository, repository: &git::Repository,
diff: &HashMap<path::PathBuf, Vec<diff::Hunk>>, diff: &HashMap<path::PathBuf, Vec<diff::Hunk>>,
) -> HashMap<path::PathBuf, Vec<VirtualBranchHunk>> { ) -> HashMap<path::PathBuf, Vec<VirtualBranchHunk>> {
let mut mtimes: HashMap<path::PathBuf, u128> = HashMap::new(); let mut mtimes: HashMap<path::PathBuf, u128> = HashMap::new();
@ -1253,7 +1298,7 @@ pub fn hunks_by_filepath(
.iter() .iter()
.map(|hunk| VirtualBranchHunk { .map(|hunk| VirtualBranchHunk {
id: format!("{}-{}", hunk.new_start, hunk.new_start + hunk.new_lines), id: format!("{}-{}", hunk.new_start, hunk.new_start + hunk.new_lines),
modified_at: get_mtime(&mut mtimes, &project_repository.path().join(file_path)), modified_at: get_mtime(&mut mtimes, &repository.path().join(file_path)),
file_path: file_path.clone(), file_path: file_path.clone(),
diff: hunk.diff.clone(), diff: hunk.diff.clone(),
start: hunk.new_start, start: hunk.new_start,
@ -1369,7 +1414,8 @@ fn get_non_applied_status(
.collect::<HashMap<_, _>>() .collect::<HashMap<_, _>>()
}) })
.collect::<HashMap<_, _>>(); .collect::<HashMap<_, _>>();
let hunks_by_filepath = hunks_by_filepath(project_repository, &diff); let hunks_by_filepath =
virtual_hunks_by_filepath(&project_repository.git_repository, &diff);
let hunks_by_filepath = hunks_by_filepath let hunks_by_filepath = hunks_by_filepath
.values() .values()
.flatten() .flatten()
@ -1409,7 +1455,8 @@ fn get_applied_status(
) )
.context("failed to diff")?; .context("failed to diff")?;
let mut hunks_by_filepath = hunks_by_filepath(project_repository, &diff); let mut hunks_by_filepath =
virtual_hunks_by_filepath(&project_repository.git_repository, &diff);
// sort by order, so that the default branch is first (left in the ui) // sort by order, so that the default branch is first (left in the ui)
virtual_branches.sort_by(|a, b| a.order.cmp(&b.order)); virtual_branches.sort_by(|a, b| a.order.cmp(&b.order));
@ -1584,7 +1631,7 @@ fn get_applied_status(
Ok(files_by_branch) Ok(files_by_branch)
} }
fn hunks_to_files( fn virtual_hunks_to_virtual_files(
project_repository: &project_repository::Repository, project_repository: &project_repository::Repository,
hunks: &[VirtualBranchHunk], hunks: &[VirtualBranchHunk],
) -> Vec<VirtualBranchFile> { ) -> Vec<VirtualBranchFile> {
@ -1619,7 +1666,7 @@ fn group_virtual_hunks(
hunks_by_branch hunks_by_branch
.iter() .iter()
.map(|(branch, hunks)| { .map(|(branch, hunks)| {
let mut files = hunks_to_files(project_repository, hunks); let mut files = virtual_hunks_to_virtual_files(project_repository, hunks);
files.sort_by(|a, b| { files.sort_by(|a, b| {
branch branch
.ownership .ownership

View File

@ -1,4 +1,4 @@
import type { Branch, BranchData, BaseBranch, WritableReloadable } from './types'; import type { Branch, RemoteBranch, BaseBranch, WritableReloadable } from './types';
import * as toasts from '$lib/toasts'; import * as toasts from '$lib/toasts';
import { invoke } from '$lib/ipc'; import { invoke } from '$lib/ipc';
@ -6,7 +6,7 @@ export class BranchController {
constructor( constructor(
readonly projectId: string, readonly projectId: string,
readonly virtualBranchStore: WritableReloadable<Branch[] | undefined>, readonly virtualBranchStore: WritableReloadable<Branch[] | undefined>,
readonly remoteBranchStore: WritableReloadable<BranchData[] | undefined>, readonly remoteBranchStore: WritableReloadable<RemoteBranch[] | undefined>,
readonly targetBranchStore: WritableReloadable<BaseBranch | undefined> readonly targetBranchStore: WritableReloadable<BaseBranch | undefined>
) {} ) {}

View File

@ -1,5 +1,5 @@
import { asyncWritable, type Readable } from '@square/svelte-store'; import { asyncWritable, type Readable } from '@square/svelte-store';
import { BaseBranch, Branch, BranchData, type WritableReloadable } from './types'; import { BaseBranch, Branch, RemoteBranch, type WritableReloadable } from './types';
import { plainToInstance } from 'class-transformer'; import { plainToInstance } from 'class-transformer';
import { invoke } from '$lib/ipc'; import { invoke } from '$lib/ipc';
import { isDelete, isInsert, type Delta } from '$lib/api/ipc/deltas'; import { isDelete, isInsert, type Delta } from '$lib/api/ipc/deltas';
@ -36,13 +36,13 @@ export function getRemoteBranchStore(projectId: string, asyncStores: Readable<an
async () => getRemoteBranchesData({ projectId }), async () => getRemoteBranchesData({ projectId }),
async (newRemotes) => newRemotes, async (newRemotes) => newRemotes,
{ reloadable: true, trackState: true } { reloadable: true, trackState: true }
) as WritableReloadable<BranchData[] | undefined>; ) as WritableReloadable<RemoteBranch[] | undefined>;
} }
export function getBaseBranchStore(projectId: string, asyncStores: Readable<any>[]) { export function getBaseBranchStore(projectId: string, asyncStores: Readable<any>[]) {
return asyncWritable( return asyncWritable(
asyncStores, asyncStores,
async () => getBaseBranchData({ projectId }), async () => getBaseBranch({ projectId }),
async (newBaseBranch) => newBaseBranch, async (newBaseBranch) => newBaseBranch,
{ reloadable: true, trackState: true } { reloadable: true, trackState: true }
) as WritableReloadable<BaseBranch | undefined>; ) as WritableReloadable<BaseBranch | undefined>;
@ -56,11 +56,13 @@ export async function listVirtualBranches(params: { projectId: string }): Promis
return result; return result;
} }
export async function getRemoteBranchesData(params: { projectId: string }): Promise<BranchData[]> { export async function getRemoteBranchesData(params: {
return plainToInstance(BranchData, await invoke<any[]>('git_remote_branches_data', params)); projectId: string;
}): Promise<RemoteBranch[]> {
return plainToInstance(RemoteBranch, await invoke<any[]>('git_remote_branches_data', params));
} }
export async function getBaseBranchData(params: { projectId: string }): Promise<BaseBranch> { export async function getBaseBranch(params: { projectId: string }): Promise<BaseBranch> {
const baseBranch = plainToInstance(BaseBranch, await invoke<any>('get_base_branch_data', params)); const baseBranch = plainToInstance(BaseBranch, await invoke<any>('get_base_branch_data', params));
if (baseBranch) { if (baseBranch) {
// The rust code performs a fetch when get_base_branch_data is invoked // The rust code performs a fetch when get_base_branch_data is invoked

View File

@ -57,6 +57,27 @@ export class Commit {
files!: File[]; files!: File[];
} }
export class RemoteCommit {
id!: string;
author!: Author;
description!: string;
@Transform((obj) => new Date(obj.value))
createdAt!: Date;
@Type(() => RemoteFile)
files!: RemoteFile[];
}
export class RemoteHunk {
diff!: string;
}
export class RemoteFile {
path!: string;
@Type(() => RemoteHunk)
hunks!: RemoteHunk[];
binary!: boolean;
}
export class Author { export class Author {
email!: string; email!: string;
name!: string; name!: string;
@ -65,14 +86,14 @@ export class Author {
} }
// TODO: For consistency change Ts suffix to At, and return milliseconds from back end // TODO: For consistency change Ts suffix to At, and return milliseconds from back end
export class BranchData { export class RemoteBranch {
sha!: string; sha!: string;
name!: string; name!: string;
behind!: number; behind!: number;
upstream?: string; upstream?: string;
mergeable!: boolean; mergeable!: boolean;
@Type(() => Commit) @Type(() => RemoteCommit)
commits!: Commit[]; commits!: RemoteCommit[];
ahead(): number { ahead(): number {
return this.commits.length; return this.commits.length;
@ -98,10 +119,10 @@ export class BaseBranch {
baseSha!: string; baseSha!: string;
currentSha!: string; currentSha!: string;
behind!: number; behind!: number;
@Type(() => Commit) @Type(() => RemoteCommit)
upstreamCommits!: Commit[]; upstreamCommits!: RemoteCommit[];
@Type(() => Commit) @Type(() => RemoteCommit)
recentCommits!: Commit[]; recentCommits!: RemoteCommit[];
fetchedAt!: Date; fetchedAt!: Date;
get repoBaseUrl(): string { get repoBaseUrl(): string {

View File

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import type { Commit } from '$lib/vbranches/types'; import type { Commit, RemoteCommit } from '$lib/vbranches/types';
import TimeAgo from '$lib/components/TimeAgo/TimeAgo.svelte'; import TimeAgo from '$lib/components/TimeAgo/TimeAgo.svelte';
import Tooltip from '$lib/components/Tooltip/Tooltip.svelte'; import Tooltip from '$lib/components/Tooltip/Tooltip.svelte';
import { getCommitDiff } from '$lib/api/git/diffs'; import { getCommitDiff } from '$lib/api/git/diffs';
@ -10,7 +10,7 @@
import { IconExpandUpDown, IconExpandUp, IconExpandDown } from '$lib/icons'; import { IconExpandUpDown, IconExpandUp, IconExpandDown } from '$lib/icons';
import { Button, Modal } from '$lib/components'; import { Button, Modal } from '$lib/components';
export let commit: Commit; export let commit: Commit | RemoteCommit;
export let isIntegrated = false; export let isIntegrated = false;
export let url: string | undefined = undefined; export let url: string | undefined = undefined;
export let projectId: string; export let projectId: string;

View File

@ -2,7 +2,7 @@
import IconChevronLeft from '$lib/icons/IconChevronLeft.svelte'; import IconChevronLeft from '$lib/icons/IconChevronLeft.svelte';
import { SETTINGS_CONTEXT, type SettingsStore } from '$lib/userSettings'; import { SETTINGS_CONTEXT, type SettingsStore } from '$lib/userSettings';
import type { BranchController } from '$lib/vbranches/branchController'; import type { BranchController } from '$lib/vbranches/branchController';
import { BaseBranch, Branch, BranchData } from '$lib/vbranches/types'; import { BaseBranch, Branch, RemoteBranch } from '$lib/vbranches/types';
import { getContext } from 'svelte'; import { getContext } from 'svelte';
import type { Readable } from '@square/svelte-store'; import type { Readable } from '@square/svelte-store';
import BaseBranchPeek from './BaseBranchPeek.svelte'; import BaseBranchPeek from './BaseBranchPeek.svelte';
@ -11,7 +11,7 @@
import Lane from './BranchLane.svelte'; import Lane from './BranchLane.svelte';
import type { getCloudApiClient } from '$lib/api/cloud/api'; import type { getCloudApiClient } from '$lib/api/cloud/api';
export let item: Readable<BranchData | Branch | BaseBranch | undefined> | undefined; export let item: Readable<RemoteBranch | Branch | BaseBranch | undefined> | undefined;
export let cloud: ReturnType<typeof getCloudApiClient>; export let cloud: ReturnType<typeof getCloudApiClient>;
export let base: BaseBranch | undefined; export let base: BaseBranch | undefined;
export let branchController: BranchController; export let branchController: BranchController;
@ -68,7 +68,7 @@
class="h-full max-h-full w-full flex-grow overflow-y-hidden" class="h-full max-h-full w-full flex-grow overflow-y-hidden"
style:width={`${$userSettings.peekTrayWidth}px`} style:width={`${$userSettings.peekTrayWidth}px`}
> >
{#if $item instanceof BranchData} {#if $item instanceof RemoteBranch}
<RemoteBranchPeek {branchController} {base} branch={$item} /> <RemoteBranchPeek {branchController} {base} branch={$item} />
{:else if $item instanceof Branch} {:else if $item instanceof Branch}
<Lane <Lane

View File

@ -1,10 +1,10 @@
<script lang="ts"> <script lang="ts">
import Button from '$lib/components/Button/Button.svelte'; import Button from '$lib/components/Button/Button.svelte';
import type { BranchController } from '$lib/vbranches/branchController'; import type { BranchController } from '$lib/vbranches/branchController';
import type { BaseBranch, BranchData } from '$lib/vbranches/types'; import type { BaseBranch, RemoteBranch } from '$lib/vbranches/types';
import CommitCard from './CommitCard.svelte'; import CommitCard from './CommitCard.svelte';
export let branch: BranchData | undefined; export let branch: RemoteBranch | undefined;
export let base: BaseBranch | undefined; export let base: BaseBranch | undefined;
export let branchController: BranchController; export let branchController: BranchController;
</script> </script>

View File

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import { Link } from '$lib/components'; import { Link } from '$lib/components';
import { Branch, BaseBranch, BranchData } from '$lib/vbranches/types'; import { Branch, BaseBranch, RemoteBranch } from '$lib/vbranches/types';
import { IconBranch, IconGitBranch, IconRemote } from '$lib/icons'; import { IconBranch, IconGitBranch, IconRemote } from '$lib/icons';
import { IconTriangleDown, IconTriangleUp } from '$lib/icons'; import { IconTriangleDown, IconTriangleUp } from '$lib/icons';
import { accordion } from './accordion'; import { accordion } from './accordion';
@ -25,7 +25,7 @@
import { computedAddedRemoved } from '$lib/vbranches/fileStatus'; import { computedAddedRemoved } from '$lib/vbranches/fileStatus';
export let vbranchStore: Loadable<Branch[] | undefined>; export let vbranchStore: Loadable<Branch[] | undefined>;
export let remoteBranchStore: Loadable<BranchData[] | undefined>; export let remoteBranchStore: Loadable<RemoteBranch[] | undefined>;
export let baseBranchStore: Readable<BaseBranch | undefined>; export let baseBranchStore: Readable<BaseBranch | undefined>;
export let branchController: BranchController; export let branchController: BranchController;
export let peekTransitionsDisabled = false; export let peekTransitionsDisabled = false;
@ -50,11 +50,11 @@
let rbSection: HTMLElement; let rbSection: HTMLElement;
let baseContents: HTMLElement; let baseContents: HTMLElement;
let selectedItem: Readable<Branch | BranchData | BaseBranch | undefined> | undefined; let selectedItem: Readable<Branch | RemoteBranch | BaseBranch | undefined> | undefined;
let overlayOffsetTop = 0; let overlayOffsetTop = 0;
let fetching = false; let fetching = false;
function select(detail: Branch | BranchData | BaseBranch | undefined, i: number): void { function select(detail: Branch | RemoteBranch | BaseBranch | undefined, i: number): void {
if (peekTrayExpanded && selectedItem && detail == get(selectedItem)) { if (peekTrayExpanded && selectedItem && detail == get(selectedItem)) {
peekTrayExpanded = false; peekTrayExpanded = false;
return; return;
@ -65,7 +65,7 @@
); );
const element = vbContents.children[i] as HTMLDivElement; const element = vbContents.children[i] as HTMLDivElement;
overlayOffsetTop = element.offsetTop + vbViewport.offsetTop - vbViewport.scrollTop; overlayOffsetTop = element.offsetTop + vbViewport.offsetTop - vbViewport.scrollTop;
} else if (detail instanceof BranchData) { } else if (detail instanceof RemoteBranch) {
selectedItem = derived(remoteBranchStore, (branches) => selectedItem = derived(remoteBranchStore, (branches) =>
branches?.find((remoteBranch) => remoteBranch.sha == detail.sha) branches?.find((remoteBranch) => remoteBranch.sha == detail.sha)
); );