paginate videos
parent
60d3191e74
commit
0bb0db7784
|
@ -24,7 +24,7 @@ object Video extends LilaController {
|
|||
}
|
||||
|
||||
private def renderIndex(control: UserControl)(implicit ctx: Context) =
|
||||
env.api.video.byTags(control.filter.tags, 15) map { videos =>
|
||||
env.api.video.byTags(control.filter.tags, getInt("page") | 1) map { videos =>
|
||||
Ok(html.video.index(videos, control))
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ object Video extends LilaController {
|
|||
|
||||
def author(author: String) = Open { implicit ctx =>
|
||||
WithUserControl { control =>
|
||||
env.api.video byAuthor author map { videos =>
|
||||
env.api.video.byAuthor(author, getInt("page") | 1) map { videos =>
|
||||
Ok(html.video.author(author, videos, control))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@(author: String, videos: List[lila.video.Video], control: lila.video.UserControl)(implicit ctx: Context)
|
||||
@(author: String, videos: Paginator[lila.video.Video], control: lila.video.UserControl)(implicit ctx: Context)
|
||||
|
||||
@layout(
|
||||
title = s"$author • Free Chess Videos",
|
||||
|
@ -7,12 +7,17 @@ control = control) {
|
|||
<div class="content_box_top">
|
||||
<a class="is4 text lichess_title" data-icon="i" href="@routes.Video.index?@control.filter.queryString"></a>
|
||||
<h1 class="lichess_title">
|
||||
@author • @pluralize("video", videos.size) found
|
||||
@author • @pluralize("video", videos.nbResults) found
|
||||
</h1>
|
||||
</div>
|
||||
<div class="list">
|
||||
@videos.map { video =>
|
||||
<div class="list infinitescroll">
|
||||
@videos.currentPageResults.map { video =>
|
||||
@card(video, control)
|
||||
}
|
||||
@videos.nextPage.map { next =>
|
||||
<div class="pager none">
|
||||
<a href="@routes.Video.author(author)?@control.filter.queryString&page=@next">Next</a>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@(video: lila.video.Video, control: lila.video.UserControl)(implicit ctx: Context)
|
||||
|
||||
<a class="card" href="@routes.Video.show(video.id)?@control.filter.queryString">
|
||||
<a class="card paginated_element" href="@routes.Video.show(video.id)?@control.filter.queryString">
|
||||
<span class="img" style="background-image: url(@video.thumbnail)"></span>
|
||||
<span class="info">
|
||||
<span class="title">@video.title</span>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@(videos: List[lila.video.Video], control: lila.video.UserControl)(implicit ctx: Context)
|
||||
@(videos: Paginator[lila.video.Video], control: lila.video.UserControl)(implicit ctx: Context)
|
||||
|
||||
@layout(
|
||||
title = "Free Chess Videos",
|
||||
|
@ -7,19 +7,24 @@ control = control) {
|
|||
<div class="content_box_top">
|
||||
<h1 data-icon="@openingBrace" class="is4 text lichess_title">
|
||||
@if(control.filter.tags.nonEmpty) {
|
||||
@pluralize("video", videos.size) found
|
||||
@pluralize("video", videos.nbResults) found
|
||||
} else {
|
||||
Video library
|
||||
}
|
||||
</h1>
|
||||
</div>
|
||||
<div class="list">
|
||||
@videos.map { video =>
|
||||
@if(control.filter.tags.isEmpty) {
|
||||
<p class="explain">
|
||||
All videos are free for everyone. Click one or many tags on the left to filter.
|
||||
</p>
|
||||
}
|
||||
<div class="list infinitescroll">
|
||||
@videos.currentPageResults.map { video =>
|
||||
@card(video, control)
|
||||
}
|
||||
@if(videos.size < 4) {
|
||||
<div class="not_much nb_@videos.size">
|
||||
@if(videos.isEmpty) {
|
||||
@if(videos.currentPageResults.size < 4) {
|
||||
<div class="not_much nb_@videos.nbResults">
|
||||
@if(videos.currentPageResults.isEmpty) {
|
||||
No videos for these tags!
|
||||
} else {
|
||||
That's all we got for these tags!
|
||||
|
@ -29,5 +34,10 @@ control = control) {
|
|||
<a href="@routes.Video.index" class="button">Clear search</a>
|
||||
</div>
|
||||
}
|
||||
@videos.nextPage.map { next =>
|
||||
<div class="pager none">
|
||||
<a href="@routes.Video.index?@control.filter.queryString&page=@next">Next</a>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
}
|
||||
|
||||
@evenMoreJs = {
|
||||
@jsTag("video.js")
|
||||
@jsTag("vendor/jquery.infinitescroll.min.js")
|
||||
}
|
||||
|
||||
@base.layout(
|
||||
|
|
|
@ -6,6 +6,8 @@ import reactivemongo.core.commands._
|
|||
import scala.concurrent.duration._
|
||||
import spray.caching.{ LruCache, Cache }
|
||||
|
||||
import lila.common.paginator._
|
||||
import lila.db.paginator.BSONAdapter
|
||||
import lila.db.Types.Coll
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
|
@ -26,6 +28,8 @@ private[video] final class VideoApi(
|
|||
|
||||
object video {
|
||||
|
||||
private val maxPerPage = 15
|
||||
|
||||
def find(id: Video.ID): Fu[Option[Video]] =
|
||||
videoColl.find(BSONDocument("_id" -> id)).one[Video]
|
||||
|
||||
|
@ -55,28 +59,39 @@ private[video] final class VideoApi(
|
|||
doc flatMap (_.getAs[String]("_id"))
|
||||
}
|
||||
|
||||
def popular(max: Int): Fu[List[Video]] =
|
||||
videoColl.find(BSONDocument())
|
||||
.sort(BSONDocument("metadata.likes" -> -1))
|
||||
.cursor[Video]
|
||||
.collect[List](max)
|
||||
def popular(page: Int): Fu[Paginator[Video]] = Paginator(
|
||||
adapter = new BSONAdapter[Video](
|
||||
collection = videoColl,
|
||||
selector = BSONDocument(),
|
||||
sort = BSONDocument("metadata.likes" -> -1)
|
||||
),
|
||||
currentPage = page,
|
||||
maxPerPage = maxPerPage)
|
||||
|
||||
def byTags(tags: List[Tag], max: Int): Fu[List[Video]] =
|
||||
if (tags.isEmpty) popular(max)
|
||||
else videoColl.find(BSONDocument(
|
||||
"tags" -> BSONDocument("$all" -> tags)
|
||||
)).sort(BSONDocument(
|
||||
"metadata.likes" -> -1
|
||||
)).cursor[Video]
|
||||
.collect[List]()
|
||||
def byTags(tags: List[Tag], page: Int): Fu[Paginator[Video]] =
|
||||
if (tags.isEmpty) popular(page)
|
||||
else Paginator(
|
||||
adapter = new BSONAdapter[Video](
|
||||
collection = videoColl,
|
||||
selector = BSONDocument(
|
||||
"tags" -> BSONDocument("$all" -> tags)
|
||||
),
|
||||
sort = BSONDocument("metadata.likes" -> -1)
|
||||
),
|
||||
currentPage = page,
|
||||
maxPerPage = maxPerPage)
|
||||
|
||||
def byAuthor(author: String): Fu[List[Video]] =
|
||||
videoColl.find(BSONDocument(
|
||||
"author" -> author
|
||||
)).sort(BSONDocument(
|
||||
"metadata.likes" -> -1
|
||||
)).cursor[Video]
|
||||
.collect[List]()
|
||||
def byAuthor(author: String, page: Int): Fu[Paginator[Video]] =
|
||||
Paginator(
|
||||
adapter = new BSONAdapter[Video](
|
||||
collection = videoColl,
|
||||
selector = BSONDocument(
|
||||
"author" -> author
|
||||
),
|
||||
sort = BSONDocument("metadata.likes" -> -1)
|
||||
),
|
||||
currentPage = page,
|
||||
maxPerPage = maxPerPage)
|
||||
|
||||
def similar(video: Video, max: Int): Fu[List[Video]] =
|
||||
videoColl.find(BSONDocument(
|
||||
|
@ -112,7 +127,9 @@ private[video] final class VideoApi(
|
|||
|
||||
def popularAnd(max: Int, forced: List[Tag]): Fu[List[TagNb]] = popular map { all =>
|
||||
val tags = all take max
|
||||
val missing = forced filterNot tags.contains
|
||||
val missing = forced filterNot { t =>
|
||||
tags exists (_.tag == t)
|
||||
}
|
||||
tags.take(max - missing.size) ::: missing.flatMap { t =>
|
||||
all find (_.tag == t)
|
||||
}
|
||||
|
|
|
@ -143,3 +143,7 @@
|
|||
#video .not_much.nb_0 {
|
||||
margin-top: 200px;
|
||||
}
|
||||
#video .explain {
|
||||
text-align: center;
|
||||
margin: 50px 0 35px 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue