basic video list
parent
c4a2c1f098
commit
077dfc9de0
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 = "{"
|
||||
}
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
||||
}
|
|
@ -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>
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
Binary file not shown.
|
@ -100,4 +100,5 @@
|
|||
<glyph unicode="^" 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="[" 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="_" 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="{" 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.
Binary file not shown.
|
@ -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() {
|
|
@ -317,3 +317,6 @@
|
|||
.icon-keypad:before {
|
||||
content: "_";
|
||||
}
|
||||
.icon-youtube-play:before {
|
||||
content: "{";
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue