Merge branch 'master' into ian/visual-changes-2023-07-11-1

This commit is contained in:
Ian Donahue 2023-07-11 18:09:50 +02:00 committed by GitHub
commit b9c9b18aff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 322 additions and 249 deletions

View File

@ -84,7 +84,7 @@
"svelte-check": "^3.0.1",
"svelte-floating-ui": "^1.5.2",
"svelte-french-toast": "^1.0.3",
"svelte-loadable-store": "^1.2.3",
"svelte-loadable-store": "^2.0.0",
"svelte-outclick": "^3.5.0",
"svelte-resize-observer": "^2.0.0",
"tailwindcss": "^3.1.5",

View File

@ -200,8 +200,8 @@ devDependencies:
specifier: ^1.0.3
version: 1.0.3(svelte@3.55.1)
svelte-loadable-store:
specifier: ^1.2.3
version: 1.2.3(svelte@3.55.1)
specifier: ^2.0.0
version: 2.0.0(svelte@3.55.1)
svelte-outclick:
specifier: ^3.5.0
version: 3.5.0(svelte@3.55.1)
@ -213,10 +213,10 @@ devDependencies:
version: 3.2.4(postcss@8.4.21)
tauri-plugin-log-api:
specifier: github:tauri-apps/tauri-plugin-log
version: github.com/tauri-apps/tauri-plugin-log/21921031d74f871180381317a338559f588ad8e9
version: github.com/tauri-apps/tauri-plugin-log/fbbb126e6d7fba7a7e6772d33f99c0fb689f32b6
tauri-plugin-websocket-api:
specifier: github:tauri-apps/tauri-plugin-websocket
version: github.com/tauri-apps/tauri-plugin-websocket/7832cb121d2ecaf6b52c9bdee77df18fddaac5d9
version: github.com/tauri-apps/tauri-plugin-websocket/39b7ba2c0c27a9b0093b00120830ed23774f5403
tinykeys:
specifier: ^1.4.0
version: 1.4.0
@ -4717,8 +4717,8 @@ packages:
svelte: 3.55.1
dev: true
/svelte-loadable-store@1.2.3(svelte@3.55.1):
resolution: {integrity: sha512-efoCRCGLxzU+RE1D09cpnKKBO2CVXAzjUY0/RatOtPXSNPbb0/HeGcV/baH5davabwiDm7iWf2rqI9ogIRQ1Pw==}
/svelte-loadable-store@2.0.0(svelte@3.55.1):
resolution: {integrity: sha512-2mnbj99fnbQg4WwXW3WZWUqAbcaXkHacFFulb7r+VdSic9PkkKq/117V94lVeCrC9BxMR7KaOdESE7+JZTsWxg==}
peerDependencies:
svelte: ^3.0.0
dependencies:
@ -5459,16 +5459,16 @@ packages:
engines: {node: '>=12.20'}
dev: true
github.com/tauri-apps/tauri-plugin-log/21921031d74f871180381317a338559f588ad8e9:
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-log/tar.gz/21921031d74f871180381317a338559f588ad8e9}
github.com/tauri-apps/tauri-plugin-log/fbbb126e6d7fba7a7e6772d33f99c0fb689f32b6:
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-log/tar.gz/fbbb126e6d7fba7a7e6772d33f99c0fb689f32b6}
name: tauri-plugin-log-api
version: 0.0.0
dependencies:
'@tauri-apps/api': 1.4.0
dev: true
github.com/tauri-apps/tauri-plugin-websocket/7832cb121d2ecaf6b52c9bdee77df18fddaac5d9:
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-websocket/tar.gz/7832cb121d2ecaf6b52c9bdee77df18fddaac5d9}
github.com/tauri-apps/tauri-plugin-websocket/39b7ba2c0c27a9b0093b00120830ed23774f5403:
resolution: {tarball: https://codeload.github.com/tauri-apps/tauri-plugin-websocket/tar.gz/39b7ba2c0c27a9b0093b00120830ed23774f5403}
name: tauri-plugin-websocket-api
version: 0.0.0
dependencies:

View File

@ -563,9 +563,9 @@ impl Repository {
// lookup a branch by name
let branch = repo.find_branch(target_branch, git2::BranchType::Remote)?;
let remote = repo.branch_remote_name(branch.get().name().unwrap())?;
let remote_url = repo.find_remote(remote.as_str().unwrap())?;
let remote_url_str = remote_url.url().unwrap();
let remote_name = repo.branch_remote_name(branch.get().name().unwrap())?;
let remote = repo.find_remote(remote_name.as_str().unwrap())?;
let remote_url = remote.url().unwrap();
// get a list of currently active virtual branches
@ -604,8 +604,9 @@ impl Repository {
}
let target = virtual_branches::target::Target {
name: branch.name().unwrap().unwrap().to_string(),
remote: remote_url_str.to_string(),
branch_name: branch.name()?.unwrap().to_string(),
remote_name: remote.name().unwrap().to_string(),
remote_url: remote_url.to_string(),
sha: commit_oid,
behind: 0,
};

View File

@ -101,8 +101,9 @@ mod tests {
fn test_target() -> target::Target {
target::Target {
name: format!("target_name_{}", unsafe { TEST_TARGET_INDEX }),
remote: format!("remote_{}", unsafe { TEST_TARGET_INDEX }),
branch_name: format!("branch name{}", unsafe { TEST_TARGET_INDEX }),
remote_name: format!("remote name {}", unsafe { TEST_TARGET_INDEX }),
remote_url: format!("remote url {}", unsafe { TEST_TARGET_INDEX }),
sha: git2::Oid::from_str(&format!(
"0123456789abcdef0123456789abcdef0123456{}",
unsafe { TEST_TARGET_INDEX }

View File

@ -752,7 +752,6 @@ pub fn list_virtual_branches(
let mut upstream_commit = None;
if !branch.upstream.is_empty() {
// get the target remote
let remote_url = &default_target.remote;
let remotes = repo.remotes()?;
let mut upstream_remote = None;
for remote_name in remotes.iter() {
@ -767,7 +766,7 @@ pub fn list_virtual_branches(
None => continue,
};
if url == remote_url {
if url == default_target.remote_url {
upstream_remote = Some(remote);
break;
}
@ -1564,12 +1563,12 @@ pub fn update_branch_target(
let repo = &project_repository.git_repository;
let branch = repo
.find_branch(&target.name, git2::BranchType::Remote)
.context(format!("failed to find branch {}", target.name))?;
let new_target_commit = branch
.get()
.peel_to_commit()
.context(format!("failed to peel branch {} to commit", target.name))?;
.find_branch(&target.branch_name, git2::BranchType::Remote)
.context(format!("failed to find branch {}", target.branch_name))?;
let new_target_commit = branch.get().peel_to_commit().context(format!(
"failed to peel branch {} to commit",
target.branch_name
))?;
let new_target_oid = new_target_commit.id();
//
// if the target has not changed, do nothing
@ -1938,13 +1937,13 @@ pub fn get_target_data(
Some(mut target) => {
let repo = &project_repository.git_repository;
let branch = repo
.find_branch(&target.name, git2::BranchType::Remote)
.find_branch(&target.branch_name, git2::BranchType::Remote)
.unwrap();
let commit = branch.get().peel_to_commit().unwrap();
let oid = commit.id();
target.behind = project_repository
.behind(oid, target.sha)
.context(format!("failed to get behind for {}", target.name))?;
.context(format!("failed to get behind for {}", target.branch_name))?;
Ok(Some(target))
}
}
@ -2026,8 +2025,9 @@ mod tests {
let project_repository = project_repository::Repository::open(&project)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin".to_string(),
remote: "origin".to_string(),
remote_name: "origin".to_string(),
branch_name: "master".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -2093,8 +2093,9 @@ mod tests {
let project_repository = project_repository::Repository::open(&project)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin".to_string(),
remote: "origin".to_string(),
remote_name: "origin".to_string(),
branch_name: "master".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -2153,8 +2154,9 @@ mod tests {
gb_repository::Repository::open(gb_repo_path, project.id, project_store, user_store)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin".to_string(),
remote: "origin".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -2200,8 +2202,9 @@ mod tests {
gb_repository::Repository::open(gb_repo_path, project.id, project_store, user_store)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin".to_string(),
remote: "origin".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -2242,8 +2245,9 @@ mod tests {
let project_repository = project_repository::Repository::open(&project)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin".to_string(),
remote: "origin".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -2329,8 +2333,9 @@ mod tests {
let project_repository = project_repository::Repository::open(&project)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin".to_string(),
remote: "origin".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -2388,8 +2393,9 @@ mod tests {
let project_repository = project_repository::Repository::open(&project)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin".to_string(),
remote: "origin".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -2509,8 +2515,9 @@ mod tests {
let project_repository = project_repository::Repository::open(&project)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin".to_string(),
remote: "origin".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -2624,8 +2631,9 @@ mod tests {
let project_repository = project_repository::Repository::open(&project)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin".to_string(),
remote: "origin".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -2719,8 +2727,9 @@ mod tests {
let project_repository = project_repository::Repository::open(&project)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin".to_string(),
remote: "origin".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -2784,8 +2793,9 @@ mod tests {
let project_repository = project_repository::Repository::open(&project)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin/master".to_string(),
remote: "origin".to_string(),
branch_name: "origin/master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -2891,8 +2901,9 @@ mod tests {
let project_repository = project_repository::Repository::open(&project)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin/master".to_string(),
remote: "origin".to_string(),
branch_name: "origin/master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -2970,8 +2981,9 @@ mod tests {
let project_repository = project_repository::Repository::open(&project)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin/master".to_string(),
remote: "origin".to_string(),
branch_name: "origin/master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -3055,8 +3067,9 @@ mod tests {
commit_all(&repository)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin/master".to_string(),
remote: "origin".to_string(),
branch_name: "origin/master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -3160,8 +3173,9 @@ mod tests {
commit_all(&repository)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin/master".to_string(),
remote: "origin".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -3249,8 +3263,9 @@ mod tests {
commit_all(&repository)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin/master".to_string(),
remote: "origin".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -3419,8 +3434,9 @@ mod tests {
commit_all(&repository)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin/master".to_string(),
remote: "http://origin.com/project".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "http://origin.com/project".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -3529,8 +3545,9 @@ mod tests {
commit_all(&repository)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin/master".to_string(),
remote: "http://origin.com/project".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "http://origin.com/project".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -3681,8 +3698,9 @@ mod tests {
)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin/master".to_string(),
remote: "http://origin.com/project".to_string(),
remote_name: "origin".to_string(),
branch_name: "master".to_string(),
remote_url: "http://origin.com/project".to_string(),
sha: upstream_commit,
behind: 0,
})?;
@ -3785,8 +3803,9 @@ mod tests {
commit_all(&repository)?;
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin".to_string(),
remote: "origin".to_string(),
branch_name: "origin".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: repository.head().unwrap().target().unwrap(),
behind: 0,
})?;
@ -3941,8 +3960,9 @@ mod tests {
let commit1_oid = repository.head().unwrap().target().unwrap();
let commit1 = repository.find_commit(commit1_oid).unwrap();
target::Writer::new(&gb_repo).write_default(&target::Target {
name: "origin".to_string(),
remote: "origin".to_string(),
branch_name: "master".to_string(),
remote_name: "origin".to_string(),
remote_url: "origin".to_string(),
sha: commit1_oid,
behind: 0,
})?;

View File

@ -8,8 +8,9 @@ pub use writer::TargetWriter as Writer;
#[derive(Debug, PartialEq, Clone)]
pub struct Target {
pub name: String,
pub remote: String,
pub branch_name: String,
pub remote_name: String,
pub remote_url: String,
pub sha: git2::Oid,
pub behind: u32,
}
@ -19,26 +20,56 @@ impl Serialize for Target {
where
S: Serializer,
{
let mut state = serializer.serialize_struct("Target", 3)?;
state.serialize_field("name", &self.name)?;
state.serialize_field("remote", &self.remote)?;
let mut state = serializer.serialize_struct("Target", 5)?;
state.serialize_field("branchName", &self.branch_name)?;
state.serialize_field("remoteName", &self.remote_name)?;
state.serialize_field("remoteUrl", &self.remote_url)?;
state.serialize_field("behind", &self.behind)?;
state.serialize_field("sha", &self.sha.to_string())?;
state.end()
}
}
// this is a backwards compatibile with the old format
fn read_remote_url(reader: &dyn crate::reader::Reader) -> Result<String, crate::reader::Error> {
match reader.read_string("remote_url") {
Ok(url) => Ok(url),
// fallback to the old format
Err(crate::reader::Error::NotFound) => reader.read_string("remote"),
Err(e) => Err(e),
}
}
// returns (remote_name, branch_name)
fn read_remote_name_branch_name(
reader: &dyn crate::reader::Reader,
) -> Result<(String, String), crate::reader::Error> {
match reader.read_string("name") {
Ok(branch) => {
let parts = branch.split('/').collect::<Vec<_>>();
Ok((parts[0].to_string(), branch))
}
Err(crate::reader::Error::NotFound) => {
// fallback to the old format
let remote_name = reader.read_string("remote_name")?;
let branch_name = reader.read_string("branch_name")?;
Ok((remote_name, branch_name))
}
Err(e) => Err(e),
}
}
impl TryFrom<&dyn crate::reader::Reader> for Target {
type Error = crate::reader::Error;
fn try_from(reader: &dyn crate::reader::Reader) -> Result<Self, Self::Error> {
let name = reader.read_string("name").map_err(|e| {
let (remote_name, branch_name) = read_remote_name_branch_name(reader).map_err(|e| {
crate::reader::Error::IOError(std::io::Error::new(
std::io::ErrorKind::Other,
format!("name: {}", e),
format!("branch: {}", e),
))
})?;
let remote = reader.read_string("remote").map_err(|e| {
let remote_url = read_remote_url(reader).map_err(|e| {
crate::reader::Error::IOError(std::io::Error::new(
std::io::ErrorKind::Other,
format!("remote: {}", e),
@ -61,8 +92,9 @@ impl TryFrom<&dyn crate::reader::Reader> for Target {
})?;
Ok(Self {
name,
remote,
branch_name,
remote_name,
remote_url,
sha,
behind: 0,
})

View File

@ -33,6 +33,7 @@ impl<'reader> TargetReader<'reader> {
#[cfg(test)]
mod tests {
use crate::writer::Writer;
use anyhow::Result;
use tempfile::tempdir;
@ -116,6 +117,54 @@ mod tests {
Ok(())
}
#[test]
fn test_read_deprecated_format() -> Result<()> {
let repository = test_repository()?;
let project = projects::Project::try_from(&repository)?;
let gb_repo_path = tempdir()?.path().to_str().unwrap().to_string();
let storage = storage::Storage::from_path(tempdir()?.path());
let user_store = users::Storage::new(storage.clone());
let project_store = projects::Storage::new(storage);
project_store.add_project(&project)?;
let gb_repo =
gb_repository::Repository::open(gb_repo_path, project.id, project_store, user_store)?;
let writer = crate::writer::DirWriter::open(gb_repo.root());
writer
.write_string("branches/target/name", "origin/master")
.unwrap();
writer
.write_string(
"branches/target/remote",
"git@github.com:gitbutlerapp/gitbutler-client.git",
)
.unwrap();
writer
.write_string(
"branches/target/sha",
"dd945831869e9593448aa622fa4342bbfb84813d",
)
.unwrap();
let session = gb_repo.get_or_create_current_session()?;
let session_reader = sessions::Reader::open(&gb_repo, &session)?;
let reader = TargetReader::new(&session_reader);
let read = reader.read_default().unwrap();
assert_eq!(read.branch_name, "origin/master");
assert_eq!(read.remote_name, "origin");
assert_eq!(
read.remote_url,
"git@github.com:gitbutlerapp/gitbutler-client.git"
);
assert_eq!(
read.sha,
git2::Oid::from_str("dd945831869e9593448aa622fa4342bbfb84813d").unwrap()
);
Ok(())
}
#[test]
fn test_read_override_target() -> Result<()> {
let repository = test_repository()?;
@ -131,15 +180,17 @@ mod tests {
let branch = test_branch();
let target = Target {
name: "target".to_string(),
remote: "remote".to_string(),
remote_name: "remote".to_string(),
branch_name: "branch".to_string(),
remote_url: "remote url".to_string(),
sha: git2::Oid::from_str("fedcba9876543210fedcba9876543210fedcba98").unwrap(),
behind: 0,
};
let default_target = Target {
name: "default_target".to_string(),
remote: "default_remote".to_string(),
remote_name: "default remote".to_string(),
branch_name: "default branch".to_string(),
remote_url: "default remote url".to_string(),
sha: git2::Oid::from_str("0123456789abcdef0123456789abcdef01234567").unwrap(),
behind: 0,
};

View File

@ -31,11 +31,14 @@ impl<'writer> TargetWriter<'writer> {
}
self.writer
.write_string("branches/target/name", &target.name)
.context("Failed to write default target name")?;
.write_string("branches/target/branch_name", &target.branch_name)
.context("Failed to write default target branch name")?;
self.writer
.write_string("branches/target/remote", &target.remote)
.context("Failed to write default target remote")?;
.write_string("branches/target/remote_name", &target.remote_name)
.context("Failed to write default target remote name ")?;
self.writer
.write_string("branches/target/remote_url", &target.remote_url)
.context("Failed to write default target remote name ")?;
self.writer
.write_string("branches/target/sha", &target.sha.to_string())
.context("Failed to write default target sha")?;
@ -53,10 +56,22 @@ impl<'writer> TargetWriter<'writer> {
}
self.writer
.write_string(&format!("branches/{}/target/name", id), &target.name)
.context("Failed to write branch target name")?;
.write_string(
&format!("branches/{}/target/branch_name", id),
&target.branch_name,
)
.context("Failed to write branch target branch name")?;
self.writer
.write_string(&format!("branches/{}/target/remote", id), &target.remote)
.write_string(
&format!("branches/{}/target/remote_name", id),
&target.remote_name,
)
.context("Failed to write branch target remote")?;
self.writer
.write_string(
&format!("branches/{}/target/remote_url", id),
&target.remote_url,
)
.context("Failed to write branch target remote")?;
self.writer
.write_string(
@ -143,8 +158,9 @@ mod tests {
let branch = test_branch();
let target = Target {
name: "target_name".to_string(),
remote: "target_remote".to_string(),
branch_name: "branch name".to_string(),
remote_name: "remote name".to_string(),
remote_url: "remote url".to_string(),
sha: git2::Oid::from_str("0123456789abcdef0123456789abcdef01234567").unwrap(),
behind: 0,
};
@ -163,14 +179,19 @@ mod tests {
branch.name
);
assert_eq!(
fs::read_to_string(root.join("target").join("name").to_str().unwrap())
fs::read_to_string(root.join("target").join("branch_name").to_str().unwrap())
.context("Failed to read branch target name")?,
target.name
target.branch_name
);
assert_eq!(
fs::read_to_string(root.join("target").join("remote").to_str().unwrap())
.context("Failed to read branch target remote")?,
target.remote
fs::read_to_string(root.join("target").join("remote_name").to_str().unwrap())
.context("Failed to read branch target name name")?,
target.remote_name
);
assert_eq!(
fs::read_to_string(root.join("target").join("remote_url").to_str().unwrap())
.context("Failed to read branch target remote url")?,
target.remote_url
);
assert_eq!(
fs::read_to_string(root.join("target").join("sha").to_str().unwrap())
@ -230,8 +251,9 @@ mod tests {
let branch = test_branch();
let target = Target {
name: "target_name".to_string(),
remote: "target_remote".to_string(),
remote_name: "remote name".to_string(),
branch_name: "branch name".to_string(),
remote_url: "remote url".to_string(),
sha: git2::Oid::from_str("0123456789abcdef0123456789abcdef01234567").unwrap(),
behind: 0,
};
@ -242,8 +264,9 @@ mod tests {
target_writer.write(&branch.id, &target)?;
let updated_target = Target {
name: "updated_target_name".to_string(),
remote: "updated_target_remote".to_string(),
remote_name: "updated remote name".to_string(),
branch_name: "updated branch name".to_string(),
remote_url: "updated remote url".to_string(),
sha: git2::Oid::from_str("fedcba9876543210fedcba9876543210fedcba98").unwrap(),
behind: 0,
};
@ -253,14 +276,20 @@ mod tests {
let root = gb_repo.root().join("branches").join(&branch.id);
assert_eq!(
fs::read_to_string(root.join("target").join("name").to_str().unwrap())
.context("Failed to read branch target name")?,
updated_target.name
fs::read_to_string(root.join("target").join("branch_name").to_str().unwrap())
.context("Failed to read branch target branch name")?,
updated_target.branch_name
);
assert_eq!(
fs::read_to_string(root.join("target").join("remote_name").to_str().unwrap())
.context("Failed to read branch target remote name")?,
updated_target.remote_name
);
assert_eq!(
fs::read_to_string(root.join("target").join("remote").to_str().unwrap())
.context("Failed to read branch target remote")?,
updated_target.remote
fs::read_to_string(root.join("target").join("remote_url").to_str().unwrap())
.context("Failed to read branch target remote url")?,
updated_target.remote_url
);
assert_eq!(
fs::read_to_string(root.join("target").join("sha").to_str().unwrap())

View File

@ -12,8 +12,9 @@ static mut TEST_TARGET_INDEX: usize = 0;
fn test_target() -> virtual_branches::target::Target {
virtual_branches::target::Target {
name: format!("target_name_{}", unsafe { TEST_TARGET_INDEX }),
remote: format!("remote_{}", unsafe { TEST_TARGET_INDEX }),
branch_name: format!("branch name {}", unsafe { TEST_TARGET_INDEX }),
remote_name: format!("remote name {}", unsafe { TEST_TARGET_INDEX }),
remote_url: format!("remote url {}", unsafe { TEST_TARGET_INDEX }),
sha: git2::Oid::from_str(&format!(
"0123456789abcdef0123456789abcdef0123456{}",
unsafe { TEST_TARGET_INDEX }

View File

@ -1,7 +1,6 @@
import { handleErrorWithSentry, init } from '@sentry/sveltekit';
import type { NavigationEvent } from '@sveltejs/kit';
import { dev } from '$app/environment';
import { log } from '$lib';
init({
enabled: !dev,
@ -10,7 +9,7 @@ init({
tracesSampleRate: 1.0
});
log.info(`sentry init`);
console.log(`sentry init`);
function myErrorHandler({ error, event }: { error: any; event: NavigationEvent }) {
console.error('An error occurred on the client side:', error, event);

View File

@ -1,6 +1,5 @@
import { PUBLIC_API_BASE_URL } from '$env/static/public';
import { PUBLIC_CHAIN_API } from '$env/static/public';
import * as log from '$lib/log';
import { nanoid } from 'nanoid';
const apiUrl = new URL('/api/', new URL(PUBLIC_API_BASE_URL));
@ -72,13 +71,13 @@ const withRequestId: FetchMiddleware = (fetch) => async (url, options) => {
};
const withLog: FetchMiddleware = (fetch) => async (url, options) => {
log.info('fetch', url, options);
console.log('fetch', url, options);
try {
const resp = await fetch(url, options);
log.info(resp);
console.log(resp);
return resp;
} catch (e: any) {
log.error('fetch', e);
console.error('fetch', e);
throw e;
}
};

View File

@ -1,6 +1,6 @@
<script lang="ts">
import { type LoginToken, CloudApi } from '$lib/api';
import { toasts, log, stores } from '$lib';
import { toasts, stores } from '$lib';
import { derived, writable } from '@square/svelte-store';
import { open } from '@tauri-apps/api/shell';
import Button from './Button';
@ -31,7 +31,7 @@
.then(cloud.login.token.create)
.then(token.set)
.catch((e) => {
log.error(e);
console.error(e);
toasts.error('Something went wrong');
})
.finally(() => (signUpOrLoginLoading = false));

View File

@ -1,9 +1,6 @@
import { building } from '$app/environment';
import { events } from '$lib';
export async function on(combo: string, callback: (event: KeyboardEvent) => void) {
if (building) return () => {};
const comboContainsControlKeys =
combo.includes('Meta') || combo.includes('Alt') || combo.includes('Ctrl');

View File

@ -1,5 +1,4 @@
export * as api from './api';
export * as log from './log';
export * as toasts from './toasts';
export { Toaster } from './toasts';
export * as week from './week';

View File

@ -1,14 +1,11 @@
import { building } from '$app/environment';
import type { EventCallback, EventName } from '@tauri-apps/api/event';
import { invoke as invokeTauri } from '@tauri-apps/api/tauri';
import { listen as listenTauri } from '@tauri-apps/api/event';
export async function invoke<T>(command: string, params: Record<string, unknown> = {}): Promise<T> {
return building
? Promise.reject('cannot invoke ipc command while building')
: import('@tauri-apps/api').then(({ invoke }) => invoke<T>(command, params));
return invokeTauri<T>(command, params);
}
export function listen<T>(event: EventName, handle: EventCallback<T>) {
return building
? Promise.reject('cannot listen to ipc events while building')
: import('@tauri-apps/api/event').then(({ listen }) => listen(event, handle));
return listenTauri(event, handle);
}

View File

@ -1,42 +0,0 @@
import { building } from '$app/environment';
export async function setup() {
if (!building) {
await (await import('tauri-plugin-log-api')).attachConsole();
}
}
const logger = async () =>
building
? {
debug: () => {},
info: () => {},
error: () => {}
}
: import('tauri-plugin-log-api').then((tauri) => ({
debug: tauri.debug,
info: tauri.info,
error: tauri.error
}));
const toString = (value: any) => {
if (value instanceof Error) {
return value.message;
} else if (typeof value === 'object') {
return JSON.stringify(value);
} else {
return value.toString();
}
};
export async function debug(...args: any[]) {
return (await logger()).debug(args.map(toString).join(' '));
}
export async function info(...args: any[]) {
return (await logger()).info(args.map(toString).join(' '));
}
export async function error(...args: any[]) {
(await logger()).error(args.map(toString).join(' '));
}

View File

@ -1,4 +1,4 @@
import { writable, type Loadable, derived, Value } from 'svelte-loadable-store';
import { writable, type Loadable, derived, Loaded } from 'svelte-loadable-store';
import { bookmarks, type Bookmark } from '$lib/api';
import { get as getValue, type Readable } from '@square/svelte-store';
@ -12,7 +12,7 @@ export function list(params: { projectId: string }) {
const oldValue = getValue(store);
if (oldValue.isLoading) {
bookmarks.list(params).then(set);
} else if (Value.isError(oldValue.value)) {
} else if (Loaded.isError(oldValue)) {
bookmarks.list(params).then(set);
} else {
set(oldValue.value.filter((b) => b.timestampMs !== bookmark.timestampMs).concat(bookmark));

View File

@ -1,4 +1,4 @@
import { writable, type Loadable, Value } from 'svelte-loadable-store';
import { writable, type Loadable, Loaded } from 'svelte-loadable-store';
import { deltas, type Delta } from '$lib/api';
import { get, type Readable } from '@square/svelte-store';
@ -13,7 +13,7 @@ export default (params: { projectId: string; sessionId: string }) => {
const oldValue = get(store);
if (oldValue.isLoading) {
deltas.list(params).then(set);
} else if (Value.isError(oldValue.value)) {
} else if (Loaded.isError(oldValue)) {
deltas.list(params).then(set);
} else {
set({

View File

@ -1,4 +1,4 @@
import { writable, type Loadable, Value } from 'svelte-loadable-store';
import { writable, type Loadable, Loaded } from 'svelte-loadable-store';
import { files } from '$lib/api';
import { get, type Readable } from '@square/svelte-store';
@ -13,7 +13,7 @@ export default (params: { projectId: string; sessionId: string }) => {
const oldValue = get(store);
if (oldValue.isLoading) {
files.list(params).then(set);
} else if (Value.isError(oldValue.value)) {
} else if (Loaded.isError(oldValue)) {
files.list(params).then(set);
} else {
set({

View File

@ -1,4 +1,4 @@
import { derived, writable, type Loadable, Value } from 'svelte-loadable-store';
import { derived, writable, type Loadable, Loaded } from 'svelte-loadable-store';
import { sessions, type Session } from '$lib/api';
import { get, type Readable } from '@square/svelte-store';
@ -13,7 +13,7 @@ export default (params: { projectId: string }) => {
const oldValue = get(store);
if (oldValue.isLoading) {
sessions.list(params).then(set);
} else if (Value.isError(oldValue.value)) {
} else if (Loaded.isError(oldValue)) {
sessions.list(params).then(set);
} else {
set(

View File

@ -1,4 +1,3 @@
import { building } from '$app/environment';
import { writable, type Writable } from '@square/svelte-store';
import { appWindow, type Theme } from '@tauri-apps/api/window';
import type { SettingsStore } from './userSettings';
@ -9,7 +8,6 @@ let systemTheme: string | null;
let selectedTheme: string | undefined;
export function initTheme(userSettings: SettingsStore) {
if (building) return;
appWindow.theme().then((value: Theme | null) => {
systemTheme = value;
updateDom();

View File

@ -1,4 +1,4 @@
import { writable, type Loadable, Value } from 'svelte-loadable-store';
import { writable, type Loadable, Loaded } from 'svelte-loadable-store';
import type { Readable } from '@square/svelte-store';
import { git } from '$lib/api/ipc';
import { stores } from '$lib';
@ -19,10 +19,11 @@ export class BranchStoresCache {
if (cachedStore) {
return cachedStore;
}
const writableStore = writable(ipc.listVirtualBranches({ projectId }), (set) => {
stores.sessions({ projectId }).subscribe((sessions) => {
if (sessions.isLoading) return;
if (Value.isError(sessions.value)) return;
if (Loaded.isError(sessions)) return;
const lastSession = sessions.value.at(-1);
if (!lastSession) return;
return stores.deltas({ projectId, sessionId: lastSession.id }).subscribe(() => {

View File

@ -63,7 +63,8 @@ export class BranchData {
export class Target {
sha!: string;
name!: string;
remote!: string;
branchName!: string;
remoteName!: string;
remoteUrl!: string;
behind!: number;
}

View File

@ -1,11 +1,10 @@
<script lang="ts">
import { page } from '$app/stores';
import { log } from '$lib';
$: if ($page.error) {
log.error($page.url, $page.error);
console.error($page.url, $page.error);
} else {
log.error($page.url, $page.status);
console.log($page.url, $page.status);
}
$: message = $page.error

View File

@ -1,5 +1,5 @@
import type { LayoutLoad } from './$types';
import { api, log } from '$lib';
import { api } from '$lib';
import Posthog from '$lib/posthog';
import Sentry from '$lib/sentry';
import { BranchStoresCache } from '$lib/vbranches';
@ -7,7 +7,7 @@ import { wrapLoadWithSentry } from '@sentry/sveltekit';
import { loadUserSettings } from '$lib/userSettings';
export const ssr = false;
export const prerender = true;
export const prerender = false;
export const csr = true;
import { dev } from '$app/environment';
@ -17,7 +17,6 @@ import { dev } from '$app/environment';
// I examined the call stack and found a section suggesting it might not happen in prod.
// TODO(mattias): Investigate and decide what to do
function loadFn({ fetch: realFetch }: { fetch: typeof fetch }) {
log.setup();
return {
projects: api.projects.Projects(),
cloud: api.CloudApi({ fetch: realFetch }),

View File

@ -2,7 +2,7 @@
import { format, startOfDay } from 'date-fns';
import type { Delta } from '$lib/api';
import { generateBuckets } from './histogram';
import { derived, Value } from 'svelte-loadable-store';
import { derived, Loaded } from 'svelte-loadable-store';
import FileActivity from './FileActivity.svelte';
import { page } from '$app/stores';
import { Link } from '$lib/components';
@ -44,7 +44,7 @@
<h2 class="text-2xl font-bold text-zinc-400">Loading file changes...</h2>
</div>
</li>
{:else if Value.isError($deltasByDate.value) || Value.isError($buckets.value)}
{:else if Loaded.isError($deltasByDate) || Loaded.isError($buckets)}
<li class="flex flex-1 space-y-4 rounded-lg border border-dashed border-zinc-400">
<div class="flex flex-1 flex-col items-center justify-center gap-4">
<IconSparkle class="h-16 w-16 text-zinc-400 " />

View File

@ -9,7 +9,7 @@
import { error, success } from '$lib/toasts';
import { fly } from 'svelte/transition';
import { Modal } from '$lib/components';
import { log, hotkeys, stores } from '$lib';
import { hotkeys, stores } from '$lib';
import { IconChevronDown, IconChevronUp } from '$lib/icons';
import { onMount } from 'svelte';
import { unsubscribe } from '$lib/utils';
@ -193,7 +193,7 @@
await project.update({ api: { ...$project.api, sync: true } });
}
} catch (e) {
log.error(`Failed to update project sync status: ${e}`);
console.error(`Failed to update project sync status: ${e}`);
error('Failed to update project sync status');
}
};

View File

@ -2,7 +2,7 @@
import { page } from '$app/stores';
import { stores, api } from '$lib';
import { format } from 'date-fns';
import { derived, Value } from 'svelte-loadable-store';
import { derived, Loaded } from 'svelte-loadable-store';
const sessions = stores.sessions({ projectId: $page.params.projectId });
@ -32,7 +32,7 @@
</script>
<div id="player-page" class="flex h-full w-full flex-col">
{#if !$dates.isLoading && Value.isValue($dates.value)}
{#if !$dates.isLoading && Loaded.isValue($dates)}
{#if $dates.value.length === 0}
<div class="text-center">
<h2 class="text-2xl">I haven't seen any changes yet</h2>

View File

@ -1,7 +1,7 @@
<script lang="ts">
import type { LayoutData } from './$types';
import { page } from '$app/stores';
import { derived, Value } from 'svelte-loadable-store';
import { derived, Loaded } from 'svelte-loadable-store';
import { format } from 'date-fns';
import { onMount } from 'svelte';
import { api, events, hotkeys, stores } from '$lib';
@ -85,7 +85,7 @@
<IconLoading class="mb-4 h-12 w-12 animate-spin ease-linear" />
<h2 class="text-center text-2xl font-medium text-gray-500">Loading...</h2>
</div>
{:else if Value.isError($richSessions.value) || Value.isError($currentSession.value)}
{:else if Loaded.isError($richSessions) || Loaded.isError($currentSession)}
<div class="flex h-full flex-col items-center justify-center">
<h2 class="text-center text-2xl font-medium text-gray-500">Error</h2>
</div>
@ -102,10 +102,10 @@
<header class="flex items-center gap-3 bg-card-active px-3 py-2">
{#if $currentSession.isLoading || $richSessions.isLoading}
<span>Loading...</span>
{:else if Loaded.isError($currentSession) || Loaded.isError($richSessions)}
<span>Error</span>
{:else if !$currentSession.value}
<span>No session found</span>
{:else if Value.isError($currentSession.value) || Value.isError($richSessions.value)}
<span>Error</span>
{:else}
<SessionNavigations currentSession={$currentSession.value} sessions={$richSessions.value} />
{/if}

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { log, toasts, api } from '$lib';
import { toasts, api } from '$lib';
import { Button, Modal } from '$lib/components';
import { IconBookmarkFilled } from '$lib/icons';
@ -47,7 +47,7 @@
modal.close();
})
.catch((err) => {
log.error(err);
console.error(err);
toasts.error('Failed to create bookmark');
})
.finally(() => (isCreating = false));

View File

@ -5,9 +5,9 @@
import { derived } from '@square/svelte-store';
import { stores } from '$lib';
import { IconBookmarkFilled } from '$lib/icons';
import { Value } from 'svelte-loadable-store';
import { line } from '$lib/diff';
import { Stats } from '$lib/components';
import { Loaded } from 'svelte-loadable-store';
export let isCurrent: boolean;
export let session: Session;
@ -53,7 +53,7 @@
$: bookmarks = derived(stores.bookmarks.list({ projectId: session.projectId }), (bookmarks) => {
if (bookmarks.isLoading) return [];
if (Value.isError(bookmarks.value)) return [];
if (Loaded.isError(bookmarks)) return [];
const timestamps = Object.values(deltas ?? {}).flatMap((deltas) =>
deltas.map((d) => d.timestampMs)
);

View File

@ -8,7 +8,7 @@
import { unsubscribe } from '$lib/utils';
import type { Readable } from '@square/svelte-store';
import { onMount } from 'svelte';
import { Value, type Loadable } from 'svelte-loadable-store';
import { Loaded, type Loadable } from 'svelte-loadable-store';
import { derived } from 'svelte-loadable-store';
import { format } from 'date-fns';
@ -57,19 +57,11 @@
onMount(() =>
unsubscribe(
hotkeys.on('Shift+ArrowRight', () => {
if (
!$nextSessionId.isLoading &&
Value.isValue($nextSessionId.value) &&
$nextSessionId.value
)
if (!$nextSessionId.isLoading && Loaded.isValue($nextSessionId) && $nextSessionId.value)
goto(getSessionURI($nextSessionId.value));
}),
hotkeys.on('Shift+ArrowLeft', () => {
if (
!$prevSessionId.isLoading &&
Value.isValue($prevSessionId.value) &&
$prevSessionId.value
)
if (!$prevSessionId.isLoading && Loaded.isValue($prevSessionId) && $prevSessionId.value)
goto(getSessionURI($prevSessionId.value));
})
)
@ -83,7 +75,7 @@
</span>
<div class="flex items-center gap-1">
{#if !$prevSessionId.isLoading && !$nextSessionId.isLoading && Value.isValue($prevSessionId.value) && Value.isValue($nextSessionId.value)}
{#if !$prevSessionId.isLoading && !$nextSessionId.isLoading && Loaded.isValue($prevSessionId) && Loaded.isValue($nextSessionId)}
<a
href={$prevSessionId.value && getSessionURI($prevSessionId.value)}
class="rounded border border-zinc-500 bg-zinc-600 p-0.5"

View File

@ -1,7 +1,7 @@
<script lang="ts">
import type { Delta, Session } from '$lib/api';
import type { Readable } from '@square/svelte-store';
import { Value, type Loadable } from 'svelte-loadable-store';
import { Loaded, type Loadable } from 'svelte-loadable-store';
import { derived } from 'svelte-loadable-store';
import SessionCard from './SessionCard.svelte';
@ -26,7 +26,7 @@
...session,
visible:
!$visibleDeltas.isLoading &&
!Value.isError($visibleDeltas.value) &&
!Loaded.isError($visibleDeltas) &&
Object.keys($visibleDeltas.value[i]).length > 0
}));
</script>
@ -48,7 +48,7 @@
>
{#each visibleSessions as session, i}
{@const isCurrent = session.id === currentSession?.id}
{#if session.visible && !$visibleDeltas.isLoading && !Value.isError($visibleDeltas.value) && !$visibleFiles.isLoading && !Value.isError($visibleFiles.value)}
{#if session.visible && !$visibleDeltas.isLoading && !Loaded.isError($visibleDeltas) && !$visibleFiles.isLoading && !Loaded.isError($visibleFiles)}
<SessionCard
{isCurrent}
{session}

View File

@ -3,7 +3,7 @@
import type { PageData } from './$types';
import { page } from '$app/stores';
import { get, writable } from '@square/svelte-store';
import { derived, Value } from 'svelte-loadable-store';
import { derived, Loaded } from 'svelte-loadable-store';
import { format } from 'date-fns';
import { stores } from '$lib';
import Playback from './Playback.svelte';
@ -55,7 +55,7 @@
richSessions?.subscribe((sessions) => {
if (sessions.isLoading) return;
if (Value.isError(sessions.value)) return;
if (Loaded.isError(sessions)) return;
if (sessions.value.length === 0) return;
if (!sessions.value.some((s) => s.id === $currentSessionId)) {
$currentSessionId = sessions.value[0].id;
@ -74,7 +74,7 @@
$: {
// this hook updates player value if current page url has changed
if (!$richSessions.isLoading && Value.isValue($richSessions.value)) {
if (!$richSessions.isLoading && Loaded.isValue($richSessions)) {
const currentSessionIndex = $richSessions.value.findIndex(
(s) => s.id === $page.params.sessionId
);
@ -83,7 +83,7 @@
.filter((_, index) => index < currentSessionIndex)
.reduce((acc, s) => {
const deltas = get(s.deltas);
if (!deltas.isLoading && Value.isValue(deltas.value)) {
if (!deltas.isLoading && Loaded.isValue(deltas)) {
return acc + deltas.value.length;
} else {
return acc;
@ -100,7 +100,7 @@
/>
<h2 class="text-center text-2xl font-medium text-gray-500">Loading...</h2>
</div>
{:else if Value.isError($richSessions.value)}
{:else if Loaded.isError($richSessions)}
<div class="flex h-full flex-col items-center justify-center">
<h2 class="text-center text-2xl font-medium text-gray-500">Something went wrong</h2>
</div>

View File

@ -3,7 +3,7 @@
import type { Frame } from './frame';
import { DeltasViewer } from '$lib/components';
import type { Readable } from '@square/svelte-store';
import { Value, type Loadable } from 'svelte-loadable-store';
import { Loaded, type Loadable } from 'svelte-loadable-store';
export let context: number;
export let fullContext: boolean;
@ -17,8 +17,8 @@
if (
!$deltas.isLoading &&
!$files.isLoading &&
Value.isValue($deltas.value) &&
Value.isValue($files.value)
Loaded.isValue($deltas) &&
Loaded.isValue($files)
) {
let i = value;
for (const j in $deltas.value) {

View File

@ -3,8 +3,8 @@
import { collapse } from '$lib/paths';
import { IconBookmark, IconBookmarkFilled } from '$lib/icons';
import { format } from 'date-fns';
import { Value } from 'svelte-loadable-store';
import { page } from '$app/stores';
import { Loaded } from 'svelte-loadable-store';
export let timestampMs: number;
export let filename: string;
@ -13,7 +13,7 @@
const toggleBookmark = () => {
if ($bookmark.isLoading) return;
if (Value.isError($bookmark.value)) return;
if (Loaded.isError($bookmark)) return;
api.bookmarks.upsert(
!$bookmark.value
? {
@ -30,7 +30,7 @@
};
</script>
{#if !$bookmark.isLoading && !Value.isError($bookmark.value)}
{#if !$bookmark.isLoading && !Loaded.isError($bookmark)}
<div
class="flex max-w-[357px] flex-col gap-2 rounded-[18px] py-2 px-4 shadow"
style="border: 0.5px solid rgba(63, 63, 70, 0.5);

View File

@ -6,7 +6,7 @@
import { onMount } from 'svelte';
import { hotkeys } from '$lib';
import type { Readable } from '@square/svelte-store';
import { type Loadable, derived, Value } from 'svelte-loadable-store';
import { type Loadable, derived, Loaded } from 'svelte-loadable-store';
export let value: number;
export let context: number;
@ -39,7 +39,7 @@
const gotoNextDelta = () => {
if ($maxDeltaIndex.isLoading) return;
if (Value.isError($maxDeltaIndex.value)) return;
if (Loaded.isError($maxDeltaIndex)) return;
if (value < $maxDeltaIndex.value) {
value += 1;
} else {

View File

@ -1,6 +1,6 @@
<script lang="ts">
import type { Bookmark, Delta } from '$lib/api';
import { derived, Value, type Loadable } from 'svelte-loadable-store';
import { derived, Loaded, type Loadable } from 'svelte-loadable-store';
import type { Readable } from '@square/svelte-store';
import { ModuleChapters, ModuleMarkers, type Marker } from './slider';
import { JSR, ModuleSlider } from 'mm-jsr';
@ -89,7 +89,7 @@
};
</script>
{#if !$totalDeltas.isLoading && Value.isValue($totalDeltas.value) && !$chapters.isLoading && Value.isValue($chapters.value) && !$markers.isLoading && Value.isValue($markers.value)}
{#if !$totalDeltas.isLoading && Loaded.isValue($totalDeltas) && !$chapters.isLoading && Loaded.isValue($chapters) && !$markers.isLoading && Loaded.isValue($markers)}
<div
use:jsrSlider={{
min: 0,

View File

@ -2,7 +2,7 @@
import { Button, Modal } from '$lib/components';
import type { PageData } from './$types';
import { open } from '@tauri-apps/api/shell';
import { log, toasts, api, stores, events } from '$lib';
import { toasts, api, stores, events } from '$lib';
import { goto } from '$app/navigation';
import CloudForm from './CloudForm.svelte';
import DetailsForm from './DetailsForm.svelte';
@ -22,7 +22,7 @@
.then(() => api.projects.del({ id: $project?.id }))
.then(() => deleteConfirmationModal.close())
.catch((e) => {
log.error(e);
console.error(e);
toasts.error('Failed to delete project');
})
.then(() => goto('/'))

View File

@ -1,5 +1,5 @@
<script lang="ts">
import { stores, log, toasts } from '$lib';
import { stores, toasts } from '$lib';
import { CloudApi, type Project } from '$lib/api';
import { Login, Checkbox } from '$lib/components';
import { createEventDispatcher, onMount } from 'svelte';
@ -37,7 +37,7 @@
}));
dispatch('updated', { ...project, api: { ...cloudProject, sync } });
} catch (error) {
log.error(`Failed to update project sync status: ${error}`);
console.error(`Failed to update project sync status: ${error}`);
toasts.error('Failed to update project sync status');
}
};

View File

@ -5,7 +5,6 @@ import { WebglAddon } from 'xterm-addon-webgl';
import { FitAddon } from 'xterm-addon-fit';
import { Unicode11Addon } from 'xterm-addon-unicode11';
import WebSocket, { type Message } from 'tauri-plugin-websocket-api';
import { log } from '$lib';
import { dev } from '$app/environment';
const isWebgl2Supported = (() => {
@ -48,7 +47,7 @@ const newSession = async (params: { project: Project }) => {
return WebSocket.connect(`ws://localhost:${port}/${project.id}`).then((conn) => {
const sendMessage = (message: Message) => {
conn.send(message).catch((e: any) => {
log.error(`failed to send message to terminal: ${e}`);
console.error(`failed to send message to terminal: ${e}`);
});
};

View File

@ -2,9 +2,9 @@
import Board from './Board.svelte';
import Tray from './Tray.svelte';
import type { PageData } from './$types';
import { Value } from 'svelte-loadable-store';
import { Button } from '$lib/components';
import { BranchController } from '$lib/vbranches';
import { Loaded } from 'svelte-loadable-store';
export let data: PageData;
let {
@ -25,15 +25,15 @@
);
$: remoteBranches =
!$remoteBranchStore.isLoading && !Value.isError($remoteBranchStore.value)
!$remoteBranchStore.isLoading && !Loaded.isError($remoteBranchStore)
? $remoteBranchStore.value
: [];
$: target =
!$targetBranchStore.isLoading && !Value.isError($targetBranchStore.value)
!$targetBranchStore.isLoading && !Loaded.isError($targetBranchStore)
? $targetBranchStore.value
: undefined;
$: branches =
!$vbranchStore.isLoading && !Value.isError($vbranchStore.value) ? $vbranchStore.value : [];
!$vbranchStore.isLoading && !Loaded.isError($vbranchStore) ? $vbranchStore.value : [];
let targetChoice: string | undefined;
function onSetTargetClick() {

View File

@ -69,7 +69,7 @@
<div
class="flex w-full flex-row items-center justify-between border-b border-light-400 pb-1 pl-2 pr-1 text-light-900 dark:border-dark-500 dark:bg-dark-700 dark:text-dark-100"
>
<div class="flex-grow pb-1 font-bold" title={behindMessage}>{target.name}</div>
<div class="flex-grow pb-1 font-bold" title={behindMessage}>{target.branchName}</div>
<div class="flex items-center gap-1">
<div class="pb-1">{target.behind > 0 ? `behind ${target.behind}` : 'up-to-date'}</div>
<div class="flex-shrink-0 text-light-700 dark:text-dark-100" title={behindMessage}>

View File

@ -1,7 +1,7 @@
<script lang="ts">
import { Button, Modal, Login } from '$lib/components';
import type { PageData } from './$types';
import { log, stores, toasts } from '$lib';
import { stores, toasts } from '$lib';
import { deleteAllData } from '$lib/api';
import { goto } from '$app/navigation';
import Logo from '$lib/assets/logo-310x310.png';
@ -59,7 +59,7 @@
});
toasts.success('Profile updated');
} catch (e) {
log.error(e);
console.error(e);
toasts.error('Failed to update user');
}
@ -78,7 +78,7 @@
.then(() => user.set(null))
.then(() => toasts.success('All data deleted'))
.catch((e) => {
log.error(e);
console.error(e);
toasts.error('Failed to delete project');
})
.then(() => deleteConfirmationModal.close())