Skip to content

Commit

Permalink
Merge pull request #106 from squidowl/fix/typing-history-enhancement
Browse files Browse the repository at this point in the history
Persist input history outside widget tree
  • Loading branch information
tarkah authored Jul 6, 2023
2 parents 928addd + b3d06cc commit 603a5aa
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 62 deletions.
2 changes: 1 addition & 1 deletion data/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
use crate::user::Nick;
use crate::{channel, Server};

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Buffer {
Server(Server),
Channel(Server, String),
Expand Down
19 changes: 18 additions & 1 deletion data/src/history.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::collections::HashMap;
use std::path::PathBuf;
use std::time::Duration;
use std::{fmt, io};
Expand All @@ -10,7 +11,7 @@ use tokio::time::Instant;
pub use self::manager::{Manager, Resource};
use crate::time::Posix;
use crate::user::Nick;
use crate::{compression, environment, message, server, Message};
use crate::{compression, environment, message, server, Buffer, Message};

pub mod manager;

Expand All @@ -21,6 +22,7 @@ const MAX_MESSAGES: usize = 10_000;
const TRUNC_COUNT: usize = 500;
/// Duration to wait after receiving last message before flushing
const FLUSH_AFTER_LAST_RECEIVED: Duration = Duration::from_secs(5);
const INPUT_HISTORY_LENGTH: usize = 100;

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Kind {
Expand Down Expand Up @@ -272,6 +274,21 @@ pub struct View<'a> {
pub new_messages: Vec<&'a Message>,
}

#[derive(Debug, Clone, Default)]
struct Input(HashMap<Buffer, Vec<String>>);

impl Input {
fn get<'a>(&'a self, buffer: &Buffer) -> &'a [String] {
self.0.get(buffer).map(Vec::as_slice).unwrap_or_default()
}

fn push(&mut self, buffer: &Buffer, text: String) {
let history = self.0.entry(buffer.clone()).or_default();
history.insert(0, text);
history.truncate(INPUT_HISTORY_LENGTH);
}
}

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
Expand Down
19 changes: 17 additions & 2 deletions data/src/history/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use tokio::time::Instant;
use crate::history::{self, History};
use crate::message::{self, Limit};
use crate::time::Posix;
use crate::user::Nick;
use crate::{server, Server};
use crate::user::{Nick, NickRef};
use crate::{server, Buffer, Input, Server};

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Resource {
Expand Down Expand Up @@ -164,6 +164,16 @@ impl Manager {
}
}

pub fn record_input(&mut self, input: Input, our_nick: NickRef) {
if let Some(message) = input.message(our_nick) {
self.record_message(input.server(), message);
}

if let Some(text) = input.raw() {
self.data.input.push(input.buffer(), text.to_string());
}
}

pub fn record_message(&mut self, server: &Server, message: crate::Message) {
self.data.add_message(
server.clone(),
Expand Down Expand Up @@ -274,6 +284,10 @@ impl Manager {
self.record_message(server, message);
});
}

pub fn input_history<'a>(&'a self, buffer: &Buffer) -> &'a [String] {
self.data.input.get(buffer)
}
}

fn with_limit<'a>(
Expand All @@ -297,6 +311,7 @@ fn with_limit<'a>(
#[derive(Debug, Default)]
struct Data {
map: HashMap<server::Server, HashMap<history::Kind, History>>,
input: history::Input,
}

impl Data {
Expand Down
16 changes: 15 additions & 1 deletion data/src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,33 @@ pub fn parse(buffer: Buffer, input: &str) -> Result<Input, command::Error> {
Err(error) => return Err(error),
};

Ok(Input { buffer, content })
Ok(Input {
buffer,
content,
raw: Some(input.to_string()),
})
}

#[derive(Debug, Clone)]
pub struct Input {
buffer: Buffer,
content: Content,
raw: Option<String>,
}

impl Input {
pub fn command(buffer: Buffer, command: Command) -> Self {
Self {
buffer,
content: Content::Command(command),
raw: None,
}
}

pub fn buffer(&self) -> &Buffer {
&self.buffer
}

pub fn server(&self) -> &Server {
self.buffer.server()
}
Expand Down Expand Up @@ -78,6 +88,10 @@ impl Input {

Some(message::Encoded::from(proto::Message::from(command)))
}

pub fn raw(&self) -> Option<&str> {
self.raw.as_deref()
}
}

#[derive(Debug, Clone)]
Expand Down
12 changes: 3 additions & 9 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,9 @@ impl Buffer {
pub fn data(&self) -> Option<data::Buffer> {
match self {
Buffer::Empty => None,
Buffer::Channel(state) => Some(data::Buffer::Channel(
state.server.clone(),
state.channel.clone(),
)),
Buffer::Server(state) => Some(data::Buffer::Server(state.server.clone())),
Buffer::Query(state) => Some(data::Buffer::Query(
state.server.clone(),
state.nick.clone(),
)),
Buffer::Channel(state) => Some(state.buffer()),
Buffer::Server(state) => Some(state.buffer()),
Buffer::Query(state) => Some(state.buffer()),
}
}

Expand Down
17 changes: 8 additions & 9 deletions src/buffer/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub fn view<'a>(
settings: &'a buffer::Settings,
is_focused: bool,
) -> Element<'a, Message> {
let buffer = state.buffer();
let input_history = history.input_history(&buffer);
let our_nick = clients.nickname(&state.server);

let messages = container(
Expand Down Expand Up @@ -85,12 +87,7 @@ pub fn view<'a>(
let users = clients.get_channel_users(&state.server, &state.channel);
let nick_list = nick_list::view(users).map(Message::UserContext);
let text_input = (is_focused && status.connected()).then(|| {
input_view::view(
&state.input_view,
data::Buffer::Channel(state.server.clone(), state.channel.clone()),
users,
)
.map(Message::InputView)
input_view::view(&state.input_view, buffer, users, input_history).map(Message::InputView)
});

let content = match (
Expand Down Expand Up @@ -138,6 +135,10 @@ impl Channel {
}
}

pub fn buffer(&self) -> data::Buffer {
data::Buffer::Channel(self.server.clone(), self.channel.clone())
}

pub fn update(
&mut self,
message: Message,
Expand All @@ -155,9 +156,7 @@ impl Channel {
(command.map(Message::ScrollView), event)
}
Message::InputView(message) => {
let (command, event) =
self.input_view
.update(message, &self.server, clients, history);
let (command, event) = self.input_view.update(message, clients, history);
let command = command.map(Message::InputView);

match event {
Expand Down
21 changes: 12 additions & 9 deletions src/buffer/input_view.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use data::user::User;
use data::{client, history, Buffer, Input, Server};
use data::{client, history, Buffer, Input};
use iced::Command;

use crate::widget::{input, Element};
Expand All @@ -14,11 +14,17 @@ pub enum Message {
CompletionSelected,
}

pub fn view<'a>(state: &State, buffer: Buffer, users: &'a [User]) -> Element<'a, Message> {
pub fn view<'a>(
state: &State,
buffer: Buffer,
users: &'a [User],
history: &'a [String],
) -> Element<'a, Message> {
input(
state.input_id.clone(),
buffer,
users,
history,
Message::Send,
Message::CompletionSelected,
)
Expand All @@ -39,20 +45,17 @@ impl State {
pub fn update(
&mut self,
message: Message,
server: &Server,
clients: &mut client::Map,
history: &mut history::Manager,
) -> (Command<Message>, Option<Event>) {
match message {
Message::Send(input) => {
if let Some(encoded) = input.encoded() {
clients.send(server, encoded);
clients.send(input.server(), encoded);
}
if let Some(message) = clients
.nickname(server)
.and_then(|nick| input.message(nick))
{
history.record_message(server, message);

if let Some(nick) = clients.nickname(input.server()) {
history.record_input(input, nick);
}

(Command::none(), Some(Event::InputSent))
Expand Down
18 changes: 9 additions & 9 deletions src/buffer/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub fn view<'a>(
settings: &'a buffer::Settings,
is_focused: bool,
) -> Element<'a, Message> {
let buffer = state.buffer();
let input_history = history.input_history(&buffer);

let messages = container(
scroll_view::view(
&state.scroll_view,
Expand Down Expand Up @@ -71,12 +74,7 @@ pub fn view<'a>(
.height(Length::Fill);
let spacing = is_focused.then_some(vertical_space(4));
let text_input = (is_focused && status.connected()).then(|| {
input_view::view(
&state.input_view,
data::Buffer::Query(state.server.clone(), state.nick.clone()),
&[],
)
.map(Message::InputView)
input_view::view(&state.input_view, buffer, &[], input_history).map(Message::InputView)
});

let scrollable = column![messages]
Expand Down Expand Up @@ -109,6 +107,10 @@ impl Query {
}
}

pub fn buffer(&self) -> data::Buffer {
data::Buffer::Query(self.server.clone(), self.nick.clone())
}

pub fn update(
&mut self,
message: Message,
Expand All @@ -126,9 +128,7 @@ impl Query {
(command.map(Message::ScrollView), event)
}
Message::InputView(message) => {
let (command, event) =
self.input_view
.update(message, &self.server, clients, history);
let (command, event) = self.input_view.update(message, clients, history);
let command = command.map(Message::InputView);

match event {
Expand Down
18 changes: 9 additions & 9 deletions src/buffer/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ pub fn view<'a>(
settings: &'a buffer::Settings,
is_focused: bool,
) -> Element<'a, Message> {
let buffer = state.buffer();
let input_history = history.input_history(&buffer);

let messages = container(
scroll_view::view(
&state.scroll_view,
Expand All @@ -38,12 +41,7 @@ pub fn view<'a>(
.height(Length::Fill);
let spacing = is_focused.then_some(vertical_space(4));
let text_input = (is_focused && status.connected()).then(|| {
input_view::view(
&state.input_view,
data::Buffer::Server(state.server.clone()),
&[],
)
.map(Message::InputView)
input_view::view(&state.input_view, buffer, &[], input_history).map(Message::InputView)
});

let scrollable = column![messages]
Expand Down Expand Up @@ -74,6 +72,10 @@ impl Server {
}
}

pub fn buffer(&self) -> data::Buffer {
data::Buffer::Server(self.server.clone())
}

pub fn update(
&mut self,
message: Message,
Expand All @@ -86,9 +88,7 @@ impl Server {
command.map(Message::ScrollView)
}
Message::InputView(message) => {
let (command, event) =
self.input_view
.update(message, &self.server, clients, history);
let (command, event) = self.input_view.update(message, clients, history);
let command = command.map(Message::InputView);

match event {
Expand Down
Loading

0 comments on commit 603a5aa

Please sign in to comment.