seperate pure functions from IO

This commit is contained in:
Marko Andjelic 2026-02-04 02:38:17 +00:00
commit 28e5d6ec36
2 changed files with 28 additions and 14 deletions

View file

@ -10,6 +10,8 @@ module EpubParser
, getChapter
, getChapterTitle
, Tag(..)
, prepareView
, ChapterView(..)
) where
import Codec.Archive.Zip (Archive, findEntryByPath, fromEntry, toArchive)
@ -21,7 +23,7 @@ import Control.Monad.Reader (ReaderT, MonadReader(ask), liftIO)
import Control.Monad.Except (runExceptT)
import System.FilePath (takeDirectory, (</>), normalise)
import Data.List (find)
import Text.HTML.TagSoup (parseTags, innerText, Tag(..))
import Text.HTML.TagSoup (parseTags, innerText, Tag(..), renderTags)
import Control.Concurrent.Async (Async)
import Codec.Epub.Parse (getSpine, getMetadata, getManifest)
import qualified Codec.Epub.Data.Metadata as DMeta
@ -52,6 +54,12 @@ data EpubEnv = EpubEnv
, eManifest :: DMan.Manifest
}
data ChapterView = ChapterView
{ viewTitle :: T.Text
, viewHtml :: T.Text
, viewIdx :: Int
}
openEpub :: FilePath -> IO (Either String EpubEnv)
openEpub path = do
rawZip <- B.readFile path
@ -164,3 +172,13 @@ getChapterTitle tags =
ishding _ = False
isclose n (TagClose n') = n == n'
isclose _ _ = False
prepareView :: AppState -> Int -> Maybe ChapterView
prepareView st index
| index < 0 || index >= length (cAllChapters st) = Nothing
| otherwise = Just $ ChapterView
{ viewTitle = bTitle st <> " - " <> getChapterTitle tags
, viewHtml = renderTags tags
, viewIdx = index
}
where tags = cAllChapters st !! index

View file

@ -15,10 +15,9 @@ import Data.List (find)
import Data.GI.Base (AttrOp(..))
import Control.Monad.Reader (runReaderT)
import Control.Concurrent.STM (newTVarIO, readTVar, atomically, modifyTVar)
import Text.HTML.TagSoup (renderTags)
import Control.Concurrent.Async (async)
import Codec.Epub.Data.Metadata (metaTitles, titleType, titleText)
import EpubParser (EpubEnv(..), AppState(..), resolveSpine, getChapter, getChapterTitle)
import EpubParser (EpubEnv(..), AppState(..), resolveSpine, getChapter, prepareView, ChapterView(..))
import Persistence (saveLastRead, loadLastRead)
runApp :: EpubEnv -> IO ()
@ -48,17 +47,14 @@ runApp env' = do
-- load all chapters on another thread
let loadChapter index = do
st <- atomically $ readTVar stateTVar
let chapters = cAllChapters st
if null chapters || index < 0 || index >= length chapters
then pure ()
else do
let tags = chapters !! index
let html = renderTags tags
let fullTitle = bTitle st <> " - " <> getChapterTitle tags
Gtk.set window [ #title := fullTitle ]
WebKit.webViewLoadHtml webView html Nothing
atomically $ modifyTVar stateTVar $ \s -> s { cIdx = index }
_ <- async $ saveLastRead (bookPath env') index
case prepareView st index of
Nothing -> pure ()
Just view -> do
Gtk.set window [ #title := viewTitle view ]
WebKit.webViewLoadHtml webView (viewHtml view) Nothing
atomically $ modifyTVar stateTVar $ \s -> s { cIdx = viewIdx view}
_ <- async $ saveLastRead (bookPath env') (viewIdx view)
pure ()
-- keyboard handling