diff --git a/app/EpubParser.hs b/app/EpubParser.hs index 6884345..177ab73 100644 --- a/app/EpubParser.hs +++ b/app/EpubParser.hs @@ -114,4 +114,4 @@ embedImages arch bdir = map processTag Just entry -> let rawData = B.toStrict $ fromEntry entry b64 = TE.decodeUtf8 $ B64.encode rawData - in "data:" <> getMimeType fullPath <> ";base64," <> b64 + in "data:" <> getMimeType fullPath <> ";base64," <> b64 diff --git a/app/Gui.hs b/app/Gui.hs index 9a62106..ed91ce1 100644 --- a/app/Gui.hs +++ b/app/Gui.hs @@ -1,30 +1,65 @@ {-# LANGUAGE OverloadedStrings, OverloadedLabels #-} -module Gui (runWindow) where +module Gui (runReader) where import qualified GI.Gtk as Gtk import qualified GI.Gio as Gio +import qualified GI.Gdk as Gdk import qualified GI.WebKit as WebKit -import qualified Data.Text as T -runWindow :: String -> IO () -runWindow htmlContent = do +import Data.IORef (newIORef, readIORef, writeIORef) +import Control.Monad.Reader (runReaderT) +import Text.HTML.TagSoup (renderTags) +import EpubParser (EpubEnv, resolveSpine, getChapter) + +runReader :: EpubEnv -> IO () +runReader env = do app <- Gtk.applicationNew (Just "com.svitak.reader") [] _ <- Gtk.on app #activate $ do - window <- Gtk.applicationWindowNew app Gtk.windowSetTitle window (Just "Svitak") - Gtk.windowSetDefaultSize window 800 600 + -- Web View webView <- WebKit.webViewNew - - WebKit.webViewLoadHtml webView (T.pack htmlContent) (Just "file:///") - Gtk.windowSetChild window (Just webView) + -- Book Data + spine <- runReaderT resolveSpine env + currentChapterIndex <- newIORef 0 + + let loadChapter index = do + let maxIdx = length spine - 1 + -- index to valid range + let safeIdx = max 0 (min index maxIdx) + + -- Update state + writeIORef currentChapterIndex safeIdx + + let filename = spine !! safeIdx + tags <- runReaderT (getChapter filename) env + + WebKit.webViewLoadHtml webView (renderTags tags) (Just "file:///") + + loadChapter 0 + + -- Keyboard Input + keyController <- Gtk.eventControllerKeyNew + Gtk.widgetAddController window keyController + + _ <- Gtk.on keyController #keyPressed $ \keyval _ _ -> do + currentIndex <- readIORef currentChapterIndex + case keyval of + Gdk.KEY_Right -> do + loadChapter (currentIndex + 1) + return True + Gdk.KEY_Left -> do + loadChapter (currentIndex - 1) + return True + _ -> return False + #present window _ <- Gio.applicationRun app Nothing diff --git a/app/Main.hs b/app/Main.hs index 99bb368..ec552cf 100644 --- a/app/Main.hs +++ b/app/Main.hs @@ -1,37 +1,16 @@ -module Main (main) where +module Main where import System.Environment (getArgs) -import Control.Monad.Reader (runReaderT) -import EpubParser (EpubAction, openEpub, resolveSpine, getChapter) -import Gui (runWindow) -import qualified Data.Text as T -import Text.HTML.TagSoup (renderTags) +import EpubParser (openEpub) +import UI (runApp) main :: IO () main = do - args <- getArgs - case args of - [] -> do - putStrLn "Starting GUI..." - runWindow "
Please input an epub file.
" - - (path:_) -> runSvitak path - -runSvitak :: FilePath -> IO () -runSvitak path = do - result <- openEpub path - case result of - Left err -> putStrLn $ "Error: " ++ err - Right env -> do - htmlContent <- runReaderT loadBook env - runWindow htmlContent - -loadBook :: EpubAction String -loadBook = do - spine <- resolveSpine - case spine of - [] -> pure "