Hagia
log in
morj / hagia
overview
files
history
wiki
Viewing at
module Routes.User
( getUserR
, getCreateRepoR
, postCreateRepoR
) where

import ClassyPrelude hiding (Handler)

import qualified Git
import qualified Yesod
import qualified Yesod.Auth as Auth

import Database (Repository (..), Unique (UniqueUsername), User (User, userUsername))
import Database.Persist (entityKey, entityVal, insert_, selectList, (==.))
import Database.Persist.Class.PersistUnique (getByValueUniques)
import HagiaSite (HagiaSite (..), Handler, Route (CreateRepoR, RepoR), Widget, repoPath)
import Path (PathSegment, pathSegmentFromDbString, toText)
import Yesod (FormResult, MForm, getYesod, runDB)
import Yesod.Auth (maybeAuthId)
import Yesod.Core (Html, whamlet)

getUserR :: PathSegment -> Handler Html
getUserR userName = do
user <-
runDB (getByValueUniques [UniqueUsername $ toText userName]) >>= \case
Nothing -> Yesod.notFound
Just x -> pure $ entityKey x
repos <- map entityVal <$> runDB (selectList [#user ==. user] [])

authId <- maybeAuthId
let visibleRepos =
if authId == Just user
then repos
else filter (not . repositoryPrivate) repos

Yesod.defaultLayout $ do
Yesod.setTitle $ Yesod.toHtml userName
[whamlet|
<div .content .row-g5 style="margin-top: 5px">
<!-- User personality -->
<div .column-g5 style="width: 25%; align-items: start">
<div style="font-size: 40px">
#{userName}
$if isJust authId
<a .seamless-a href=@{CreateRepoR}> Create repository
<!-- Repos -->
<div .column-g5 style="width: 65%; margin-left: auto; align-items: start; font-size: 20px">
$forall repo <- visibleRepos
$with name <- pathSegmentFromDbString $ repositoryName repo
<a href=@{RepoR userName name}>
#{userName} / #{name}
|]

data CreateRepoForm = CreateRepoForm
{ repoName :: !Text
, repoSummary :: !(Maybe Text)
, private :: !Bool
}
deriving (Eq, Show)

createRepoForm :: Html -> MForm Handler (FormResult CreateRepoForm, Widget)
createRepoForm =
Yesod.renderDivs $
CreateRepoForm
<$> Yesod.areq Yesod.textField "New repo name" Nothing
<*> Yesod.aopt Yesod.textField "Short description (optional)" Nothing
<*> Yesod.areq Yesod.checkBoxField "Private" (Just False)

getCreateRepoR :: Handler Html
getCreateRepoR = do
(widget, enctype) <- Yesod.generateFormPost createRepoForm
Yesod.defaultLayout $ do
Yesod.setTitle "Create repository"
[whamlet|
<h1> Create repo
<form method=post action=@{CreateRepoR} enctype=#{enctype}>
^{widget}
<button> Create
|]

postCreateRepoR :: Handler Html
postCreateRepoR = do
userId <- Auth.requireAuthId
User{userUsername} <-
runDB $
Yesod.get userId >>= \case
Nothing -> error "XXX Authorized user doesn't exist"
Just x -> pure x
((result, widget), enctype) <- Yesod.runFormPost createRepoForm
case result of
Yesod.FormSuccess CreateRepoForm{repoName, repoSummary, private} -> do
let username = pathSegmentFromDbString userUsername
let reponame = pathSegmentFromDbString repoName
projectRoot <- repoPath username reponame
-- TODO: create directory for user? Maybe this is done when creating users
HagiaSite{git} <- getYesod
liftIO $ Git.createRepo git projectRoot
runDB $
insert_
Repository
{ repositoryName = repoName
, repositorySummary = repoSummary
, repositoryUser = userId
, repositoryPrivate = private
}
Yesod.redirect $ RepoR username reponame
_ ->
Yesod.defaultLayout $ do
Yesod.setTitle "Create repository"
[whamlet|
<h1> Create repo
Something went wrong, try again with different values
<form method=post action=@{CreateRepoR} enctype=#{enctype}>
^{widget}
<button> Create
|]