From b7fc8b84f78ecc092c9015c6b422e09146d47c38 Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Mon, 23 Feb 2015 10:57:07 +0100 Subject: [PATCH] contrib/nitrpg: display achievements in front end Signed-off-by: Alexandre Terrasa --- contrib/nitrpg/src/templates/panels.nit | 77 ++++++++++++++++++++- contrib/nitrpg/src/templates/templates_base.nit | 23 +++++- contrib/nitrpg/src/templates/templates_events.nit | 18 ++++- contrib/nitrpg/src/web.nit | 41 +++++++++++ 4 files changed, 156 insertions(+), 3 deletions(-) diff --git a/contrib/nitrpg/src/templates/panels.nit b/contrib/nitrpg/src/templates/panels.nit index 89d6431..14538c5 100644 --- a/contrib/nitrpg/src/templates/panels.nit +++ b/contrib/nitrpg/src/templates/panels.nit @@ -112,7 +112,9 @@ class GameStatusPanel redef fun render_body do add "{game.load_players.length}" - add " players

" + add " players
" + add "{game.stats["achievements"]}" + add " achievements

" add "{game.stats["pulls"]} pull requests" add " ({game.stats["pulls_open"]} open)
" add "{game.stats["issues"]} issues" @@ -144,6 +146,7 @@ class PlayerStatusPanel add "

ranked " add " # {ranking[player.name]}

" add "{player.nitcoins} nitcoins

" + add "{player.stats["achievements"]} achievements

" add "{player.stats["pulls"]} pull requests
" add "{player.stats["issues"]} issues
" add "{player.stats["commits"]} commits" @@ -360,3 +363,75 @@ class EventListPanel add "" end end + +# Achievement unlocked list panel. +class AchievementsListPanel + super Panel + + # Entity to load the events from. + var entity: GameEntity + + redef fun render_title do + add "  " + add "Achievements unlocked" + end + + redef fun render_body do + var achs = entity.load_achievements.values.to_a + if achs.is_empty then + add "No achievement yet..." + return + end + for ach in achs do add ach.list_item + end +end + +# Achievement detail panel. +class AchievementPanel + super Panel + + # Achievement to display. + var achievement: Achievement + + redef fun render_title do + add "  " + add "Achievement details" + end + + redef fun render_body do + add """

+ +{{{achievement.reward}}} + {{{achievement.name}}} +

+

{{{achievement.desc}}}

""" + + var events = achievement.load_events + + if events.is_empty then + add "Never unlocked..." + return + end + + var event = events.last + var tpl = event.tpl_event + var player = tpl.player + add "
" + add """
+ + #1 + {{{player.name}}} + +
+

Unlocked first by {{{player.link}}}

+ at {{{event.time}}} +
+
""" + + if events.length > 1 then + add """


Also unlocked by + {{{events.length}}} players.

""" + end + end +end diff --git a/contrib/nitrpg/src/templates/templates_base.nit b/contrib/nitrpg/src/templates/templates_base.nit index 9b28d57..8b85a4d 100644 --- a/contrib/nitrpg/src/templates/templates_base.nit +++ b/contrib/nitrpg/src/templates/templates_base.nit @@ -17,7 +17,7 @@ # Base HTML rendering templates for `nitpg`. module templates_base -import statistics +import achievements redef class GameEntity @@ -50,3 +50,24 @@ redef class Issue # Return a HTML link to this Issue. fun link: String do return "#{number}" end + +redef class Achievement + # Return a HTML link to this Issue. + fun link: String do return "{name}" + + fun list_item: String do + return """
+
+ + +{{{reward}}} +
+
+

{{{link}}}

+ {{{desc}}} +
+
""" + + end +end diff --git a/contrib/nitrpg/src/templates/templates_events.nit b/contrib/nitrpg/src/templates/templates_events.nit index 20f7b58..234c9e5 100644 --- a/contrib/nitrpg/src/templates/templates_events.nit +++ b/contrib/nitrpg/src/templates/templates_events.nit @@ -17,7 +17,7 @@ # Templates to display `GameEvent` kinds. module templates_events -import events +import achievements import templates_base redef class GameEvent @@ -29,6 +29,8 @@ redef class GameEvent return new TplPullMerged(self) else if kind == "pull_review" then return new TplPullReview(self) + else if kind == "achievement_unlocked" then + return new TplAchievementUnlocked(self) end abort end @@ -63,6 +65,11 @@ class TplEvent return new IssueCommentEvent.from_json(event.game.api, obj) end + # Load `achievement` data key as an Achievement. + var achievement: Achievement is lazy do + return player.load_achievement(event.data["achievement"].to_s).as(not null) + end + # Display a media item for a reward event. fun media_item: String do return """
@@ -109,3 +116,12 @@ class TplPullReview return "{player.link} reviewed {issue.link}" end end + +# Event: achievement_unlocked +class TplAchievementUnlocked + super TplEvent + + redef var title is lazy do + return "{player.link} unlocked {achievement.link}" + end +end diff --git a/contrib/nitrpg/src/web.nit b/contrib/nitrpg/src/web.nit index ac7f91d..b27c457 100644 --- a/contrib/nitrpg/src/web.nit +++ b/contrib/nitrpg/src/web.nit @@ -114,6 +114,7 @@ class RepoHome 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) + page.flow_panels.add new AchievementsListPanel(game) rsp.body = page.write_to_string return rsp end @@ -152,12 +153,50 @@ 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 AchievementsListPanel(player) page.flow_panels.add new EventListPanel(player, list_limit, list_from) rsp.body = page.write_to_string return rsp end end +# Display the list of achievements unlocked for this game. +class ListAchievements + super GameAction + + redef fun answer(request, url) do + var rsp = prepare_response(request, url) + page.breadcrumbs.add_link(game.url / "achievements", "achievements") + page.flow_panels.add new AchievementsListPanel(game) + rsp.body = page.write_to_string + return rsp + end +end + +# Player details page. +class AchievementHome + super GameAction + + redef fun answer(request, url) do + var rsp = prepare_response(request, url) + var name = request.param("achievement") + if name == null then + var msg = "Bad request: should look like /:owner/:repo/achievements/:achievement." + return bad_request(msg) + end + var achievement = game.load_achievement(name) + if achievement == null then + return bad_request("Request Error: unknown achievement {name}.") + end + page.breadcrumbs.add_link(game.url / "achievements", "achievements") + page.breadcrumbs.add_link(achievement.url, achievement.name) + page.flow_panels.add new AchievementPanel(achievement) + page.flow_panels.add new EventListPanel(achievement, list_limit, list_from) + rsp.body = page.write_to_string + return rsp + end +end + if args.length != 3 then print "Error: missing argument" print "" @@ -175,6 +214,8 @@ var vh = new VirtualHost(iface) vh.routes.add new Route("/styles/", new FileServer("www/styles")) vh.routes.add new Route("/games/:owner/:repo/players/:player", new PlayerHome(root)) vh.routes.add new Route("/games/:owner/:repo/players", new ListPlayers(root)) +vh.routes.add new Route("/games/:owner/:repo/achievements/:achievement", new AchievementHome(root)) +vh.routes.add new Route("/games/:owner/:repo/achievements", new ListAchievements(root)) vh.routes.add new Route("/games/:owner/:repo", new RepoHome(root)) var fac = new HttpFactory.and_libevent -- 1.7.9.5