forked from marko/svitak
refactor epPicker into smaller functions using ExceptT
This commit is contained in:
parent
8be29359fc
commit
9f9e59b450
1 changed files with 28 additions and 12 deletions
40
app/UI.hs
40
app/UI.hs
|
|
@ -1,11 +1,13 @@
|
|||
{-# LANGUAGE OverloadedLabels #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE ScopedTypeVariables #-}
|
||||
|
||||
-- | The GTK4 / WebKit front end. The book's structure loads in the background;
|
||||
-- chapters are rendered lazily (and cached) the first time they're visited,
|
||||
-- with neighbours preloaded so arrow-key paging feels instant.
|
||||
module UI (runApp) where
|
||||
|
||||
import Data.Bifunctor (first)
|
||||
import Control.Concurrent.Async (async)
|
||||
import Control.Concurrent.STM (TVar, atomically, modifyTVar', newTVarIO, readTVarIO, writeTVar, readTVar, modifyTVar')
|
||||
import Data.List (minimumBy)
|
||||
|
|
@ -18,6 +20,8 @@ import qualified Data.Text as T
|
|||
import Data.Word (Word32)
|
||||
import Data.Bits ((.|.))
|
||||
import Control.Exception (SomeException, try)
|
||||
import Control.Monad.Except
|
||||
import Control.Monad.IO.Class (liftIO)
|
||||
import EpubParser (EpubEnv, openEpub) -- brings the `BookInfo EpubEnv` instance into scope
|
||||
import qualified GI.GLib as GLib
|
||||
import qualified GI.GLib.Constants as GLibConst
|
||||
|
|
@ -272,18 +276,30 @@ epPicker :: Maybe Gtk.ApplicationWindow -> Ctx -> IO ()
|
|||
epPicker window ctx = do
|
||||
dg <- Gtk.fileDialogNew
|
||||
Gtk.fileDialogOpen dg window (Nothing :: Maybe Gio.Cancellable) $ Just $ \_ result -> do
|
||||
outcome <- try (Gtk.fileDialogOpenFinish dg result) :: IO (Either SomeException Gio.File)
|
||||
case outcome of
|
||||
Left _err -> putStrLn "picker cancelled or failed"
|
||||
Right file -> do
|
||||
mp <- Gio.fileGetPath file
|
||||
case mp of
|
||||
Nothing -> putStrLn "selected file has no local path"
|
||||
Just path -> do
|
||||
env <- openEpub path
|
||||
case env of
|
||||
Left err -> putStrLn ("open failed: " ++ err)
|
||||
Right e -> loadBook e ctx
|
||||
outcome <- runExceptT $ do
|
||||
file <- pickerGetFile dg result
|
||||
path <- getFilePath file
|
||||
|
||||
env <- extractEnv path
|
||||
|
||||
liftIO $ loadBook env ctx
|
||||
|
||||
either putStrLn pure outcome
|
||||
|
||||
pickerGetFile :: Gtk.FileDialog -> Gio.AsyncResult -> ExceptT String IO Gio.File
|
||||
pickerGetFile dg result =
|
||||
ExceptT $ first (const "picker cancelled or failed")
|
||||
<$> (try (Gtk.fileDialogOpenFinish dg result) :: IO (Either SomeException Gio.File))
|
||||
|
||||
getFilePath :: Gio.File -> ExceptT String IO FilePath
|
||||
getFilePath file = do
|
||||
mp <- liftIO $ Gio.fileGetPath file
|
||||
maybe (throwError "selected file has no local path") pure mp
|
||||
|
||||
|
||||
extractEnv :: FilePath -> ExceptT String IO EpubEnv
|
||||
extractEnv path =
|
||||
ExceptT $ first ("open failed: " ++) <$> openEpub path
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Navigation + rendering
|
||||
|
|
|
|||
Loading…
Reference in a new issue