Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Feb 9, 2021. It is now read-only.

Commit c3d1872

Browse files
committed
Fetch gameplays for leaderboard features
1 parent d3a34b2 commit c3d1872

File tree

3 files changed

+197
-35
lines changed

3 files changed

+197
-35
lines changed

‎assets/css/app.css‎

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,18 +61,20 @@ header {
6161

6262
/* Players */
6363

64-
.player-item {
65-
display: flex;
66-
}
67-
6864
.player-score {
69-
margin-bottom:0;
65+
margin-left:1em;
7066
}
7167

7268
.player-name {
7369
margin-left: 1em;
7470
}
7571

72+
/* Gameplays */
73+
74+
.gameplays, .gameplays-empty {
75+
margin-left: 2em;
76+
}
77+
7678
/* Buttons */
7779

7880
.button {

‎assets/elm/src/Main.elm‎

Lines changed: 179 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ main =
2727

2828
type alias Model =
2929
{ gamesList : List Game
30+
, gameplaysList : List Gameplay
3031
, playersList : List Player
3132
}
3233

@@ -41,8 +42,16 @@ type alias Game =
4142
}
4243

4344

45+
type alias Gameplay =
46+
{ gameId : Int
47+
, playerId : Int
48+
, playerScore : Int
49+
}
50+
51+
4452
type alias Player =
45-
{ displayName : Maybe String
53+
{ displayGameplays : Bool
54+
, displayName : Maybe String
4655
, id : Int
4756
, score : Int
4857
, username : String
@@ -52,6 +61,7 @@ type alias Player =
5261
initialModel : Model
5362
initialModel =
5463
{ gamesList = []
64+
, gameplaysList = []
5565
, playersList = []
5666
}
5767

@@ -60,6 +70,7 @@ initialCommand : Cmd Msg
6070
initialCommand =
6171
Cmd.batch
6272
[ fetchGamesList
73+
, fetchGameplaysList
6374
, fetchPlayersList
6475
]
6576

@@ -81,6 +92,14 @@ fetchGamesList =
8192
}
8293

8394

95+
fetchGameplaysList : Cmd Msg
96+
fetchGameplaysList =
97+
Http.get
98+
{ url = "/api/gameplays"
99+
, expect = Http.expectJson FetchGameplaysList decodeGameplaysList
100+
}
101+
102+
84103
fetchPlayersList : Cmd Msg
85104
fetchPlayersList =
86105
Http.get
@@ -107,6 +126,21 @@ decodeGame =
107126
(Decode.field "title" Decode.string)
108127

109128

129+
decodeGameplaysList : Decode.Decoder (List Gameplay)
130+
decodeGameplaysList =
131+
decodeGameplay
132+
|> Decode.list
133+
|> Decode.at [ "data" ]
134+
135+
136+
decodeGameplay : Decode.Decoder Gameplay
137+
decodeGameplay =
138+
Decode.map3 Gameplay
139+
(Decode.field "game_id" Decode.int)
140+
(Decode.field "player_id" Decode.int)
141+
(Decode.field "player_score" Decode.int)
142+
143+
110144
decodePlayersList : Decode.Decoder (List Player)
111145
decodePlayersList =
112146
decodePlayer
@@ -116,7 +150,8 @@ decodePlayersList =
116150

117151
decodePlayer : Decode.Decoder Player
118152
decodePlayer =
119-
Decode.map4 Player
153+
Decode.map5 Player
154+
(Decode.succeed False)
120155
(Decode.maybe (Decode.field "display_name" Decode.string))
121156
(Decode.field "id" Decode.int)
122157
(Decode.field "score" Decode.int)
@@ -129,7 +164,9 @@ decodePlayer =
129164

130165
type Msg
131166
= FetchGamesList (Result Http.Error (List Game))
167+
| FetchGameplaysList (Result Http.Error (List Gameplay))
132168
| FetchPlayersList (Result Http.Error (List Player))
169+
| TogglePlayerGameplays Player
133170

134171

135172
update : Msg -> Model -> ( Model, Cmd Msg )
@@ -144,15 +181,45 @@ update msg model =
144181
Debug.log "Error fetching games from API."
145182
( model, Cmd.none )
146183

147-
FetchPlayersList result ->
184+
FetchGameplaysList result ->
148185
case result of
149-
Ok players ->
150-
( { model | playersList = players }, Cmd.none )
186+
Ok gameplays ->
187+
( { model | gameplaysList = gameplays }, Cmd.none )
151188

152189
Err _ ->
190+
Debug.log "Error fetching gameplays from API."
191+
( model, Cmd.none )
192+
193+
FetchPlayersList result ->
194+
case result of
195+
Ok players ->
196+
let
197+
updatedPlayersList =
198+
players
199+
|> List.map
200+
(\player -> { player | score = findTotalScoreForPlayer model player })
201+
in
202+
( { model | playersList = updatedPlayersList }, Cmd.none )
203+
204+
Err message ->
153205
Debug.log "Error fetching players from API."
154206
( model, Cmd.none )
155207

208+
TogglePlayerGameplays player ->
209+
let
210+
updatedPlayersList =
211+
List.map
212+
(\p ->
213+
if p.id == player.id then
214+
{ player | displayGameplays = not player.displayGameplays }
215+
216+
else
217+
p
218+
)
219+
model.playersList
220+
in
221+
( { model | playersList = updatedPlayersList }, Cmd.none )
222+
156223

157224

158225
-- SUBSCRIPTIONS
@@ -252,45 +319,127 @@ gamesListItem game =
252319
-- PLAYERS
253320

254321

255-
playersIndex : Model -> Html msg
322+
playersIndex : Model -> Html Msg
256323
playersIndex model =
257324
if List.isEmpty model.playersList then
258325
div [] []
259326

260327
else
261328
div [ class "players-index container" ]
262-
[ h2 [] [ text "Players" ]
263-
, model.playersList
264-
|> playersSortedByScore
265-
|> playersList
329+
[ h2 [] [ text "Player Scores" ]
330+
, playersList model
266331
]
267332

268333

269-
playersSortedByScore : List Player -> List Player
270-
playersSortedByScore players =
271-
players
272-
|> List.sortBy .score
273-
|> List.reverse
334+
playersList : Model -> Html Msg
335+
playersList model =
336+
model.playersList
337+
|> sortPlayersByScore
338+
|> List.map (playersListItem model)
339+
|> ul [ class "players-list" ]
274340

275341

276-
playersList : List Player -> Html msg
277-
playersList players =
278-
ul [ class "players-list" ] (List.map playersListItem players)
342+
playersListItem : Model -> Player -> Html Msg
343+
playersListItem model player =
344+
li [ class "player-item" ]
345+
[ playersListItemName player
346+
, playersListItemScore model player
347+
, if player.displayGameplays then
348+
gameplaysList model player
349+
350+
else
351+
div [] []
352+
]
279353

280354

281-
playersListItem : Player -> Html msg
282-
playersListItem player =
355+
playersListItemName : Player -> Html Msg
356+
playersListItemName player =
283357
let
284-
playerLink name =
285-
a [ href ("players/" ++ String.fromInt player.id) ]
286-
[ strong [ class "player-name" ] [ text name ] ]
358+
displayName =
359+
case player.displayName of
360+
Just name ->
361+
name
362+
363+
Nothing ->
364+
player.username
287365
in
288-
li [ class "player-item"]
289-
[ p [ class "player-score"][ text (String.fromInt player.score) ]
290-
,case player.displayName of
291-
Just displayName ->
292-
playerLink displayName
366+
strong []
367+
[ a [ onClick (TogglePlayerGameplays player) ]
368+
[ text displayName ]
369+
]
370+
293371

294-
Nothing ->
295-
playerLink player.username
372+
playersListItemScore : Model -> Player -> Html Msg
373+
playersListItemScore model player =
374+
let
375+
playerScore =
376+
findTotalScoreForPlayer model player
377+
in
378+
span [ class "player-score" ]
379+
[ text (String.fromInt playerScore) ]
380+
381+
382+
383+
-- GAMEPLAYS
384+
385+
386+
gameplaysList : Model -> Player -> Html msg
387+
gameplaysList model player =
388+
let
389+
gameplays =
390+
findGameplaysForPlayer model player
391+
in
392+
if List.isEmpty gameplays then
393+
div [ class "gameplays-empty" ]
394+
[ text "No gameplays to display yet!" ]
395+
396+
else
397+
div [ class "gameplays" ]
398+
(List.map (gameplaysListItem model) gameplays)
399+
400+
401+
gameplaysListItem : Model -> Gameplay -> Html msg
402+
gameplaysListItem model gameplay =
403+
let
404+
gameTitle =
405+
case findGameForGameplay model gameplay of
406+
Just game ->
407+
game.title
408+
409+
Nothing ->
410+
String.fromInt gameplay.gameId
411+
in
412+
div []
413+
[ strong [] [ text (gameTitle ++ ": ") ]
414+
, span [] [ text (String.fromInt gameplay.playerScore) ]
296415
]
416+
417+
418+
419+
-- HELPERS
420+
421+
422+
findGameplaysForPlayer : Model -> Player -> List Gameplay
423+
findGameplaysForPlayer model player =
424+
List.filter (\gameplay -> gameplay.playerId == player.id) model.gameplaysList
425+
426+
427+
findGameForGameplay : Model -> Gameplay -> Maybe Game
428+
findGameForGameplay model gameplay =
429+
model.gamesList
430+
|> List.filter (\game -> game.id == gameplay.gameId)
431+
|> List.head
432+
433+
434+
findTotalScoreForPlayer : Model -> Player -> Int
435+
findTotalScoreForPlayer model player =
436+
findGameplaysForPlayer model player
437+
|> List.map .playerScore
438+
|> List.sum
439+
440+
441+
sortPlayersByScore : List Player -> List Player
442+
sortPlayersByScore players =
443+
players
444+
|> List.sortBy .score
445+
|> List.reverse

‎lib/platform_web/templates/layout/app.html.eex‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,18 @@
3232
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
3333
<%= render @view_module, @view_template, assigns %>
3434
</main>
35+
3536
<script>window.userToken = encodeURIComponent("<%= assigns[:user_token] %>");</script>
3637
<script src="<%= Routes.static_path(@conn, "/js/app.js") %>"></script>
38+
39+
<!-- Google Analytics -->
40+
<script>
41+
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
42+
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
43+
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
44+
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
45+
ga('create', 'UA-96476785-1', 'auto');
46+
ga('send', 'pageview');
47+
</script>
3748
</body>
3849
</html>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /