liked ublog list
parent
3ed848b539
commit
1fbd805d6b
|
@ -206,7 +206,7 @@ final class Ublog(env: Env) extends LilaController(env) {
|
|||
|
||||
def community(page: Int) = Open { implicit ctx =>
|
||||
NotForKids {
|
||||
Reasonable(page, 10) {
|
||||
Reasonable(page, 20) {
|
||||
env.ublog.paginator.liveByCommunity(page) map { posts =>
|
||||
Ok(html.ublog.index.community(posts))
|
||||
}
|
||||
|
@ -214,6 +214,18 @@ final class Ublog(env: Env) extends LilaController(env) {
|
|||
}
|
||||
}
|
||||
|
||||
def liked(page: Int) = Auth { implicit ctx => me =>
|
||||
NotForKids {
|
||||
Reasonable(page, 15) {
|
||||
ctx.me ?? { me =>
|
||||
env.ublog.paginator.liveByLiked(me, page) map { posts =>
|
||||
Ok(html.ublog.index.liked(posts))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def userAtom(username: String) = Action.async {
|
||||
env.user.repo.enabledNamed(username) flatMap {
|
||||
case None => NotFound.fuccess
|
||||
|
|
|
@ -12,8 +12,9 @@ object bits {
|
|||
|
||||
def menu(year: Option[Int], active: Option[String]) =
|
||||
st.nav(cls := "page-menu__menu subnav")(
|
||||
a(cls := active.has("friends").option("active"), href := routes.Ublog.friends())("Friends blogs"),
|
||||
a(cls := active.has("community").option("active"), href := routes.Ublog.community())("Community blogs"),
|
||||
a(cls := active.has("friends").option("active"), href := routes.Ublog.friends())("Friends blogs"),
|
||||
a(cls := active.has("liked").option("active"), href := routes.Ublog.liked())("Liked blog posts"),
|
||||
a(cls := active.has("lichess").option("active"), href := routes.Blog.index())("Lichess blog"),
|
||||
year.isDefined || active.has("lichess") option lila.blog.allYears.map { y =>
|
||||
a(cls := (year has y).option("active"), href := routes.Blog.year(y))(y)
|
||||
|
|
|
@ -25,7 +25,8 @@ object blog {
|
|||
atomLinkTag = link(
|
||||
href := routes.Ublog.userAtom(user.username),
|
||||
st.title := title
|
||||
).some
|
||||
).some,
|
||||
robots = netConfig.crawlable && blog.listed
|
||||
) {
|
||||
main(cls := "box box-pad page page-small ublog-index")(
|
||||
div(cls := "box__top")(
|
||||
|
|
|
@ -8,6 +8,7 @@ import lila.app.ui.ScalatagsTemplate._
|
|||
import lila.common.paginator.Paginator
|
||||
import lila.ublog.UblogPost
|
||||
import lila.user.User
|
||||
import play.api.mvc.Call
|
||||
|
||||
object index {
|
||||
|
||||
|
@ -39,47 +40,53 @@ object index {
|
|||
)
|
||||
}
|
||||
|
||||
def friends(posts: Paginator[UblogPost.PreviewPost])(implicit ctx: Context) =
|
||||
def friends(posts: Paginator[UblogPost.PreviewPost])(implicit ctx: Context) = list(
|
||||
title = "Friends blogs",
|
||||
posts = posts,
|
||||
menuItem = "friends",
|
||||
route = routes.Ublog.friends _,
|
||||
onEmpty = "Nothing to show. Follow some authors!"
|
||||
)
|
||||
|
||||
def liked(posts: Paginator[UblogPost.PreviewPost])(implicit ctx: Context) = list(
|
||||
title = "Liked blog posts",
|
||||
posts = posts,
|
||||
menuItem = "liked",
|
||||
route = routes.Ublog.liked _,
|
||||
onEmpty = "Nothing to show. Like some posts!"
|
||||
)
|
||||
|
||||
def community(posts: Paginator[UblogPost.PreviewPost])(implicit ctx: Context) = list(
|
||||
title = "Community blogs",
|
||||
posts = posts,
|
||||
menuItem = "community",
|
||||
route = routes.Ublog.community _,
|
||||
onEmpty = "Nothing to show."
|
||||
)
|
||||
|
||||
private def list(
|
||||
title: String,
|
||||
posts: Paginator[UblogPost.PreviewPost],
|
||||
menuItem: String,
|
||||
route: Int => Call,
|
||||
onEmpty: => Frag
|
||||
)(implicit ctx: Context) =
|
||||
views.html.base.layout(
|
||||
moreCss = cssTag("ublog"),
|
||||
moreJs = posts.hasNextPage option infiniteScrollTag,
|
||||
title = "Friends blogs"
|
||||
title = title
|
||||
) {
|
||||
main(cls := "page-menu")(
|
||||
views.html.blog.bits.menu(none, "friends".some),
|
||||
views.html.blog.bits.menu(none, menuItem.some),
|
||||
main(cls := "page-menu__content box box-pad ublog-index")(
|
||||
div(cls := "box__top")(
|
||||
h1("Friends blogs")
|
||||
),
|
||||
div(cls := "box__top")(h1(title)),
|
||||
if (posts.nbResults > 0)
|
||||
div(cls := "ublog-index__posts ublog-post-cards infinite-scroll")(
|
||||
posts.currentPageResults map { postView.card(_, showAuthor = true) },
|
||||
pagerNext(posts, np => routes.Ublog.friends(np).url)
|
||||
pagerNext(posts, np => route(np).url)
|
||||
)
|
||||
else
|
||||
div(cls := "ublog-index__posts--empty")(
|
||||
"Nothing to show. Follow some authors!"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
def community(posts: Paginator[UblogPost.PreviewPost])(implicit ctx: Context) =
|
||||
views.html.base.layout(
|
||||
moreCss = cssTag("ublog"),
|
||||
moreJs = posts.hasNextPage option infiniteScrollTag,
|
||||
title = "Community blogs"
|
||||
) {
|
||||
main(cls := "page-menu")(
|
||||
views.html.blog.bits.menu(none, "community".some),
|
||||
main(cls := "page-menu__content box box-pad ublog-index")(
|
||||
div(cls := "box__top")(
|
||||
h1("Community blogs")
|
||||
),
|
||||
div(cls := "ublog-index__posts ublog-post-cards infinite-scroll")(
|
||||
posts.currentPageResults map { postView.card(_, showAuthor = true) },
|
||||
pagerNext(posts, np => routes.Ublog.community(np).url)
|
||||
)
|
||||
div(cls := "ublog-index__posts--empty")(onEmpty)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -37,7 +37,8 @@ object post {
|
|||
url = s"$netBaseUrl${routes.Ublog.post(user.username, post.slug, post.id.value)}",
|
||||
description = post.intro
|
||||
)
|
||||
.some
|
||||
.some,
|
||||
robots = netConfig.crawlable && blog.listed
|
||||
) {
|
||||
main(cls := "box box-pad page page-small ublog-post")(
|
||||
thumbnail(post, _.Large)(cls := "ublog-post__image"),
|
||||
|
|
|
@ -28,6 +28,7 @@ db.ublog_post.createIndex(
|
|||
name: 'liveByRank',
|
||||
}
|
||||
);
|
||||
db.ublog_post.createIndex({ likers: 1, rank: -1 }, { partialFilterExpression: { live: true }, name: 'liveByLiked' });
|
||||
|
||||
db.ublog_post.find({ blog: { $exists: false } }).forEach(p => {
|
||||
blogId = `user:${p.user}`;
|
||||
|
|
|
@ -101,6 +101,7 @@ GET /blog/:id/:slug controllers.Blog.show(id: String, slug: S
|
|||
GET /blog.atom controllers.Blog.atom
|
||||
GET /blog.txt controllers.Blog.sitemapTxt
|
||||
GET /blog/friends controllers.Ublog.friends(page: Int ?= 1)
|
||||
GET /blog/liked controllers.Ublog.liked(page: Int ?= 1)
|
||||
GET /blog/community controllers.Ublog.community(page: Int ?= 1)
|
||||
|
||||
# Training - Coordinate
|
||||
|
|
|
@ -52,6 +52,19 @@ final class UblogPaginator(
|
|||
maxPerPage = maxPerPage
|
||||
)
|
||||
|
||||
def liveByLiked(me: User, page: Int): Fu[Paginator[PreviewPost]] =
|
||||
Paginator(
|
||||
adapter = new Adapter[PreviewPost](
|
||||
collection = colls.post,
|
||||
selector = $doc("live" -> true, "likers" -> me.id),
|
||||
projection = previewPostProjection.some,
|
||||
sort = $sort desc "rank",
|
||||
readPreference = ReadPreference.secondaryPreferred
|
||||
),
|
||||
currentPage = page,
|
||||
maxPerPage = maxPerPage
|
||||
)
|
||||
|
||||
object liveByFollowed {
|
||||
|
||||
def apply(user: User, page: Int): Fu[Paginator[PreviewPost]] =
|
||||
|
|
|
@ -17,7 +17,31 @@ final class UblogRank(colls: UblogColls)(implicit ec: ExecutionContext) {
|
|||
colls.post.exists($id(post.id) ++ selectLiker(user.id))
|
||||
|
||||
def like(postId: UblogPost.Id, user: User, v: Boolean): Fu[UblogPost.Likes] =
|
||||
fetchRankData(postId).flatMap {
|
||||
colls.post
|
||||
.aggregateOne() { framework =>
|
||||
import framework._
|
||||
Match($id(postId)) -> List(
|
||||
PipelineOperator($lookup.simple(colls.blog, "blog", "blog", "_id")),
|
||||
UnwindField("blog"),
|
||||
Project(
|
||||
$doc(
|
||||
"_id" -> false,
|
||||
"tier" -> "$blog.tier",
|
||||
"likes" -> $doc("$size" -> "$likers"),
|
||||
"at" -> "$lived.at"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
.map { docOption =>
|
||||
for {
|
||||
doc <- docOption
|
||||
likes <- doc.getAsOpt[UblogPost.Likes]("likes")
|
||||
liveAt <- doc.getAsOpt[DateTime]("at")
|
||||
tier <- doc int "tier"
|
||||
} yield (likes, liveAt, tier)
|
||||
}
|
||||
.flatMap {
|
||||
case None => fuccess(UblogPost.Likes(v ?? 1))
|
||||
case Some((prevLikes, liveAt, tier)) =>
|
||||
val likes = UblogPost.Likes(prevLikes.value + (if (v) 1 else -1))
|
||||
|
@ -71,32 +95,4 @@ final class UblogRank(colls: UblogColls)(implicit ec: ExecutionContext) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private def fetchRankData(postId: UblogPost.Id): Fu[Option[(UblogPost.Likes, DateTime, UblogBlog.Tier)]] =
|
||||
colls.post
|
||||
.aggregateOne() { framework =>
|
||||
import framework._
|
||||
Match($id(postId)) -> List(
|
||||
PipelineOperator($lookup.simple(colls.blog, "blog", "blog", "_id")),
|
||||
UnwindField("blog"),
|
||||
Project(
|
||||
$doc(
|
||||
"_id" -> false,
|
||||
"blog.tier" -> true,
|
||||
"likes" -> $doc("$size" -> "$likers"),
|
||||
"lived.at" -> true
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
.map { docOption =>
|
||||
for {
|
||||
doc <- docOption
|
||||
likes <- doc.getAsOpt[UblogPost.Likes]("likes")
|
||||
lived <- doc.getAsOpt[Bdoc]("lived")
|
||||
liveAt <- lived.getAsOpt[DateTime]("at")
|
||||
blog <- doc.getAsOpt[Bdoc]("blog")
|
||||
tier <- blog int "tier"
|
||||
} yield (likes, liveAt, tier)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue