more general palette code, dedupe some main.rs code, start of branch switcher

This commit is contained in:
Scott Chacon 2023-03-12 13:16:30 -07:00
parent 01a5c572dc
commit 524591821a
3 changed files with 90 additions and 80 deletions

View File

@ -177,15 +177,7 @@ fn list_sessions(
handle: tauri::AppHandle,
project_id: &str,
) -> Result<Vec<sessions::Session>, Error> {
let app_state = handle.state::<App>();
let repo = repositories::Repository::open(
&app_state.projects_storage,
&app_state.users_storage,
project_id,
)
.with_context(|| format!("Failed to open repository for project {}", project_id))?;
let repo = repo_for_project(handle, project_id)?;
let sessions = repo
.sessions()
.with_context(|| format!("Failed to list sessions for project {}", project_id))?;
@ -338,16 +330,8 @@ fn list_session_files(
session_id: &str,
paths: Option<Vec<&str>>,
) -> Result<HashMap<String, String>, Error> {
let app_state = handle.state::<App>();
let repo = repositories::Repository::open(
&app_state.projects_storage,
&app_state.users_storage,
project_id,
)?;
let repo = repo_for_project(handle, project_id)?;
let files = repo.files(session_id, paths)?;
Ok(files)
}
@ -357,16 +341,8 @@ fn list_deltas(
project_id: &str,
session_id: &str,
) -> Result<HashMap<String, Vec<Delta>>, Error> {
let app_state = handle.state::<App>();
let repo = repositories::Repository::open(
&app_state.projects_storage,
&app_state.users_storage,
project_id,
)?;
let repo = repo_for_project(handle, project_id)?;
let deltas = repo.deltas(session_id)?;
Ok(deltas)
}
@ -375,29 +351,14 @@ fn git_status(
handle: tauri::AppHandle,
project_id: &str,
) -> Result<HashMap<String, String>, Error> {
let app_state = handle.state::<App>();
let repo = repositories::Repository::open(
&app_state.projects_storage,
&app_state.users_storage,
project_id,
)?;
let repo = repo_for_project(handle, project_id)?;
let files = repo.status().with_context(|| "Failed to get git status")?;
Ok(files)
}
#[tauri::command]
fn git_file_paths(handle: tauri::AppHandle, project_id: &str) -> Result<Vec<String>, Error> {
let app_state = handle.state::<App>();
let repo = repositories::Repository::open(
&app_state.projects_storage,
&app_state.users_storage,
project_id,
)?;
let repo = repo_for_project(handle, project_id)?;
let files = repo
.file_paths()
.with_context(|| "Failed to get file paths")?;
@ -411,6 +372,18 @@ fn git_match_paths(
project_id: &str,
match_pattern: &str,
) -> Result<Vec<String>, Error> {
let repo = repo_for_project(handle, project_id)?;
let files = repo
.match_file_paths(match_pattern)
.with_context(|| "Failed to get file paths")?;
Ok(files)
}
fn repo_for_project(
handle: tauri::AppHandle,
project_id: &str,
) -> Result<repositories::Repository, Error> {
let app_state = handle.state::<App>();
let repo = repositories::Repository::open(
@ -419,10 +392,15 @@ fn git_match_paths(
project_id,
)?;
let files = repo
.match_file_paths(match_pattern)
.with_context(|| "Failed to get file paths")?;
Ok(repo)
}
#[tauri::command]
fn git_branches(handle: tauri::AppHandle, project_id: &str) -> Result<Vec<String>, Error> {
let repo = repo_for_project(handle, project_id)?;
let files = repo
.branches()
.with_context(|| "Failed to get file paths")?;
Ok(files)
}
@ -434,14 +412,7 @@ fn git_commit(
files: Vec<&str>,
push: bool,
) -> Result<bool, Error> {
let app_state = handle.state::<App>();
let repo = repositories::Repository::open(
&app_state.projects_storage,
&app_state.users_storage,
project_id,
)?;
let repo = repo_for_project(handle, project_id)?;
let success = repo
.commit(message, files, push)
.with_context(|| "Failed to commit")?;
@ -563,6 +534,7 @@ fn main() {
git_status,
git_file_paths,
git_match_paths,
git_branches,
git_commit
]);

View File

@ -156,6 +156,15 @@ impl Repository {
}
}
pub fn branches(&self) -> Result<Vec<String>> {
let mut branches = vec![];
for branch in self.git_repository.branches(None)? {
let (branch, _) = branch?;
branches.push(branch.name()?.unwrap().to_string());
}
Ok(branches)
}
// get file status from git
pub fn status(&self) -> Result<HashMap<String, String>> {
let mut options = git2::StatusOptions::new();

View File

@ -11,6 +11,7 @@
import { shortPath } from '$lib/paths';
import { currentProject } from '$lib/current_project';
import type { Project } from '$lib/projects';
import { placeholder } from '@codemirror/view';
let showPalette = <string | false>false;
let keysDown = <string[]>[];
@ -19,6 +20,7 @@
let changedFiles = {};
let commitMessage = '';
let commitMessageInput: HTMLElement;
let paletteMode = 'command';
const listFiles = (params: { projectId: string }) =>
invoke<Record<string, string>>('git_status', params);
@ -26,6 +28,9 @@
const matchFiles = (params: { projectId: string; matchPattern: string }) =>
invoke<Array<string>>('git_match_paths', params);
const listBranches = (params: { projectId: string }) =>
invoke<Array<string>>('git_branches', params);
const listProjects = () => invoke<Project[]>('list_projects');
const commit = (params: {
@ -44,6 +49,7 @@
break;
case 'Escape':
showPalette = false;
paletteMode = 'command';
break;
case 'ArrowDown':
if (showPalette == 'command') {
@ -78,6 +84,9 @@
if (keysDown.includes('e')) {
executeCommand('contact');
}
if (keysDown.includes('r')) {
executeCommand('branch');
}
}
}
@ -170,7 +179,8 @@
case 'bookmark':
break;
case 'branch':
showBranch = true;
showPalette = 'command';
branchSwitcher();
break;
}
}
@ -224,11 +234,11 @@
if (!showCommand) {
search = '';
}
if (searchValue.length == 0) {
if (searchValue.length == 0 && paletteMode == 'command') {
updateMenu([]);
return;
}
if ($currentProject) {
if ($currentProject && searchValue.length > 0) {
const searchPattern = '.*' + Array.from(searchValue).join('(.*)');
matchFiles({ projectId: $currentProject.id, matchPattern: searchPattern }).then((files) => {
let searchResults = [];
@ -240,6 +250,20 @@
}
}
function branchSwitcher() {
console.log('branchSwitcher', $currentProject);
paletteMode = 'branch';
if ($currentProject) {
listBranches({ projectId: $currentProject.id }).then((refs) => {
let branches = <Object[]>[];
refs.forEach((b) => {
branches.push({ text: b, icon: BranchIcon });
});
menuItems = branches;
});
}
}
function updateMenu(searchResults: Array<{ text: string }>) {
if (searchResults.length == 0) {
menuItems = commandList();
@ -299,29 +323,34 @@
background-color: rgba(24, 24, 27, 0.60);
border: 0.5px solid rgba(63, 63, 70, 0.50);"
>
<div class="relative">
<svg
class="pointer-events-none absolute top-3.5 left-4 h-5 w-5 text-zinc-500"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
{#if paletteMode == 'command'}
<div class="relative">
<svg
class="pointer-events-none absolute top-3.5 left-4 h-5 w-5 text-zinc-500"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z"
/>
</svg>
<input
id="command"
type="text"
bind:value={search}
class="h-12 w-full border-0 bg-transparent pl-11 pr-4 text-white focus:ring-0 sm:text-sm"
placeholder="Search..."
/>
</svg>
<input
id="command"
type="text"
bind:value={search}
class="h-12 w-full border-0 bg-transparent pl-11 pr-4 text-white focus:ring-0 sm:text-sm"
placeholder="Search..."
/>
</div>
</div>
{/if}
{#if paletteMode == 'branch'}
<div class="text-lg p-4">Branch Switcher</div>
{/if}
<!-- Default state, show/hide based on command palette state. -->
<ul class="scroll-py-2 divide-y divide-zinc-500 divide-opacity-20 overflow-y-auto">