mirror of
https://github.com/gitbutlerapp/gitbutler.git
synced 2024-12-12 07:13:34 +03:00
Open new existing projects with Alt + click
in project popup.
This is intentionally non-obvious for now while it's new.
This commit is contained in:
parent
c310942b12
commit
24b8bdaa86
@ -99,6 +99,10 @@ export class ProjectService {
|
||||
}
|
||||
}
|
||||
|
||||
async openProjectInNewWindow(projectId: string) {
|
||||
await invoke('open_project_in_window', { id: projectId });
|
||||
}
|
||||
|
||||
async addProject() {
|
||||
const path = await this.promptForDirectory();
|
||||
if (!path) return;
|
||||
|
@ -13,7 +13,7 @@
|
||||
label: string;
|
||||
selected?: boolean;
|
||||
icon?: string;
|
||||
onclick: () => void;
|
||||
onclick: (event?: any) => void;
|
||||
}
|
||||
|
||||
interface ProjectsPopupProps {
|
||||
@ -110,8 +110,12 @@
|
||||
label: project.title,
|
||||
selected,
|
||||
icon: selected ? 'tick' : undefined,
|
||||
onclick: () => {
|
||||
onclick: async (event: any) => {
|
||||
if (event.altKey) {
|
||||
await projectService.openProjectInNewWindow(project.id);
|
||||
} else {
|
||||
goto(`/${project.id}/`);
|
||||
}
|
||||
hide();
|
||||
}
|
||||
})}
|
||||
|
@ -18,8 +18,8 @@ pub mod commands;
|
||||
|
||||
pub mod logs;
|
||||
pub mod menu;
|
||||
mod window;
|
||||
pub use window::WindowState;
|
||||
pub mod window;
|
||||
pub use window::state::WindowState;
|
||||
|
||||
pub mod askpass;
|
||||
pub mod config;
|
||||
|
@ -40,21 +40,10 @@ fn main() {
|
||||
.target(LogTarget::LogDir)
|
||||
.level(log::LevelFilter::Error);
|
||||
|
||||
let builder = tauri::Builder::default();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
let builder = builder
|
||||
.on_window_event(|event| {
|
||||
if let tauri::WindowEvent::CloseRequested { api, .. } = event.event() {
|
||||
hide_window(&event.window().app_handle()).expect("Failed to hide window");
|
||||
api.prevent_close();
|
||||
}
|
||||
});
|
||||
|
||||
builder
|
||||
tauri::Builder::default()
|
||||
.setup(move |tauri_app| {
|
||||
let window =
|
||||
create_window(&tauri_app.handle()).expect("Failed to create window");
|
||||
gitbutler_tauri::window::create(&tauri_app.handle(), "main", "index.html".into()).expect("Failed to create window");
|
||||
#[cfg(debug_assertions)]
|
||||
window.open_devtools();
|
||||
|
||||
@ -162,6 +151,7 @@ fn main() {
|
||||
projects::commands::delete_project,
|
||||
projects::commands::list_projects,
|
||||
projects::commands::set_project_active,
|
||||
projects::commands::open_project_in_window,
|
||||
repo::commands::git_get_local_config,
|
||||
repo::commands::git_set_local_config,
|
||||
repo::commands::check_signing_settings,
|
||||
@ -213,6 +203,14 @@ fn main() {
|
||||
.on_window_event(|event| {
|
||||
let window = event.window();
|
||||
match event.event() {
|
||||
#[cfg(target_os = "macos")]
|
||||
tauri::WindowEvent::CloseRequested { api, .. } => {
|
||||
if window.app_handle().windows().len() == 1 {
|
||||
tracing::debug!("Hiding all application windows and preventing exit");
|
||||
window.app_handle().hide().ok();
|
||||
api.prevent_close();
|
||||
}
|
||||
}
|
||||
tauri::WindowEvent::Destroyed => {
|
||||
window.app_handle()
|
||||
.state::<WindowState>()
|
||||
@ -231,7 +229,8 @@ fn main() {
|
||||
.run(|app_handle, event| {
|
||||
#[cfg(target_os = "macos")]
|
||||
if let tauri::RunEvent::ExitRequested { api, .. } = event {
|
||||
hide_window(app_handle).expect("Failed to hide window");
|
||||
tracing::debug!("Hiding all windows and preventing exit");
|
||||
app_handle.hide().ok();
|
||||
api.prevent_exit();
|
||||
}
|
||||
|
||||
@ -243,40 +242,3 @@ fn main() {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn create_window(handle: &tauri::AppHandle) -> tauri::Result<tauri::Window> {
|
||||
let app_title = handle.package_info().name.clone();
|
||||
let window =
|
||||
tauri::WindowBuilder::new(handle, "main", tauri::WindowUrl::App("index.html".into()))
|
||||
.resizable(true)
|
||||
.title(app_title)
|
||||
.disable_file_drop_handler()
|
||||
.min_inner_size(800.0, 600.0)
|
||||
.inner_size(1160.0, 720.0)
|
||||
.build()?;
|
||||
tracing::info!("app window created");
|
||||
Ok(window)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn create_window(handle: &tauri::AppHandle) -> tauri::Result<tauri::Window> {
|
||||
let window =
|
||||
tauri::WindowBuilder::new(handle, "main", tauri::WindowUrl::App("index.html".into()))
|
||||
.resizable(true)
|
||||
.title(handle.package_info().name.clone())
|
||||
.min_inner_size(800.0, 600.0)
|
||||
.inner_size(1160.0, 720.0)
|
||||
.hidden_title(true)
|
||||
.disable_file_drop_handler()
|
||||
.title_bar_style(tauri::TitleBarStyle::Overlay)
|
||||
.build()?;
|
||||
tracing::info!("window created");
|
||||
Ok(window)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn hide_window(handle: &tauri::AppHandle) -> tauri::Result<()> {
|
||||
handle.hide()?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ pub mod commands {
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::window::WindowState;
|
||||
use crate::{window, WindowState};
|
||||
|
||||
#[tauri::command(async)]
|
||||
#[instrument(skip(controller), err(Debug))]
|
||||
@ -49,15 +49,34 @@ pub mod commands {
|
||||
///
|
||||
/// We use it to start watching for filesystem events.
|
||||
#[tauri::command(async)]
|
||||
#[instrument(skip(controller, watchers, window), err(Debug))]
|
||||
#[instrument(skip(controller, window_state, window), err(Debug))]
|
||||
pub async fn set_project_active(
|
||||
controller: State<'_, Controller>,
|
||||
watchers: State<'_, WindowState>,
|
||||
window_state: State<'_, WindowState>,
|
||||
window: Window,
|
||||
id: ProjectId,
|
||||
) -> Result<(), Error> {
|
||||
let project = controller.get(id).context("project not found")?;
|
||||
Ok(watchers.set_project_to_window(window.label(), &project)?)
|
||||
Ok(window_state.set_project_to_window(window.label(), &project)?)
|
||||
}
|
||||
|
||||
/// Open the project with the given ID in a new Window, or focus an existing one.
|
||||
///
|
||||
/// Note that this command is blocking the main thread just to prevent the chance for races
|
||||
/// without haveing to lock explicitly.
|
||||
#[tauri::command]
|
||||
#[instrument(skip(handle), err(Debug))]
|
||||
pub async fn open_project_in_window(
|
||||
handle: tauri::AppHandle,
|
||||
id: ProjectId,
|
||||
) -> Result<(), Error> {
|
||||
let label = std::time::UNIX_EPOCH
|
||||
.elapsed()
|
||||
.or_else(|_| std::time::UNIX_EPOCH.duration_since(std::time::SystemTime::now()))
|
||||
.map(|d| d.as_millis().to_string())
|
||||
.context("didn't manage to get any time-based unique ID")?;
|
||||
window::create(&handle, &label, format!("{id}/board")).map_err(anyhow::Error::from)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command(async)]
|
||||
|
@ -15,7 +15,7 @@ pub mod commands {
|
||||
use tauri::{AppHandle, Manager};
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::window;
|
||||
use crate::WindowState;
|
||||
|
||||
#[tauri::command(async)]
|
||||
#[instrument(skip(handle), err(Debug))]
|
||||
@ -511,7 +511,7 @@ pub mod commands {
|
||||
|
||||
async fn emit_vbranches(handle: &AppHandle, project_id: projects::ProjectId) {
|
||||
if let Err(error) = handle
|
||||
.state::<window::WindowState>()
|
||||
.state::<WindowState>()
|
||||
.post(gitbutler_watcher::Action::CalculateVirtualBranches(
|
||||
project_id,
|
||||
))
|
||||
|
@ -1,3 +1,4 @@
|
||||
pub(super) mod state {
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
@ -87,7 +88,7 @@ impl Drop for State {
|
||||
}
|
||||
|
||||
type WindowLabel = String;
|
||||
type WindowLabelRef = str;
|
||||
pub(super) type WindowLabelRef = str;
|
||||
|
||||
/// State associated to windows
|
||||
/// Note that this type is managed in Tauri and thus needs to be `Send` and `Sync`.
|
||||
@ -137,13 +138,14 @@ impl WindowState {
|
||||
let mut lock_file =
|
||||
fslock::LockFile::open(project.gb_dir().join(WINDOW_LOCK_FILE).as_os_str())?;
|
||||
lock_file
|
||||
.lock()
|
||||
.try_lock()
|
||||
.context("Another GitButler Window already has the project opened")?;
|
||||
|
||||
let handler = handler_from_app(&self.app_handle)?;
|
||||
let worktree_dir = project.path.clone();
|
||||
let project_id = project.id;
|
||||
let watcher = gitbutler_watcher::watch_in_background(handler, worktree_dir, project_id)?;
|
||||
let watcher =
|
||||
gitbutler_watcher::watch_in_background(handler, worktree_dir, project_id)?;
|
||||
let mut state_by_label = block_on(self.state.lock());
|
||||
state_by_label.insert(
|
||||
window.to_owned(),
|
||||
@ -193,3 +195,48 @@ impl WindowState {
|
||||
state_by_label.remove(window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
pub fn create(
|
||||
handle: &tauri::AppHandle,
|
||||
label: &state::WindowLabelRef,
|
||||
window_relative_url: String,
|
||||
) -> tauri::Result<tauri::Window> {
|
||||
tracing::info!("creating window '{label}' created at '{window_relative_url}'");
|
||||
let window = tauri::WindowBuilder::new(
|
||||
handle,
|
||||
label,
|
||||
tauri::WindowUrl::App(window_relative_url.into()),
|
||||
)
|
||||
.resizable(true)
|
||||
.title(handle.package_info().name.clone())
|
||||
.disable_file_drop_handler()
|
||||
.min_inner_size(800.0, 600.0)
|
||||
.inner_size(1160.0, 720.0)
|
||||
.build()?;
|
||||
Ok(window)
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn create(
|
||||
handle: &tauri::AppHandle,
|
||||
label: &state::WindowLabelRef,
|
||||
window_relative_url: String,
|
||||
) -> tauri::Result<tauri::Window> {
|
||||
tracing::info!("creating window '{label}' created at '{window_relative_url}'");
|
||||
let window = tauri::WindowBuilder::new(
|
||||
handle,
|
||||
label,
|
||||
tauri::WindowUrl::App(window_relative_url.into()),
|
||||
)
|
||||
.resizable(true)
|
||||
.title(handle.package_info().name.clone())
|
||||
.min_inner_size(800.0, 600.0)
|
||||
.inner_size(1160.0, 720.0)
|
||||
.hidden_title(true)
|
||||
.disable_file_drop_handler()
|
||||
.title_bar_style(tauri::TitleBarStyle::Overlay)
|
||||
.build()?;
|
||||
Ok(window)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user