Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support automatically toggling room focus #337

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions src/windows/room/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,80 @@
&self.room_id
}

pub fn auto_toggle_focus(
&mut self,
act: &EditorAction,
ctx: &ProgramContext,
store: &mut ProgramStore,

Check warning on line 656 in src/windows/room/chat.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] src/windows/room/chat.rs#L656

warning: unused variable: `store` --> src/windows/room/chat.rs:656:9 | 656 | store: &mut ProgramStore, | ^^^^^ help: if this is intentional, prefix it with an underscore: `_store` | = note: `#[warn(unused_variables)]` on by default
Raw output
src/windows/room/chat.rs:656:9:w:warning: unused variable: `store`
   --> src/windows/room/chat.rs:656:9
    |
656 |         store: &mut ProgramStore,
    |         ^^^^^ help: if this is intentional, prefix it with an underscore: `_store`
    |
    = note: `#[warn(unused_variables)]` on by default


__END__
) -> Option<EditorAction> {
let is_insert = ctx.get_insert_style().is_some();

match (self.focus, act) {
(RoomFocus::Scrollback, _) if is_insert => {
// Insert mode commands should switch focus.
self.focus = RoomFocus::MessageBar;
None
},
(RoomFocus::Scrollback, EditorAction::InsertText(_)) => {
// Pasting or otherwise inserting text should switch.
self.focus = RoomFocus::MessageBar;
None
},
(
RoomFocus::Scrollback,
EditorAction::Edit(
op,
EditTarget::Motion(mov @ MoveType::Line(MoveDir1D::Next), count),
),
) if ctx.resolve(op).is_motion() => {
let count = ctx.resolve(count);

if count > 0 && self.scrollback.is_latest() {
// Trying to move down a line when already at the end of room history should
// switch.
self.focus = RoomFocus::MessageBar;

// And decrement the count for the action.
let count = count.saturating_sub(1).into();
let target = EditTarget::Motion(mov.clone(), count);
let dec = EditorAction::Edit(op.clone(), target);

Some(dec)
} else {
None
}
},
(
RoomFocus::MessageBar,
EditorAction::Edit(
op,
EditTarget::Motion(mov @ MoveType::Line(MoveDir1D::Previous), count),
),
) if !is_insert && ctx.resolve(op).is_motion() => {
let count = ctx.resolve(count);

if count > 0 && self.tbox.get_cursor().y == 0 {
// Trying to move up a line when already at the top of the msgbar should
// switch as long as we're not in Insert mode.
self.focus = RoomFocus::Scrollback;

// And decrement the count for the action.
let count = count.saturating_sub(1).into();
let target = EditTarget::Motion(mov.clone(), count);
let dec = EditorAction::Edit(op.clone(), target);

Some(dec)
} else {
None
}
},
(RoomFocus::Scrollback, _) | (RoomFocus::MessageBar, _) => {
// Do not switch.
None
},
}
}

pub fn typing_notice(
&self,
act: &EditorAction,
Expand Down Expand Up @@ -751,8 +825,16 @@
ctx: &ProgramContext,
store: &mut ProgramStore,
) -> EditResult<EditInfo, IambInfo> {
// Check whether we should automatically switch between
// the message bar or message scrollback, and use an
// adjusted action if we do so.
let adjusted = self.auto_toggle_focus(act, ctx, store);
let act = adjusted.as_ref().unwrap_or(act);

// Send typing notice if needed.
self.typing_notice(act, ctx, store);

// And now we can finally run the editor command.
match delegate!(self, w => w.editor_command(act, ctx, store)) {
res @ Ok(_) => res,
Err(EditError::WrongBuffer(IambBufferId::Room(room_id, thread, focus)))
Expand Down
23 changes: 17 additions & 6 deletions src/windows/room/scrollback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,26 +79,33 @@
}

fn nth_before(pos: MessageKey, n: usize, thread: &Messages) -> MessageCursor {
nth_key_before(pos, n, thread).into()
let key = nth_key_before(pos, n, thread);

if matches!(thread.last_key_value(), Some((last, _)) if &key == last) {
MessageCursor::latest()
} else {
MessageCursor::from(key)
}
}

fn nth_key_after(pos: MessageKey, n: usize, thread: &Messages) -> MessageKey {
fn nth_key_after(pos: MessageKey, n: usize, thread: &Messages) -> Option<MessageKey> {
let mut end = &pos;
let iter = thread.range(&pos..).enumerate();
let mut iter = thread.range(&pos..).enumerate();

for (i, (key, _)) in iter {
while let Some((i, (key, _))) = iter.next() {

Check warning on line 95 in src/windows/room/scrollback.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] src/windows/room/scrollback.rs#L95

warning: this loop could be written as a `for` loop --> src/windows/room/scrollback.rs:95:5 | 95 | while let Some((i, (key, _))) = iter.next() { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for (i, (key, _)) in iter.by_ref()` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#while_let_on_iterator = note: `#[warn(clippy::while_let_on_iterator)]` on by default
Raw output
src/windows/room/scrollback.rs:95:5:w:warning: this loop could be written as a `for` loop
  --> src/windows/room/scrollback.rs:95:5
   |
95 |     while let Some((i, (key, _))) = iter.next() {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for (i, (key, _)) in iter.by_ref()`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#while_let_on_iterator
   = note: `#[warn(clippy::while_let_on_iterator)]` on by default


__END__
end = key;

if i >= n {
break;
}
}

end.clone()
// Avoid returning the key if it's at the end.
iter.next().map(|_| end.clone())
}

fn nth_after(pos: MessageKey, n: usize, thread: &Messages) -> MessageCursor {
nth_key_after(pos, n, thread).into()
nth_key_after(pos, n, thread).map(MessageCursor::from).unwrap_or_default()
}

fn prevmsg<'a>(key: &MessageKey, thread: &'a Messages) -> Option<&'a Message> {
Expand Down Expand Up @@ -150,6 +157,10 @@
}
}

pub fn is_latest(&self) -> bool {
self.cursor.timestamp.is_none()
}

pub fn goto_latest(&mut self) {
self.cursor = MessageCursor::latest();
}
Expand Down
Loading