diff --git a/app/assets/css/cfp.less b/app/assets/css/cfp.less index e3fa8f64..2ab79eb3 100644 --- a/app/assets/css/cfp.less +++ b/app/assets/css/cfp.less @@ -922,6 +922,14 @@ div.chat_list { background-color: #f6f6f6; } +div.chat_new_comments_indicator { + text-align: center; + background-color: #f6f6f6; + border-top: 1px solid red; + color: red; + border-bottom: 1px solid red; +} + div.chat_people { overflow: hidden; clear: both; diff --git a/app/controllers/CFPAdmin.scala b/app/controllers/CFPAdmin.scala index 13e87f4f..7fd3957f 100644 --- a/app/controllers/CFPAdmin.scala +++ b/app/controllers/CFPAdmin.scala @@ -91,7 +91,8 @@ object CFPAdmin extends SecureCFPController { val proposalsByAuths = allProposalByProposal(proposal) val userWatchPref = ProposalUserWatchPreference.proposalUserWatchPreference(proposal.id, userId) val maybeDelayedReviewReason = Review.proposalDelayedReviewReason(userId, proposal.id) - views.html.CFPAdmin.showProposal(proposal, proposalsByAuths, speakerDiscussion, internalDiscussion, msgToSpeakerForm, msgInternalForm, voteForm, maybeMyVote, maybeMyPreviousVote, userId, userWatchPref, maybeDelayedReviewReason) + val proposalLastVisit = Proposal.userProposalLastVisits(userId).get(proposal.id) + views.html.CFPAdmin.showProposal(proposal, proposalsByAuths, speakerDiscussion, internalDiscussion, msgToSpeakerForm, msgInternalForm, voteForm, maybeMyVote, maybeMyPreviousVote, userId, userWatchPref, maybeDelayedReviewReason, proposalLastVisit) } def openForReview(proposalId: String) = SecuredAction(IsMemberOf("cfp")) { diff --git a/app/views/CFPAdmin/showProposal.scala.html b/app/views/CFPAdmin/showProposal.scala.html index 075e8cd3..e4400210 100644 --- a/app/views/CFPAdmin/showProposal.scala.html +++ b/app/views/CFPAdmin/showProposal.scala.html @@ -1,4 +1,4 @@ -@(proposal: Proposal, proposalsByAuths: Map[String, Map[String, Proposal]], speakerComments: List[Comment], internalComments: List[Comment], msgToSpeakerForm: Form[String], msgInternalForm: Form[String], voteForm: Form[Int], maybeMyVote: Option[Review], maybeMyPreviousVote: Option[Review], currentUser: String, userWatchPref: ProposalUserWatchPreference, maybeVoteDelayedReason: Option[String])(implicit flash: Flash, lang: Lang, req: RequestHeader) +@(proposal: Proposal, proposalsByAuths: Map[String, Map[String, Proposal]], speakerComments: List[Comment], internalComments: List[Comment], msgToSpeakerForm: Form[String], msgInternalForm: Form[String], voteForm: Form[Int], maybeMyVote: Option[Review], maybeMyPreviousVote: Option[Review], currentUser: String, userWatchPref: ProposalUserWatchPreference, maybeVoteDelayedReason: Option[String], proposalLastVisit: Option[org.joda.time.DateTime])(implicit flash: Flash, lang: Lang, req: RequestHeader) @main("[CFP] " + proposal.id + "/" + proposal.title) {
@@ -258,7 +258,7 @@

@Messages("admin.sp.commi }

- @tags.renderComments(speakerComments) + @tags.renderComments(speakerComments, proposalLastVisit)
@@ -306,7 +306,7 @@

@Messages("admin.sp.internal")

}
- @tags.renderComments(internalComments) + @tags.renderComments(internalComments, proposalLastVisit)
diff --git a/app/views/CallForPaper/showCommentForProposal.scala.html b/app/views/CallForPaper/showCommentForProposal.scala.html index ef0c93cf..7034564e 100644 --- a/app/views/CallForPaper/showCommentForProposal.scala.html +++ b/app/views/CallForPaper/showCommentForProposal.scala.html @@ -52,7 +52,7 @@

@Messages("comment.proposal")

- @tags.renderComments(comments) + @tags.renderComments(comments, None)
diff --git a/app/views/tags/renderComments.scala.html b/app/views/tags/renderComments.scala.html index eaceab7c..0f369653 100644 --- a/app/views/tags/renderComments.scala.html +++ b/app/views/tags/renderComments.scala.html @@ -1,35 +1,42 @@ -@(comments: List[models.Comment]) - @comments.map { c => - @models.Speaker.findByUUID(c.uuidAuthor).map { speaker => - @models.Webuser.findByUUID(c.uuidAuthor).map { webuser => -
-
-
- @if(speaker.avatarUrl.isEmpty) { - @webuser.cleanName - } else { - @webuser.cleanName - } -
-
-
- @webuser.cleanName - @Messages("tags.renderComment.postedBy", - library.FormatDate.jodaDateFormat(c.eventDate.get, play.api.i18n.Lang.defaultLang), - library.FormatDate.jodaTimeFormat(c.eventDate.get, play.api.i18n.Lang.defaultLang)) -
- @defining(c.msg.replaceAll("script", ".script").replaceAll("\n", "
")) { message: String => -

@Html(message)

- @models.Proposal.ProposalIDRegExp.findAllIn(message).map { proposalIdRef => -

@tags.linkToProposal(proposalIdRef)

- } - @models.Proposal.HttpUrl.findAllIn(message).map { test => -

@test

- } - } -
-
-
- } +@(comments: List[models.Comment], maybeProposalLastVisit: Option[org.joda.time.DateTime]) + @defining(comments.reverse.find{ comment => maybeProposalLastVisit.map { proposalLastVisit => proposalLastVisit.isBefore(comment.eventDate.get) }.getOrElse(true) }){ maybeFirstUnwatchedComment: Option[Comment] => + @comments.zipWithIndex.map{ case (c, index) => + @models.Speaker.findByUUID(c.uuidAuthor).map { speaker => + @models.Webuser.findByUUID(c.uuidAuthor).map { webuser => +
+
+
+ @if(speaker.avatarUrl.isEmpty) { + @webuser.cleanName + } else { + @webuser.cleanName + } +
+
+
+ @webuser.cleanName + @Messages("tags.renderComment.postedBy", + library.FormatDate.jodaDateFormat(c.eventDate.get, play.api.i18n.Lang.defaultLang), + library.FormatDate.jodaTimeFormat(c.eventDate.get, play.api.i18n.Lang.defaultLang)) +
+ @defining(c.msg.replaceAll("script", ".script").replaceAll("\n", "
")) { message: String => +

@Html(message)

+ @models.Proposal.ProposalIDRegExp.findAllIn(message).map { proposalIdRef => +

@tags.linkToProposal(proposalIdRef)

+ } + @models.Proposal.HttpUrl.findAllIn(message).map { test => +

@test

+ } + } +
+
+
+ @if(maybeFirstUnwatchedComment.map(c == _).getOrElse(false)) { +
+ @Messages("tags.renderComment.newMessages") +
+ } } + } + } } diff --git a/conf/messages b/conf/messages index 36497803..dc55f3b0 100644 --- a/conf/messages +++ b/conf/messages @@ -444,6 +444,7 @@ admin.draft.warning3=Current proposal state : newProposal.maxLength=Max size is 1200 characters (including Markdown characters, if you want to use it) preview.txt=Preview Conference guide (sample page) tags.renderComment.postedBy=Posted on {0} at {1} +tags.renderComment.newMessages=New messages admin.btn.sponsor=VIP view on proposals leaderboard.compute=Computing stats diff --git a/conf/messages.fr b/conf/messages.fr index 51fb88f7..e7cb1d08 100644 --- a/conf/messages.fr +++ b/conf/messages.fr @@ -383,6 +383,7 @@ admin.draft.warning3=Etat actuel de cette proposition : newProposal.maxLength=Maximum 1200 caractères. Possibilité d''utiliser Markdown preview.txt=Aperçu de votre présentation dans le programme papier tags.renderComment.postedBy=Posté le {0} à {1} +tags.renderComment.newMessages=Nouveaux messages admin.btn.sponsor=Voir comme un sponsor leaderboard.compute=Calcul des stats en cours...