lila/app/views/ublog/post.scala

220 lines
8.1 KiB
Scala

package views.html.ublog
import controllers.routes
import play.api.mvc.Call
import lila.api.Context
import lila.app.templating.Environment._
import lila.app.ui.ScalatagsTemplate._
import lila.ublog.UblogForm.UblogPostData
import lila.ublog.{ UblogBlog, UblogPost }
import lila.user.User
object post {
def apply(
user: User,
blog: UblogBlog,
post: UblogPost,
markup: Frag,
others: List[UblogPost.PreviewPost],
liked: Boolean,
followed: Boolean
)(implicit
ctx: Context
) =
views.html.base.layout(
moreCss = cssTag("ublog"),
moreJs = frag(
jsModule("expandText"),
ctx.isAuth option jsModule("ublog")
),
title = s"${trans.ublog.xBlog.txt(user.username)}${post.title}",
openGraph = lila.app.ui
.OpenGraph(
`type` = "article",
image = post.image.isDefined option thumbnail.url(post, _.Large),
title = post.title,
url = s"$netBaseUrl${routes.Ublog.post(user.username, post.slug, post.id.value)}",
description = post.intro
)
.some,
robots = netConfig.crawlable && blog.listed && (post.indexable || blog.tier >= UblogBlog.Tier.HIGH)
) {
main(cls := "page-menu page-small")(
views.html.blog.bits.menu(none, (if (ctx is user) "mine" else "community").some),
div(cls := "page-menu__content box box-pad ublog-post")(
post.image.map { image =>
frag(
thumbnail(post, _.Large)(cls := "ublog-post__image"),
image.credit.map { p(cls := "ublog-post__image-credit")(_) }
)
},
ctx.is(user) || isGranted(_.ModerateBlog) option standardFlash(),
h1(cls := "ublog-post__title")(post.title),
div(cls := "ublog-post__meta")(
a(
href := routes.Ublog.index(user.username),
cls := userClass(user.id, none, withOnline = true),
dataHref := routes.User.show(user.username)
)(
lineIcon(user),
titleTag(user.title),
user.username,
!ctx.is(user) && isGranted(_.ModerateBlog) option
(if (blog.tier <= UblogBlog.Tier.VISIBLE) badTag else goodTag)(
cls := "ublog-post__tier"
)(UblogBlog.Tier.name(blog.tier))
),
iconTag("")(
cls := "ublog-post__meta__disclaimer",
st.title := "Opinions expressed by Lichess contributors are their own."
),
post.lived map { live =>
span(cls := "ublog-post__meta__date")(semanticDate(live.at))
},
likeButton(post, liked, showText = false),
span(cls := "ublog-post__views")(
trans.ublog.nbViews.plural(post.views.value, strong(post.views.value.localize))
),
if (ctx is user)
div(cls := "ublog-post__meta__owner")(
(if (post.live) goodTag else badTag)(
if (post.live) trans.ublog.thisPostIsPublished() else trans.ublog.thisIsADraft()
),
" ",
editButton(post)
)
else if (isGranted(_.ModerateBlog)) editButton(post)
else
a(
titleOrText(trans.reportXToModerators.txt(user.username)),
cls := "button button-empty ublog-post__meta__report",
href := s"${routes.Report.form}?username=${user.username}&postUrl=${urlencode(s"${netBaseUrl}${urlOfPost(post).url}")}&reason=comm",
dataIcon := ""
)
),
div(cls := "ublog-post__topics")(
post.topics.map { topic =>
a(href := routes.Ublog.topic(topic.url, 1))(topic.value)
}
),
strong(cls := "ublog-post__intro")(post.intro),
div(cls := "ublog-post__markup expand-text")(markup),
div(cls := "ublog-post__footer")(
(ctx.isAuth && !ctx.is(user)) option
div(cls := "ublog-post__actions")(
likeButton(post, liked, showText = true),
followButton(user, post, followed)
),
h2(a(href := routes.Ublog.index(user.username))(trans.ublog.moreBlogPostsBy(user.username))),
others.size > 0 option div(cls := "ublog-post-cards")(others map { card(_) })
)
)
)
}
private def editButton(post: UblogPost)(implicit ctx: Context) = a(
href := editUrlOfPost(post),
cls := "button button-empty text",
dataIcon := ""
)(trans.edit())
private def likeButton(post: UblogPost, liked: Boolean, showText: Boolean)(implicit ctx: Context) = {
val text = if (liked) trans.study.unlike.txt() else trans.study.like.txt()
button(
tpe := "button",
cls := List(
"ublog-post__like is" -> true,
"ublog-post__like--liked" -> liked,
"ublog-post__like--big button button-big button-red" -> showText,
"ublog-post__like--mini button-link" -> !showText
),
dataRel := post.id.value,
title := text
)(
span(cls := "ublog-post__like__nb")(post.likes.value.localize),
showText option span(
cls := "button-label",
attr("data-i18n-like") := trans.study.like.txt(),
attr("data-i18n-unlike") := trans.study.unlike.txt()
)(text)
)
}
private def followButton(user: User, post: UblogPost, followed: Boolean)(implicit ctx: Context) =
div(
cls := List(
"ublog-post__follow" -> true,
"followed" -> followed
)
)(
List(
("yes", trans.unfollowX, routes.Relation.unfollow _, ""),
("no", trans.followX, routes.Relation.follow _, "")
).map { case (role, text, route, icon) =>
button(
cls := s"ublog-post__follow__$role button button-big",
dataIcon := icon,
dataRel := route(user.id)
)(
span(cls := "button-label")(text(user.titleUsername))
)
}
)
def card(
post: UblogPost.BasePost,
makeUrl: UblogPost.BasePost => Call = urlOfPost,
showAuthor: Boolean = false,
showIntro: Boolean = true
)(implicit ctx: Context) =
a(cls := "ublog-post-card ublog-post-card--link", href := makeUrl(post))(
thumbnail(post, _.Small)(cls := "ublog-post-card__image"),
span(cls := "ublog-post-card__content")(
h2(cls := "ublog-post-card__title")(post.title),
showIntro option span(cls := "ublog-post-card__intro")(shorten(post.intro, 100)),
post.lived map { live => semanticDate(live.at)(ctx.lang)(cls := "ublog-post-card__over-image") },
showAuthor option userIdSpanMini(post.created.by)(ctx.lang)(cls := "ublog-post-card__over-image")
)
)
def miniCard(post: UblogPost.BasePost)(implicit ctx: Context) =
span(cls := "ublog-post-card ublog-post-card--mini")(
thumbnail(post, _.Small)(cls := "ublog-post-card__image"),
h3(cls := "ublog-post-card__title")(post.title)
)
def urlOfPost(post: UblogPost.BasePost) = post.blog match {
case UblogBlog.Id.User(userId) =>
routes.Ublog.post(usernameOrId(userId), post.slug, post.id.value)
}
def editUrlOfPost(post: UblogPost.BasePost) = routes.Ublog.edit(post.id.value)
private[ublog] def newPostLink(implicit ctx: Context) = ctx.me map { u =>
a(
href := routes.Ublog.form(u.username),
cls := "button button-green",
dataIcon := "",
title := trans.ublog.newPost.txt()
)
}
object thumbnail {
def apply(post: UblogPost.BasePost, size: UblogPost.thumbnail.SizeSelector) =
img(
cls := "ublog-post-image",
widthA := size(UblogPost.thumbnail).width,
heightA := size(UblogPost.thumbnail).height,
alt := post.image.flatMap(_.alt)
)(src := url(post, size))
def url(post: UblogPost.BasePost, size: UblogPost.thumbnail.SizeSelector) =
post.image match {
case Some(image) => UblogPost.thumbnail(picfitUrl, image.id, size)
case _ => assetUrl("images/user-blog-default.png")
}
}
}