Nomyx-0.3.0: src/Web/MainPage.hs
{-# LANGUAGE OverloadedStrings, TypeSynonymInstances, FlexibleContexts, FlexibleInstances, TemplateHaskell,
EmptyDataDecls, TypeFamilies, MultiParamTypeClasses, DeriveDataTypeable, PackageImports, GADTs,
ScopedTypeVariables, NamedFieldPuns, Rank2Types, DoAndIfThenElse, StandaloneDeriving, OverloadedStrings,
ExtendedDefaultRules, RecordWildCards#-}
module Web.MainPage (launchWebServer) where
import Prelude hiding (div)
import Text.Blaze.Html5 hiding (map)
import Text.Blaze.Html5.Attributes hiding (dir)
import qualified Text.Blaze.Html5 as H
import qualified Text.Blaze.Html5.Attributes as A
import Web.Routes.Site
import Web.Routes.PathInfo
import Web.Routes.Happstack
import Web.Routes.RouteT
import Text.Blaze.Internal
import Control.Monad
import Paths_Nomyx as PN
import Paths_Nomyx_Language as PNL
import Control.Monad.State
import Data.Monoid
import Control.Concurrent.STM
import Language.Nomyx
import Happstack.Server as HS
import System.Directory
import System.FilePath
import System.Posix.Files
import qualified Web.Help as Help
import Types as T
import Web.Game
import Web.Common as W
import Web.Settings
import Web.NewGame
import Web.Login
import Utils
import Data.Maybe
import Data.Text(Text, pack)
import qualified Language.Nomyx.Game as G
import Happstack.Auth
default (Integer, Double, Data.Text.Text)
viewMulti :: PlayerNumber -> Session -> RoutedNomyxServer Html
viewMulti pn s = do
pfd <- getProfile s pn
let isAdmin = _isAdmin $ _pAdmin $ fromJust pfd
gns <- viewGamesTab (map G._game $ _games $ _multi s) isAdmin
mgn <- liftRouteT $ lift $ getPlayersGame pn s
g <- case mgn of
Just g -> viewGame (G._game g) pn (_pLastRule $ fromJust pfd) isAdmin
Nothing -> ok $ h3 "Not viewing any game"
ok $ do
div ! A.id "gameList" $ gns
div ! A.id "game" $ g
viewGamesTab :: [Game] -> Bool -> RoutedNomyxServer Html
viewGamesTab gs isAdmin = do
gns <- mapM (viewGameName isAdmin) gs
newGameLink <- showURL NewGame
settingsLink <- showURL W.PlayerSettings
advLink <- showURL Advanced
logoutURL <- showURL (U_AuthProfile $ AuthURL A_Logout)
dd <- lift $ lift $ PN.getDataDir
mods <- lift $ lift $ getDirectoryContents $ dd </> modDir
fmods <- lift $ lift $ filterM (getFileStatus . (\f -> joinPath [dd, modDir, f]) >=> return . isRegularFile) $ mods
ok $ do
h3 "Main menu" >> br
"Active games:" >> br
table $ do
case gs of
[] -> tr $ td "No Games"
_ -> sequence_ gns
br >> "Nomyx language files:" >> br
H.a "Rules examples" ! (href $ "/src/Language/Nomyx/Examples.hs") >> br
H.a "Basic rules" ! (href $ "/src/Language/Nomyx/Rule.hs") >> br
H.a "Rules definitions" ! (href $ "/src/Language/Nomyx/Definition.hs") >> br
H.a "Rules types" ! (href $ "/src/Language/Nomyx/Expression.hs") >> br
H.a "Voting system" ! (href $ "/src/Language/Nomyx/Vote.hs") >> br
mapM_ (\f -> (H.a $ toHtml f ) ! (href $ toValue (pathSeparator : modDir </> f)) >> br) fmods
br >> "Settings:" >> br
when isAdmin $ H.a "Create a new game" ! (href $ toValue newGameLink) >> br
H.a "Player settings" ! (href $ toValue settingsLink) >> br
H.a "Advanced" ! (href $ toValue advLink) >> br
H.a "Logout " ! (href $ toValue logoutURL) >> br
viewGameName :: Bool -> Game -> RoutedNomyxServer Html
viewGameName isAdmin g = do
let gn = _gameName g
join <- showURL (JoinGame gn)
leave <- showURL (LeaveGame gn)
view <- showURL (ViewGame gn)
del <- showURL (DelGame gn)
ok $ tr $ do
td ! A.id "gameName" $ string $ (gn ++ " ")
td $ H.a "View" ! (href $ toValue view) ! (A.title $ toValue Help.view)
td $ H.a "Join" ! (href $ toValue $ "#openModalJoin" ++ gn) ! (A.title $ toValue Help.join)
td $ H.a "Leave" ! (href $ toValue leave)
when isAdmin $ td $ H.a "Del" ! (href $ toValue del)
div ! A.id (toValue $ "openModalJoin" ++ gn) ! A.class_ "modalWindow" $ do
div $ do
h2 "Joining the game. Please register in the Agora (see the link) and introduce yourself to the other players! \n \
If you do not wich to play, you can just view the game."
H.a "Join" ! (href $ toValue join) ! A.class_ "join" ! (A.title $ toValue Help.join)
H.a "View" ! (href $ toValue view) ! A.class_ "view" ! (A.title $ toValue Help.view)
nomyxPage :: (TVar Session) -> RoutedNomyxServer Response
nomyxPage ts = do
pn <- getPlayerNumber ts
s <- liftIO $ atomically $ readTVar ts
m <- viewMulti pn s
name <- liftIO $ getPlayersName pn s
playAs <- getPlayAs ts
playAsName <- liftIO $ getPlayersName playAs s
let body = do
string $ "Welcome to Nomyx, " ++ name ++ "! "
when (playAs /= pn) $ (b ! A.style "color:red;" $ string ("Playing as: " ++ playAsName ++ " (Player #" ++ (show playAs) ++ ")") )
mainPage' "Welcome to Nomyx!"
body
(H.div ! A.id "multi" $ m)
False
nomyxSite :: (TVar Session) -> Site PlayerCommand (ServerPartT IO Response)
nomyxSite tm = setDefault HomePage $ mkSitePI (runRouteT $ routedNomyxCommands tm)
routedNomyxCommands :: (TVar Session) -> PlayerCommand -> RoutedNomyxServer Response
routedNomyxCommands ts (U_AuthProfile auth) = authenticate ts auth
routedNomyxCommands ts PostAuth = postAuthenticate ts
routedNomyxCommands ts HomePage = homePage ts
routedNomyxCommands ts MainPage = nomyxPage ts
routedNomyxCommands ts (JoinGame game) = joinGame ts game
routedNomyxCommands ts (LeaveGame game) = leaveGame ts game
routedNomyxCommands ts (ViewGame game) = viewGamePlayer ts game
routedNomyxCommands ts (DelGame game) = delGame ts game
routedNomyxCommands ts NewRule = newRule ts >>= return . toResponse
routedNomyxCommands _ NewGame = newGamePage >>= return . toResponse
routedNomyxCommands ts SubmitNewGame = newGamePost ts >>= return . toResponse
routedNomyxCommands ts (DoInput en) = newInput en ts >>= return . toResponse
routedNomyxCommands ts Upload = newUpload ts >>= return . toResponse
routedNomyxCommands ts W.PlayerSettings = playerSettings ts >>= return . toResponse
routedNomyxCommands ts SubmitPlayerSettings = newPlayerSettings ts >>= return . toResponse
routedNomyxCommands ts Advanced = advanced ts >>= return . toResponse
routedNomyxCommands ts SubmitPlayAs = newPlayAsSettings ts >>= return . toResponse
routedNomyxCommands ts SubmitAdminPass = newAdminPass ts >>= return . toResponse
routedNomyxCommands ts SubmitSettings = newSettings ts >>= return . toResponse
launchWebServer :: (TVar Session) -> Network -> IO ()
launchWebServer tm net = do
putStrLn $ "Starting web server...\nTo connect, drive your browser to \"" ++ nomyxURL net ++ "/Nomyx\""
d <- PN.getDataDir
d' <- PNL.getDataDir
simpleHTTP nullConf {HS.port = T._port net} $ server d d' tm net
--serving Nomyx web page as well as data from this package and the language library package
server :: FilePath -> FilePath -> (TVar Session) -> Network -> ServerPartT IO Response
server d d' tm net = mconcat [
serveDirectory DisableBrowsing [] d,
serveDirectory DisableBrowsing [] d',
do decodeBody (defaultBodyPolicy "/tmp/" 102400 4096 4096)
html <- implSite (pack (nomyxURL net)) "/Nomyx" (nomyxSite tm)
return $ toResponse html]