basic video list

pull/382/head
Thibault Duplessis 2015-03-22 13:38:01 +01:00
parent c4a2c1f098
commit 077dfc9de0
19 changed files with 138 additions and 7 deletions

View File

@ -0,0 +1,22 @@
package controllers
import play.api.data._, Forms._
import play.api.mvc._
import play.twirl.api.Html
import lila.api.Context
import lila.app._
import lila.common.HTTPRequest
import lila.video.{ View, Video => VideoModel }
import views._
object Video extends LilaController {
private def env = Env.video
def index = Open { implicit ctx =>
env.api.video.popular(9) map { videos =>
html.video.index(videos)
}
}
}

View File

@ -67,4 +67,6 @@ object Environment
def reportNbUnprocessed(implicit ctx: lila.api.Context): Int =
isGranted(_.SeeReport) ?? lila.report.Env.current.api.nbUnprocessed.await
val openingBrace = "{"
}

View File

@ -0,0 +1,8 @@
@(video: lila.video.Video)(implicit ctx: Context)
<a class="card" href="#">
<span class="img" style="background-image: url(@video.thumbnail)"></span>
<span class="info">
<span class="title">@video.title</span>
</span>
</a>

View File

@ -0,0 +1,19 @@
@(videos: List[lila.video.Video])(implicit ctx: Context)
@side = {
}
@layout(
title = "Video library",
side = side.some) {
<div class="content_box_top">
<h1 data-icon="@openingBrace" class="is4 text lichess_title">Video library</h1>
</div>
<div class="list">
@videos.map { video =>
@card(video)
}
</div>
</table>
}

View File

@ -0,0 +1,21 @@
@(title: String, side: Option[Html] = None)(body: Html)(implicit ctx: Context)
@sideSection = {
<div class="side">
@side
</div>
}
@evenMoreJs = {
@jsTag("video.js")
}
@base.layout(
title = title,
moreCss = cssTag("video.css"),
moreJs = evenMoreJs,
side = sideSection.some) {
<div id="video" class="content_box no_padding">
@body
</div>
}

View File

@ -181,6 +181,9 @@ GET /setup/filter controllers.Setup.filterForm
POST /setup/filter controllers.Setup.filter
GET /setup/validate-fen controllers.Setup.validateFen
# Video
GET /video controllers.Video.index
# I18n
GET /translation/contribute controllers.I18n.contribute
GET /translation/form/:lang controllers.I18n.translationForm(lang: String)

View File

@ -16,6 +16,8 @@ case class Video(
updatedAt: DateTime) {
def id = _id
def thumbnail = s"http://img.youtube.com/vi/$id/0.jpg"
}
object Target {

View File

@ -50,6 +50,12 @@ private[video] final class VideoApi(
).cursor[BSONDocument].collect[List]() map { doc =>
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)
}
object view {

View File

@ -22,8 +22,8 @@ private[video] final class Youtube(
entries.map { entry =>
api.video.setMetadata(entry.id, Metadata(
views = ~parseIntOption(entry.statistics.viewCount),
likes = ~parseIntOption(entry.statistics.likeCount),
dislikes = ~parseIntOption(entry.statistics.dislikeCount))
likes = ~parseIntOption(entry.statistics.likeCount) -
~parseIntOption(entry.statistics.dislikeCount))
).recover {
case e: Exception => logerr(s"[video youtube] ${e.getMessage}")
}
@ -49,12 +49,11 @@ private[video] final class Youtube(
object Youtube {
def empty = Metadata(0, 0, 0)
def empty = Metadata(0, 0)
case class Metadata(
views: Int,
likes: Int,
dislikes: Int)
likes: Int)
private[video] case class Entry(
id: String,

Binary file not shown.

View File

@ -100,4 +100,5 @@
<glyph unicode="&#94;" d="M256 480c-141 0-256-115-256-256 0 0 0-96 0-128 0-32 32-64 64-64 32 0 352 0 384 0 32 0 64 32 64 64 0 32 0 128 0 128 0 141-114 256-256 256z m48-384l-96 0c-9 0-16 7-16 16 0 9 7 16 16 16l96 0c9 0 16-7 16-16 0-9-7-16-16-16z m144 64c0-16-16-32-32-32-16 0-64 0-64 0 0 16-16 32-32 32-16 0-112 0-128 0-16 0-32-16-32-32 0 0-48 0-64 0-16 0-32 16-32 32 0 16 0 180 0 180 39 64 110 108 192 108 82 0 153-44 192-108 0 0 0-164 0-180z m-64 192c-16 0-240 0-256 0-16 0-32-16-32-32 0-16 0-48 0-64 0-16 16-32 32-32 16 0 240 0 256 0 16 0 32 16 32 32 0 16 0 48 0 64 0 16-16 32-32 32z m0-64l-32-32-64 0-32 32-32-32-64 0-32 32 0 32 32 0 32-32 32 32 64 0 32-32 32 32 32 0z"/>
<glyph unicode="&#91;" d="M484 396c0-19-16-35-36-35l-384 0c-20 0-36 16-36 35 0 19 16 35 36 35l384 0c20 0 36-16 36-35z m0-140c0-19-16-35-36-35l-384 0c-20 0-36 16-36 35 0 19 16 35 36 35l384 0c20 0 36-16 36-35z m0-140c0-19-16-35-36-35l-384 0c-20 0-36 16-36 35 0 19 16 35 36 35l384 0c20 0 36-16 36-35z"/>
<glyph unicode="&#95;" d="M160 426c0-6-4-10-10-10l-76 0c-6 0-10 4-10 10l0 76c0 6 4 10 10 10l76 0c6 0 10-4 10-10z m147 0c0-6-4-10-10-10l-76 0c-6 0-10 4-10 10l0 76c0 6 4 10 10 10l76 0c6 0 10-4 10-10z m141 0c0-6-4-10-10-10l-76 0c-6 0-10 4-10 10l0 76c0 6 4 10 10 10l76 0c6 0 10-4 10-10z m-288-128c0-6-4-10-10-10l-76 0c-6 0-10 4-10 10l0 76c0 6 4 10 10 10l76 0c6 0 10-4 10-10z m147 0c0-6-4-10-10-10l-76 0c-6 0-10 4-10 10l0 76c0 6 4 10 10 10l76 0c6 0 10-4 10-10z m141 0c0-6-4-10-10-10l-76 0c-6 0-10 4-10 10l0 76c0 6 4 10 10 10l76 0c6 0 10-4 10-10z m-288-128c0-6-4-10-10-10l-76 0c-6 0-10 4-10 10l0 76c0 6 4 10 10 10l76 0c6 0 10-4 10-10z m147 0c0-6-4-10-10-10l-76 0c-6 0-10 4-10 10l0 76c0 6 4 10 10 10l76 0c6 0 10-4 10-10z m0-128c0-6-4-10-10-10l-76 0c-6 0-10 4-10 10l0 76c0 6 4 10 10 10l76 0c6 0 10-4 10-10z m141 128c0-6-4-10-10-10l-76 0c-6 0-10 4-10 10l0 76c0 6 4 10 10 10l76 0c6 0 10-4 10-10z"/>
<glyph unicode="&#123;" d="M366 256c0 7-3 12-9 15l-146 92c-6 4-12 4-19 0-6-3-9-8-9-16l0-182c0-8 3-13 9-16 3-2 6-3 9-3 4 0 7 1 10 3l146 92c6 3 9 8 9 15z m146 0c0-18 0-33 0-43 0-10-1-23-3-39-1-16-3-30-6-42-3-14-10-26-20-35-10-10-22-15-35-17-43-4-106-7-192-7-86 0-149 3-192 7-13 2-25 7-35 17-10 9-17 21-20 35-3 12-5 26-6 42-2 16-3 29-3 39 0 10 0 25 0 43 0 18 0 33 0 43 0 10 1 23 3 39 1 16 3 30 6 42 3 14 10 26 20 35 10 10 22 15 35 17 43 4 106 7 192 7 86 0 149-3 192-7 13-2 25-7 35-17 10-9 17-21 20-35 3-12 5-26 6-42 2-16 3-29 3-39 0-10 0-25 0-43z"/>
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

View File

@ -417,6 +417,10 @@ h2{font-size:18px;padding:0 0 21px 5px;margin:45px 0 0 0;text-transform:uppercas
<div class="icon icon-keypad"></div>
<input type="text" readonly="readonly" value="keypad">
</li>
<li>
<div class="icon icon-youtube-play"></div>
<input type="text" readonly="readonly" value="youtube-play">
</li>
</ul>
<h2>Character mapping</h2>
<ul class="glyphs character-mapping">
@ -792,6 +796,10 @@ h2{font-size:18px;padding:0 0 21px 5px;margin:45px 0 0 0;text-transform:uppercas
<div data-icon="_" class="icon"></div>
<input type="text" readonly="readonly" value="_">
</li>
<li>
<div data-icon="{" class="icon"></div>
<input type="text" readonly="readonly" value="{">
</li>
</ul>
</div><script type="text/javascript">
(function() {

View File

@ -317,3 +317,6 @@
.icon-keypad:before {
content: "_";
}
.icon-youtube-play:before {
content: "{";
}

View File

View File

@ -58,8 +58,8 @@ time {
}
@font-face {
font-family: "lichess";
src: url("../font33/fonts/lichess.eot");
src: url("../font33/fonts/lichess.eot?#iefix") format("embedded-opentype"), url("../font33/fonts/lichess.woff") format("woff"), url("../font33/fonts/lichess.ttf") format("truetype"), url("../font33/fonts/lichess.svg#lichess") format("svg");
src: url("../font34/fonts/lichess.eot");
src: url("../font34/fonts/lichess.eot?#iefix") format("embedded-opentype"), url("../font34/fonts/lichess.woff") format("woff"), url("../font34/fonts/lichess.ttf") format("truetype"), url("../font34/fonts/lichess.svg#lichess") format("svg");
font-weight: normal;
font-style: normal;
}

View File

@ -0,0 +1,37 @@
#video .content_box_top {
padding-bottom: 10px;
}
#video .list {
overflow: hidden;
padding: 8px;
}
#video .card {
float: left;
width: 238px;
margin: 10px;
text-decoration: none;
overflow: hidden;
}
#video .card:hover {
box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.16), 0px 2px 10px 0px rgba(0, 0, 0, 0.12);
}
#video .card .img {
width: 100%;
height: 180px;
display: block;
background-size: contain;
}
#video .card .info {
display: block;
padding: 5px 5px;
background-color: #f0f0f0;
background-image: linear-gradient(to bottom, #fafafa 0%, #f0f0f0 100%);
text-shadow: 0px 1px 0px #FFF;
border: 1px solid #ccc;
border-top: 0;
}
#video .card .title {
font-weight: bold;
line-height: 30px;
white-space: nowrap;
}