Skip to content

Implement a TUI client using console_engine#1

Open
VincentFoulon80 wants to merge 11 commits intoLoipesMas:mainfrom
VincentFoulon80:feature/rich-tui-client
Open

Implement a TUI client using console_engine#1
VincentFoulon80 wants to merge 11 commits intoLoipesMas:mainfrom
VincentFoulon80:feature/rich-tui-client

Conversation

@VincentFoulon80
Copy link

@VincentFoulon80 VincentFoulon80 commented Apr 30, 2022

Hello !

I wanted to try to implement the TUI client of Accord using my own crate console_engine.
It's more of a "proof-of-concept", so I won't mind if you close this PR right away.
Feel free to comment my code if you see anything wrong, I'm still learning the language so any comment is appreciated.

Here's a changelog of what this PR changes :

🆕 Features

🐞 Bugfixes

  • Fixed Windows terminals sending \r\n as Enter key instead of the expected \n

📋 Todos (for later)

  • Implement login with the TUI crate
  • Implement auto scrolling
  • Allow moving the text cursor
  • handle more keyboard keys (home, end, del, ...)

Copy link
Owner

@LoipesMas LoipesMas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This look really nice, thanks!
I only found a few minor issues.
And if you'd finish what you mentioned in todos, I would definitely merge this, since it's clearly an improvement over what I made.

@VincentFoulon80 VincentFoulon80 force-pushed the feature/rich-tui-client branch from 5e48553 to 73a53b3 Compare May 1, 2022 17:59
@VincentFoulon80
Copy link
Author

I fixed the issues, and also resolved conflicts.

I'm working on implementing the rest of the todolist, I'm changing this PR to a draft.

Thanks for your review !

@VincentFoulon80 VincentFoulon80 marked this pull request as draft May 1, 2022 18:10
@VincentFoulon80 VincentFoulon80 force-pushed the feature/rich-tui-client branch from f181c8c to 59f7a95 Compare May 1, 2022 21:17
@VincentFoulon80 VincentFoulon80 marked this pull request as ready for review May 1, 2022 21:19
@VincentFoulon80
Copy link
Author

I just finished implementing my todolist into this PR, I hope I haven't made too much of a mess, moving all this code around and writing some cryptic code like in Message::print() where I "enabled" text_wrapping by inserting \n in messages (console_engine only handles text wrapping when we try to print \n characters).

Copy link
Owner

@LoipesMas LoipesMas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!
The code is indeed a bit messy, but I think mainly because it has too much code. I'd suggest abstracting some functions (e.g. the wrapping), so it looks clearer.

Another thing that I would like to see is better error handling. So instead of panicking on incorrect password, just display a message and allow the user to try again.

And maybe address input should be added to login screen as well? But I'm not sure.

@VincentFoulon80
Copy link
Author

Thanks for the review ! I'll look into it in detail later.

All this motivated me to implement Forms into my TUI crate directly, to simplify the code here but also allow everybody to have access to this kind of input in their own application. I'd be glad if one day you could review the PR out (when I'll be done with it), you've given me some precious advice and I truly appreciate the time you take to help me. Thank you !

@VincentFoulon80
Copy link
Author

VincentFoulon80 commented May 26, 2022

I finally finished my PR to add forms directly into the TUI crate, adding more features like checkboxes and radios, validation...

If you ever feel like taking a peek at the code, it's here.

Once the PR is merged (in a day or two, in case of someone wanting to review), I'll work on cleaning this mess up once and for all 🙂

@LoipesMas
Copy link
Owner

Sorry for the late reply 😅 I got kinda busy and forgot about this.
I can take a look at that PR tomorrow.

@VincentFoulon80
Copy link
Author

No worries about this, take your time and thanks a million for your help on this 😄
If you don't have time to check it it's also fine.

I'm on my way to adapt my work here to the future release, by the way. It's looking cleaner for sure 😉

@VincentFoulon80 VincentFoulon80 force-pushed the feature/rich-tui-client branch from 7c678e1 to f031b26 Compare June 4, 2022 13:59
@VincentFoulon80
Copy link
Author

VincentFoulon80 commented Jun 4, 2022

Hello ! Since I released console_engine version 2.4.0, I updated my code here to use the new features. I used clap to manage parameters (like address and port of the server)

I also took the freedom to change colors of the terminal, to mimic the GUI version

Let me know if you see anything I should change

Copy link
Owner

@LoipesMas LoipesMas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!
Only a few minor issues.

Also, as I said before, I think it's better to move address (and port) input to login screen. Unless you have arguments against.

Comment on lines +40 to +52
.chars()
.enumerate()
.flat_map(|(i, chr)| {
if i != 0 && i % screen.get_width() as usize == 0 {
lines += 1;
Some('\n')
} else {
None
}
.into_iter()
.chain(std::iter::once(chr))
})
.collect::<String>();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest abstracting this out to a separate function for readability and easier changes.
Also I think this code will fail if there is \n in the message (which right now is not allowed because it caused me trouble, but it probably could (and should) be allowed after this PR is merged).

Comment on lines +143 to +146
self.user_list.clear();
for entry in new_list {
self.add_user(entry)
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be replaced with:

self.user_list = BTreeSet::from(new_list.iter());
self.dirty = true;

?
I think this would be clearer. Unless we want something to happen in add_user in the future?

Comment on lines +150 to +153
if !self.user_list.contains(&username) {
self.dirty = true;
self.user_list.insert(username);
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about:

self.dirty |= !self.user_list.insert(username);

?
This should behave the same, because insert already checks if user_list contains the value (and returns if it was there).

Comment on lines +157 to +160
if self.user_list.contains(&username) {
self.dirty = true;
self.user_list.remove(&username);
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here:

self.dirty |= self.user_list.remove(&username);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants