Skip to content

Commit

Permalink
Stage 4
Browse files Browse the repository at this point in the history
  • Loading branch information
AurevoirXavier committed Jun 19, 2024
1 parent 82b5975 commit 8f78bcf
Show file tree
Hide file tree
Showing 12 changed files with 353 additions and 505 deletions.
420 changes: 132 additions & 288 deletions Cargo.lock

Large diffs are not rendered by default.

75 changes: 37 additions & 38 deletions src/air.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
// TODO: use unwrap here and return result in other places.

// std
use std::{
sync::{atomic::Ordering, Once},
time::Duration,
};
use std::sync::Once;
// crates.io
use eframe::{egui::*, Frame, *};
use tokio::runtime::Runtime;
use eframe::{egui::*, glow::Context as GlowContext, Frame, *};
// self
use crate::{
component::Components,
Expand All @@ -21,7 +17,6 @@ use crate::{
#[derive(Debug)]
struct AiR {
once: Once,
runtime: Runtime,
components: Components,
state: State,
services: Services,
Expand All @@ -32,13 +27,12 @@ impl AiR {
Self::set_fonts(&ctx);

let once = Once::new();
let runtime = Runtime::new().unwrap();
let mut components = Components::init().unwrap();
let components = Components::init().unwrap();
let state = Default::default();
let services = Services::init(&ctx, &runtime, &mut components, &state).unwrap();
let services = Services::init(&ctx, &components, &state).unwrap();
let uis = Uis::init();

Self { once, runtime, components, state, services, uis }
Self { once, components, state, services, uis }
}

fn set_fonts(ctx: &Context) {
Expand All @@ -65,24 +59,6 @@ impl AiR {

ctx.set_fonts(fonts);
}

fn try_unhide(&mut self, ctx: &Context) {
let to_hide = self.state.to_hide.load(Ordering::SeqCst);
let focused = ctx.input(|i| i.focused);

if to_hide && !focused {
self.components.active_timer.refresh();
self.state.to_hide.store(true, Ordering::SeqCst);

// TODO: https://github.com/emilk/egui/discussions/4635.
// ctx.send_viewport_cmd(ViewportCommand::Minimized(true));
Os::hide();
} else if !to_hide && focused {
// TODO: find a better place to initialize this.
self.once.call_once(Os::set_move_to_active_space);
self.state.to_hide.store(true, Ordering::SeqCst);
}
}
}
impl App for AiR {
fn update(&mut self, ctx: &Context, _: &mut Frame) {
Expand All @@ -94,21 +70,44 @@ impl App for AiR {
};

self.uis.draw(air_ctx);
// TODO: these will be called multiple times, move to focus service.
self.try_unhide(ctx);
}

// TODO: move to timer service.
if self.components.active_timer.duration() > Duration::from_secs(15) {
self.components.active_timer.refresh();
fn save(&mut self, _: &mut dyn Storage) {
self.components.setting.save().unwrap();
}

if self.uis.chat.input.is_empty() {
self.components.quote.refresh(&self.runtime);
fn raw_input_hook(&mut self, _: &Context, raw_input: &mut RawInput) {
if let Some(focused) = raw_input.events.iter().find_map(|e| {
if let Event::WindowFocused(focused) = e {
Some(*focused)
} else {
None
}
}) {
if focused {
// This must be called on the main thread and after the window fully get
// initialized.
// If possible find a place to call this only once.
self.once.call_once(Os::set_move_to_active_space);
}
// TODO: https://github.com/emilk/egui/issues/4468.
// Allow 1 second for initialization during the first boot.
else if raw_input.time.unwrap_or_default() >= 1. {
// TODO: https://github.com/emilk/egui/discussions/4635.
// We can get rid of the OS API if this works.
// ctx.send_viewport_cmd(ViewportCommand::Minimized(false));
Os::hide();
}
}
}

fn save(&mut self, _: &mut dyn Storage) {
self.components.setting.save().unwrap();
fn on_exit(&mut self, _: Option<&GlowContext>) {
self.services.quoter.abort();
self.services.hotkey.abort();

if let Some(rt) = self.services.rt.take() {
rt.shutdown_background();
}
}
}

Expand Down
12 changes: 2 additions & 10 deletions src/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,11 @@ pub mod net;
pub mod openai;
use openai::OpenAi;

mod quote;
use quote::Quoter;
pub mod quote;

pub mod setting;
use setting::Setting;

pub mod timer;
use timer::Timer;

pub mod util;

// std
Expand All @@ -30,21 +26,17 @@ use crate::prelude::*;

#[derive(Debug)]
pub struct Components {
pub active_timer: Timer,
pub setting: Setting,
pub quote: Quoter,
pub tokenizer: Tokenizer,
pub openai: Arc<OpenAi>,
}
impl Components {
pub fn init() -> Result<Self> {
let active_timer = Timer::default();
let setting = Setting::load()?;
let quote = Quoter::default();
let tokenizer = Tokenizer::new(setting.ai.model.as_str());
// TODO: no clone.
let openai = Arc::new(OpenAi::new(setting.ai.clone()));

Ok(Self { active_timer, setting, quote, tokenizer, openai })
Ok(Self { setting, tokenizer, openai })
}
}
41 changes: 8 additions & 33 deletions src/component/quote.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,13 @@
// std
use std::{
borrow::Cow,
sync::{Arc, RwLock},
};
// serde
use serde::Deserialize;
use tokio::runtime::Runtime;
// self
use super::net::{Http, Response, HTTP_CLIENT};
use crate::prelude::*;

#[derive(Debug)]
pub struct Quoter {
pub quote: Arc<RwLock<String>>,
}
pub struct Quoter;
impl Quoter {
const DEFAULT: &'static str = r#" -----------
pub const DEFAULT: &'static str = r#" -----------
< Thinking... >
-----------
\ ^__^
Expand All @@ -23,31 +16,13 @@ impl Quoter {
||----w |
|| ||"#;

pub fn refresh(&mut self, runtime: &Runtime) {
let quote = self.quote.clone();

runtime.spawn(async move {
tracing::info!("fetching quote");
pub async fn fetch(&self) -> Result<String> {
tracing::info!("fetching quote");

if let Ok(r) =
HTTP_CLIENT.get_with_reties("https://api.quotable.io/random", 3, 500).await
{
if let Ok(Quote { author, content }) = r.json::<Quote>() {
if let Ok(mut q) = quote.write() {
*q = format!("{content}\n\n{author}");
}
}
}
});
}
let b = HTTP_CLIENT.get_with_reties("https://api.quotable.io/random", 3, 500).await?;
let q = b.json::<Quote>()?;

pub fn get(&self) -> Cow<str> {
self.quote.read().map(|q| Cow::Owned(q.to_owned())).unwrap_or(Cow::Borrowed(Self::DEFAULT))
}
}
impl Default for Quoter {
fn default() -> Self {
Self { quote: Arc::new(RwLock::new(Self::DEFAULT.into())) }
Ok(format!("{}\n\n{}", q.content, q.author))
}
}

Expand Down
19 changes: 0 additions & 19 deletions src/component/timer.rs

This file was deleted.

2 changes: 2 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub enum Error {
#[error(transparent)]
OpenAi(#[from] async_openai::error::OpenAIError),
#[error(transparent)]
Reqwew(#[from] reqwew::error::Error),
#[error(transparent)]
Toml(#[from] toml::de::Error),

#[error(transparent)]
Expand Down
1 change: 1 addition & 0 deletions src/os/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ impl AppKit for Os {
// let window: *mut AnyObject = objc2::msg_send![app, mainWindow];
// let _: () = objc2::msg_send![window, setCollectionBehavior: 1_u64<<1];

// TODO: handle the error.
NSApplication::sharedApplication(MainThreadMarker::new_unchecked())
.mainWindow()
.unwrap()
Expand Down
18 changes: 10 additions & 8 deletions src/service.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
mod hotkey;
use hotkey::Hotkey;

mod quoter;
use quoter::Quoter;

// crates.io
use eframe::egui::Context;
use tokio::runtime::Runtime;
Expand All @@ -9,17 +12,16 @@ use crate::{component::Components, prelude::*, state::State};

#[derive(Debug)]
pub struct Services {
pub rt: Option<Runtime>,
pub quoter: Quoter,
pub hotkey: Hotkey,
}
impl Services {
pub fn init(
ctx: &Context,
runtime: &Runtime,
components: &mut Components,
state: &State,
) -> Result<Self> {
let hotkey = Hotkey::init(ctx, runtime, components, state)?;
pub fn init(ctx: &Context, components: &Components, state: &State) -> Result<Self> {
let rt = Runtime::new()?;
let quoter = Quoter::init(&rt, state.chat.quote.clone());
let hotkey = Hotkey::init(ctx, &rt, components, state)?;

Ok(Self { hotkey })
Ok(Self { rt: Some(rt), quoter, hotkey })
}
}
Loading

0 comments on commit 8f78bcf

Please sign in to comment.