Implement inbox with infinite scroll
parent
43254bde81
commit
a226e85f0f
|
@ -0,0 +1,25 @@
|
|||
package controllers
|
||||
|
||||
import lila._
|
||||
import views._
|
||||
import http.Context
|
||||
|
||||
import play.api._
|
||||
import play.api.mvc._
|
||||
import play.api.mvc.Results._
|
||||
import scalaz.effects._
|
||||
|
||||
object Message extends LilaController {
|
||||
|
||||
def api = env.message.api
|
||||
def forms = env.message.forms
|
||||
|
||||
def inbox(page: Int) = Auth { implicit ctx ⇒
|
||||
implicit me ⇒
|
||||
Ok(html.message.inbox(api.inbox(me, page)))
|
||||
}
|
||||
def thread(id: String) = TODO
|
||||
def form = TODO
|
||||
def create = TODO
|
||||
def delete(id: String) = TODO
|
||||
}
|
|
@ -35,6 +35,11 @@ final class CoreEnv private (application: Application, val settings: Settings) {
|
|||
mongodb = mongodb.apply _,
|
||||
userRepo = user.userRepo)
|
||||
|
||||
lazy val message = new lila.message.MessageEnv(
|
||||
settings = settings,
|
||||
mongodb = mongodb.apply _,
|
||||
userRepo = user.userRepo)
|
||||
|
||||
lazy val lobby = new lila.lobby.LobbyEnv(
|
||||
app = app,
|
||||
settings = settings,
|
||||
|
|
|
@ -8,6 +8,15 @@ import com.github.ornicar.paginator._
|
|||
import scala.math.ceil
|
||||
|
||||
final class Api(
|
||||
threadRepo: ThreadRepo,
|
||||
maxPerPage: Int) {
|
||||
threadRepo: ThreadRepo,
|
||||
maxPerPage: Int) {
|
||||
|
||||
def inbox(user: User, page: Int): Paginator[Thread] = Paginator(
|
||||
SalatAdapter(
|
||||
dao = threadRepo,
|
||||
query = threadRepo visibleByUserQuery user,
|
||||
sort = threadRepo.sortQuery),
|
||||
currentPage = page,
|
||||
maxPerPage = maxPerPage
|
||||
) | inbox(user, 1)
|
||||
}
|
||||
|
|
|
@ -27,6 +27,10 @@ case class Thread(
|
|||
def nbUnreadBy(user: User) = isCreator(user).fold(
|
||||
posts count { post ⇒ post.isByInvited && post.isUnRead },
|
||||
posts count { post ⇒ post.isByCreator && post.isUnRead })
|
||||
|
||||
def userIds = List(creatorId, invitedId)
|
||||
|
||||
def otherUserId(user: User) = isCreator(user).fold(creatorId, invitedId)
|
||||
}
|
||||
|
||||
object Topic {
|
||||
|
|
|
@ -14,9 +14,9 @@ final class SiteMenu(trans: I18nKeys) {
|
|||
val game = new Elem(routes.Game.realtime, trans.games)
|
||||
val user = new Elem(routes.User.list(page = 1), trans.people)
|
||||
val forum = new Elem(routes.ForumCateg.index, trans.forum)
|
||||
val inbox = new Elem(routes.Lobby.home, trans.inbox)
|
||||
val message = new Elem(routes.Message.inbox(page = 1), trans.inbox)
|
||||
|
||||
val all = List(play, game, user, forum)
|
||||
val all = List(play, game, user, message, forum)
|
||||
}
|
||||
|
||||
object SiteMenu {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
@menu
|
||||
</div>
|
||||
<div class="all_games infinitescroll">
|
||||
<div class="pager"><a href="@next">Next</a></div>
|
||||
<div class="pager none"><a href="@next">Next</a></div>
|
||||
@game.widgets(paginator.currentPageResults)
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
@(threads: Paginator[lila.message.Thread])(implicit ctx: Context, me: User)
|
||||
|
||||
@message.layout(
|
||||
title = trans.inbox.str()) {
|
||||
<div class="head">
|
||||
<h1>@trans.inbox()</h1>
|
||||
</div>
|
||||
<table>
|
||||
@if(threads.nbResults > 0) {
|
||||
<tbody class="infinitescroll">
|
||||
@if(threads.hasToPaginate) {
|
||||
<tr><th class="pager none">
|
||||
<a href="@routes.Message.inbox(threads.nextPage | 1)">Next</a>
|
||||
</th></tr>
|
||||
}
|
||||
@threads.currentPageResults.map { thread =>
|
||||
<tr class="paginated_element @thread.isUnReadBy(me).fold(" new", "")">
|
||||
<td class="subject">
|
||||
<a href="@routes.Message.thread(thread.id)#bottom">@thread.name</a>
|
||||
</td>
|
||||
<td class="author">
|
||||
@userIdLink(thread.otherUserId(me).toString.some)
|
||||
</td>
|
||||
<td class="date">
|
||||
@showDate(thread.updatedAt)
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
} else {
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<br />
|
||||
No message!
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
@(title: String)(body: Html)(implicit ctx: Context)
|
||||
|
||||
@moreCss = {
|
||||
@cssTag("message.css")
|
||||
}
|
||||
|
||||
@moreJs = {
|
||||
@jsTag("vendor/jquery.infinitescroll.min.js")
|
||||
}
|
||||
|
||||
@base.layout(
|
||||
title = title,
|
||||
moreCss = moreCss,
|
||||
moreJs = moreJs,
|
||||
active = siteMenu.message.some) {
|
||||
<div id="lichess_message" class="content_box">
|
||||
@body
|
||||
</div>
|
||||
}
|
|
@ -21,7 +21,7 @@ goodies = goodies.some) {
|
|||
<input id="search_user_input" class="search_user autocomplete" data-provider="@routes.User.autocomplete" />
|
||||
</form>
|
||||
<div class="infinitescroll">
|
||||
<div class="pager"><a href="@routes.User.list(paginator.nextPage | 1)">Next</a></div>
|
||||
<div class="pager none"><a href="@routes.User.list(paginator.nextPage | 1)">Next</a></div>
|
||||
<ol start="@{ 1+(paginator.currentPage-1)*paginator.maxPerPage }" class="users paginated_element">
|
||||
@paginator.currentPageResults.map { u => <li>@userLink(u, None, true)</li> }
|
||||
</ol>
|
||||
|
|
|
@ -98,6 +98,13 @@ GET /forum/:categSlug/:slug controllers.ForumTopic.show(categSlug: St
|
|||
POST /forum/:categSlug/:slug/new controllers.ForumPost.create(categSlug: String, slug: String, page: Int ?= 1)
|
||||
POST /forum/delete/post/:id controllers.ForumPost.delete(id: String)
|
||||
|
||||
# Message
|
||||
GET /inbox controllers.Message.inbox(page: Int ?= 1)
|
||||
GET /inbox/new controllers.Message.form
|
||||
POST /inbox/new controllers.Message.create
|
||||
GET /inbox/$id<[\w]{8}> controllers.Message.thread(id: String)
|
||||
POST /inbox/$id<[\w]{8}>/delete controllers.Message.delete(id: String)
|
||||
|
||||
# Monitor
|
||||
GET /monitor controllers.Monitor.index
|
||||
GET /monitor/stream controllers.Monitor.stream
|
||||
|
|
|
@ -118,11 +118,11 @@ $(function() {
|
|||
});
|
||||
}
|
||||
|
||||
$('div.infinitescroll').each(function() {
|
||||
$('.infinitescroll').each(function() {
|
||||
$(this).infinitescroll({
|
||||
navSelector: "div.pager",
|
||||
nextSelector: "div.pager a:last",
|
||||
itemSelector: "div.infinitescroll .paginated_element",
|
||||
navSelector: ".pager",
|
||||
nextSelector: ".pager a:last",
|
||||
itemSelector: ".infinitescroll .paginated_element",
|
||||
loadingText: "",
|
||||
donetext: "---"
|
||||
}, function() {
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
#lichess_message h1 {
|
||||
font-size: 1.8em;
|
||||
color: #666;
|
||||
font-weight: normal;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
#lichess_message {
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
div.sidebar {
|
||||
margin-top: 30px;
|
||||
}
|
||||
div.sidebar a {
|
||||
display: block;
|
||||
font-size: 1.2em;
|
||||
padding: 1em 0 1em 1em;
|
||||
}
|
||||
|
||||
#lichess_message table {
|
||||
width: 100%;
|
||||
}
|
||||
#lichess_message tr {
|
||||
border-top: 1px solid #e4e4e4;
|
||||
}
|
||||
#lichess_message tr.odd {
|
||||
background: #f4f4f4;
|
||||
}
|
||||
|
||||
#lichess_message td.subject a {
|
||||
display: block;
|
||||
padding: 1em;
|
||||
font-size: 120%;
|
||||
}
|
||||
#lichess_message tr.new td.subject a {
|
||||
color: #0090b0;
|
||||
font-weight: bold;
|
||||
}
|
||||
#lichess_message td.author, #lichess_message td.date {
|
||||
white-space: nowrap;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
#lichess_message div.thread_actions {
|
||||
margin-top: 0.4em;
|
||||
float: right;
|
||||
}
|
||||
|
||||
#lichess_message div.thread_message {
|
||||
font-size: 1.2em;
|
||||
margin-top: 2em;
|
||||
border-top: 1px solid #d4d4d4;
|
||||
padding-top: 2em;
|
||||
}
|
||||
#lichess_message div.thread_message span.infos {
|
||||
margin-bottom: 1em;
|
||||
display: block;
|
||||
}
|
||||
#lichess_message div.answer {
|
||||
margin-top: 3em;
|
||||
}
|
||||
|
||||
#lichess_message div.form {
|
||||
font-size: 1.1em;
|
||||
border-top: 1px solid #d4d4d4;
|
||||
padding-top: 2em;
|
||||
}
|
||||
#lichess_message div.form div.actions,
|
||||
#lichess_message div.answer div.actions {
|
||||
padding: 0.5em 0;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
#lichess_message div.form .actions a,
|
||||
#lichess_message div.answer div.actions a {
|
||||
margin-left: 1em;
|
||||
}
|
||||
#lichess_message label {
|
||||
float: left;
|
||||
width: 60px;
|
||||
text-align: right;
|
||||
margin-right: 10px;
|
||||
vertical-align: middle;
|
||||
margin-top: 3px;
|
||||
}
|
||||
#lichess_message .field_to input,
|
||||
#lichess_message .field_subject input {
|
||||
width: 450px;
|
||||
border: 1px solid #D4D4D4;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
#lichess_message .field_to,
|
||||
#lichess_message .field_subject {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
#lichess_message form textarea {
|
||||
width: 547px;
|
||||
height: 150px;
|
||||
padding: 10px;
|
||||
border: 1px solid #D4D4D4;
|
||||
}
|
||||
#lichess_message ul {
|
||||
color: red;
|
||||
margin-left: 60px;
|
||||
}
|
Loading…
Reference in New Issue