packages feed

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 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