diff --git a/Cargo.toml b/Cargo.toml index e7491d9..7f10966 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "jiji" -version = "1.0.1" +version = "1.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/jiji.project b/jiji.project index 50f73e2..0c38548 100644 --- a/jiji.project +++ b/jiji.project @@ -1 +1 @@ -{"categories":[{"name":"to do","content":[{"name":"clean up bot code","description":"try to remove unnecessary code\n\nunindent\n\ngive sender to function ?","id":2},{"name":"trayable ?","description":"// Hello there","id":5},{"name":"new message marker","description":"perma if too complicated to detect read","id":2},{"name":"proper links","description":"when there is a link, ability to click it","id":3},{"name":"move config","description":"move config from .jiji/save.json\nto .config/jiji/config.json","id":2}]},{"name":"in progress","content":[]},{"name":"done","content":[{"name":"run discord bot","description":"make it so the bot is running","id":1},{"name":"fixed token in github","description":"// Hello there","id":1},{"name":"fetch previous messages","description":"// Hello there","id":4},{"name":"ability to write messages","description":"// Hello there","id":5},{"name":"get incoming messages","description":"read","id":2},{"name":"unread system","description":"add a * when a channel just received a message","id":1},{"name":"remember channel id for dm","description":"and put in config file\n\nmaybe load message ? dm first ?","id":3},{"name":"bug : does not save notification state for dm","description":"// Hello there","id":1},{"name":"handle unknown channel better","description":"when receiving a message from a not yet scanned guild, create the channel and put the message\n\nallow scanning if guild selected\n\ndo not add duplicate channel","id":1},{"name":"guild unread ?","description":"// Hello there","id":2},{"name":"timestamps","description":"// Hello there","id":1},{"name":"better ui error display","description":"handle the error packet for better display","id":1},{"name":"notifications !!!","description":"// Hello there","id":4}]},{"name":"bugs","content":[]},{"name":"v1.0","content":[{"name":"ability to change token","description":"use a config file to store token so that \n\n1- it is away from github\n\n2- it is configurable if need be","id":1}]},{"name":"+","content":[]}]} \ No newline at end of file +{"categories":[{"name":"to do","content":[{"name":"clean up bot code","description":"try to remove unnecessary code\n\nunindent\n\ngive sender to function ?","id":2},{"name":"trayable ?","description":"// Hello there","id":5}]},{"name":"in progress","content":[]},{"name":"done","content":[{"name":"run discord bot","description":"make it so the bot is running","id":1},{"name":"fixed token in github","description":"// Hello there","id":1},{"name":"fetch previous messages","description":"// Hello there","id":4},{"name":"ability to write messages","description":"// Hello there","id":5},{"name":"get incoming messages","description":"read","id":2},{"name":"unread system","description":"add a * when a channel just received a message","id":1},{"name":"remember channel id for dm","description":"and put in config file\n\nmaybe load message ? dm first ?","id":3},{"name":"bug : does not save notification state for dm","description":"// Hello there","id":1},{"name":"handle unknown channel better","description":"when receiving a message from a not yet scanned guild, create the channel and put the message\n\nallow scanning if guild selected\n\ndo not add duplicate channel","id":1},{"name":"guild unread ?","description":"// Hello there","id":2},{"name":"timestamps","description":"// Hello there","id":1},{"name":"better ui error display","description":"handle the error packet for better display","id":1},{"name":"notifications !!!","description":"// Hello there","id":4},{"name":"ability to change token","description":"use a config file to store token so that \n\n1- it is away from github\n\n2- it is configurable if need be","id":1},{"name":"fix timestam (utc+2)","description":"// Hello there","id":1},{"name":"move config","description":"move config from .jiji/save.json\nto .config/jiji/config.json","id":2},{"name":"scroll to bottom when new message","description":"// Hello there","id":1}]},{"name":"bugs","content":[]},{"name":"v1.0","content":[]},{"name":"v1.1","content":[{"name":"proper links","description":"when there is a link, ability to click it","id":3},{"name":"new message marker","description":"perma if too complicated to detect read","id":2},{"name":"text emoji","description":"( ˘ w˘(˘w ˘ )","id":2}]},{"name":"+","content":[]}]} \ No newline at end of file diff --git a/shell.nix b/shell.nix index ab6295d..d718dee 100644 --- a/shell.nix +++ b/shell.nix @@ -1,13 +1,6 @@ -{ pkgs ? import { overlays = [ (import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz)) ]; }, - unstable ? import { config = { allowUnfree = true; }; } -}: +{ pkgs ? import { overlays = [ (import (builtins.fetchTarball https://github.com/mozilla/nixpkgs-mozilla/archive/master.tar.gz)) ]; },}: with pkgs; -let - # Specify Pillow as a build input - pillow = python3Packages.pillow; -in - mkShell { nativeBuildInputs = with xorg; [ libxcb @@ -17,8 +10,11 @@ mkShell { pkg-config ] ++ [ cargo - unstable.rustc - python3 + rustc + atk + gdk-pixbuf + webkitgtk + glib libGL libGLU libxkbcommon diff --git a/src/discord_structure.rs b/src/discord_structure.rs index 2fadb47..d36207d 100644 --- a/src/discord_structure.rs +++ b/src/discord_structure.rs @@ -79,6 +79,10 @@ pub struct Channel { pub messages: Vec, pub notify: bool, pub unread: bool, + pub scroll_offset: f32, + pub content_size: f32, + pub inner_size: f32, + pub registered_messages: usize, } impl Channel { @@ -90,6 +94,10 @@ impl Channel { messages: vec![Message::create("0".into(), id, guild_id, "+".into(), "".into(), "".into())], notify: false, unread: false, + scroll_offset: 0.0, + content_size: 0.0, + inner_size: 0.0, + registered_messages: 0, } } diff --git a/src/main.rs b/src/main.rs index d4cb08a..8bd6828 100644 --- a/src/main.rs +++ b/src/main.rs @@ -63,6 +63,7 @@ struct Jiji { current_message: String, channels_to_notify: Vec, errors: Vec, + redraw: bool, } impl Jiji { @@ -96,6 +97,7 @@ impl Jiji { current_message: "".into(), channels_to_notify: app_state.channels_to_notify.clone(), errors: vec![], + redraw: false, } } } @@ -120,6 +122,10 @@ impl eframe::App for Jiji { if self.pending_bot_requests > 0 { egui::Context::request_repaint_after(ctx, Duration::from_secs_f32(RUNNING_REQUEST_REFRESH_DELAY)); } + if self.redraw { + egui::Context::request_repaint(ctx); + self.redraw = false; + } egui::Context::request_repaint_after(ctx, Duration::from_secs_f32(BACKGROUND_REFRESH_DELAY)); } @@ -133,7 +139,8 @@ pub fn save_path() -> PathBuf { .unwrap() .unwrap() .as_path() - .join(".jiji") + .join(".config") + .join("jiji") .join("save.json") .to_path_buf() } diff --git a/src/ui.rs b/src/ui.rs index 989f359..75efe6f 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,5 +1,5 @@ use eframe::egui; -use chrono::DateTime; +use chrono::{DateTime, Local}; use crate::postman; use crate::Jiji; @@ -165,31 +165,31 @@ impl Jiji { pub fn draw_feed(&mut self, ctx: &egui::Context) { egui::CentralPanel::default().show(ctx, |ui| { - egui::ScrollArea::vertical() - .stick_to_bottom(true) - .show(ui, |ui| { - if let Some(selected_guild_index) = &self.selected_guild { - if let Some(selected_channel_index) = &self.selected_channel { + if let Some(selected_guild_index) = &self.selected_guild { + if let Some(selected_channel_index) = &self.selected_channel { + let selected_guild = &mut self.guilds[*selected_guild_index]; + let selected_channel = &mut selected_guild.channels[*selected_channel_index]; + + let scrollarea_result = egui::ScrollArea::vertical() + .stick_to_bottom(true) + .vertical_scroll_offset(selected_channel.scroll_offset) + .show(ui, |ui| { let mut last_author = "".to_string(); - if self.guilds[*selected_guild_index].channels[*selected_channel_index].messages.len() < 2 { + if selected_channel.messages.len() < 2 { return } - for message in &self.guilds[*selected_guild_index].channels[*selected_channel_index].messages { + for message in &selected_channel.messages { if message.author_name == "+" { if ui.button("+").clicked() { - if let Some(selected_guild_index) = &self.selected_guild { - if let Some(selected_channel_index) = &self.selected_channel { - let _ = self.sender.send(postman::Packet::FetchMessages( - self.guilds[*selected_guild_index].id.clone(), - self.guilds[*selected_guild_index].channels[*selected_channel_index].id.clone(), - self.guilds[*selected_guild_index].channels[*selected_channel_index].messages[1].id.clone(), - )); - self.pending_bot_requests += 1; - } - } + let _ = self.sender.send(postman::Packet::FetchMessages( + selected_guild.id.clone(), + selected_channel.id.clone(), + selected_channel.messages[1].id.clone(), + )); + self.pending_bot_requests += 1; } continue } @@ -198,7 +198,8 @@ impl Jiji { ui.horizontal( |ui| { ui.colored_label(hex_str_to_color("#3399ff"), &message.author_name); if let Ok(timestamp) = DateTime::parse_from_rfc2822(&message.timestamp) { - ui.label(timestamp.format("%H:%M (%a, %e %b)").to_string()); + let local_timestamp = timestamp.with_timezone(&Local); + ui.label(local_timestamp.format("%H:%M (%a, %e %b)").to_string()); } }); } else { @@ -207,9 +208,29 @@ impl Jiji { ui.label(&message.content); last_author = message.author_name.clone(); } + }); + + let new_content_size = scrollarea_result.content_size[1]; + let new_inner_size = scrollarea_result.inner_rect.max.y - scrollarea_result.inner_rect.min.y; + + if selected_channel.registered_messages != selected_channel.messages.len() { + if selected_channel.scroll_offset >= selected_channel.content_size - selected_channel.inner_size * 1.5 { + selected_channel.scroll_offset = new_content_size - new_inner_size; + } else if selected_channel.scroll_offset < 1.0 { + selected_channel.scroll_offset = new_content_size - selected_channel.content_size; + } + + selected_channel.registered_messages = selected_channel.messages.len(); + self.redraw = true; + + } else { + selected_channel.scroll_offset = scrollarea_result.state.offset[1]; } + + selected_channel.content_size = new_content_size; + selected_channel.inner_size = new_inner_size; } - }); + } }); } }