Nomyx-Web 0.7.0 → 0.7.2
raw patch · 9 files changed
+242/−247 lines, 9 filesdep +splitdep ~Nomyx-Coredep ~Nomyx-Languagesetup-changed
Dependencies added: split
Dependency ranges changed: Nomyx-Core, Nomyx-Language
Files
- Nomyx-Web.cabal +4/−3
- Setup.hs +2/−0
- Setup.lhs +0/−6
- data/static/css/nomyx.css +157/−177
- src/Nomyx/Web/Common.hs +9/−3
- src/Nomyx/Web/Game.hs +67/−55
- src/Nomyx/Web/Help.hs +1/−1
- src/Nomyx/Web/MainPage.hs +1/−1
- src/Nomyx/Web/Settings.hs +1/−1
Nomyx-Web.cabal view
@@ -1,5 +1,5 @@ name: Nomyx-Web-version: 0.7.0+version: 0.7.2 cabal-version: >=1.6 build-type: Simple license: BSD3@@ -16,8 +16,8 @@ extra-source-files: README.md library- build-depends: Nomyx-Language == 0.7.0,- Nomyx-Core == 0.7.0,+ build-depends: Nomyx-Language == 0.7.2,+ Nomyx-Core == 0.7.2, base >= 4.6 && <5, blaze-html == 0.7.*, blaze-markup == 0.6.*,@@ -35,6 +35,7 @@ reform-blaze == 0.2.*, reform-happstack == 0.2.*, safe == 0.3.*,+ split == 0.2.*, stm == 2.4.*, text == 1.1.*, time == 1.4.*,
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
− Setup.lhs
@@ -1,6 +0,0 @@-#!/usr/bin/runhaskell -> module Main where-> import Distribution.Simple-> main :: IO ()-> main = defaultMain-
data/static/css/nomyx.css view
@@ -2,13 +2,6 @@ color:#04B404; } -#multi {- top:40px;- vertical-align:middle;--}-- #gameList { position:absolute; background-color:#F4F4F4;@@ -16,7 +9,7 @@ width:250px; padding:10px; top:60px;- left:15px;+ left:10px; overflow: auto; } @@ -25,9 +18,9 @@ background-color:#FFFFFF; height:90%; top:57px;- left:295px;- right:14px;- padding-right:20px;+ left:288px;+ right:10px;+ padding-right:23px; overflow: auto; } @@ -37,25 +30,17 @@ top:20px; left:250px; right:20px;- /**/ } -/*-#IORuleTitle {- position:relative;- top:-30px;- background-color:#F4F4F4;-- height:20px;-}*/- #IORule {- border:1px dotted black;- padding:10px;- padding-bottom:0px;- padding-top:0px;- margin-bottom:10px;- display : block;+ border:1px dotted black;+ padding:10px;+ padding-bottom:0px;+ padding-top:0px;+ margin-bottom:10px;+ display: block;+ max-height:450pt;+ overflow-y:auto; } .table {@@ -69,22 +54,21 @@ padding:6px; } -.codetd {- border:1px solid black;- padding:6px;+#codeDiv {+ padding:3px; } pre {- white-space: pre-wrap; /* css-3 */- white-space: -moz-pre-wrap; /* Mozilla, since 1999 */- white-space: -pre-wrap; /* Opera 4-6 */- white-space: -o-pre-wrap; /* Opera 7 */- word-wrap: break-word; /* Internet Explorer 5.5+ */+ white-space: pre-wrap; /* css-3 */+ white-space: -moz-pre-wrap; /* Mozilla, since 1999 */+ white-space: -pre-wrap; /* Opera 4-6 */+ white-space: -o-pre-wrap; /* Opera 7 */+ word-wrap: break-word; /* Internet Explorer 5.5+ */ } thead {- font-weight:bold- }+ font-weight:bold+} #victory { float:left;@@ -110,188 +94,161 @@ padding-right: 10px; } -/* #eventsBody {- display:none;-}*/- #header {- border-top:1px solid silver;- border-bottom:1px solid silver;- margin-top:10px;- margin-bottom:10px;- color:gray;- padding-top:10px;- padding-bottom:5px;- background-color:#F4F4F4;- top:0;- position:relative;- width:100%;+ border-top:1px solid silver;+ border-bottom:1px solid silver;+ margin-top:10px;+ margin-bottom:10px;+ color:gray;+ padding-top:10px;+ padding-bottom:5px;+ background-color:#F4F4F4;+ top:0;+ position:relative;+ width:100%; } #footer {- border-top:1px solid silver;- border-bottom:1px solid silver;- margin-top:10px;- margin-bottom:10px;- color:gray;- padding-top:10px;- padding-bottom:5px;- background-color:#F4F4F4;- bottom:0;- position:absolute;- width:100%;-}---.ruleCode {+ border-top:1px solid silver;+ border-bottom:1px solid silver;+ margin-top:10px;+ margin-bottom:10px;+ color:gray;+ padding-top:10px;+ padding-bottom:5px;+ background-color:#F4F4F4;+ bottom:0;+ position:absolute; width:100%; } -.ruleName {-}--.ruleDescr {- width:50%;-}---.agora {- width:400px;-}- input[type="file"]{ font: normal 11px Arial; } -#description {- width:50%;-} .modalDialog {- position: fixed;- font-family: Arial, Helvetica, sans-serif;- top: 0;- right: 0;- bottom: 0;- left: 0;- background: rgba(0,0,0,0.8);- z-index: 99999;- opacity:0;- -webkit-transition: opacity 400ms ease-in;- -moz-transition: opacity 400ms ease-in;- transition: opacity 400ms ease-in;- pointer-events: none;+ position: fixed;+ font-family: Arial, Helvetica, sans-serif;+ top: 0;+ right: 0;+ bottom: 0;+ left: 0;+ background: rgba(0,0,0,0.8);+ z-index: 99999;+ opacity:0;+ -webkit-transition: opacity 400ms ease-in;+ -moz-transition: opacity 400ms ease-in;+ transition: opacity 400ms ease-in;+ pointer-events: none; } .modalDialog:target {- opacity:1;- pointer-events: auto;+ opacity:1;+ pointer-events: auto; } .modalDialog > div {- width: 1000px;- position: relative;- margin: 10% auto;- padding: 5px 20px 13px 20px;- border-radius: 10px;- background: #fff;- /* background: -moz-linear-gradient(#fff, #999);- background: -webkit-linear-gradient(#fff, #999);- background: -o-linear-gradient(#fff, #999);*/+ width: 1000px;+ position: relative;+ margin: 10% auto;+ padding: 5px 20px 13px 20px;+ border-radius: 10px;+ background: #fff; } .close {- background: #606061;- color: #FFFFFF;- line-height: 25px;- position: absolute;- right: -12px;- text-align: center;- top: -10px;- width: 24px;- text-decoration: none;- font-weight: bold;- -webkit-border-radius: 12px;- -moz-border-radius: 12px;- border-radius: 12px;- -moz-box-shadow: 1px 1px 3px #000;- -webkit-box-shadow: 1px 1px 3px #000;- box-shadow: 1px 1px 3px #000;+ background: #606061;+ color: #FFFFFF;+ line-height: 25px;+ position: absolute;+ right: -12px;+ text-align: center;+ top: -10px;+ width: 24px;+ text-decoration: none;+ font-weight: bold;+ -webkit-border-radius: 12px;+ -moz-border-radius: 12px;+ border-radius: 12px;+ -moz-box-shadow: 1px 1px 3px #000;+ -webkit-box-shadow: 1px 1px 3px #000;+ box-shadow: 1px 1px 3px #000; } -.close:hover { background: #00d9ff; }+.close:hover {+ background: #00d9ff;+} .modalWindow {- position: fixed;- font-family: arial;- font-size:80%;- top: 0;- right: 0;- bottom: 0;- left: 0;- background: rgba(0,0,0,0.2);- z-index: 99999;- opacity:0;- -webkit-transition: opacity 400ms ease-in;- -moz-transition: opacity 400ms ease-in;- transition: opacity 400ms ease-in;- pointer-events: none;+ position: fixed;+ font-family: arial;+ font-size:80%;+ top: 0;+ right: 0;+ bottom: 0;+ left: 0;+ background: rgba(0,0,0,0.2);+ z-index: 99999;+ opacity:0;+ -webkit-transition: opacity 400ms ease-in;+ -moz-transition: opacity 400ms ease-in;+ transition: opacity 400ms ease-in;+ pointer-events: none; } .modalButton {- background: #606061;- color: #FFFFFF;- line-height: 25px;- text-align: center;- text-decoration: none;- font-weight: bold;- -webkit-border-radius: 2px;- -moz-border-radius: 2px;- border-radius: 2px;- -moz-box-shadow: 1px 1px 3px #000;- -webkit-box-shadow: 1px 1px 3px #000;- box-shadow: 1px 1px 3px #000;- width:80px;- float:right;- margin-left:20px;-+ background: #606061;+ color: #FFFFFF;+ line-height: 25px;+ text-align: center;+ text-decoration: none;+ font-weight: bold;+ -webkit-border-radius: 2px;+ -moz-border-radius: 2px;+ border-radius: 2px;+ -moz-box-shadow: 1px 1px 3px #000;+ -webkit-box-shadow: 1px 1px 3px #000;+ box-shadow: 1px 1px 3px #000;+ width:80px;+ float:right;+ margin-left:20px; } .modalWindow:target {- opacity:1;- pointer-events: auto;+ opacity:1;+ pointer-events: auto; } .modalWindow > div {-- width: 500px;- position: relative;- margin: 10% auto;- -webkit-border-radius: 5px;- -moz-border-radius: 5px;- border-radius: 5px;- background: #fff;- padding-left:20px; - padding-right:10px;- padding-top:5px;- padding-bottom:10px;- max-height: 70%;- }+ width: 500px;+ position: relative;+ margin: 10% auto;+ -webkit-border-radius: 5px;+ -moz-border-radius: 5px;+ border-radius: 5px;+ background: #fff;+ padding-left:20px; + padding-right:10px;+ padding-top:5px;+ padding-bottom:10px;+ max-height: 70%;+} #InputForm {- display:inline;+ display:inline; } #modalCode {- overflow: auto;- height: 60%;+ overflow: auto;+ height: 60%; } pre {- -moz-tab-size: 16;- -o-tab-size: 16;- -webkit-tab-size: 16;- -ms-tab-size: 16;- tab-size: 16;+ -moz-tab-size: 16;+ -o-tab-size: 16;+ -webkit-tab-size: 16;+ -ms-tab-size: 16;+ tab-size: 16; } .playasform {@@ -299,3 +256,26 @@ font-weight: bold; padding-bottom:10px; }++#ruleName {+ font-weight: bold;+ margin-top: 15pt;+}++#proposedBy {+ font-style: italic;+ color: blue;+}++.ruleCode {+ width:100%;+}+ +.ruleDescr {+ width:50%;+}++#playerName {+ padding-right: 20pt;+}+
src/Nomyx/Web/Common.hs view
@@ -5,7 +5,9 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GADTs #-} module Nomyx.Web.Common where @@ -63,7 +65,6 @@ -- | A structure to hold the active games and players data Server = Server [PlayerClient] deriving (Eq, Show) - data PlayerCommand = NotLogged | Auth AuthProfileURL | PostAuth@@ -73,7 +74,7 @@ | LeaveGame GameName | DelGame GameName | ForkGame GameName- | DoInput EventNumber FieldAddress GameName+ | DoInput EventNumber FieldAddress FormField GameName | NewRule GameName | NewGame | SubmitNewGame@@ -93,8 +94,13 @@ type RoutedNomyxServer a = RouteT PlayerCommand (ServerPartT IO) a + instance PathInfo FieldAddressElem instance PathInfo FieldAddress+instance PathInfo FormField+instance PathInfo (Int, String)+instance PathInfo [(Int, String)]+ $(derivePathInfo ''PlayerCommand) $(derivePathInfo ''LoginName) @@ -211,7 +217,7 @@ numberOfGamesOwned gis pn = length $ filter (maybe False (==pn) . _ownedBy) gis getFirstGame :: Session -> Maybe GameInfo-getFirstGame = headMay . _gameInfos . _multi+getFirstGame = headMay . (filter _isPublic) ._gameInfos . _multi instance FormError NomyxError where type ErrorInputType NomyxError = [HS.Input]
src/Nomyx/Web/Game.hs view
@@ -15,9 +15,9 @@ import Data.Maybe import Data.String import Data.List+import Data.List.Split import Data.Text (Text) import Data.Time-import Data.Lens import Text.Printf import System.Locale import Language.Nomyx@@ -35,7 +35,6 @@ import Nomyx.Web.Common as NWC import Nomyx.Core.Types as T import Nomyx.Core.Mail-import Nomyx.Core.Utils import Nomyx.Core.Engine import Nomyx.Core.Session as S import Nomyx.Core.Profile as Profile@@ -68,31 +67,33 @@ p $ do h3 $ fromString $ "Viewing game: " ++ _gameName g when (isJust playAs) $ h4 $ fromString $ "You are playing as player " ++ (show $ fromJust playAs)- p $ do- h4 "Description:"- fromString (_desc $ _gameDesc g)+ p $ pre $ fromString (_desc $ _gameDesc g) p $ h4 $ "This game is discussed in the " >> a "Agora" ! (A.href $ toValue (_agora $ _gameDesc g)) >> "." p $ h4 "Players in game:"- when gameAdmin "(click on the player's name to \"play as\" this player)"+ when gameAdmin "(click on a player name to \"play as\" this player)" vp p $ viewVictory g viewPlayers :: [PlayerInfo] -> GameName -> Bool -> RoutedNomyxServer Html viewPlayers pis gn gameAdmin = do- vp <- mapM (viewPlayer gn gameAdmin) (sort pis)+ let plChunks = transpose $ chunksOf 15 (sort pis)+ vp <- mapM mkRow plChunks ok $ table $ mconcat vp- --let plChunks = transpose $ chunksOf (1 + (length pis) `Prelude.div` 3) (sort pis)- --table $ mapM_ (\row -> tr $ mapM_ (viewPlayer pn) row) plChunks+ where mkRow :: [PlayerInfo] -> RoutedNomyxServer Html+ mkRow row = do+ r <- mapM (viewPlayer gn gameAdmin) row+ ok $ tr $ mconcat r viewPlayer :: GameName -> Bool -> PlayerInfo -> RoutedNomyxServer Html viewPlayer gn gameAdmin (PlayerInfo pn name _) = do pad <- playAsDiv pn gn- ok $ tr $ do- let inf = fromString (show pn ++ "\t" ++ name)+ let inf = fromString name+ ok $ do pad- td $ if gameAdmin+ td $ div ! A.id "playerNumber" $ fromString $ show pn+ td $ div ! A.id "playerName" $ if gameAdmin then a inf ! (href $ toValue $ "#openModalPlayAs" ++ show pn) else inf @@ -136,35 +137,43 @@ td ! class_ "td" $ "#" td ! class_ "td" $ "Name" td ! class_ "td" $ "Description"- td ! class_ "td" $ "Proposed by" td ! class_ "td" $ "Code of the rule"- td ! class_ "td" $ "Assessed by" forM_ nrs (viewRule g) viewRule :: Game -> RuleInfo -> Html-viewRule g nr = tr $ do- let pl = fromMaybe ("Player " ++ (show $ _rProposedBy nr)) (_playerName <$> (Profile.getPlayerInfo g $ _rProposedBy nr))- td ! class_ "td" $ fromString . show $ _rNumber nr- td ! class_ "td" $ fromString $ _rName nr- td ! class_ "td" $ fromString $ _rDescription nr- td ! class_ "td" $ fromString $ if _rProposedBy nr == 0 then "System" else pl- td ! class_ "codetd" $ viewRuleFunc nr- td ! class_ "td" $ fromString $ case _rAssessedBy nr of- Nothing -> "Not assessed"- Just 0 -> "System"- Just a -> "Rule " ++ show a+viewRule g ri = tr $ do+ let pl = fromMaybe ("Player " ++ (show $ _rProposedBy ri)) (_playerName <$> (Profile.getPlayerInfo g $ _rProposedBy ri))+ td ! class_ "td" $ p (fromString . show $ _rNumber ri) ! A.id "ruleNumber"+ td ! class_ "td" $ do+ div ! A.id "ruleName" $ (fromString $ _rName ri)+ br+ div ! A.id "proposedBy" $ (fromString $ "by " ++ (if _rProposedBy ri == 0 then "System" else pl))+ td ! class_ "td" $ fromString $ _rDescription ri+ td ! class_ "td" $ viewRuleFunc ri viewRuleFunc :: RuleInfo -> Html-viewRuleFunc nr = do- let code = displayCode $ _rRuleCode nr- let ref = "openModalCode" ++ (show $ _rNumber nr)- div ! A.id "showCodeLink" $ a ! (href $ toValue $ "#" ++ ref) $ "show code" >> br- code+viewRuleFunc ri = do+ let code = lines $ _rRuleCode ri+ let codeCutLines = 7+ let ref = "openModalCode" ++ (show $ _rNumber ri)+ let assessedBy = case _rAssessedBy ri of+ Nothing -> "not assessed"+ Just 0 -> "the system"+ Just a -> "rule " ++ show a+ div ! A.id "showCodeLink" $ a ! (href $ toValue $ "#" ++ ref) $ "show more..." >> br+ div ! A.id "codeDiv" $ displayCode $ unlines $ take codeCutLines code+ div $ when (length code >= codeCutLines) $ fromString "(...)" div ! A.id (toValue ref) ! class_ "modalDialog" $ do div $ do p "Code of the rule:" a ! href "#close" ! title "Close" ! class_ "close" $ "X"- div ! A.id "modalCode" $ code+ div ! A.id "modalCode" $ do+ displayCode $ unlines code+ br+ case _rStatus ri of+ Active -> (fromString $ "This rule was activated by " ++ assessedBy ++ ".") ! A.id "assessedBy"+ Reject -> (fromString $ "This rule was deleted by " ++ assessedBy ++ ".") ! A.id "assessedBy"+ Pending -> return () viewDetails :: PlayerNumber -> Game -> Html viewDetails pn g = showHideTitle "Details" False False (h3 "Details") $ do@@ -202,7 +211,7 @@ viewIORule pn g r = do vior <- viewIORuleM pn (_rNumber r) g ok $ when (isJust vior) $ div ! A.id "IORule" $ do- div ! A.id "IORuleTitle" $ h4 $ fromString $ "IO for Rule \"" ++ _rName r ++ "\" (#" ++ (show $ _rNumber r) ++ "):"+ div ! A.id "IORuleTitle" $ h4 $ fromString $ "Rule #" ++ (show $ _rNumber r) ++ " \"" ++ _rName r ++ "\": " fromJust vior @@ -226,11 +235,11 @@ viewOutputsRule :: PlayerNumber -> RuleNumber -> Game -> Maybe Html viewOutputsRule pn rn g = do- let filtered = filter (\o -> _oRuleNumber o == rn) (_outputs g)- let myos = filter (isPn pn) (reverse filtered)+ let filtered = filter (\o -> _oRuleNumber o == rn && _oStatus o == SActive) (_outputs g)+ let myos = filter (isPn pn) (sort filtered) case myos of [] -> Nothing- os -> Just $ mapM_ (viewOutput g) os+ os -> Just $ sequence_ $ mapMaybe (viewOutput g) os isPn pn (Output _ _ (Just mypn) _ SActive) = mypn == pn isPn _ (Output _ _ Nothing _ SActive) = True@@ -247,15 +256,16 @@ viewInput' :: PlayerNumber -> GameName -> EventNumber -> (FieldAddress, SomeField) -> RoutedNomyxServer (Maybe Html) viewInput' me gn en (fa, ev@(SomeField (Input pn title _))) | me == pn = do lf <- lift $ viewForm "user" $ inputForm ev- link <- showURL (DoInput en fa gn)+ link <- showURL (DoInput en fa (fromJust $ getFormField ev) gn) return $ Just $ tr $ td $ do fromString title fromString " " blazeForm lf link ! A.id "InputForm" viewInput' _ _ _ _ = return Nothing -viewOutput :: Game -> Output -> Html-viewOutput g o = pre $ fromString (evalOutput g o) >> br+viewOutput :: Game -> Output -> Maybe Html+viewOutput g o = if (s /= "") then Just (pre $ fromString s >> br) else Nothing where+ s = (evalOutput g o) viewVars :: [Var] -> Html viewVars vs = table ! class_ "table" $ do@@ -333,22 +343,16 @@ td $ p $ fromString s -- | a form result has been sent-newInput :: EventNumber -> FieldAddress -> GameName -> TVar Session -> RoutedNomyxServer Response-newInput en fa gn ts = toResponse <$> do- pn <- fromJust <$> getPlayerNumber ts- s <- liftIO $ atomically $ readTVar ts- let lg = _loggedGame $ fromJust $ find ((== gn) . getL gameNameLens) (_gameInfos $ _multi s)- let ei = getEventInfo en lg- methodM POST- case (getInput ei fa (_game lg)) of- Nothing -> error "Input not found"- Just bs -> do- r <- liftRouteT $ eitherForm environment "user" (inputForm bs)- link <- showURL MainPage- case r of- (Right c) -> webCommand ts $ S.inputResult pn en fa c gn- (Left _) -> liftIO $ putStrLn "cannot retrieve form data"- seeOther (link `appendAnchor` inputAnchor) "Redirecting..."+newInput :: EventNumber -> FieldAddress -> FormField -> GameName -> TVar Session -> RoutedNomyxServer Response+newInput en fa ft gn ts = toResponse <$> do+ pn <- fromJust <$> getPlayerNumber ts+ link <- showURL MainPage+ methodM POST+ r <- liftRouteT $ eitherForm environment "user" (inputForm' ft)+ case r of+ (Right c) -> webCommand ts $ S.inputResult pn en fa ft c gn+ (Left _) -> liftIO $ putStrLn "cannot retrieve form data"+ seeOther (link `appendAnchor` inputAnchor) "Redirecting..." newPlayAs :: GameName -> TVar Session -> RoutedNomyxServer Response newPlayAs gn ts = toResponse <$> do@@ -364,7 +368,7 @@ settingsLink <- showURL $ SubmitPlayAs gn mainPage "Admin settings" "Admin settings" (blazeForm errorForm settingsLink) False True -+-- TODO: merge SomeField and FormField... inputForm :: SomeField -> NomyxForm InputData inputForm (SomeField (Input _ _ (Radio choices))) = RadioData <$> NWC.inputRadio' (zip [0..] (snd <$> choices)) (== 0) <++ label (" " :: String) inputForm (SomeField (Input _ _ Text)) = TextData <$> RB.inputText "" <++ label (" " :: String)@@ -372,6 +376,14 @@ inputForm (SomeField (Input _ _ Button)) = pure ButtonData inputForm (SomeField (Input _ _ (Checkbox choices))) = CheckboxData <$> inputCheckboxes (zip [0..] (snd <$> choices)) (const False) <++ label (" " :: String) inputForm _ = error "Not an input form"+++inputForm' :: FormField -> NomyxForm InputData+inputForm' (RadioField _ _ choices) = RadioData <$> NWC.inputRadio' choices (== 0) <++ label (" " :: String)+inputForm' (TextField _ _) = TextData <$> RB.inputText "" <++ label (" " :: String)+inputForm' (TextAreaField _ _) = TextAreaData <$> textarea 50 5 "" <++ label (" " :: String)+inputForm' (ButtonField _ _) = pure ButtonData+inputForm' (CheckboxField _ _ choices) = CheckboxData <$> inputCheckboxes choices (const False) <++ label (" " :: String) showHideTitle :: String -> Bool -> Bool -> Html -> Html -> Html showHideTitle id visible empty title rest = do
src/Nomyx/Web/Help.hs view
@@ -15,7 +15,7 @@ module Nomyx.Web.Help where upload = "In the following form you can upload your file containing custom rules. The file must be a haskell .hs file containing a module, \n" ++ "like in the given example. Once correctly loaded, the content of the file will be \"in scope\" and you will be able to propose the functions \n" ++- "contained in the file as new rules (in this example, you will be able to propose myRule).\n" +++ "contained in the file as new rules (in this example, you will be able to propose the rule \"myRule\").\n" ++ "Additionally, your file will appear as a link on the left hand side on the main page.\n" ++ "Warning, files uploaded here cannot be overwritten. If your uploaded file contains a mistake,\n" ++ "re-upload it with a different name (a version number suffixed for example) or ask the administrator to delete it.\n"
src/Nomyx/Web/MainPage.hs view
@@ -174,7 +174,7 @@ routedNomyxCommands (NewRule game) = newRule game routedNomyxCommands NewGame = newGamePage routedNomyxCommands SubmitNewGame = newGamePost-routedNomyxCommands (DoInput en inn game) = newInput en inn game+routedNomyxCommands (DoInput en fa ft g) = newInput en fa ft g routedNomyxCommands Upload = newUpload routedNomyxCommands W.PlayerSettings = playerSettings routedNomyxCommands SubmitPlayerSettings = newPlayerSettings
src/Nomyx/Web/Settings.hs view
@@ -155,7 +155,7 @@ NoUpload -> p "" hr p $ do- h5 "Enter admin password to get admin rights (necessary to create a new game):"+ h5 "Enter admin password to get admin rights (necessary to create public games):" blazeForm ap submitAdminPass when isAdmin $ h5 "You are admin" when isAdmin $ do