Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update setup.rs to refactor window and view setup logic #1374

Open
wants to merge 1 commit into
base: v2-dev
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
335 changes: 140 additions & 195 deletions src-tauri/src/core/setup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,21 @@ use crate::core::{

pub fn init(app: &mut App) -> Result<(), Box<dyn std::error::Error>> {
let handle = app.handle();

let conf = &AppConf::load(handle)?;
let conf = AppConf::load(handle)?;
let ask_mode_height = if conf.ask_mode { ASK_HEIGHT } else { 0.0 };

template::Template::new(AppConf::get_scripts_path(handle)?);

tauri::async_runtime::spawn({
let handle = handle.clone();
let scale_factor: f64;

async move {
let mut core_window = WindowBuilder::new(&handle, "core").title("ChatGPT");
let mut core_window = WindowBuilder::new(&handle, "core")
.title("ChatGPT")
.resizable(true)
.inner_size(800.0, 600.0)
.min_inner_size(300.0, 200.0)
.theme(Some(AppConf::get_theme(&handle)));

#[cfg(target_os = "macos")]
{
Expand All @@ -37,222 +42,162 @@ pub fn init(app: &mut App) -> Result<(), Box<dyn std::error::Error>> {
.hidden_title(true);
}

core_window = core_window
.resizable(true)
.inner_size(800.0, 600.0)
.min_inner_size(300.0, 200.0)
.theme(Some(AppConf::get_theme(&handle)));

let core_window = core_window
.build()
.expect("[core:window] Failed to build window");

let win_size = core_window
.inner_size()
.expect("[core:window] Failed to get window size");
// Wrap the window in Arc<Mutex<_>> to manage ownership across threads
let win_size = core_window.inner_size().expect("[core:window] Failed to get window size");
let window = Arc::new(Mutex::new(core_window));
scale_factor = window.lock().unwrap().scale_factor().unwrap();

let main_view =
WebviewBuilder::new("main", WebviewUrl::App("https://chatgpt.com".into()))
.auto_resize()
.on_download({
let app_handle = handle.clone();
let download_path = Arc::new(Mutex::new(PathBuf::new()));
move |_, event| {
match event {
DownloadEvent::Requested { destination, .. } => {
let download_dir = app_handle
.path()
.download_dir()
.expect("[view:download] Failed to get download directory");
let mut locked_path = download_path
.lock()
.expect("[view:download] Failed to lock download path");
*locked_path = download_dir.join(&destination);
*destination = locked_path.clone();
}
DownloadEvent::Finished { success, .. } => {
let final_path = download_path
.lock()
.expect("[view:download] Failed to lock download path")
.clone();
let download_path = Arc::new(Mutex::new(PathBuf::new()));
let app_handle = handle.clone();

if success {
app_handle
.shell()
.open(final_path.to_string_lossy(), None)
.expect("[view:download] Failed to open file");
}
}
_ => (),
}
true
}
})
.initialization_script(&AppConf::load_script(&handle, "ask.js"))
.initialization_script(INIT_SCRIPT);
let main_view = WebviewBuilder::new("main", WebviewUrl::App("https://chatgpt.com".into()))
.auto_resize()
.on_download(move |_, event| handle_download_event(&app_handle, &download_path, event))
.initialization_script(&AppConf::load_script(&handle, "ask.js"))
.initialization_script(INIT_SCRIPT);

let titlebar_view = WebviewBuilder::new(
"titlebar",
WebviewUrl::App("index.html".into()),
)
.auto_resize();
let titlebar_view = WebviewBuilder::new("titlebar", WebviewUrl::App("index.html".into()))
.auto_resize();

let ask_view =
WebviewBuilder::new("ask", WebviewUrl::App("index.html".into()))
.auto_resize();
let ask_view = WebviewBuilder::new("ask", WebviewUrl::App("index.html".into()))
.auto_resize();

let win = window.lock().unwrap();
let scale_factor = win.scale_factor().unwrap();
let titlebar_height = (scale_factor * TITLEBAR_HEIGHT).round() as u32;
let ask_height = (scale_factor * ask_mode_height).round() as u32;

#[cfg(target_os = "macos")]
{
let main_area_height = win_size.height - titlebar_height;

win.add_child(
titlebar_view,
LogicalPosition::new(0, 0),
PhysicalSize::new(win_size.width, titlebar_height),
)
.unwrap();
win.add_child(
ask_view,
LogicalPosition::new(
0.0,
(win_size.height as f64 / scale_factor) - ask_mode_height,
),
PhysicalSize::new(win_size.width, ask_height),
)
.unwrap();
win.add_child(
main_view,
LogicalPosition::new(0.0, TITLEBAR_HEIGHT),
PhysicalSize::new(win_size.width, main_area_height - ask_height),
)
.unwrap();
}
setup_macos_views(&win, &main_view, &titlebar_view, &ask_view, win_size, titlebar_height, ask_height);

#[cfg(not(target_os = "macos"))]
{
win.add_child(
ask_view,
LogicalPosition::new(
0.0,
(win_size.height as f64 / scale_factor) - ask_mode_height,
),
PhysicalSize::new(win_size.width, ask_height),
)
.unwrap();
win.add_child(
titlebar_view,
LogicalPosition::new(
0.0,
(win_size.height as f64 / scale_factor) - ask_mode_height - TITLEBAR_HEIGHT,
),
PhysicalSize::new(win_size.width, titlebar_height),
)
.unwrap();
win.add_child(
main_view,
LogicalPosition::new(0.0, 0.0),
PhysicalSize::new(
win_size.width,
win_size.height - (ask_height + titlebar_height),
),
)
.unwrap();
}
setup_non_macos_views(&win, &main_view, &titlebar_view, &ask_view, win_size, titlebar_height, ask_height);

let window_clone = Arc::clone(&window);
let set_view_properties =
|view: &tauri::Webview, position: LogicalPosition<f64>, size: PhysicalSize<u32>| {
if let Err(e) = view.set_position(position) {
eprintln!("[view:position] Failed to set view position: {}", e);
}
if let Err(e) = view.set_size(size) {
eprintln!("[view:size] Failed to set view size: {}", e);
}
};

win.on_window_event(move |event| {
let conf = &AppConf::load(&handle).unwrap();
let ask_mode_height = if conf.ask_mode { ASK_HEIGHT } else { 0.0 };
let ask_height = (scale_factor * ask_mode_height).round() as u32;

if let WindowEvent::Resized(size) = event {
let win = window_clone.lock().unwrap();

let main_view = win
.get_webview("main")
.expect("[view:main] Failed to get webview window");
let titlebar_view = win
.get_webview("titlebar")
.expect("[view:titlebar] Failed to get webview window");
let ask_view = win
.get_webview("ask")
.expect("[view:ask] Failed to get webview window");

#[cfg(target_os = "macos")]
{
set_view_properties(
&main_view,
LogicalPosition::new(0.0, TITLEBAR_HEIGHT),
PhysicalSize::new(
size.width,
size.height - (titlebar_height + ask_height),
),
);
set_view_properties(
&titlebar_view,
LogicalPosition::new(0.0, 0.0),
PhysicalSize::new(size.width, titlebar_height),
);
set_view_properties(
&ask_view,
LogicalPosition::new(
0.0,
(size.height as f64 / scale_factor) - ask_mode_height,
),
PhysicalSize::new(size.width, ask_height),
);
}

#[cfg(not(target_os = "macos"))]
{
set_view_properties(
&main_view,
LogicalPosition::new(0.0, 0.0),
PhysicalSize::new(
size.width,
size.height - (ask_height + titlebar_height),
),
);
set_view_properties(
&titlebar_view,
LogicalPosition::new(
0.0,
(size.height as f64 / scale_factor) - TITLEBAR_HEIGHT,
),
PhysicalSize::new(size.width, titlebar_height),
);
set_view_properties(
&ask_view,
LogicalPosition::new(
0.0,
(size.height as f64 / scale_factor)
- ask_mode_height
- TITLEBAR_HEIGHT,
),
PhysicalSize::new(size.width, ask_height),
);
}
update_view_positions(&window_clone, size, scale_factor, titlebar_height, ask_height);
}
});
}
});

Ok(())
}

// Function to handle download events
fn handle_download_event(app_handle: &tauri::AppHandle, download_path: &Arc<Mutex<PathBuf>>, event: DownloadEvent) {
match event {
DownloadEvent::Requested { destination, .. } => {
let download_dir = app_handle.path().download_dir().expect("[view:download] Failed to get download directory");
let mut locked_path = download_path.lock().expect("[view:download] Failed to lock download path");
*locked_path = download_dir.join(&destination);
*destination = locked_path.clone();
}
DownloadEvent::Finished { success, .. } => {
let final_path = download_path.lock().expect("[view:download] Failed to lock download path").clone();
if success {
app_handle.shell().open(final_path.to_string_lossy(), None).expect("[view:download] Failed to open file");
}
}
_ => (),
}
}

// Setup views for macOS
#[cfg(target_os = "macos")]
fn setup_macos_views(win: &tauri::Window, main_view: &WebviewBuilder, titlebar_view: &WebviewBuilder, ask_view: &WebviewBuilder, win_size: PhysicalSize<u32>, titlebar_height: u32, ask_height: u32) {
win.add_child(
titlebar_view,
LogicalPosition::new(0, 0),
PhysicalSize::new(win_size.width, titlebar_height),
).unwrap();
win.add_child(
ask_view,
LogicalPosition::new(0.0, (win_size.height as f64 / win.scale_factor().unwrap()) - ASK_HEIGHT),
PhysicalSize::new(win_size.width, ask_height),
).unwrap();
win.add_child(
main_view,
LogicalPosition::new(0.0, TITLEBAR_HEIGHT),
PhysicalSize::new(win_size.width, win_size.height - titlebar_height - ask_height),
).unwrap();
}

// Setup views for non-macOS
#[cfg(not(target_os = "macos"))]
fn setup_non_macos_views(win: &tauri::Window, main_view: &WebviewBuilder, titlebar_view: &WebviewBuilder, ask_view: &WebviewBuilder, win_size: PhysicalSize<u32>, titlebar_height: u32, ask_height: u32) {
win.add_child(
ask_view,
LogicalPosition::new(0.0, (win_size.height as f64 / win.scale_factor().unwrap()) - ASK_HEIGHT),
PhysicalSize::new(win_size.width, ask_height),
).unwrap();
win.add_child(
titlebar_view,
LogicalPosition::new(0.0, (win_size.height as f64 / win.scale_factor().unwrap()) - ASK_HEIGHT - TITLEBAR_HEIGHT),
PhysicalSize::new(win_size.width, titlebar_height),
).unwrap();
win.add_child(
main_view,
LogicalPosition::new(0.0, 0.0),
PhysicalSize::new(win_size.width, win_size.height - (ask_height + titlebar_height)),
).unwrap();
}

// Update view positions based on window resize
fn update_view_positions(window_clone: &Arc<Mutex<tauri::Window>>, size: PhysicalSize<u32>, scale_factor: f64, titlebar_height: u32, ask_height: u32) {
let win = window_clone.lock().unwrap();
let main_view = win.get_webview("main").expect("[view:main] Failed to get webview window");
let titlebar_view = win.get_webview("titlebar").expect("[view:titlebar] Failed to get webview window");
let ask_view = win.get_webview("ask").expect("[view:ask] Failed to get webview window");

#[cfg(target_os = "macos")]
{
set_view_properties(
&main_view,
LogicalPosition::new(0.0, TITLEBAR_HEIGHT),
PhysicalSize::new(size.width, size.height - (titlebar_height + ask_height)),
);
set_view_properties(
&titlebar_view,
LogicalPosition::new(0.0, 0.0),
PhysicalSize::new(size.width, titlebar_height),
);
set_view_properties(
&ask_view,
LogicalPosition::new(0.0, (size.height as f64 / scale_factor) - ASK_HEIGHT),
PhysicalSize::new(size.width, ask_height),
);
}

#[cfg(not(target_os = "macos"))]
{
set_view_properties(
&main_view,
LogicalPosition::new(0.0, 0.0),
PhysicalSize::new(size.width, size.height - (ask_height + titlebar_height)),
);
set_view_properties(
&titlebar_view,
LogicalPosition::new(0.0, (size.height as f64 / scale_factor) - TITLEBAR_HEIGHT),
PhysicalSize::new(size.width, titlebar_height),
);
set_view_properties(
&ask_view,
LogicalPosition::new(0.0, (size.height as f64 / scale_factor) - ASK_HEIGHT - TITLEBAR_HEIGHT),
PhysicalSize::new(size.width, ask_height),
);
}
}

// Helper function to set view properties
fn set_view_properties(view: &tauri::Webview, position: LogicalPosition<f64>, size: PhysicalSize<u32>) {
if let Err(e) = view.set_position(position) {
eprintln!("[view:position] Failed to set view position: {}", e);
}
if let Err(e) = view.set_size(size) {
eprintln!("[view:size] Failed to set view size: {}", e);
}
}