mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-11 10:32:54 +03:00
Merge pull request #3716 from gitbutlerapp/list-snapshots-with-optional-sha-1
snapshot list pagination
This commit is contained in:
commit
01576361aa
@ -3,16 +3,19 @@
|
||||
import { invoke } from '$lib/backend/ipc';
|
||||
import { getContext } from '$lib/utils/context';
|
||||
import { VirtualBranchService } from '$lib/vbranches/virtualBranch';
|
||||
import { onMount } from 'svelte';
|
||||
import { onMount, onDestroy } from 'svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
export let projectId: string;
|
||||
|
||||
const snapshotsLimit = 100;
|
||||
|
||||
const vbranchService = getContext(VirtualBranchService);
|
||||
vbranchService.activeBranches.subscribe(() => {
|
||||
listSnapshots(projectId, snapshotsLimit);
|
||||
// whenever virtual branches change, we need to reload the snapshots
|
||||
// TODO: if the list has results from more pages, merge into it?
|
||||
listSnapshots(projectId).then((rsp) => {
|
||||
snapshots = rsp;
|
||||
listElement?.scrollTo(0, 0);
|
||||
});
|
||||
});
|
||||
|
||||
type Trailer = {
|
||||
@ -34,12 +37,13 @@
|
||||
createdAt: number;
|
||||
};
|
||||
let snapshots: Snapshot[] = [];
|
||||
async function listSnapshots(projectId: string, limit: number) {
|
||||
async function listSnapshots(projectId: string, sha?: string) {
|
||||
const resp = await invoke<Snapshot[]>('list_snapshots', {
|
||||
projectId: projectId,
|
||||
limit: limit
|
||||
limit: 32,
|
||||
sha: sha
|
||||
});
|
||||
snapshots = resp;
|
||||
return resp;
|
||||
}
|
||||
async function restoreSnapshot(projectId: string, sha: string) {
|
||||
await invoke<string>('restore_snapshot', {
|
||||
@ -49,12 +53,27 @@
|
||||
// TODO: is there a better way to update all the state?
|
||||
await goto(window.location.href, { replaceState: true });
|
||||
}
|
||||
function onLastInView() {
|
||||
if (!listElement) return;
|
||||
if (listElement.scrollTop + listElement.clientHeight >= listElement.scrollHeight) {
|
||||
listSnapshots(projectId, snapshots[snapshots.length - 1].id).then((rsp) => {
|
||||
snapshots = [...snapshots, ...rsp.slice(1)];
|
||||
});
|
||||
}
|
||||
}
|
||||
let listElement: HTMLElement | undefined = undefined;
|
||||
onMount(async () => {
|
||||
listSnapshots(projectId, snapshotsLimit);
|
||||
listSnapshots(projectId).then((rsp) => {
|
||||
snapshots = rsp;
|
||||
});
|
||||
if (listElement) listElement.addEventListener('scroll', onLastInView, true);
|
||||
});
|
||||
onDestroy(() => {
|
||||
listElement?.removeEventListener('scroll', onLastInView, true);
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="container" bind:this={listElement}>
|
||||
{#each snapshots as entry, idx}
|
||||
<div class="card" style="margin-bottom: 4px;">
|
||||
<div class="entry" style="padding: 6px;">
|
||||
|
@ -49,7 +49,7 @@ fn main() -> Result<()> {
|
||||
|
||||
fn list_snapshots(repo_dir: &str) -> Result<()> {
|
||||
let project = project_from_path(repo_dir);
|
||||
let snapshots = project.list_snapshots(100)?;
|
||||
let snapshots = project.list_snapshots(100, None)?;
|
||||
for snapshot in snapshots {
|
||||
let ts = chrono::DateTime::from_timestamp(snapshot.created_at / 1000, 0);
|
||||
let details = snapshot.details;
|
||||
|
@ -37,7 +37,7 @@ pub trait Oplog {
|
||||
/// An alternative way of retrieving the snapshots would be to manually the oplog head `git log <oplog_head>` available in `.git/gitbutler/oplog.toml`.
|
||||
///
|
||||
/// If there are no snapshots, an empty list is returned.
|
||||
fn list_snapshots(&self, limit: usize) -> Result<Vec<Snapshot>>;
|
||||
fn list_snapshots(&self, limit: usize, sha: Option<String>) -> Result<Vec<Snapshot>>;
|
||||
/// Reverts to a previous state of the working directory, virtual branches and commits.
|
||||
/// The provided sha must refer to a valid snapshot commit.
|
||||
/// Upon success, a new snapshot is created.
|
||||
@ -146,17 +146,22 @@ impl Oplog for Project {
|
||||
Ok(Some(new_commit_oid.to_string()))
|
||||
}
|
||||
|
||||
fn list_snapshots(&self, limit: usize) -> Result<Vec<Snapshot>> {
|
||||
fn list_snapshots(&self, limit: usize, sha: Option<String>) -> Result<Vec<Snapshot>> {
|
||||
let repo_path = self.path.as_path();
|
||||
let repo = git2::Repository::init(repo_path)?;
|
||||
|
||||
let oplog_state = OplogHandle::new(&self.gb_dir());
|
||||
let head_sha = oplog_state.get_oplog_head()?;
|
||||
if head_sha.is_none() {
|
||||
// there are no snapshots to return
|
||||
return Ok(vec![]);
|
||||
}
|
||||
let head_sha = head_sha.unwrap();
|
||||
let head_sha = match sha {
|
||||
Some(sha) => sha,
|
||||
None => {
|
||||
let oplog_state = OplogHandle::new(&self.gb_dir());
|
||||
if let Some(sha) = oplog_state.get_oplog_head()? {
|
||||
sha
|
||||
} else {
|
||||
// there are no snapshots so return an empty list
|
||||
return Ok(vec![]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let oplog_head_commit = repo.find_commit(git2::Oid::from_str(&head_sha)?)?;
|
||||
|
||||
@ -525,7 +530,7 @@ mod tests {
|
||||
.create_snapshot(SnapshotDetails::new(OperationType::UpdateWorkspaceBase))
|
||||
.unwrap();
|
||||
|
||||
let initial_snapshot = &project.list_snapshots(10).unwrap()[1];
|
||||
let initial_snapshot = &project.list_snapshots(10, None).unwrap()[1];
|
||||
assert_eq!(
|
||||
initial_snapshot.files_changed,
|
||||
vec![
|
||||
@ -536,7 +541,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(initial_snapshot.lines_added, 3);
|
||||
assert_eq!(initial_snapshot.lines_removed, 0);
|
||||
let second_snapshot = &project.list_snapshots(10).unwrap()[0];
|
||||
let second_snapshot = &project.list_snapshots(10, None).unwrap()[0];
|
||||
assert_eq!(
|
||||
second_snapshot.files_changed,
|
||||
vec![
|
||||
|
@ -13,12 +13,13 @@ pub async fn list_snapshots(
|
||||
handle: tauri::AppHandle,
|
||||
project_id: ProjectId,
|
||||
limit: usize,
|
||||
sha: Option<String>,
|
||||
) -> Result<Vec<Snapshot>, Error> {
|
||||
let project = handle
|
||||
.state::<projects::Controller>()
|
||||
.get(&project_id)
|
||||
.context("failed to get project")?;
|
||||
let snapshots = project.list_snapshots(limit)?;
|
||||
let snapshots = project.list_snapshots(limit, sha)?;
|
||||
Ok(snapshots)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user