actions menu
[?]
Jul 23, 2025, 12:22 PM
A6Z4O6RC33HYWP7JIVQ6FDWE4EOCQWQTIGENK2WAHUGSHDDLSA7QCDependencies
- [2]
WT3GA27Padd cursor with selection - [3]
KT5UYXGKfix selection after adding file, add changed file diffs - [4]
ELG3UDT6allow to rm added files - [5]
S2NVIFXRallow to enter record msg - [6]
D7A7MSIHallow to defer or abandon record, add buttons - [7]
ZVI4AWERwoot contents_diff - [8]
AHWWRC73navigate log entries - [9]
L6KSEFQImove cursor related stuff into its module - [10]
23SFYK4Qbig view refactor into a new crate - [11]
OPXFZKEBview tests setup - [12]
3QVNMRNMtest non-empty repo app view - [13]
MYGIBRRHwip custom theme - [14]
PKJCFSBMtheme improvements - [15]
XSZZB47Urefactor stuff into lib - [16]
3BK22XE5add a test for hover btn and more refactors - [17]
ACDXXAX2refactor main's updates into smaller fns - [18]
I56UGW7Umake record test, fix log update - [19]
X6AK4QPXfinish recording test - [20]
KMB6FND3test view update fn rather than direct fn calls - [21]
YYKXNBFLtest: add untracked file - [22]
5CYU7UT7test: rm added file - [23]
ESMM3FELtest selection reindexing - [24]
TSFQFCB2test got repo change - [25]
7SSBM4UQview: refactor repo view - [26]
OC6DLIZ3test record when nothing to record - [27]
ZD56BUSUadd back +/- bg colors - [28]
I2AG42PAnew cols layout - [29]
SASAN2XCuse nav-scrollable - [30]
YKHE3XMWrefactor diffs handling - [31]
KWTBNTO3diffs selection and scrolling - [32]
5MUEECMJsmooth scrolling nav - [33]
PTWZYQFRuse nav-scrollable for repo status - [34]
UR4J677Rnav for log changes and refactors - [35]
K63JN6CRrefactor out non-view field from cursor - [36]
FLQWY7L4iced-nav-scrollable more docs - [37]
WW36JYLRadd iced_nav_scrollable widget crate - [38]
3TLPJ57Balt scroll via context and couple fixes - [39]
A5YBC77Vrecord! - [40]
GOLHUD6Rnav-scrollable: set skip-able sections - [41]
65DXFP3Yfix status overflow - [42]
6YZAVBWUInitial commit - [43]
BFN2VHZSrefactor file stuff into sub-mod - [44]
S2T7RUKWadd nav back placeholder - [45]
W7IUT3ZVstart recording impl - [46]
KEPKF3WOunify diffs handling, simplify view - [47]
YBJRDOTCmake all repo actions async - [48]
TEI5NQ3Sadd log files selection - [*]
VCNKFNUFapp init test
Change contents
- edit in inflorescence_view/src/theme.rs at line 60
const ACTIONS_BG: Background = Background::Color(BLUE_DARKER); - edit in inflorescence_view/src/theme.rs at line 86
ActionsBg, - edit in inflorescence_view/src/theme.rs at line 197
Container::ActionsBg => container::Style {background: Some(ACTIONS_BG),..default()}, - replacement in inflorescence_view/src/app.rs at line 12
use iced::{font, window, Element, Font, Length};use iced::{font, window, Element, Font, Length, Padding}; - edit in inflorescence_view/src/app.rs at line 27
pub cursor: &'a cursor::State, - edit in inflorescence_view/src/app.rs at line 52
is_added_from_untracked: bool, - replacement in inflorescence_view/src/app.rs at line 88
DeferRecord,PostponeRecord, - replacement in inflorescence_view/src/app.rs at line 90
AbandonRecord,DiscardRecord, - edit in inflorescence_view/src/app.rs at line 101
AddUntrackedFile,RmAddedFile,StartRecord, - edit in inflorescence_view/src/app.rs at line 120
cursor, - replacement in inflorescence_view/src/app.rs at line 124
view_repo(window_size, repo_path, repo, cursor, record_msg, selection)view_repo(window_size, repo_path, repo, record_msg, selection) - edit in inflorescence_view/src/app.rs at line 139
cursor: &'a cursor::State, - replacement in inflorescence_view/src/app.rs at line 166
let is_selected = matches!(cursor.selection.as_ref() ,Some(cursor::Selection::UntrackedFile{ ix: selected_ix, .. }) if &ix == selected_ixlet is_selected = matches!(selection.as_ref() ,Some(Selection::UntrackedFile{ ix: selected_ix, .. }) if &ix == selected_ix - replacement in inflorescence_view/src/app.rs at line 185
let is_selected = matches!(cursor.selection.as_ref(),Some(cursor::Selection::ChangedFile{ ix: selected_ix, .. }) if &ix == selected_ixlet is_selected = matches!(selection.as_ref(),Some(Selection::ChangedFile{ ix: selected_ix, .. }) if &ix == selected_ix - replacement in inflorescence_view/src/app.rs at line 210
let is_selected = matches!(cursor.selection.as_ref(),Some(cursor::Selection::LogChange { ix: selected_ix, .. }) if &ix == selected_ixlet is_selected = matches!(selection.as_ref(),Some(Selection::Log { ix: selected_ix, .. }) if &ix == selected_ix - replacement in inflorescence_view/src/app.rs at line 234
el(button(text("Defer")).on_press(Msg::DeferRecord)),el(button(text("Abandon")).on_press(Msg::AbandonRecord)),el(button(text("Postpone")).on_press(Msg::PostponeRecord)),el(button(text("Discard")).on_press(Msg::DiscardRecord)), - replacement in inflorescence_view/src/app.rs at line 262
Some(Selection::ChangedFile { path, ix: _, diff }) => {Some(Selection::ChangedFile {path,ix: _,diff,is_added_from_untracked: _,}) => { - replacement in inflorescence_view/src/app.rs at line 336
} else if let Some(selection) = cursor.selection.as_ref() {} else if let Some(selection) = selection.as_ref() { - replacement in inflorescence_view/src/app.rs at line 338
cursor::Selection::UntrackedFile { .. }| cursor::Selection::ChangedFile { .. }| cursor::Selection::LogChange { file: None, .. } => 1,cursor::Selection::LogChange { file: Some(_), .. } => 2,Selection::UntrackedFile { .. }| Selection::ChangedFile { .. }| Selection::Log { file: None, .. } => 1,Selection::Log { file: Some(_), .. } => 2, - replacement in inflorescence_view/src/app.rs at line 396
el(button(row([el(text("← ").font(Font::MONOSPACE)),el(text("Status")),]))el(button(row([el(text("← Status").shaping(text::Shaping::Advanced))])) - replacement in inflorescence_view/src/app.rs at line 466
if let Some(col_2) = col_2 {let main = if let Some(col_2) = col_2 { - replacement in inflorescence_view/src/app.rs at line 468
el(row(cols).spacing(SPACING))el(row(cols).spacing(SPACING).width(Length::Fill).height(Length::Fill)) - replacement in inflorescence_view/src/app.rs at line 474
el(row(cols).spacing(SPACING))}el(row(cols).spacing(SPACING).width(Length::Fill).height(Length::Fill))};let actions_inner = view_actions(action_state(repo, record_msg, selection));let actions = el(container(actions_inner).class(theme::Container::ActionsBg).width(Length::Fill).height(Length::Shrink).padding(Padding::from([4, 6])));el(column([main, actions])) - edit in inflorescence_view/src/app.rs at line 495
}fn view_actions<'a>(state: ActionState) -> Element<'a, Msg, Theme> {let left = || {action_button("← | h",Msg::Cursor(cursor::Msg::PressDir(cursor::Dir::Left)),)};let down = || {action_button("↓ | j",Msg::Cursor(cursor::Msg::PressDir(cursor::Dir::Down)),)};let up = || {action_button("↑ | k",Msg::Cursor(cursor::Msg::PressDir(cursor::Dir::Up)),)};let right = || {action_button("→ | l",Msg::Cursor(cursor::Msg::PressDir(cursor::Dir::Right)),)};let down_no_skip = || {action_button("S-(↓ | j): no skip",Msg::Cursor(cursor::Msg::AltPressDir(cursor::Dir::Down)),)};let up_no_skip = || {action_button("S-(↑ | k): no skip",Msg::Cursor(cursor::Msg::AltPressDir(cursor::Dir::Up)),)};let add_untracked =|| action_button("a: track file", Msg::AddUntrackedFile);let rm_added_file = || action_button("x: untrack file", Msg::RmAddedFile);let start_record = || action_button("r: record", Msg::StartRecord);let save_record = || action_button("C-s: save record", Msg::SaveRecord);let postpone_record =|| action_button("C-d: postpone record", Msg::PostponeRecord);let discard_record =|| action_button("C-d: discard record", Msg::DiscardRecord);let add_if = |predicate: bool,button: Element<'a, Msg, Theme>,row: row::Row<'a, Msg, Theme>| {if predicate {row.push(button)} else {row}};let buttons = match state {ActionState::Main {selection,can_select_right,can_record,} => {let row = row([down(), up()]);match selection {MainSelection::Untracked => {let row = row.push(add_untracked());let row = add_if(can_select_right, right(), row);add_if(can_record, start_record(), row)}MainSelection::AddedFromUntracked => {let row = row.push(rm_added_file());let row = add_if(can_select_right, right(), row);add_if(can_record, start_record(), row)}MainSelection::Other => {let row = add_if(can_select_right, right(), row);add_if(can_record, start_record(), row)}}}ActionState::LogChange {can_select_right,can_record,} => {let row = row([left(), down(), up()]);let row = add_if(can_select_right, right(), row);add_if(can_record, start_record(), row)}ActionState::Diff { can_record } => {let row = row([left(), down(), up(), down_no_skip(), up_no_skip()]);add_if(can_record, start_record(), row)}ActionState::Recording => {row([save_record(), postpone_record(), discard_record()])}};el(buttons.spacing(2).wrap()) - edit in inflorescence_view/src/app.rs at line 597
enum ActionState {/// Main statusMain {selection: MainSelection,can_select_right: bool,can_record: bool,},/// Selected a log change, but not diffLogChange {can_select_right: bool,can_record: bool,},/// Untracked, changed of log change's diffDiff { can_record: bool },/// Making a record from current changesRecording,}enum MainSelection {Untracked,AddedFromUntracked,Other,}/// Determine state for actions menufn action_state<'a>(repo: &'a Repo,record_msg: Option<&'a RecordMsg>,selection: Option<Selection<'a>>,) -> ActionState {match record_msg {Some(RecordMsg::Typing(_)) => return ActionState::Recording,Some(RecordMsg::Canceled { .. }) | None => {}} - edit in inflorescence_view/src/app.rs at line 633
let can_record = !repo.state.changed_files.is_empty();match selection {Some(Selection::UntrackedFile {ix: _,path: _,diff,}) => {if let Some(diff) = diff {if diff.is_selected {ActionState::Diff { can_record }} else {ActionState::Main {selection: MainSelection::Untracked,can_select_right: matches!(diff.nav.ready,Some(iced_nav_scrollable::NeedsScrolling::Yes)),can_record,}}} else {ActionState::Main {selection: MainSelection::Untracked,can_select_right: false,can_record,}}}Some(Selection::ChangedFile {ix: _,path: _,diff,is_added_from_untracked,}) => {let main_selection = || {if is_added_from_untracked {MainSelection::AddedFromUntracked} else {MainSelection::Other}};if let Some(diff) = diff {if diff.is_selected {ActionState::Diff { can_record }} else {ActionState::Main {selection: main_selection(),can_select_right: matches!(diff.nav.ready,Some(iced_nav_scrollable::NeedsScrolling::Yes)),can_record,}}} else {ActionState::Main {selection: main_selection(),can_select_right: false,can_record,}}}Some(Selection::Log {ix: _,hash: _,message: _,file,nav,}) => match file {Some(LogChangeFileSelection {ix: _,path: _,diff,}) => {if let Some(diff) = diff {if diff.is_selected {ActionState::Diff { can_record }} else {ActionState::LogChange {can_select_right: matches!(diff.nav.ready,Some(iced_nav_scrollable::NeedsScrolling::Yes)),can_record,}}} else {ActionState::LogChange {can_select_right: false,can_record,}}}None => ActionState::Main {selection: MainSelection::Other,can_select_right: nav.and_then(|nav| nav.ready).is_some(),can_record,},},None => ActionState::Main {selection: MainSelection::Other,can_select_right: false,can_record,},}}fn action_button<'a>(label: &'a str, on_press: Msg) -> Element<'a, Msg, Theme> {el(button(text(label).shaping(text::Shaping::Advanced)).on_press(on_press))} - replacement in inflorescence_view/src/app/test.rs at line 1
use super::{cursor, view, Repo, State};use super::{view, Repo, Selection, State}; - edit in inflorescence_view/src/app/test.rs at line 31
let cursor = cursor::State::default(); - edit in inflorescence_view/src/app/test.rs at line 37
cursor: &cursor, - edit in inflorescence_view/src/app/test.rs at line 64
cursor: &cursor, - edit in inflorescence_view/src/app/test.rs at line 104
cursor: &cursor, - edit in inflorescence_view/src/app/test.rs at line 117
cursor: &cursor, - replacement in inflorescence_view/src/app/test.rs at line 135[13.8738]→[13.8738:8830](∅→∅),[13.8830]→[14.3390:3409](∅→∅),[14.3409]→[13.8849:8883](∅→∅),[13.8849]→[13.8849:8883](∅→∅),[13.8883]→[31.7414:7448](∅→∅),[31.7448]→[13.8883:8895](∅→∅),[13.8883]→[13.8883:8895](∅→∅),[13.8895]→[32.695:719](∅→∅),[32.719]→[13.8895:8902](∅→∅),[13.8895]→[13.8895:8902](∅→∅)
let cursor = cursor::State {selection: Some(cursor::Selection::UntrackedFile {ix: 0,path: "".to_string(),diff_selected: false,}),held_key: None,};let selection = Some(Selection::UntrackedFile {ix: 0,path: "",diff: None,}); - edit in inflorescence_view/src/app/test.rs at line 144
cursor: &cursor, - replacement in inflorescence_view/src/app/test.rs at line 145
selection: None,selection, - replacement in inflorescence/src/test.rs at line 120
let _task = update(&mut state, Msg::AddUntrackedFile);let _task = update(&mut state, Msg::View(app::Msg::AddUntrackedFile)); - replacement in inflorescence/src/test.rs at line 130
let _task = update(&mut state, Msg::StartRecord);let _task = update(&mut state, Msg::View(app::Msg::StartRecord)); - replacement in inflorescence/src/test.rs at line 187
state.cursor.selection = Some(cursor::Selection::UntrackedFile {state.cursor.view.selection = Some(cursor::Selection::UntrackedFile { - replacement in inflorescence/src/test.rs at line 194
let _task = update(&mut state, Msg::AddUntrackedFile);let _task = update(&mut state, Msg::View(app::Msg::AddUntrackedFile)); - replacement in inflorescence/src/test.rs at line 204
let _task = update(&mut state, Msg::StartRecord);let _task = update(&mut state, Msg::View(app::Msg::StartRecord)); - replacement in inflorescence/src/test.rs at line 226
let _task = update(&mut state, Msg::View(app::Msg::AbandonRecord));let _task = update(&mut state, Msg::View(app::Msg::DiscardRecord)); - replacement in inflorescence/src/test.rs at line 233
let _task = update(&mut state, Msg::StartRecord);let _task = update(&mut state, Msg::View(app::Msg::StartRecord)); - replacement in inflorescence/src/test.rs at line 255
let _task = update(&mut state, Msg::View(app::Msg::DeferRecord));let _task = update(&mut state, Msg::View(app::Msg::PostponeRecord)); - replacement in inflorescence/src/test.rs at line 264
let _task = update(&mut state, Msg::StartRecord);let _task = update(&mut state, Msg::View(app::Msg::StartRecord)); - replacement in inflorescence/src/test.rs at line 284
let task = update(&mut state, Msg::StartRecord);let task = update(&mut state, Msg::View(app::Msg::StartRecord)); - replacement in inflorescence/src/test.rs at line 348
let _task = update(&mut state, Msg::AddUntrackedFile);let _task = update(&mut state, Msg::View(app::Msg::AddUntrackedFile)); - replacement in inflorescence/src/test.rs at line 381
let _task = update(&mut state, Msg::RmAddedFile);let _task = update(&mut state, Msg::View(app::Msg::RmAddedFile)); - replacement in inflorescence/src/test.rs at line 431
assert!(state.cursor.selection.is_none());assert!(state.cursor.view.selection.is_none()); - replacement in inflorescence/src/test.rs at line 441
assert!(state.cursor.selection.is_none());assert!(state.cursor.view.selection.is_none()); - replacement in inflorescence/src/test.rs at line 455
state.cursor.selection = Some(cursor::Selection::UntrackedFile {state.cursor.view.selection = Some(cursor::Selection::UntrackedFile { - replacement in inflorescence/src/test.rs at line 468
assert!(state.cursor.selection.is_some());assert!(state.cursor.view.selection.is_some()); - replacement in inflorescence/src/test.rs at line 470
state.cursor.selection.as_ref().unwrap(),state.cursor.view.selection.as_ref().unwrap(), - replacement in inflorescence/src/test.rs at line 490
state.cursor.selection = Some(cursor::Selection::UntrackedFile {state.cursor.view.selection = Some(cursor::Selection::UntrackedFile { - replacement in inflorescence/src/test.rs at line 503
assert!(state.cursor.selection.is_none());assert!(state.cursor.view.selection.is_none()); - replacement in inflorescence/src/test.rs at line 521
state.cursor.selection = Some(cursor::Selection::ChangedFile {state.cursor.view.selection = Some(cursor::Selection::ChangedFile { - replacement in inflorescence/src/test.rs at line 534
assert!(state.cursor.selection.is_some());assert!(state.cursor.view.selection.is_some()); - replacement in inflorescence/src/test.rs at line 536
state.cursor.selection.as_ref().unwrap(),state.cursor.view.selection.as_ref().unwrap(), - replacement in inflorescence/src/test.rs at line 558
state.cursor.selection = Some(cursor::Selection::ChangedFile {state.cursor.view.selection = Some(cursor::Selection::ChangedFile { - replacement in inflorescence/src/test.rs at line 571
assert!(state.cursor.selection.is_some());assert!(state.cursor.view.selection.is_some()); - replacement in inflorescence/src/test.rs at line 573
state.cursor.selection.as_ref().unwrap(),state.cursor.view.selection.as_ref().unwrap(), - replacement in inflorescence/src/test.rs at line 584
state.cursor.selection = Some(cursor::Selection::ChangedFile {state.cursor.view.selection = Some(cursor::Selection::ChangedFile { - replacement in inflorescence/src/test.rs at line 597
assert!(state.cursor.selection.is_none());assert!(state.cursor.view.selection.is_none()); - replacement in inflorescence/src/test.rs at line 626
state.cursor.selection = Some(cursor::Selection::LogChange {state.cursor.view.selection = Some(cursor::Selection::LogChange { - replacement in inflorescence/src/test.rs at line 640
assert!(state.cursor.selection.is_some());assert!(state.cursor.view.selection.is_some()); - replacement in inflorescence/src/test.rs at line 642
state.cursor.selection.as_ref().unwrap(),state.cursor.view.selection.as_ref().unwrap(), - replacement in inflorescence/src/test.rs at line 653
state.cursor.selection = Some(cursor::Selection::UntrackedFile {state.cursor.view.selection = Some(cursor::Selection::UntrackedFile { - replacement in inflorescence/src/test.rs at line 666
assert!(state.cursor.selection.is_none());assert!(state.cursor.view.selection.is_none()); - replacement in inflorescence/src/test.rs at line 690
assert!(state.cursor.selection.is_none());assert!(state.cursor.view.selection.is_none()); - replacement in inflorescence/src/test.rs at line 694
assert!(state.cursor.selection.is_none());assert!(state.cursor.view.selection.is_none()); - replacement in inflorescence/src/test.rs at line 699
state.cursor.selection = Some(cursor::Selection::LogChange {state.cursor.view.selection = Some(cursor::Selection::LogChange { - replacement in inflorescence/src/test.rs at line 708
assert!(state.cursor.selection.is_some());assert!(state.cursor.view.selection.is_some()); - replacement in inflorescence/src/test.rs at line 713
state.cursor.selection = Some(cursor::Selection::LogChange {state.cursor.view.selection = Some(cursor::Selection::LogChange { - replacement in inflorescence/src/test.rs at line 722[30.2892]→[24.2025:2072](∅→∅),[34.8102]→[24.2025:2072](∅→∅),[31.8653]→[24.2025:2072](∅→∅),[24.2025]→[24.2025:2072](∅→∅)
assert!(state.cursor.selection.is_some());assert!(state.cursor.view.selection.is_some()); - edit in inflorescence/src/main.rs at line 135[9.42]→[3.4615:4637](∅→∅),[8.682]→[3.4615:4637](∅→∅),[7.2918]→[3.4615:4637](∅→∅),[2.735]→[3.4615:4637](∅→∅),[3.4637]→[4.632:649](∅→∅),[4.649]→[17.125:142](∅→∅)
AddUntrackedFile,RmAddedFile,StartRecord, - edit in inflorescence/src/main.rs at line 166
Msg::AddUntrackedFile => add_untracked_file(state),Msg::RmAddedFile => rm_added_file(state),Msg::StartRecord => start_record(state), - replacement in inflorescence/src/main.rs at line 284
app::Msg::DeferRecord => defer_record(state),app::Msg::AbandonRecord => abandon_record(state),app::Msg::PostponeRecord => defer_record(state),app::Msg::DiscardRecord => abandon_record(state), - edit in inflorescence/src/main.rs at line 294
app::Msg::AddUntrackedFile => add_untracked_file(state),app::Msg::RmAddedFile => rm_added_file(state),app::Msg::StartRecord => start_record(state), - replacement in inflorescence/src/main.rs at line 868
"a" => Some(Msg::AddUntrackedFile),"a" => Some(Msg::View(app::Msg::AddUntrackedFile)), - replacement in inflorescence/src/main.rs at line 881[32.1535]→[17.13721:13772](∅→∅),[10.27805]→[17.13721:13772](∅→∅),[17.13772]→[10.27851:27902](∅→∅),[10.27851]→[10.27851:27902](∅→∅)
"r" => Some(Msg::StartRecord),"x" => Some(Msg::RmAddedFile),"r" => Some(Msg::View(app::Msg::StartRecord)),"x" => Some(Msg::View(app::Msg::RmAddedFile)), - edit in inflorescence/src/main.rs at line 902[5.1479]→[6.2103:2159](∅→∅),[6.2159]→[10.28198:28263](∅→∅),[10.28263]→[6.2212:2234](∅→∅),[6.2212]→[6.2212:2234](∅→∅)
"a" if mods == Modifiers::CTRL => {Some(Msg::View(app::Msg::AbandonRecord))} - replacement in inflorescence/src/main.rs at line 903
Some(Msg::View(app::Msg::DeferRecord))Some(Msg::View(app::Msg::DiscardRecord)) - edit in inflorescence/src/main.rs at line 905
"p" if mods == Modifiers::CTRL => {Some(Msg::View(app::Msg::PostponeRecord))} - replacement in inflorescence/src/main.rs at line 1107
let selection = match state.cursor.view.selection.as_ref() {let selection = match cursor.view.selection.as_ref() { - edit in inflorescence/src/main.rs at line 1162
let is_added_from_untracked = repo.as_ref().and_then(|repo| repo.state.changed_files.get(path)).map(|diffs| {diffs.iter().any(|diff| matches!(diff, repo::ChangedFileDiff::Add))}).unwrap_or_default(); - edit in inflorescence/src/main.rs at line 1177
is_added_from_untracked, - edit in inflorescence/src/main.rs at line 1232
cursor: &cursor.view, - replacement in iced_nav_scrollable/src/lib.rs at line 14
//! [`Msg::RefreshOffset`] manually.//! [`Msg::RefreshOffsets`] manually.