Skip to content
Open
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
118 changes: 109 additions & 9 deletions src/windows/room/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -653,8 +653,17 @@ impl ChatState {
&mut self,
act: &EditorAction,
ctx: &ProgramContext,
info: &RoomInfo,
) -> Option<EditorAction> {
auto_toggle_focus(&mut self.focus, act, ctx, &self.scrollback, &mut self.tbox)
auto_toggle_focus(
&mut self.focus,
act,
ctx,
&self.scrollback,
&mut self.tbox,
&mut self.reply_to,
info,
)
}

pub fn typing_notice(
Expand Down Expand Up @@ -761,7 +770,8 @@ impl Editable<ProgramContext, ProgramStore, IambInfo> for ChatState {
) -> 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);
let info = store.application.rooms.get_or_default(self.room_id.clone());
let adjusted = self.auto_toggle_focus(act, ctx, info);
let act = adjusted.as_ref().unwrap_or(act);

// Send typing notice if needed.
Expand Down Expand Up @@ -1012,17 +1022,25 @@ pub fn auto_toggle_focus(
ctx: &ProgramContext,
scrollback: &ScrollbackState,
tbox: &mut TextBoxState<IambInfo>,
reply_to: &mut Option<MessageKey>,
info: &RoomInfo,
) -> Option<EditorAction> {
let is_insert = ctx.get_insert_style().is_some();

match (focus, act) {
(f @ RoomFocus::Scrollback, _) if is_insert => {
// Insert mode commands should switch focus.
if reply_to.is_none() && !tbox.get_text().is_empty() {
*reply_to = scrollback.get_key(info);
}
f.toggle();
None
},
(f @ RoomFocus::Scrollback, EditorAction::InsertText(_)) => {
// Pasting or otherwise inserting text should switch.
if reply_to.is_none() && !tbox.get_text().is_empty() {
*reply_to = scrollback.get_key(info);
}
f.toggle();
None
},
Expand Down Expand Up @@ -1050,6 +1068,30 @@ pub fn auto_toggle_focus(
None
}
},
(
f @ RoomFocus::MessageBar,
EditorAction::Edit(
op,
EditTarget::Motion(mov @ MoveType::Line(MoveDir1D::Next), count),
),
) if !is_insert && ctx.resolve(op).is_motion() => {
let count = ctx.resolve(count);

if count > 0 && tbox.get_cursor().y == tbox.get_lines() - 1 && !scrollback.is_latest() {
// Trying to move down a line in msgbar when scrollback is not at the bottom should
// switch as long as we're not in Insert mode.
f.toggle();

// 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
}
},
(
f @ RoomFocus::MessageBar,
EditorAction::Edit(
Expand Down Expand Up @@ -1109,6 +1151,8 @@ mod tests {
let id = IambBufferId::Room(room_id, None, RoomFocus::MessageBar);
let ebuf = store.load_buffer(id);
let mut tbox = TextBoxState::new(ebuf);
let mut reply_to = None;
let info = RoomInfo::default();

// Start out focused on the scrollback.
let mut focused = RoomFocus::Scrollback;
Expand All @@ -1119,43 +1163,99 @@ mod tests {
MoveDir1D::Next,
1.into(),
));
let res = auto_toggle_focus(&mut focused, &act, &ctx, &scrollback, &mut tbox);
let res = auto_toggle_focus(
&mut focused,
&act,
&ctx,
&scrollback,
&mut tbox,
&mut reply_to,
&info,
);
assert_eq!(focused, RoomFocus::MessageBar);
assert!(res.is_none());

// Going down in message bar doesn't toggle:
let act = move_line!(MoveDir1D::Next, 1);
let res = auto_toggle_focus(&mut focused, &act, &ctx, &scrollback, &mut tbox);
let res = auto_toggle_focus(
&mut focused,
&act,
&ctx,
&scrollback,
&mut tbox,
&mut reply_to,
&info,
);
assert_eq!(focused, RoomFocus::MessageBar);
assert!(res.is_none());

// But going up will:
let act = move_line!(MoveDir1D::Previous, 1);
let res = auto_toggle_focus(&mut focused, &act, &ctx, &scrollback, &mut tbox);
let res = auto_toggle_focus(
&mut focused,
&act,
&ctx,
&scrollback,
&mut tbox,
&mut reply_to,
&info,
);
assert_eq!(focused, RoomFocus::Scrollback);
assert_eq!(res, Some(move_line!(MoveDir1D::Previous, 0)));

// Going up in scrollback doesn't toggle:
let act = move_line!(MoveDir1D::Previous, 1);
let res = auto_toggle_focus(&mut focused, &act, &ctx, &scrollback, &mut tbox);
let res = auto_toggle_focus(
&mut focused,
&act,
&ctx,
&scrollback,
&mut tbox,
&mut reply_to,
&info,
);
assert_eq!(focused, RoomFocus::Scrollback);
assert_eq!(res, None);

// And then go back down:
let act = move_line!(MoveDir1D::Next, 1);
let res = auto_toggle_focus(&mut focused, &act, &ctx, &scrollback, &mut tbox);
let res = auto_toggle_focus(
&mut focused,
&act,
&ctx,
&scrollback,
&mut tbox,
&mut reply_to,
&info,
);
assert_eq!(focused, RoomFocus::MessageBar);
assert_eq!(res, Some(move_line!(MoveDir1D::Next, 0)));

// Go up 2 will go up 1 in scrollback:
let act = move_line!(MoveDir1D::Previous, 2);
let res = auto_toggle_focus(&mut focused, &act, &ctx, &scrollback, &mut tbox);
let res = auto_toggle_focus(
&mut focused,
&act,
&ctx,
&scrollback,
&mut tbox,
&mut reply_to,
&info,
);
assert_eq!(focused, RoomFocus::Scrollback);
assert_eq!(res, Some(move_line!(MoveDir1D::Previous, 1)));

// Go down 3 will go down 2 in messagebar:
let act = move_line!(MoveDir1D::Next, 3);
let res = auto_toggle_focus(&mut focused, &act, &ctx, &scrollback, &mut tbox);
let res = auto_toggle_focus(
&mut focused,
&act,
&ctx,
&scrollback,
&mut tbox,
&mut reply_to,
&info,
);
assert_eq!(focused, RoomFocus::MessageBar);
assert_eq!(res, Some(move_line!(MoveDir1D::Next, 2)));
}
Expand Down
2 changes: 1 addition & 1 deletion src/windows/room/scrollback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ impl ScrollbackState {
self.viewctx.dimensions = (area.width as usize, area.height as usize);
}

pub fn get_key(&self, info: &mut RoomInfo) -> Option<MessageKey> {
pub fn get_key(&self, info: &RoomInfo) -> Option<MessageKey> {
self.cursor
.timestamp
.clone()
Expand Down
Loading