style load and save buttons
ci/woodpecker/push/woodpecker Pipeline was successful Details

This commit is contained in:
AnActualEmerald 2022-09-17 13:52:30 -04:00
parent 20af8b8164
commit ef1211731f
Signed by: emerald
GPG Key ID: CC76D6B296CAC8B0
6 changed files with 89 additions and 25 deletions

View File

@ -9,6 +9,12 @@ edition = "2021"
[workspace]
[profile.release]
strip = true
opt-level = "s"
lto = true
codegen-units = 1
[build-dependencies]
tauri-build = { version = "1.0.0", features = [] }

View File

@ -1,5 +1,6 @@
use std::sync::Arc;
use std::sync::Mutex;
use std::thread::sleep;
use std::time::Duration;
use anyhow::anyhow;
@ -9,7 +10,6 @@ use cpal::traits::{DeviceTrait, HostTrait};
use cpal::Device;
use cpal::InputCallbackInfo;
use log::debug;
// use cpal::OutputCallbackInfo;
use tauri::Window;
pub async fn monitor(window: Window, threshold: Arc<Mutex<f32>>, level: Arc<Mutex<f32>>) {
@ -42,7 +42,9 @@ pub async fn monitor(window: Window, threshold: Arc<Mutex<f32>>, level: Arc<Mute
stream.play().expect("Error creating input stream");
// The stream will end if it goes out of scope, so just dwell here
loop {}
loop {
sleep(Duration::from_secs(60));
}
}
fn initialize() -> Result<Device> {

View File

@ -4,7 +4,7 @@ use std::path::Path;
use base64_url as base64;
use image::ImageFormat;
use log::trace;
use log::{debug, trace};
use ray_format::Ray;
use serde::{Deserialize, Serialize};
use tauri::api::dialog::blocking::FileDialogBuilder;
@ -12,6 +12,12 @@ use tauri::api::path::home_dir;
const OBJ_URL: &'static str = "data:image/png;base64,";
#[derive(Serialize, Deserialize, Clone, Debug)]
pub(crate) struct WebRay {
frames: [String; 4],
meta: HashMap<String, String>,
}
#[tauri::command]
pub(crate) async fn open_image() -> Option<String> {
let path = FileDialogBuilder::new()
@ -47,11 +53,11 @@ pub(crate) async fn load_ray(path: impl AsRef<Path>) -> Option<WebRay> {
let mut meta = HashMap::new();
for i in 0..4 {
println!("Trying frame {}", i);
debug!("Trying frame {}", i);
if let Some(f) = ray.get_frame(i as usize) {
println!("Got frame {}", i);
debug!("Got frame {}", i);
if f.is_empty() {
println!("Frame {} was empty", i);
debug!("Frame {} was empty", i);
continue;
}
let encoded = base64::encode(&f);
@ -69,12 +75,6 @@ pub(crate) async fn load_ray(path: impl AsRef<Path>) -> Option<WebRay> {
Some(WebRay { frames, meta })
}
#[derive(Serialize, Deserialize, Clone, Debug)]
pub(crate) struct WebRay {
frames: [String; 4],
meta: HashMap<String, String>,
}
#[tauri::command]
pub(crate) async fn save_ray(ray: WebRay) -> Result<(), String> {
if let Some(path) = FileDialogBuilder::new()

View File

@ -53,9 +53,10 @@ fn main() {
if let Some(arg) = matches.args.get("file") {
if let Value::String(path) = arg.value.clone() {
let window = app.get_window("main").unwrap();
let path = Path::new(&path).canonicalize().unwrap();
tauri::async_runtime::spawn(async move {
if let Some(ray) = fs::load_ray(Path::new(&path)).await {
window.emit("load-ray", ray);
window.emit("load-ray", ray).unwrap();
}
});
}

View File

@ -65,9 +65,11 @@
width: 15vh;
height: 15vh;
user-select: none;
cursor: pointer;
}
.box {
user-select: none;
gap: 10px;
display: flex;
.context {

View File

@ -8,6 +8,7 @@
frames: Array<string>;
meta: {
threshold: string | undefined;
closeThreshold: string | undefined;
};
};
</script>
@ -22,6 +23,7 @@
import Bar from "../components/bar.svelte";
import { tick } from "svelte";
import { frames } from "../store";
import { quintInOut } from "svelte/easing";
let monitorTimer: NodeJS.Timer;
@ -44,6 +46,9 @@
if (ray.meta.threshold) {
$threshold = parseFloat(ray.meta.threshold);
}
if (ray.meta.closeThreshold) {
closeThreshold = parseFloat(ray.meta.closeThreshold);
}
};
onMount(async () => {
await appWindow.setMinSize(new PhysicalSize(720, 600));
@ -83,6 +88,7 @@
frames: [fr[0], fr[1], fr[2], fr[3]],
meta: {
threshold: $threshold.toString(),
closeThreshold: closeThreshold.toString(),
},
};
@ -106,7 +112,12 @@
/>
{#if !$transparent}
<div
transition:fly={{ duration: 200, x: -200, opacity: 100 }}
transition:fly={{
duration: 200,
x: -200,
opacity: 100,
easing: quintInOut,
}}
class="frames"
>
{#each [0, 1, 2, 3] as i}
@ -114,7 +125,15 @@
{/each}
</div>
<div transition:fly={{ duration: 200, x: 200, opacity: 100 }} class="audio">
<div
transition:fly={{
duration: 200,
x: 200,
opacity: 100,
easing: quintInOut,
}}
class="audio"
>
{#key $threshold}
<Bar
progress={$level * 100}
@ -127,23 +146,57 @@
><img src="mic.svg" alt="microphone" /></Bar
>
{/key}
<Bar
withSetpoint
progress={activation}
setpoint={closeThreshold}
onSetpointChange={(y) => (closeThreshold = y * 100)}
><img src="mouth.svg" alt="mouth" /></Bar
>
{#key closeThreshold}
<Bar
withSetpoint
progress={activation}
setpoint={closeThreshold}
onSetpointChange={(y) => (closeThreshold = y * 100)}
><img src="mouth.svg" alt="mouth" /></Bar
>
{/key}
</div>
<div
transition:fly={{
duration: 200,
y: -100,
opacity: 100,
easing: quintInOut,
}}
class="buttons"
>
<div on:click={saveRay}>Save</div>
<div on:click={loadRay}>Load</div>
</div>
<button on:click={saveRay}>Save</button>
<button on:click={loadRay}>Load</button>
{/if}
</div>
<svelte:body on:contextmenu|preventDefault />
<style lang="scss">
.buttons {
position: absolute;
top: 2vh;
left: 50%;
transform: translateX(-50%);
display: flex;
align-items: center;
justify-items: center;
gap: 5vh;
div {
color: white;
padding: 10px;
border-radius: 5px;
background-color: rgba(0.5, 0.5, 0.5, 0.5);
border: solid black 2px;
user-select: none;
cursor: pointer;
&:hover {
background-color: rgba(0.9, 0.9, 0.9, 0.9);
}
}
}
.frames {
align-items: left;
position: absolute;