ui: register: reduce "warping", keep selection at nearest txn
When the transaction list changes, eg due to toggling a query filter, and the previously selected item has disappeared, instead of moving the selection to the end, we now select the nearest transaction by date (and if several have the same date, by journal order).
This commit is contained in:
		
							parent
							
								
									eab17c8edb
								
							
						
					
					
						commit
						f666d5fc25
					
				| @ -17,7 +17,7 @@ import Data.List.Split (splitOn) | ||||
| import Data.Monoid | ||||
| import Data.Maybe | ||||
| import qualified Data.Text as T | ||||
| import Data.Time.Calendar (Day) | ||||
| import Data.Time.Calendar | ||||
| import qualified Data.Vector as V | ||||
| import Graphics.Vty (Event(..),Key(..),Modifier(..)) | ||||
| import Brick | ||||
| @ -25,6 +25,7 @@ import Brick.Widgets.List | ||||
| import Brick.Widgets.Edit | ||||
| import Brick.Widgets.Border (borderAttr) | ||||
| import Lens.Micro.Platform | ||||
| import Safe | ||||
| import System.Console.ANSI | ||||
| 
 | ||||
| 
 | ||||
| @ -101,15 +102,27 @@ rsInit d reset ui@UIState{aopts=UIOpts{cliopts_=CliOpts{reportopts_=ropts}}, ajo | ||||
|     -- build the List | ||||
|     newitems = list RegisterList (V.fromList $ displayitems ++ blankitems) 1 | ||||
| 
 | ||||
|     -- keep the selection on the previously selected transaction if possible, | ||||
|     -- (eg after toggling nonzero mode), otherwise select the last element. | ||||
|     -- decide which transaction is selected. | ||||
|     -- if reset is true, select the last (latest) transaction; | ||||
|     -- otherwise, select the previously selected transaction if possible; | ||||
|     -- otherwise, select the transaction nearest in date to it; | ||||
|     -- or if there's several with the same date, the nearest in journal order; | ||||
|     -- otherwise, select the last (latest) transaction.  | ||||
|     newitems' = listMoveTo newselidx newitems | ||||
|       where | ||||
|         newselidx = case (reset, listSelectedElement rsList) of | ||||
|                       (True, _)    -> endidx | ||||
|                       (_, Nothing) -> endidx | ||||
|                       (_, Just (_,RegisterScreenItem{rsItemTransaction=Transaction{tindex=ti}})) | ||||
|                                    -> fromMaybe endidx $ findIndex ((==ti) . tindex . rsItemTransaction) displayitems | ||||
|         newselidx =  | ||||
|           case (reset, listSelectedElement rsList) of | ||||
|             (True, _)    -> endidx | ||||
|             (_, Nothing) -> endidx | ||||
|             (_, Just (_, RegisterScreenItem{rsItemTransaction=Transaction{tindex=prevselidx, tdate=prevseld}})) -> | ||||
|               headDef endidx $ catMaybes [ | ||||
|                  findIndex ((==prevselidx) . tindex . rsItemTransaction) displayitems | ||||
|                 ,findIndex ((==nearestidbydatethenid) . Just . tindex . rsItemTransaction) displayitems | ||||
|                 ] | ||||
|               where | ||||
|                 nearestidbydatethenid = third3 <$> (headMay $ sort | ||||
|                   [(abs $ diffDays (tdate t) prevseld, abs (tindex t - prevselidx), tindex t) | t <- ts]) | ||||
|                 ts = map rsItemTransaction displayitems | ||||
|         endidx = length displayitems - 1 | ||||
| 
 | ||||
| rsInit _ _ _ = error "init function called with wrong screen type, should not happen" | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user