module Taskell
    ( go
    ) where

import ClassyPrelude

import Control.Concurrent (forkIO, threadDelay)

import Control.Lens ((^.))

import Data.Time.Zones (TZ)

import Brick
import Brick.BChan               (BChan, newBChan, writeBChan)
import Graphics.Vty              (Mode (BracketedPaste), defaultConfig, displayBounds, mkVty,
                                  outputIface, setMode, supportsMode)
import Graphics.Vty.Input.Events (Event (..))

import qualified Control.FoldDebounce as Debounce

import Taskell.Data.Lists              (Lists)
import Taskell.Events.Actions          (ActionSets, event, generateActions)
import Taskell.Events.State            (continue, countCurrent, setHeight, setTime)
import Taskell.Events.State.Types      (State, current, io, lists, mode, path, searchTerm, timeZone)
import Taskell.Events.State.Types.Mode (InsertMode (..), InsertType (..), ModalType (..), Mode (..))
import Taskell.IO                      (writeData)
import Taskell.IO.Config               (Config, debugging, generateAttrMap, getBindings, layout)
import Taskell.Types                   (ListIndex (..), TaskIndex (..))
import Taskell.UI.Draw                 (chooseCursor, draw)
import Taskell.UI.Types                (ResourceName (..))

type DebouncedMessage = (Lists, FilePath, TZ)

type DebouncedWrite = DebouncedMessage -> IO ()

type Trigger = Debounce.Trigger DebouncedMessage DebouncedMessage

-- tick
data TaskellEvent =
    Tick

oneSecond :: Int
oneSecond :: Int
oneSecond = Int
1000000

frequency :: Int
frequency :: Int
frequency = Int
60 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
oneSecond

timer :: BChan TaskellEvent -> IO ()
timer :: BChan TaskellEvent -> IO ()
timer BChan TaskellEvent
chan =
    IO ThreadId -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO ThreadId -> IO ()) -> (IO () -> IO ThreadId) -> IO () -> IO ()
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. IO () -> IO ThreadId
forkIO (IO () -> IO ThreadId) -> (IO () -> IO ()) -> IO () -> IO ThreadId
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. IO () -> IO ()
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
        BChan TaskellEvent -> TaskellEvent -> IO ()
forall a. BChan a -> a -> IO ()
writeBChan BChan TaskellEvent
chan TaskellEvent
Tick
        Int -> IO ()
threadDelay Int
frequency

-- store
store :: Config -> DebouncedMessage -> IO ()
store :: Config -> DebouncedMessage -> IO ()
store Config
config (Lists
ls, FilePath
pth, TZ
tz) = TZ -> Config -> Lists -> FilePath -> IO ()
writeData TZ
tz Config
config Lists
ls FilePath
pth

next :: DebouncedWrite -> State -> EventM ResourceName (Next State)
next :: (DebouncedMessage -> IO ())
-> State -> EventM ResourceName (Next State)
next DebouncedMessage -> IO ()
send State
state =
    case State
state State -> Getting (Maybe Lists) State (Maybe Lists) -> Maybe Lists
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Lists) State (Maybe Lists)
Lens' State (Maybe Lists)
io of
        Just Lists
ls -> do
            EventM ResourceName ()
forall n. Ord n => EventM n ()
invalidateCache
            IO () -> EventM ResourceName ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> EventM ResourceName ())
-> IO () -> EventM ResourceName ()
forall a b. (a -> b) -> a -> b
$ DebouncedMessage -> IO ()
send (Lists
ls, State
state State -> Getting FilePath State FilePath -> FilePath
forall s a. s -> Getting a s a -> a
^. Getting FilePath State FilePath
Lens' State FilePath
path, State
state State -> Getting TZ State TZ -> TZ
forall s a. s -> Getting a s a -> a
^. Getting TZ State TZ
Lens' State TZ
timeZone)
            State -> EventM ResourceName (Next State)
forall s n. s -> EventM n (Next s)
Brick.continue (State -> EventM ResourceName (Next State))
-> State -> EventM ResourceName (Next State)
forall a b. (a -> b) -> a -> b
$ State -> State
Taskell.Events.State.continue State
state
        Maybe Lists
Nothing -> State -> EventM ResourceName (Next State)
forall s n. s -> EventM n (Next s)
Brick.continue State
state

-- debouncing
debounce :: Config -> State -> IO (DebouncedWrite, Trigger)
debounce :: Config -> State -> IO (DebouncedMessage -> IO (), Trigger)
debounce Config
config State
initial = do
    Trigger
trigger <-
        Args DebouncedMessage DebouncedMessage
-> Opts DebouncedMessage DebouncedMessage -> IO Trigger
forall i o. Args i o -> Opts i o -> IO (Trigger i o)
Debounce.new
            Args :: forall i o. (o -> IO ()) -> (o -> i -> o) -> o -> Args i o
Debounce.Args
            { cb :: DebouncedMessage -> IO ()
Debounce.cb = Config -> DebouncedMessage -> IO ()
store Config
config
            , fold :: DebouncedMessage -> DebouncedMessage -> DebouncedMessage
Debounce.fold = (DebouncedMessage -> DebouncedMessage -> DebouncedMessage)
-> DebouncedMessage -> DebouncedMessage -> DebouncedMessage
forall a b c. (a -> b -> c) -> b -> a -> c
flip DebouncedMessage -> DebouncedMessage -> DebouncedMessage
forall a b. a -> b -> a
const
            , init :: DebouncedMessage
Debounce.init = (State
initial State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists, State
initial State -> Getting FilePath State FilePath -> FilePath
forall s a. s -> Getting a s a -> a
^. Getting FilePath State FilePath
Lens' State FilePath
path, State
initial State -> Getting TZ State TZ -> TZ
forall s a. s -> Getting a s a -> a
^. Getting TZ State TZ
Lens' State TZ
timeZone)
            }
            Opts DebouncedMessage DebouncedMessage
forall a. Default a => a
Debounce.def
    let send :: DebouncedMessage -> IO ()
send = Trigger -> DebouncedMessage -> IO ()
forall i o. Trigger i o -> i -> IO ()
Debounce.send Trigger
trigger
    (DebouncedMessage -> IO (), Trigger)
-> IO (DebouncedMessage -> IO (), Trigger)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (DebouncedMessage -> IO ()
send, Trigger
trigger)

-- cache clearing
clearCache :: State -> EventM ResourceName ()
clearCache :: State -> EventM ResourceName ()
clearCache State
state = do
    let (ListIndex Int
li, TaskIndex Int
ti) = State
state State
-> Getting (ListIndex, TaskIndex) State (ListIndex, TaskIndex)
-> (ListIndex, TaskIndex)
forall s a. s -> Getting a s a -> a
^. Getting (ListIndex, TaskIndex) State (ListIndex, TaskIndex)
Lens' State (ListIndex, TaskIndex)
current
    ResourceName -> EventM ResourceName ()
forall n. Ord n => n -> EventM n ()
invalidateCacheEntry (Int -> ResourceName
RNList Int
li)
    ResourceName -> EventM ResourceName ()
forall n. Ord n => n -> EventM n ()
invalidateCacheEntry ((ListIndex, TaskIndex) -> ResourceName
RNTask (Int -> ListIndex
ListIndex Int
li, Int -> TaskIndex
TaskIndex Int
ti))

clearAllTitles :: State -> EventM ResourceName ()
clearAllTitles :: State -> EventM ResourceName ()
clearAllTitles State
state = do
    let count :: Int
count = Lists -> Int
forall mono. MonoFoldable mono => mono -> Int
length (State
state State -> Getting Lists State Lists -> Lists
forall s a. s -> Getting a s a -> a
^. Getting Lists State Lists
Lens' State Lists
lists)
    let range :: [Int]
range = [Int
0 .. (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)]
    (Element [Int] -> EventM ResourceName ())
-> [Int] -> EventM ResourceName ()
forall mono (f :: * -> *) b.
(MonoFoldable mono, Applicative f) =>
(Element mono -> f b) -> mono -> f ()
traverse_ (ResourceName -> EventM ResourceName ()
forall n. Ord n => n -> EventM n ()
invalidateCacheEntry (ResourceName -> EventM ResourceName ())
-> (Int -> ResourceName) -> Int -> EventM ResourceName ()
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> ResourceName
RNList) [Int]
range
    (Element [Int] -> EventM ResourceName ())
-> [Int] -> EventM ResourceName ()
forall mono (f :: * -> *) b.
(MonoFoldable mono, Applicative f) =>
(Element mono -> f b) -> mono -> f ()
traverse_ (ResourceName -> EventM ResourceName ()
forall n. Ord n => n -> EventM n ()
invalidateCacheEntry (ResourceName -> EventM ResourceName ())
-> (Int -> ResourceName) -> Int -> EventM ResourceName ()
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (ListIndex, TaskIndex) -> ResourceName
RNTask ((ListIndex, TaskIndex) -> ResourceName)
-> (Int -> (ListIndex, TaskIndex)) -> Int -> ResourceName
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (, Int -> TaskIndex
TaskIndex (-Int
1)) (ListIndex -> (ListIndex, TaskIndex))
-> (Int -> ListIndex) -> Int -> (ListIndex, TaskIndex)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> ListIndex
ListIndex) [Int]
range

clearList :: State -> EventM ResourceName ()
clearList :: State -> EventM ResourceName ()
clearList State
state = do
    let (ListIndex Int
list, TaskIndex
_) = State
state State
-> Getting (ListIndex, TaskIndex) State (ListIndex, TaskIndex)
-> (ListIndex, TaskIndex)
forall s a. s -> Getting a s a -> a
^. Getting (ListIndex, TaskIndex) State (ListIndex, TaskIndex)
Lens' State (ListIndex, TaskIndex)
current
    let count :: Int
count = State -> Int
countCurrent State
state
    let range :: [Int]
range = [Int
0 .. (Int
count Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)]
    ResourceName -> EventM ResourceName ()
forall n. Ord n => n -> EventM n ()
invalidateCacheEntry (ResourceName -> EventM ResourceName ())
-> ResourceName -> EventM ResourceName ()
forall a b. (a -> b) -> a -> b
$ Int -> ResourceName
RNList Int
list
    (Element [Int] -> EventM ResourceName ())
-> [Int] -> EventM ResourceName ()
forall mono (f :: * -> *) b.
(MonoFoldable mono, Applicative f) =>
(Element mono -> f b) -> mono -> f ()
traverse_ (ResourceName -> EventM ResourceName ()
forall n. Ord n => n -> EventM n ()
invalidateCacheEntry (ResourceName -> EventM ResourceName ())
-> (Int -> ResourceName) -> Int -> EventM ResourceName ()
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (ListIndex, TaskIndex) -> ResourceName
RNTask ((ListIndex, TaskIndex) -> ResourceName)
-> (Int -> (ListIndex, TaskIndex)) -> Int -> ResourceName
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (,) (Int -> ListIndex
ListIndex Int
list) (TaskIndex -> (ListIndex, TaskIndex))
-> (Int -> TaskIndex) -> Int -> (ListIndex, TaskIndex)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> TaskIndex
TaskIndex) [Int]
range

clearDue :: State -> EventM ResourceName ()
clearDue :: State -> EventM ResourceName ()
clearDue State
state =
    case State
state State -> Getting Mode State Mode -> Mode
forall s a. s -> Getting a s a -> a
^. Getting Mode State Mode
Lens' State Mode
mode of
        Modal (Due Seq ((ListIndex, TaskIndex), Task)
dues Int
_) -> do
            let range :: [Int]
range = [Int
0 .. (Seq ((ListIndex, TaskIndex), Task) -> Int
forall mono. MonoFoldable mono => mono -> Int
length Seq ((ListIndex, TaskIndex), Task)
dues Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)]
            (Element [Int] -> EventM ResourceName ())
-> [Int] -> EventM ResourceName ()
forall mono (f :: * -> *) b.
(MonoFoldable mono, Applicative f) =>
(Element mono -> f b) -> mono -> f ()
traverse_ (ResourceName -> EventM ResourceName ()
forall n. Ord n => n -> EventM n ()
invalidateCacheEntry (ResourceName -> EventM ResourceName ())
-> (Int -> ResourceName) -> Int -> EventM ResourceName ()
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> ResourceName
RNDue) [Int]
range
        Mode
_ -> () -> EventM ResourceName ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

-- event handling
handleVtyEvent ::
       (DebouncedWrite, Trigger) -> ActionSets -> State -> Event -> EventM ResourceName (Next State)
handleVtyEvent :: (DebouncedMessage -> IO (), Trigger)
-> ActionSets -> State -> Event -> EventM ResourceName (Next State)
handleVtyEvent (DebouncedMessage -> IO ()
send, Trigger
trigger) ActionSets
actions State
previousState Event
e = do
    let state :: State
state = ActionSets -> Event -> State -> State
event ActionSets
actions Event
e State
previousState
    Bool -> EventM ResourceName () -> EventM ResourceName ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (State
previousState State -> Getting (Maybe Field) State (Maybe Field) -> Maybe Field
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Field) State (Maybe Field)
Lens' State (Maybe Field)
searchTerm Maybe Field -> Maybe Field -> Bool
forall a. Eq a => a -> a -> Bool
/= State
state State -> Getting (Maybe Field) State (Maybe Field) -> Maybe Field
forall s a. s -> Getting a s a -> a
^. Getting (Maybe Field) State (Maybe Field)
Lens' State (Maybe Field)
searchTerm) EventM ResourceName ()
forall n. Ord n => EventM n ()
invalidateCache
    case State
previousState State -> Getting Mode State Mode -> Mode
forall s a. s -> Getting a s a -> a
^. Getting Mode State Mode
Lens' State Mode
mode of
        (Modal ModalType
MoveTo)           -> State -> EventM ResourceName ()
clearAllTitles State
previousState
        (Insert InsertType
ITask InsertMode
ICreate Field
_) -> State -> EventM ResourceName ()
clearList State
previousState
        Mode
_                        -> () -> EventM ResourceName ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
    case State
state State -> Getting Mode State Mode -> Mode
forall s a. s -> Getting a s a -> a
^. Getting Mode State Mode
Lens' State Mode
mode of
        Mode
Shutdown -> IO () -> EventM ResourceName ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Trigger -> IO ()
forall i o. Trigger i o -> IO ()
Debounce.close Trigger
trigger) EventM ResourceName ()
-> EventM ResourceName (Next State)
-> EventM ResourceName (Next State)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> State -> EventM ResourceName (Next State)
forall s n. s -> EventM n (Next s)
Brick.halt State
state
        (Modal Due {}) -> State -> EventM ResourceName ()
clearDue State
state EventM ResourceName ()
-> EventM ResourceName (Next State)
-> EventM ResourceName (Next State)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (DebouncedMessage -> IO ())
-> State -> EventM ResourceName (Next State)
next DebouncedMessage -> IO ()
send State
state
        (Modal ModalType
MoveTo) -> State -> EventM ResourceName ()
clearAllTitles State
state EventM ResourceName ()
-> EventM ResourceName (Next State)
-> EventM ResourceName (Next State)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (DebouncedMessage -> IO ())
-> State -> EventM ResourceName (Next State)
next DebouncedMessage -> IO ()
send State
state
        (Insert InsertType
ITask InsertMode
ICreate Field
_) -> State -> EventM ResourceName ()
clearList State
state EventM ResourceName ()
-> EventM ResourceName (Next State)
-> EventM ResourceName (Next State)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (DebouncedMessage -> IO ())
-> State -> EventM ResourceName (Next State)
next DebouncedMessage -> IO ()
send State
state
        Mode
_ -> State -> EventM ResourceName ()
clearCache State
previousState EventM ResourceName ()
-> EventM ResourceName () -> EventM ResourceName ()
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> State -> EventM ResourceName ()
clearCache State
state EventM ResourceName ()
-> EventM ResourceName (Next State)
-> EventM ResourceName (Next State)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> (DebouncedMessage -> IO ())
-> State -> EventM ResourceName (Next State)
next DebouncedMessage -> IO ()
send State
state

getHeight :: EventM ResourceName Int
getHeight :: EventM ResourceName Int
getHeight = (Int, Int) -> Int
forall a b. (a, b) -> b
snd ((Int, Int) -> Int)
-> EventM ResourceName (Int, Int) -> EventM ResourceName Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (IO (Int, Int) -> EventM ResourceName (Int, Int)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Int, Int) -> EventM ResourceName (Int, Int))
-> (Output -> IO (Int, Int))
-> Output
-> EventM ResourceName (Int, Int)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Output -> IO (Int, Int)
displayBounds (Output -> EventM ResourceName (Int, Int))
-> EventM ResourceName Output -> EventM ResourceName (Int, Int)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Vty -> Output
outputIface (Vty -> Output)
-> EventM ResourceName Vty -> EventM ResourceName Output
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> EventM ResourceName Vty
forall n. EventM n Vty
getVtyHandle)

handleEvent ::
       (DebouncedWrite, Trigger)
    -> ActionSets
    -> State
    -> BrickEvent ResourceName TaskellEvent
    -> EventM ResourceName (Next State)
handleEvent :: (DebouncedMessage -> IO (), Trigger)
-> ActionSets
-> State
-> BrickEvent ResourceName TaskellEvent
-> EventM ResourceName (Next State)
handleEvent (DebouncedMessage -> IO (), Trigger)
_ ActionSets
_ State
state (AppEvent TaskellEvent
Tick) = do
    UTCTime
t <- IO UTCTime -> EventM ResourceName UTCTime
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO UTCTime
getCurrentTime
    State -> EventM ResourceName (Next State)
forall s n. s -> EventM n (Next s)
Brick.continue (State -> EventM ResourceName (Next State))
-> State -> EventM ResourceName (Next State)
forall a b. (a -> b) -> a -> b
$ UTCTime -> State -> State
setTime UTCTime
t State
state
handleEvent (DebouncedMessage -> IO (), Trigger)
_ ActionSets
_ State
state (VtyEvent (EvResize Int
_ Int
_)) = do
    EventM ResourceName ()
forall n. Ord n => EventM n ()
invalidateCache
    Int
h <- EventM ResourceName Int
getHeight
    State -> EventM ResourceName (Next State)
forall s n. s -> EventM n (Next s)
Brick.continue (Int -> State -> State
setHeight Int
h State
state)
handleEvent (DebouncedMessage -> IO (), Trigger)
db ActionSets
actions State
state (VtyEvent Event
ev) = (DebouncedMessage -> IO (), Trigger)
-> ActionSets -> State -> Event -> EventM ResourceName (Next State)
handleVtyEvent (DebouncedMessage -> IO (), Trigger)
db ActionSets
actions State
state Event
ev
handleEvent (DebouncedMessage -> IO (), Trigger)
_ ActionSets
_ State
state BrickEvent ResourceName TaskellEvent
_ = State -> EventM ResourceName (Next State)
forall s n. s -> EventM n (Next s)
Brick.continue State
state

-- | Runs when the app starts
--   Adds paste support
appStart :: State -> EventM ResourceName State
appStart :: State -> EventM ResourceName State
appStart State
state = do
    Output
output <- Vty -> Output
outputIface (Vty -> Output)
-> EventM ResourceName Vty -> EventM ResourceName Output
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> EventM ResourceName Vty
forall n. EventM n Vty
getVtyHandle
    Bool -> EventM ResourceName () -> EventM ResourceName ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Output -> Mode -> Bool
supportsMode Output
output Mode
BracketedPaste) (EventM ResourceName () -> EventM ResourceName ())
-> (IO () -> EventM ResourceName ())
-> IO ()
-> EventM ResourceName ()
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. IO () -> EventM ResourceName ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> EventM ResourceName ())
-> IO () -> EventM ResourceName ()
forall a b. (a -> b) -> a -> b
$ Output -> Mode -> Bool -> IO ()
setMode Output
output Mode
BracketedPaste Bool
True
    Int
h <- EventM ResourceName Int
getHeight
    State -> EventM ResourceName State
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> State -> State
setHeight Int
h State
state)

-- | Sets up Brick
go :: Config -> State -> IO ()
go :: Config -> State -> IO ()
go Config
config State
initial = do
    State -> AttrMap
attrMap' <- AttrMap -> State -> AttrMap
forall a b. a -> b -> a
const (AttrMap -> State -> AttrMap)
-> IO AttrMap -> IO (State -> AttrMap)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO AttrMap
generateAttrMap
    -- setup debouncing
    (DebouncedMessage -> IO (), Trigger)
db <- Config -> State -> IO (DebouncedMessage -> IO (), Trigger)
debounce Config
config State
initial
    -- get bindings
    Bindings
bindings <- IO Bindings
getBindings
    -- setup timer channel
    BChan TaskellEvent
timerChan <- Int -> IO (BChan TaskellEvent)
forall a. Int -> IO (BChan a)
newBChan Int
1
    BChan TaskellEvent -> IO ()
timer BChan TaskellEvent
timerChan
    -- create app
    let app :: App State TaskellEvent ResourceName
app =
            App :: forall s e n.
(s -> [Widget n])
-> (s -> [CursorLocation n] -> Maybe (CursorLocation n))
-> (s -> BrickEvent n e -> EventM n (Next s))
-> (s -> EventM n s)
-> (s -> AttrMap)
-> App s e n
App
            { appDraw :: State -> [Widget ResourceName]
appDraw = Config -> Bindings -> Bool -> State -> [Widget ResourceName]
draw (Config -> Config
layout Config
config) Bindings
bindings (Config -> Bool
debugging Config
config)
            , appChooseCursor :: State
-> [CursorLocation ResourceName]
-> Maybe (CursorLocation ResourceName)
appChooseCursor = State
-> [CursorLocation ResourceName]
-> Maybe (CursorLocation ResourceName)
chooseCursor
            , appHandleEvent :: State
-> BrickEvent ResourceName TaskellEvent
-> EventM ResourceName (Next State)
appHandleEvent = (DebouncedMessage -> IO (), Trigger)
-> ActionSets
-> State
-> BrickEvent ResourceName TaskellEvent
-> EventM ResourceName (Next State)
handleEvent (DebouncedMessage -> IO (), Trigger)
db (Bindings -> ActionSets
generateActions Bindings
bindings)
            , appStartEvent :: State -> EventM ResourceName State
appStartEvent = State -> EventM ResourceName State
appStart
            , appAttrMap :: State -> AttrMap
appAttrMap = State -> AttrMap
attrMap'
            }
    -- start
    let builder :: IO Vty
builder = Config -> IO Vty
mkVty Config
defaultConfig
    Vty
initialVty <- IO Vty
builder
    IO State -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO State -> IO ()) -> IO State -> IO ()
forall a b. (a -> b) -> a -> b
$ Vty
-> IO Vty
-> Maybe (BChan TaskellEvent)
-> App State TaskellEvent ResourceName
-> State
-> IO State
forall n e s.
Ord n =>
Vty -> IO Vty -> Maybe (BChan e) -> App s e n -> s -> IO s
customMain Vty
initialVty IO Vty
builder (BChan TaskellEvent -> Maybe (BChan TaskellEvent)
forall a. a -> Maybe a
Just BChan TaskellEvent
timerChan) App State TaskellEvent ResourceName
app State
initial