Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions app/src-tauri/capabilities/ready.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "ready",
"description": "Lo que el aviso de inicio necesita y nada más",
"windows": [
"ready"
],
"permissions": [
"core:default",
"core:window:allow-close"
]
}
12 changes: 3 additions & 9 deletions app/src-tauri/src/backup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,9 @@ pub struct Brought {
from_elsewhere: bool,
}

fn history() -> Result<PathBuf, String> {
Ok(crate::settings::folder()
.ok_or_else(crate::settings::nowhere)?
.join("history.db"))
}

#[tauri::command(async)]
pub fn save_backup(path: String, at: i64) -> Result<Saved, String> {
let store = cp_store::Store::open(&history()?).map_err(|why| why.to_string())?;
let store = crate::settings::open_history()?;
let to = PathBuf::from(&path);
let made = cp_store::backup::write(&store, &to, at).map_err(|why| why.to_string())?;
crate::note::note(&format!("a copy written to {path}: {} items", made.items));
Expand Down Expand Up @@ -109,7 +103,7 @@ pub fn load_backup(
}

fn bring(from: &std::path::Path, at: i64) -> Result<cp_store::Brought, String> {
let store = cp_store::Store::open(&history()?).map_err(|why| why.to_string())?;
let store = crate::settings::open_history()?;
cp_store::backup::bring(from, &store, at, &|what| crate::note::note(what))
.map_err(|why| why.to_string())
}
Expand Down Expand Up @@ -174,7 +168,7 @@ fn crossed(
from: &std::path::Path,
at: i64,
) -> Result<(cp_store::legacy::Brought, cp_store::Swept), String> {
let store = cp_store::Store::open(&history()?).map_err(|why| why.to_string())?;
let store = crate::settings::open_history()?;
let lifted = lift_the_limit(app)?;
let policy = crate::settings::policy();
let swept = |why: &str| match store.sweep(&policy, at) {
Expand Down
2 changes: 1 addition & 1 deletion app/src-tauri/src/backup_test.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::*;
use crate::settings::history;

#[test]
fn the_history_a_backup_speaks_for_is_the_one_the_panel_writes() {
Expand Down
5 changes: 4 additions & 1 deletion app/src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod links;
mod looks;
mod note;
mod panel;
mod ready;
mod report;
mod reviving;
mod settings;
Expand Down Expand Up @@ -62,7 +63,9 @@ pub fn run() {
relabel,
welcome::greeting,
welcome::tour,
welcome::open_settings
welcome::open_settings,
ready::glance,
ready::show_panel
])
.manage(update::Installing::default())
.manage(backup::Crossing::default())
Expand Down
2 changes: 1 addition & 1 deletion app/src-tauri/src/looks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use tauri::{AppHandle, Manager, Runtime, Theme, WebviewWindowBuilder};

const LIGHT: Color = Color(0xF7, 0xF8, 0xFB, 0xFF);
const DARK: Color = Color(0x1A, 0x1D, 0x2B, 0xFF);
const WINDOWS: [&str; 2] = ["main", "welcome"];
const WINDOWS: [&str; 3] = ["main", "welcome", "ready"];

fn chosen() -> Option<Theme> {
match crate::settings::settings().map(|kept| kept.theme) {
Expand Down
79 changes: 79 additions & 0 deletions app/src-tauri/src/ready.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use tauri::{
AppHandle, LogicalPosition, Manager, PhysicalRect, Runtime, WebviewUrl, WebviewWindowBuilder,
};

pub const LABEL: &str = "ready";

const WIDE: f64 = 360.0;
const TALL: f64 = 184.0;
const MARGIN: f64 = 12.0;

pub fn corner(area: PhysicalRect<i32, u32>, scale: f64, top: bool) -> LogicalPosition<f64> {
let left = f64::from(area.position.x) / scale;
let up = f64::from(area.position.y) / scale;
let x = left + f64::from(area.size.width) / scale - WIDE - MARGIN;
let y = if top {
up + MARGIN
} else {
up + f64::from(area.size.height) / scale - TALL - MARGIN
};
LogicalPosition::new(x, y)
}

pub fn open<R: Runtime>(app: &AppHandle<R>) {
if app.get_webview_window(LABEL).is_some() {
return;
}
let Ok(Some(screen)) = app.primary_monitor() else {
return;
};
let at = corner(
*screen.work_area(),
screen.scale_factor(),
cfg!(target_os = "macos"),
);
let built = crate::looks::dressed(WebviewWindowBuilder::new(
app,
LABEL,
WebviewUrl::App("index.html#ready".into()),
))
.title("CoPanda")
.inner_size(WIDE, TALL)
.position(at.x, at.y)
.resizable(false)
.maximizable(false)
.minimizable(false)
.decorations(false)
.always_on_top(true)
.skip_taskbar(true)
.focused(false)
.accept_first_mouse(true)
.build();
if let Err(why) = built {
crate::note::note(&format!("the ready card would not open: {why}"));
}
}

pub fn close<R: Runtime>(app: &AppHandle<R>) {
if let Some(window) = app.get_webview_window(LABEL) {
let _ = window.close();
}
}

#[tauri::command(async)]
pub fn glance(since: i64) -> Result<cp_store::Glance, String> {
let Some(store) = crate::settings::history_if_any()? else {
return Ok(cp_store::Glance::default());
};
store.glance(since).map_err(|why| why.to_string())
}

#[tauri::command]
pub async fn show_panel(app: AppHandle) {
close(&app);
crate::panel::show(&app);
}

#[cfg(test)]
#[path = "ready_test.rs"]
mod tests;
33 changes: 33 additions & 0 deletions app/src-tauri/src/ready_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use super::corner;
use tauri::{LogicalPosition, PhysicalPosition, PhysicalRect, PhysicalSize};

fn screen(x: i32, y: i32, width: u32, height: u32) -> PhysicalRect<i32, u32> {
PhysicalRect {
position: PhysicalPosition::new(x, y),
size: PhysicalSize::new(width, height),
}
}

#[test]
fn on_windows_it_sits_over_the_tray() {
let at = corner(screen(0, 0, 1920, 1032), 1.0, false);
assert_eq!(at, LogicalPosition::new(1548.0, 836.0));
}

#[test]
fn on_a_mac_it_hangs_under_the_menu_bar() {
let at = corner(screen(0, 25, 1440, 875), 1.0, true);
assert_eq!(at, LogicalPosition::new(1068.0, 37.0));
}

#[test]
fn a_taskbar_on_top_still_leaves_it_inside_the_free_space() {
let at = corner(screen(0, 48, 1920, 1032), 1.0, false);
assert_eq!(at.y + 184.0 + 12.0, 48.0 + 1032.0);
}

#[test]
fn a_scaled_screen_keeps_the_same_logical_corner() {
let at = corner(screen(0, 0, 3840, 2064), 2.0, false);
assert_eq!(at, LogicalPosition::new(1548.0, 836.0));
}
23 changes: 18 additions & 5 deletions app/src-tauri/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,21 @@ pub fn nowhere() -> String {
"the folder where CoPanda keeps its own was not found".to_owned()
}

pub fn history() -> Result<PathBuf, String> {
Ok(folder().ok_or_else(nowhere)?.join("history.db"))
}

pub fn open_history() -> Result<cp_store::Store, String> {
cp_store::Store::open(&history()?).map_err(|why| why.to_string())
}

pub fn history_if_any() -> Result<Option<cp_store::Store>, String> {
if !history()?.exists() {
return Ok(None);
}
open_history().map(Some)
}

pub fn settle() -> bool {
let Some(dir) = folder() else {
return false;
Expand Down Expand Up @@ -141,11 +156,9 @@ fn written(app: &tauri::AppHandle, config: Config) -> Result<Config, String> {

#[tauri::command(async)]
pub fn storage_used() -> Result<i64, String> {
let at = folder().ok_or_else(nowhere)?.join("history.db");
if !at.exists() {
let Some(store) = history_if_any()? else {
return Ok(0);
}
let store = cp_store::Store::open(&at).map_err(|why| why.to_string())?;
};
Ok(store.usage().map_err(|why| why.to_string())?.bytes)
}

Expand Down Expand Up @@ -174,7 +187,7 @@ pub struct Former {
}

fn came_over() -> Option<cp_store::legacy::Came> {
let at = folder()?.join("history.db");
let at = history().ok()?;
for wait in [0u64, 150, 400] {
if wait > 0 {
std::thread::sleep(std::time::Duration::from_millis(wait));
Expand Down
2 changes: 2 additions & 0 deletions app/src-tauri/src/tray.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ pub fn surface<R: Runtime>(app: &AppHandle<R>) {

pub fn surface_at<R: Runtime>(app: &AppHandle<R>, rail: Option<&str>) {
crate::panel::hide(app);
crate::ready::close(app);
crate::welcome::unpin(app);
if let Some(window) = app.get_webview_window("main") {
if let Some(rail) = rail {
let _ = app.emit("rail", rail);
Expand Down
11 changes: 11 additions & 0 deletions app/src-tauri/src/welcome.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ pub fn raise<R: Runtime>(app: &AppHandle<R>, fresh: bool) {
if behind(welcomed.as_deref(), &running) {
mark(app);
}
crate::ready::open(app);
}

fn mark<R: Runtime>(app: &AppHandle<R>) {
Expand Down Expand Up @@ -187,7 +188,17 @@ pub fn reopened<R: Runtime>(app: &AppHandle<R>) {
if app.get_webview_window(LABEL).is_none() {
hold(app, Greeting::Keys);
}
crate::ready::close(app);
open(app);
if let Some(window) = app.get_webview_window(LABEL) {
let _ = window.set_always_on_top(true);
}
}

pub fn unpin<R: Runtime>(app: &AppHandle<R>) {
if let Some(window) = app.get_webview_window(LABEL) {
let _ = window.set_always_on_top(false);
}
}

#[tauri::command]
Expand Down
Loading
Loading