contrib/nitrpg: display events in home and player page
authorAlexandre Terrasa <alexandre@moz-code.org>
Sat, 7 Feb 2015 00:06:43 +0000 (01:06 +0100)
committerAlexandre Terrasa <alexandre@moz-code.org>
Wed, 11 Feb 2015 01:10:04 +0000 (02:10 +0100)
Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

contrib/nitrpg/src/templates/panels.nit
contrib/nitrpg/src/templates/templates_events.nit [new file with mode: 0644]
contrib/nitrpg/src/web.nit

index 71898f6..29ee7a7 100644 (file)
@@ -17,7 +17,7 @@
 # Panels templates for `nitpg`.
 module panels
 
-import templates_base
+import templates_events
 
 # A panel can be displayed in a html page.
 #
@@ -307,3 +307,56 @@ class PlayerReviewsPanel
                end
        end
 end
+
+# A `Panel` that displays a pagined list of events stored in the `entity`.
+#
+# This way the panel can be used to view events stored under `Game`, `Player`...
+class EventListPanel
+       super Panel
+
+       # Entity to load the events from.
+       var entity: GameEntity
+
+       # Number of events to display.
+       var limit: Int
+
+       # From where to start?
+       var from: Int
+
+       redef fun render_title do
+               add "<span class=\"glyphicon glyphicon-flash\"></span>&nbsp;&nbsp;"
+               add "Last events"
+       end
+
+       redef fun render_body do
+               var events = entity.load_events
+               if events.is_empty then
+                       add "<em>No event yet...</em>"
+                       return
+               end
+               # check input
+               if limit < 0 then limit = 10
+               if from < 0 then from = 0
+               # display events
+               for i in [from .. from + limit] do
+                       if i >= events.length then break
+                       add events[i].tpl_event.media_item
+               end
+               # pagination
+               if limit > events.length then return
+               add "<hr>"
+               add """<div class="btn-group" role="group">"""
+               if from > 0 then
+                       add """<a class="btn btn-default" role="button"
+                                       href="?pfrom={{{from - limit}}}&plimit={{{limit}}}">
+                                    <span class=\"glyphicon glyphicon-chevron-left\"></span></a>"""
+               end
+               if from + limit < events.length then
+                       add """
+                         <a class="btn btn-default" role="button"
+                                  href="?pfrom={{{from + limit}}}&plimit={{{limit}}}">
+                                   <span class=\"glyphicon glyphicon-chevron-right\"></span></a>"""
+               end
+               add "</div>"
+       end
+end
diff --git a/contrib/nitrpg/src/templates/templates_events.nit b/contrib/nitrpg/src/templates/templates_events.nit
new file mode 100644 (file)
index 0000000..20f7b58
--- /dev/null
@@ -0,0 +1,111 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Copyright 2014-2015 Alexandre Terrasa <alexandre@moz-code.org>
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Templates to display `GameEvent` kinds.
+module templates_events
+
+import events
+import templates_base
+
+redef class GameEvent
+       # See `TplEvent`
+       fun tpl_event: TplEvent do
+               if kind == "pull_open" then
+                       return new TplPullOpened(self)
+               else if kind == "pull_merged" then
+                       return new TplPullMerged(self)
+               else if kind == "pull_review" then
+                       return new TplPullReview(self)
+               end
+               abort
+       end
+end
+
+# A TplEvent factorizes HTML rendering methods for `GameEvent`.
+class TplEvent
+
+       # Event to display.
+       var event: GameEvent
+
+       # Title to display.
+       var title: String is lazy do return "raw event"
+
+       # Load Player from event data.
+       var player: nullable Player is lazy do
+               return event.game.load_player(event.data["player"].to_s)
+       end
+
+       # Load reward from event data.
+       var reward: Int is lazy do return event.data["reward"].as(Int)
+
+       # Load `github_event` data key as a PullRequestEvent.
+       var pull_event: PullRequestEvent is lazy do
+               var obj = event.data["github_event"].as(JsonObject)
+               return new PullRequestEvent.from_json(event.game.api, obj)
+       end
+
+       # Load `github_event` data key as a IssueCommentEvent.
+       var issue_comment_event: IssueCommentEvent is lazy do
+               var obj = event.data["github_event"].as(JsonObject)
+               return new IssueCommentEvent.from_json(event.game.api, obj)
+       end
+
+       # Display a media item for a reward event.
+       fun media_item: String do
+               return """<div class="media">
+                       <a class="media-left" href="{{{player.url}}}">
+                                <span class="badge progress-bar-success"
+                                 style=\"position: absolute\">+{{{reward}}}</span>
+                                <img class=\"img-circle\" style="width:50px"
+                                  src="{{{player.user.avatar_url}}}" alt="{{{player.name}}}">
+                               </a>
+                               <div class="media-body">
+                                <h4 class="media-heading">{{{title}}}</h4>
+                                <span class="text-muted">at {{{event.time}}}</span>
+                               </div>
+                          </div>"""
+       end
+end
+
+# Event: pull_open
+class TplPullOpened
+       super TplEvent
+
+       redef var title is lazy do
+               var pull = pull_event.pull
+               return "{player.link} pushed {pull.link}"
+       end
+end
+
+# Event: pull_merged
+class TplPullMerged
+       super TplEvent
+
+       redef var title is lazy do
+               var pull = pull_event.pull
+               return "{player.link} merged <strong>{pull.commits}</strong> commits with {pull.link}"
+       end
+end
+
+# Event: pull_review
+class TplPullReview
+       super TplEvent
+
+       redef var title is lazy do
+               var issue = issue_comment_event.issue
+               return "{player.link} reviewed {issue.link}"
+       end
+end
index 80f7821..ac7f91d 100644 (file)
@@ -87,8 +87,22 @@ class GameAction
                page.side_panels.add new GameStatusPanel(game)
                page.breadcrumbs = new Breadcrumbs
                page.breadcrumbs.add_link(game.url, game.name)
+               prepare_pagination(request)
                return response
        end
+
+       # Parse pagination related parameters.
+       private fun prepare_pagination(request: HttpRequest) do
+               var args = request.get_args
+               list_from = args.get_or_default("pfrom", "0").to_i
+               list_limit = args.get_or_default("plimit", "10").to_i
+       end
+
+       # Limit of events to display in lists.
+       var list_limit = 10
+
+       # From where to start the display of events related lists.
+       var list_from = 0
 end
 
 # Repo overview page.
@@ -99,6 +113,7 @@ class RepoHome
                var rsp = prepare_response(request, url)
                page.side_panels.add new ShortListPlayersPanel(game)
                page.flow_panels.add new PodiumPanel(game)
+               page.flow_panels.add new EventListPanel(game, list_limit, list_from)
                rsp.body = page.write_to_string
                return rsp
        end
@@ -137,6 +152,7 @@ class PlayerHome
                page.side_panels.clear
                page.side_panels.add new PlayerStatusPanel(game, player)
                page.flow_panels.add new PlayerReviewsPanel(game, player)
+               page.flow_panels.add new EventListPanel(player, list_limit, list_from)
                rsp.body = page.write_to_string
                return rsp
        end