From 0bb0db7784ea2ea6d19e7b526103d0e04f386c08 Mon Sep 17 00:00:00 2001 From: Thibault Duplessis Date: Sun, 22 Mar 2015 19:15:35 +0100 Subject: [PATCH] paginate videos --- app/controllers/Video.scala | 4 +- app/views/video/author.scala.html | 13 ++++-- app/views/video/card.scala.html | 2 +- app/views/video/index.scala.html | 24 +++++++---- app/views/video/layout.scala.html | 2 +- modules/video/src/main/VideoApi.scala | 59 +++++++++++++++++---------- public/javascripts/video.js | 0 public/stylesheets/video.css | 4 ++ 8 files changed, 72 insertions(+), 36 deletions(-) delete mode 100644 public/javascripts/video.js diff --git a/app/controllers/Video.scala b/app/controllers/Video.scala index dad3e0175a..ffa5a7a3e0 100644 --- a/app/controllers/Video.scala +++ b/app/controllers/Video.scala @@ -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)) } } diff --git a/app/views/video/author.scala.html b/app/views/video/author.scala.html index b2b3c86750..74548cfbe5 100644 --- a/app/views/video/author.scala.html +++ b/app/views/video/author.scala.html @@ -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) {

- @author • @pluralize("video", videos.size) found + @author • @pluralize("video", videos.nbResults) found

-
- @videos.map { video => +
+ @videos.currentPageResults.map { video => @card(video, control) } + @videos.nextPage.map { next => +
+ Next +
+ }
} diff --git a/app/views/video/card.scala.html b/app/views/video/card.scala.html index e7cb134a64..4719479012 100644 --- a/app/views/video/card.scala.html +++ b/app/views/video/card.scala.html @@ -1,6 +1,6 @@ @(video: lila.video.Video, control: lila.video.UserControl)(implicit ctx: Context) - + @video.title diff --git a/app/views/video/index.scala.html b/app/views/video/index.scala.html index 15ed507750..fd8a765729 100644 --- a/app/views/video/index.scala.html +++ b/app/views/video/index.scala.html @@ -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) {

@if(control.filter.tags.nonEmpty) { - @pluralize("video", videos.size) found + @pluralize("video", videos.nbResults) found } else { Video library }

-
- @videos.map { video => +@if(control.filter.tags.isEmpty) { +

+ All videos are free for everyone. Click one or many tags on the left to filter. +

+} +
+ @videos.currentPageResults.map { video => @card(video, control) } - @if(videos.size < 4) { - } diff --git a/app/views/video/layout.scala.html b/app/views/video/layout.scala.html index 22ca586883..20aa614544 100644 --- a/app/views/video/layout.scala.html +++ b/app/views/video/layout.scala.html @@ -15,7 +15,7 @@ } @evenMoreJs = { -@jsTag("video.js") +@jsTag("vendor/jquery.infinitescroll.min.js") } @base.layout( diff --git a/modules/video/src/main/VideoApi.scala b/modules/video/src/main/VideoApi.scala index 45287c9b93..23b257e414 100644 --- a/modules/video/src/main/VideoApi.scala +++ b/modules/video/src/main/VideoApi.scala @@ -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) } diff --git a/public/javascripts/video.js b/public/javascripts/video.js deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/public/stylesheets/video.css b/public/stylesheets/video.css index 3da2d18e41..a561869ea4 100644 --- a/public/stylesheets/video.css +++ b/public/stylesheets/video.css @@ -143,3 +143,7 @@ #video .not_much.nb_0 { margin-top: 200px; } +#video .explain { + text-align: center; + margin: 50px 0 35px 0; +}