building new ui without html5up

This commit is contained in:
nek0 2016-08-30 14:22:00 +02:00
parent 094ef82c09
commit e45288badb
16 changed files with 406 additions and 244 deletions

View file

@ -29,7 +29,7 @@ import Text.Jasmine (minifym)
import Text.Hamlet (hamletFile)
import Yesod.Core.Types
-- costom imports
import Data.Text as T
import qualified Data.Text as T
import Data.Text.Encoding
import Network.Wai
import Helper
@ -116,18 +116,19 @@ renderLayout widget = do
pc <- widgetToPageContent $ do
-- add parallelism js files
$(combineScripts 'StaticR
[ js_jquery_1_11_3_js
, js_jquery_poptrox_js
, js_skel_min_js
, js_init_js
, js_picturefill_js
])
$(combineStylesheets 'StaticR
[ css_dropdown_css
, css_bootstrap_min_css
, css_style_global_css
])
-- mapM_ addScript $ map StaticR
-- -- [ js_jquery_1_11_3_js
-- -- , js_jquery_poptrox_js
-- -- , js_skel_min_js
-- -- , js_init_js
-- [ js_picturefill_js
-- ]
mapM_ addStylesheet $ map StaticR
[ css_bootstrap_min_css
, css_dropdown_css
, css_main_css
-- , css_style_global_css
]
$(widgetFile "default-layout")
withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet")
@ -144,7 +145,7 @@ approotRequest master req =
where
prefix =
if
"https://" `isPrefixOf` appRoot (appSettings master)
"https://" `T.isPrefixOf` appRoot (appSettings master)
then
"https://"
else
@ -165,8 +166,9 @@ instance Yesod App where
120 -- timeout in minutes
"config/client_session_key.aes"
defaultLayout widget =
renderLayout $(widgetFile "default-widget")
-- defaultLayout widget =
-- renderLayout $(widgetFile "default-widget")
defaultLayout = renderLayout
-- This is done to provide an optimization for serving static files from
-- a separate domain. Please see the staticRoot setting in Settings.hs

View file

@ -34,7 +34,7 @@ data Credentials = Credentials
getLoginR :: Handler Html
getLoginR =
formLayout $ do
defaultLayout $ do
setTitle "Eidolon :: Login"
$(widgetFile "login")

View file

@ -65,7 +65,7 @@ getMediumR mediumId = do
let tr = StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ mediumThumb medium) []
let pr = StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ mediumPreview medium) []
let ir = StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ mediumPath medium) []
formLayout $ do
defaultLayout $ do
setTitle $ toHtml ("Eidolon :: Medium " `T.append` (mediumTitle medium))
rssLink (CommentFeedRssR mediumId) $ "Comment feed of medium " `T.append` mediumTitle medium
atomLink (CommentFeedAtomR mediumId) $ "Comment feed of medium " `T.append` mediumTitle medium

View file

@ -26,16 +26,20 @@ import Database.Bloodhound
import Network.HTTP.Client (responseBody)
import System.FilePath.Posix
import Debug.Trace
getSearchR :: Handler Html
getSearchR = do
((res, widget), _) <- runFormGet searchForm
case res of
FormSuccess query -> do
(ru, ra, rm, rc) <- getResults query
liftIO $ traceIO $ show (ru, ra, rm, rc)
let a = decode (responseBody ru) :: Maybe (SearchResult SearchUser)
let b = decode (responseBody ra) :: Maybe (SearchResult SearchAlbum)
let c = decode (responseBody rm) :: Maybe (SearchResult SearchMedium)
let d = decode (responseBody rc) :: Maybe (SearchResult SearchComment)
liftIO $ traceIO $ show (a,b,c,d)
let hitListA = case a of {
Just as -> hits $ searchHits as;
Nothing -> []}
@ -84,6 +88,7 @@ getSearchR = do
else
Nothing
) hitListD
liftIO $ traceIO $ show (userIdList, albumIdList, mediumIdList, commentIdList)
userList <- return . catMaybes =<< mapM (\i -> runDB $ selectFirst [UserId ==. i] []) userIdList
albumList <- return . catMaybes =<< mapM (\i -> runDB $ selectFirst [AlbumId ==. i] []) albumIdList
mediumList <- return . catMaybes =<< mapM (\i -> runDB $ selectFirst [MediumId ==. i] []) mediumIdList
@ -129,7 +134,7 @@ getResults query = do
data SearchUser = SearchUser
{ suName :: T.Text
, suSlug :: T.Text
}
} deriving Show
instance FromJSON SearchUser where
parseJSON (Object o) = SearchUser
@ -138,7 +143,7 @@ instance FromJSON SearchUser where
parseJSON _ = mempty
data SearchAlbum = SearchAlbum
{ saName :: T.Text }
{ saName :: T.Text } deriving Show
instance FromJSON SearchAlbum where
parseJSON (Object o) = SearchAlbum <$> o .: "name"
@ -149,7 +154,7 @@ data SearchMedium = SearchMedium
, smTime :: UTCTime
, smDescription :: Textarea
, smTags :: [T.Text]
}
} deriving Show
instance FromJSON SearchMedium where
parseJSON (Object o) = SearchMedium
@ -163,7 +168,7 @@ data SearchComment = SearchComment
{ scAuthor :: Text
, scTime :: UTCTime
, scContent :: Text
}
} deriving Show
instance FromJSON SearchComment where
parseJSON (Object o) = SearchComment

View file

@ -45,7 +45,7 @@ getDirectUploadR albumId = do
-- is the owner present or a user with whom the album is shared
then do
(dUploadWidget, enctype) <- generateFormPost $ renderBootstrap3 BootstrapBasicForm $ dUploadForm userId albumId
formLayout $ do
defaultLayout $ do
setTitle $ toHtml ("Eidolon :: Upload medium to " `T.append` albumTitle album)
$(widgetFile "dUpload")
else do
@ -239,7 +239,7 @@ getUploadR = do
redirect NewAlbumR
else do
(uploadWidget, enctype) <- generateFormPost $ renderBootstrap3 BootstrapBasicForm $ bulkUploadForm userId
formLayout $ do
defaultLayout $ do
setTitle "Eidolon :: Upload Medium"
$(widgetFile "bulkUpload")
Nothing -> do

View file

@ -24,9 +24,9 @@
/signup SignupR GET POST
/login LoginR GET POST
/logout LogoutR GET
/activate/#Text ActivateR GET POST
/activate/#T.Text ActivateR GET POST
/profile/#UserId ProfileR GET
/user/#Text UserR GET
/user/#T.Text UserR GET
/upload UploadR GET POST
/newalbum NewAlbumR GET POST
/album/#AlbumId AlbumR GET
@ -59,7 +59,7 @@
/admin/comment/#CommentId AdminCommentDeleteR GET
/admin/repop-search AdminSearchReloadR GET
/tag/#Text TagR GET
/tag/#T.Text TagR GET
/feed/root/atom.xml RootFeedAtomR GET
/feed/root/rss.xml RootFeedRssR GET
@ -69,7 +69,7 @@
/feed/medium/#MediumId/rss.xml CommentFeedRssR GET
/feed/user/#UserId/atom.xml UserFeedAtomR GET
/feed/user/#UserId/rss.xml UserFeedRssR GET
!/feed/user/#Text/atom.xml NameFeedAtomR GET
!/feed/user/#Text/rss.xml NameFeedRssR GET
!/feed/user/#T.Text/atom.xml NameFeedAtomR GET
!/feed/user/#T.Text/rss.xml NameFeedRssR GET
/search SearchR GET

View file

@ -2,6 +2,7 @@
list-style: none;
font-weight: bold;
position: relative;
padding: 0;
}
#user-nav ul {
@ -20,7 +21,15 @@
#user-nav li a {
padding: 10px 20px 10px;
border-radius: 5px;
background-color: white;
background: white url('../img/overlay.png');
}
#user-nav li ul {
padding: 0;
}
#user-nav li ul li {
display: inline;
}
#user-nav input[type="checkbox"]:checked + ul {
@ -51,3 +60,7 @@
left: -9999px;*/
display: none;
}
.red {
background: rgba(255,0,0,0.2) url('../img/overlay.png') !important;
}

176
static/css/main.css Normal file
View file

@ -0,0 +1,176 @@
body {
display: flex;
min-height: 100vh;
flex-direction: column;
background-image: url('../img/overlay.png'), linear-gradient(top, rgba(0,0,0,0) 75%, rgba(0,0,0,0.65)), url('../img/bg.jpg');
background-image: url('../img/overlay.png'), -moz-linear-gradient(top, rgba(0,0,0,0) 75%, rgba(0,0,0,0.65)), url('../img/bg.jpg');
background-image: url('../img/overlay.png'), -ms-linear-gradient(top, rgba(0,0,0,0) 75%, rgba(0,0,0,0.65)), url('../img/bg.jpg');
background-image: url('../img/overlay.png'), -webkit-linear-gradient(top, rgba(0,0,0,0) 75%, rgba(0,0,0,0.65)), url('../img/bg.jpg');
background-image: url('../img/overlay.png'), -o-linear-gradient(top, rgba(0,0,0,0) 75%, rgba(0,0,0,0.65)), url('../img/bg.jpg');
background-size: cover;
background-attachment: fixed;
color: rgba(255,255,255,0.7);
}
#main {
margin-top: 80px;
width: 100%;
}
a {
color: white;
text-decoration: none;
font-weight: 600;
transition: color 0.25s ease-in-out;
}
a figcaption {
font-size: 14pt;
text-decoration: none;
transition: color 0.25s ease-in-out;
}
a:hover, .item a:hover, .medium a:hover, a:hover figcaption {
color: #d64760;
text-decoration: underline;
transition: color 0.25s ease-in-out;
}
#wrapper {
flex: 1;
}
#message {
padding: 1em 2em;
background: lightyellow url('../img/overlay.png');
color: #d64760;
font-size: 1.5em;
position:relative;
top: 80px;
z-index: 5;
}
#header {
margin: 40px 80px 40px;
}
#reel {
list-style: none;
display: block;
margin: 0 80px;
padding: 0;
text-align: center;
}
.middle {
position: relative;
top: 50px;
}
.item, .medium {
color: rgba(0,0,0,0.7);
display: inline-block;
position: relative;
background: rgba(255,255,255,0.8) url('../img/overlay.png');
border: 10px solid white;
}
.item {
height: 300px;
width: 400px;
margin-right: -14px;
margin-bottom: -10px;
}
.item a {
padding: 20px;
display: inline-block;
width: 100%;
height: 100%;
}
.subheader {
background: rgba(214, 71, 96, 0.7) url('../img/overlay.png');
}
.column {
margin: 0 40px 0;
}
.column > div {
width: 100%
}
.medium {
margin: 0px auto -10px;
padding: 20px;
}
.image {
text-align: center;
}
.item a, .medium a {
/*color: rgba(0,0,0,0.7);*/
color: black;
transition: color 0.25s ease-in-out;
}
figure img {
display: block;
margin: 0 auto;
}
figcaption {
text-align: center;
font-weight: bold;
}
img {
max-width: 100%;
max-height: 100%;
}
nav {
width: 100%;
padding: 1em 2em;
background: #d64760 url('../img/overlay.png');
position: fixed;
z-index: 6;
}
nav li {
display: inline-block;
}
footer {
padding: 1em 2em;
}
#search {
padding-top: 5px;
}
.left {
float: left;
}
.right {
float: right;
}
@media (max-width: 755px) {
#main {
margin-top: 120px;
}
#message {
top: 120px;
}
}
@media (max-width: 480px) {
#main, #reel {
margin-left: 0;
margin-right: 0;
}
}

View file

@ -1,4 +1,5 @@
<div id="header" class="item" data-width="400">
<form class="inner" method=post enctype=#{enctype}>
Upload multiple images
^{uploadWidget}
<div #reel .middle>
<div .medium>
<form class="inner" method=post enctype=#{enctype}>
Upload multiple images
^{uploadWidget}

View file

@ -21,3 +21,39 @@ $doctype 5
<body>
<div id="wrapper">
^{pageBody pc}
<footer>
<div class="left">
^{pageBody copyrightWidget}
<div class="right">
$case route
$of Just HomeR
get a Feed from This:
<a href="@{RootFeedAtomR}">Atom
|
<a href="@{RootFeedRssR}">RSS
$of Just (PageR _)
get a Feed from This:
<a href="@{RootFeedAtomR}">Atom
|
<a href="@{RootFeedRssR}">RSS
$of Just (ProfileR uId)
get a Feed from This:
<a href="@{UserFeedAtomR uId}">Atom
|
<a href="@{UserFeedRssR uId}">RSS
$of Just (UserR name)
get a Feed from This:
<a href="@{NameFeedAtomR name}">Atom
|
<a href="@{NameFeedRssR name}">RSS
$of Just (AlbumR aId)
get a Feed from This:
<a href="@{AlbumFeedAtomR aId}">Atom
|
<a href="@{AlbumFeedRssR aId}">RSS
$of Just (MediumR mId)
get a Feed from This:
<a href="@{CommentFeedAtomR mId}">Atom
|
<a href="@{CommentFeedRssR mId}">RSS
$of _

View file

@ -1,6 +1,6 @@
<nav>
<div .row>
<div .col-md-9>
<div .col-md-9 .col-sm-6>
<ul #user-nav>
<li>
<a href=@{HomeR}>
@ -24,13 +24,11 @@
<li>
<a href=@{LogoutR}>
Logout
$case madmin
$of Just admin
$if admin
<li>
<a href=@{AdminR} .red>
Administration
$of Nothing
$maybe admin <- madmin
$if admin
<li>
<a href=@{AdminR} .red>
Administration
$nothing
<li>
<a href=@{LoginR}>
@ -39,7 +37,7 @@
<li>
<a href=@{SignupR}>
Signup
<div .col-md-3 #search>
<div .col-md-3 .col-sm-6 #search>
^{pageBody searchWidget}
$maybe msg <- mmsg
@ -47,39 +45,3 @@ $maybe msg <- mmsg
<div id="main" role="main">
^{pageBody wc}
<div id="footer">
<div class="left">
^{pageBody copyrightWidget}
<div class="right">
$case route
$of Just HomeR
get a Feed from This:
<a href="@{RootFeedAtomR}">Atom
|
<a href="@{RootFeedRssR}">RSS
$of Just (PageR _)
get a Feed from This:
<a href="@{RootFeedAtomR}">Atom
|
<a href="@{RootFeedRssR}">RSS
$of Just (ProfileR uId)
get a Feed from This:
<a href="@{UserFeedAtomR uId}">Atom
|
<a href="@{UserFeedRssR uId}">RSS
$of Just (UserR name)
get a Feed from This:
<a href="@{NameFeedAtomR name}">Atom
|
<a href="@{NameFeedRssR name}">RSS
$of Just (AlbumR aId)
get a Feed from This:
<a href="@{AlbumFeedAtomR aId}">Atom
|
<a href="@{AlbumFeedRssR aId}">RSS
$of Just (MediumR mId)
get a Feed from This:
<a href="@{CommentFeedAtomR mId}">Atom
|
<a href="@{CommentFeedRssR mId}">RSS
$of _

View file

@ -1,18 +1,17 @@
$doctype 5
<div id="header" class="item" data-width="400">
<div class="inner">
<h1>Eidolon
<p>
A simple gallery System in Haskell and Yesod
$forall (Entity mediumId medium) <- recentMedia
<article class="item" data-width=#{mediumThumbWidth medium}>
<a href=@{MediumR mediumId}>
<figure>
<img src=@{StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ mediumThumb medium) []} title=#{mediumTitle medium}>
<figcaption>#{mediumTitle medium}
<div id="header">
<h1>Eidolon
<p>
A simple gallery System in Haskell and Yesod
<div #reel>
$forall (Entity mediumId medium) <- recentMedia
<article class="item">
<a href=@{MediumR mediumId}>
<figure>
<img src=@{StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ mediumThumb medium) []} title=#{mediumTitle medium}>
<figcaption>#{mediumTitle medium}
$if nextMedia
<div id="header" class="item" data-width="400">
<div class="inner">
<p>
<a href=@{PageR 1}>
older
<div class="pagination">
<p>
<a href=@{PageR 1}>
older

View file

@ -1,21 +1,22 @@
$newline always
<div id="header" class="item" data-width="300">
<noscript>Please enable Javascript
<h3>Login
<form class="inner r">
<div .form-group .required>
<label for="username">User:
<input .form-control #username type="text" required>
<div .form-group .required>
<label for="password">Password:
<input .form-control #password type="password" required>
<div .form-group .optional>
<button .btn .btn-default #login type="submit">Login
<div #progress>
<div #reel .middle>
<div .medium>
<noscript>Please enable Javascript
<h3>Login
<form>
<div .form-group .required>
<label for="username">User:
<input .form-control #username type="text" required>
<div .form-group .required>
<label for="password">Password:
<input .form-control #password type="password" required>
<div .form-group .optional>
<button .btn .btn-default #login type="submit">Login
<div #progress>
<a href=@{ReactivateR}>Forgot your Password?
<a href=@{ReactivateR}>Forgot your Password?
<script src="/static/js/jquery.min.js" type="text/javascript">
<script src="/static/js/jsSHA.js" type="text/javascript">
<script src="/static/js/login.js" type="text/javascript">
<script src="/static/js/jquery.min.js" type="text/javascript">
<script src="/static/js/jsSHA.js" type="text/javascript">
<script src="/static/js/login.js" type="text/javascript">

View file

@ -1,24 +0,0 @@
/*templates/medium.cassius*/
#wrapper
overflow: auto !important
#reel
width: 90% !important
max-height: auto !important
#reel .item
float: none !important
display: inline-block !important
width: 100% !important
div #main
margin-top: 60px !important
position: static !important
#footer
position: static !important
@media screen and (max-width: 650px)
#reel
width: 100% !important

View file

@ -1,70 +1,66 @@
<div data-width="1000">
<div id="header" class="item" data-width="1000">
<div class="inner">
<h1>#{mediumTitle medium}
<div .column>
<div class="medium">
<h1>#{mediumTitle medium}
<p>
by <a href=@{UserR ownerName}>#{ownerName}</a> from album <a href=@{AlbumR albumId}>#{albumTitle album}</a>
<div class="medium image">
<a href=@{ir}>
<picture>
<source srcset="@{pr}, @{ir} 2x" media="(min-width: 600px)">
<source srcset="@{tr}, @{pr} 2x">
<img src=@{pr} title=#{mediumTitle medium}>
<div class="medium">
<p class="desc">
Uploaded on: #{formatTime defaultTimeLocale "%A %F %H:%M" (mediumTime medium)}<br>
$maybe d <- mediumDescription medium
Description:<br>
#{d}
$nothing
No description given
<div class="tags">
<p>
by <a href=@{UserR ownerName}>#{ownerName}</a> from album <a href=@{AlbumR albumId}>#{albumTitle album}</a>
<div id="header" class="item image" data-width=#{dataWidth}>
<div class="inner">
<a href=@{ir}>
<picture>
<source srcset="@{pr}, @{ir} 2x" media="(min-width: 600px)">
<source srcset="@{tr}, @{pr} 2x">
<img src=@{pr} title=#{mediumTitle medium}>
<div id="header" class="item" data-width="400">
<div class="inner">
<p class="desc">
Uploaded on: #{formatTime defaultTimeLocale "%A %F %H:%M" (mediumTime medium)}<br>
$maybe d <- mediumDescription medium
Description:<br>
#{d}
$nothing
No description given
<div class="tags">
<p>
Tags:
<ul>
$if null (mediumTags medium)
none
$else
$forall tag <- mediumTags medium
<li>
<a href=@{TagR tag}>#{tag}
$if presence == True
<a href=@{MediumSettingsR mediumId}>Change medium settings
Tags:
<ul>
$if null (mediumTags medium)
none
$else
$forall tag <- mediumTags medium
<li>
<a href=@{TagR tag}>#{tag}
$if presence == True
<a href=@{MediumSettingsR mediumId}>Change medium settings
$if null comments
<div id="header" class="item" data-width="300">
<div class="medium">
<p>There are no Comments yet
$else
$forall (Entity commentId comment) <- comments
<div .medium .comment data-width="300">
<a href=@{ProfileR $ commentAuthor comment}>#{commentAuthorSlug comment}</a> wrote on #{formatTime defaultTimeLocale "%A %F %H:%M" $ commentTime comment}:
<hr>
#{commentContent comment}
$if userId /= Nothing
<hr>
<a href=@{CommentReplyR commentId}>Reply to this comment
$if userId == (Just $ commentAuthor comment)
<a href=@{CommentDeleteR commentId}>Delete this comment
$forall (Entity replyId reply) <- replies
$if commentParent reply == Just commentId
<article .comment .reply .medium>
<a href=@{ProfileR $ commentAuthor reply}>#{commentAuthorSlug reply}</a> replied on #{formatTime defaultTimeLocale "%A %F %H:%M" $ commentTime reply}:
<hr>
#{commentContent reply}
<hr>
$if userId == (Just $ commentAuthor comment)
<a href=@{CommentDeleteR replyId}>Delete this comment
$if userId /= Nothing
<div class="medium">
<div class="inner">
<p>There are no Comments yet
$forall (Entity commentId comment) <- comments
<article class="comment" data-width="300">
<a href=@{ProfileR $ commentAuthor comment}>#{commentAuthorSlug comment}</a> wrote on #{formatTime defaultTimeLocale "%A %F %H:%M" $ commentTime comment}:
<hr>
#{commentContent comment}
$if userId /= Nothing
<hr>
<a href=@{CommentReplyR commentId}>Reply to this comment
$if userId == (Just $ commentAuthor comment)
<a href=@{CommentDeleteR commentId}>Delete this comment
$forall (Entity replyId reply) <- replies
$if commentParent reply == Just commentId
<article class="comment reply">
<a href=@{ProfileR $ commentAuthor reply}>#{commentAuthorSlug reply}</a> replied on #{formatTime defaultTimeLocale "%A %F %H:%M" $ commentTime reply}:
<hr>
#{commentContent reply}
<hr>
$if userId == (Just $ commentAuthor comment)
<a href=@{CommentDeleteR replyId}>Delete this comment
$if userId /= Nothing
<div id="header" class="item" data-width="1000">
<div class="inner">
<form method=post enctype=#{enctype}>
^{commentWidget}
<form method=post enctype=#{enctype}>
^{commentWidget}
<style type="text/css">
body{background-image: url('/static/css/images/overlay.png'), -webkit-linear-gradient(top, rgba(0,0,0,0) 75%, rgba(0,0,0,0.65)), url('@{StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ mediumPath medium) []}');background-attachment:fixed;background-image: url('/static/css/images/overlay.png'), -moz-linear-gradient(center top , transparent 75%, rgba(0, 0, 0, 0.65)), url('@{StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ mediumPath medium) []}');}

View file

@ -1,53 +1,48 @@
$newline always
<div id="header" class="item" data-width="400">
<div class="inner">
<h1>Profile of #{ownerSlug}
$if presence == True
<a href=@{ProfileSettingsR ownerId}>Change your profile settings
<div #header>
<h1>Profile of #{ownerSlug}
$if presence == True
<a href=@{ProfileSettingsR ownerId}>Change your profile settings
<div id="header" class="item" data-width="400">
<div class="inner">
<div #reel>
<article .subheader .item>
$if null userAlbs
<p class="center">This user has no albums yet
$else
<h1>Albums
<p>Albums of this user:
<ul>
$forall (Entity albumId album) <- userAlbs
<article class="item" data-width=#{albumSampleWidth album}>
<a href=@{AlbumR albumId}>
<figure>
$if (albumSamplePic album) == Nothing
<img src=@{StaticR img_album_jpg} title=#{albumTitle album}>
$else
<img src=@{StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ fromJust $ albumSamplePic album) []} title=#{albumTitle album}>
<figcaption>#{albumTitle album}
$if not (null userAlbs)
$forall (Entity albumId album) <- userAlbs
<article class="item">
<a href=@{AlbumR albumId}>
<figure>
$if (albumSamplePic album) == Nothing
<img src=@{StaticR img_album_jpg} title=#{albumTitle album}>
$else
<img src=@{StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ fromJust $ albumSamplePic album) []} title=#{albumTitle album}>
<figcaption>#{albumTitle album}
$if null sharedAlbs
$else
<div id="header" class="item" data-width="400">
<div class="inner">
$if not (null sharedAlbs)
<article .subheader .item>
<h1>Shared Albums
<p>Albums shared with this user:
$forall Just (Entity albumId album) <- sharedAlbs
<article class="shared item" data-width=#{albumSampleWidth album}>
<a href=@{AlbumR albumId}>
<figure>
$if (albumSamplePic album) == Nothing
<img src=@{StaticR img_album_jpg}>
$else
<img src=@{StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ fromJust $ albumSamplePic album) []} title=#{albumTitle album}>
<figcaption>#{albumTitle album}
$forall Just (Entity albumId album) <- sharedAlbs
<article .item>
<a href=@{AlbumR albumId}>
<figure>
$if (albumSamplePic album) == Nothing
<img src=@{StaticR img_album_jpg}>
$else
<img src=@{StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ fromJust $ albumSamplePic album) []} title=#{albumTitle album}>
<figcaption>#{albumTitle album}
$if null recentMedia
$else
<div id="header" class="item" data-width="400">
<div class="inner">
$if not (null recentMedia)
<article .subheader .item>
<h1>Newest images
<p>recent uploads of #{ownerSlug}
$forall (Entity mediumId medium) <- take 10 recentMedia
<article class="recent item" data-width=#{mediumThumbWidth medium}>
<a href=@{MediumR mediumId}>
<figure>
<img src=@{StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ mediumThumb medium) []} title=#{mediumTitle medium}>
<figcaption>#{mediumTitle medium}
$forall (Entity mediumId medium) <- take 10 recentMedia
<article .item>
<a href=@{MediumR mediumId}>
<figure>
<img src=@{StaticR $ StaticRoute (drop 2 $ map T.pack $ splitDirectories $ mediumThumb medium) []} title=#{mediumTitle medium}>
<figcaption>#{mediumTitle medium}