style load and save buttons
ci/woodpecker/push/woodpecker Pipeline was successful
Details
ci/woodpecker/push/woodpecker Pipeline was successful
Details
parent
20af8b8164
commit
ef1211731f
|
@ -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 = [] }
|
||||
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -65,9 +65,11 @@
|
|||
width: 15vh;
|
||||
height: 15vh;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.box {
|
||||
user-select: none;
|
||||
gap: 10px;
|
||||
display: flex;
|
||||
.context {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue