Compare commits

...

3 Commits

5 changed files with 42 additions and 4 deletions

View File

@ -32,6 +32,7 @@ dependencies:
- brick >= 2.1.1 && < 2.2 - brick >= 2.1.1 && < 2.2
- vty >= 6.1 && < 6.2 - vty >= 6.1 && < 6.2
- mtl >= 2.3.1 && < 2.4 - mtl >= 2.3.1 && < 2.4
- easy-file >= 0.2.5 && < 0.3
ghc-options: ghc-options:
- -Wall - -Wall

View File

@ -4,7 +4,7 @@ cabal-version: 2.2
-- --
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
-- --
-- hash: fb2b45c8e1d5aead518c67637b3af5e78b55b8f0c5a95a34c20ca5d957527fa0 -- hash: d18a8e1efd32ff2d20b0b1f5ac8186be5242411bd72a6a017fd9f97d401a9836
name: passman name: passman
version: 0.3.1.1 version: 0.3.1.1
@ -46,6 +46,7 @@ library
, brick >=2.1.1 && <2.2 , brick >=2.1.1 && <2.2
, bytestring >=0.11.4.0 && <0.12 , bytestring >=0.11.4.0 && <0.12
, containers >=0.6.2.1 && <0.7 , containers >=0.6.2.1 && <0.7
, easy-file >=0.2.5 && <0.3
, microlens >=0.4.11.2 && <0.5 , microlens >=0.4.11.2 && <0.5
, microlens-mtl >=0.2.0.3 && <0.3 , microlens-mtl >=0.2.0.3 && <0.3
, microlens-th >=0.4.3.6 && <0.5 , microlens-th >=0.4.3.6 && <0.5
@ -70,6 +71,7 @@ executable passman
, brick >=2.1.1 && <2.2 , brick >=2.1.1 && <2.2
, bytestring >=0.11.4.0 && <0.12 , bytestring >=0.11.4.0 && <0.12
, containers >=0.6.2.1 && <0.7 , containers >=0.6.2.1 && <0.7
, easy-file >=0.2.5 && <0.3
, microlens >=0.4.11.2 && <0.5 , microlens >=0.4.11.2 && <0.5
, microlens-mtl >=0.2.0.3 && <0.3 , microlens-mtl >=0.2.0.3 && <0.3
, microlens-th >=0.4.3.6 && <0.5 , microlens-th >=0.4.3.6 && <0.5
@ -110,6 +112,7 @@ test-suite passman-test
, brick >=2.1.1 && <2.2 , brick >=2.1.1 && <2.2
, bytestring >=0.11.4.0 && <0.12 , bytestring >=0.11.4.0 && <0.12
, containers >=0.6.2.1 && <0.7 , containers >=0.6.2.1 && <0.7
, easy-file >=0.2.5 && <0.3
, microlens >=0.4.11.2 && <0.5 , microlens >=0.4.11.2 && <0.5
, microlens-mtl >=0.2.0.3 && <0.3 , microlens-mtl >=0.2.0.3 && <0.3
, microlens-th >=0.4.3.6 && <0.5 , microlens-th >=0.4.3.6 && <0.5

View File

@ -41,7 +41,7 @@ passmanApp = App
{ appDraw = drawFunc { appDraw = drawFunc
, appChooseCursor = showFirstCursor , appChooseCursor = showFirstCursor
, appHandleEvent = eventHandler , appHandleEvent = eventHandler
, appStartEvent = return () , appStartEvent = loadDatabase
, appAttrMap = const $ attrMap (style 0) [] , appAttrMap = const $ attrMap (style 0) []
} }

View File

@ -24,7 +24,7 @@ License along with this program. If not, see
{-# LANGUAGE LambdaCase, OverloadedStrings #-} {-# LANGUAGE LambdaCase, OverloadedStrings #-}
module Password.App.Event (eventHandler) where module Password.App.Event (eventHandler, loadDatabase) where
import Brick (BrickEvent (VtyEvent), EventM, halt) import Brick (BrickEvent (VtyEvent), EventM, halt)
import Brick.Forms (handleFormEvent) import Brick.Forms (handleFormEvent)
@ -39,13 +39,24 @@ import Brick.Keybindings
, onEvent , onEvent
) )
import Control.Monad (unless) import Control.Monad (unless)
import Control.Monad.State.Class (gets) import Control.Monad.IO.Class (liftIO)
import Control.Monad.State.Class (gets, put)
import Data.Aeson (decodeFileStrict)
import Graphics.Vty.Input.Events (Event (EvKey)) import Graphics.Vty.Input.Events (Event (EvKey))
import Lens.Micro ((^.)) import Lens.Micro ((^.))
import Lens.Micro.Mtl (zoom) import Lens.Micro.Mtl (zoom)
import System.EasyFile
( createDirectoryIfMissing
, doesFileExist
, getAppUserDataDirectory
, (</>)
)
import Password.App.Types import Password.App.Types
dbFile :: String
dbFile = "database.json"
data KEventID = QuitKE deriving (Eq, Ord, Show) data KEventID = QuitKE deriving (Eq, Ord, Show)
-- | The main event handler -- | The main event handler
@ -55,6 +66,16 @@ eventHandler e@(VtyEvent (EvKey k m)) = do
handleKey disp k m >>= flip unless (fallbackHandler e) handleKey disp k m >>= flip unless (fallbackHandler e)
eventHandler e = fallbackHandler e eventHandler e = fallbackHandler e
loadDatabase :: EventM ResName AppState ()
loadDatabase = zoom database $ liftIO
( do
dir <- mkAppDir
let fn = dir </> dbFile
doesFileExist fn >>= \case
True -> decodeFileStrict fn
False -> return Nothing
) >>= mapM_ put
fallbackHandler :: BrickEvent ResName () -> EventM ResName AppState () fallbackHandler :: BrickEvent ResName () -> EventM ResName AppState ()
fallbackHandler e = gets (^.appMode) >>= \case fallbackHandler e = gets (^.appMode) >>= \case
InitMode _ -> zoom (appMode.initState.setPassForm) $ InitMode _ -> zoom (appMode.initState.setPassForm) $
@ -76,4 +97,10 @@ getKeyDispatcher s = either (error "can't build dispatcher") id $
keyBindingsFor :: AppState -> [(KEventID, [Binding])] keyBindingsFor :: AppState -> [(KEventID, [Binding])]
keyBindingsFor = const [(QuitKE, [ctrl 'c'])] keyBindingsFor = const [(QuitKE, [ctrl 'c'])]
mkAppDir :: IO FilePath
mkAppDir = do
path <- getAppUserDataDirectory "passman"
createDirectoryIfMissing True path
return path
--jl --jl

View File

@ -33,6 +33,7 @@ module Password.App.Types (
-- * Lenses -- * Lenses
-- ** AppState -- ** AppState
randGen, randGen,
database,
appMode, appMode,
-- ** AppMode -- ** AppMode
initState, initState,
@ -51,11 +52,16 @@ import Lens.Micro (_1, _2)
import Lens.Micro.TH (makeLenses) import Lens.Micro.TH (makeLenses)
import System.Random (StdGen, initStdGen) import System.Random (StdGen, initStdGen)
import Password
-- | The application state -- | The application state
data AppState = AppState data AppState = AppState
{ _randGen :: StdGen { _randGen :: StdGen
-- ^ The random number generator -- ^ The random number generator
, _database :: PWDatabase
-- ^ The password database
, _appMode :: AppMode , _appMode :: AppMode
-- ^ The current operating mode
} }
-- | The applicaiton's mode -- | The applicaiton's mode
@ -88,6 +94,7 @@ concat <$> mapM makeLenses
mkInitialState :: MonadIO m => m AppState mkInitialState :: MonadIO m => m AppState
mkInitialState = AppState mkInitialState = AppState
<$> initStdGen <$> initStdGen
<*> return newPWDatabase
<*> return (InitMode newInitState) <*> return (InitMode newInitState)
-- | New `InitState` value -- | New `InitState` value