Skip to content

Commit b4f2965

Browse files
committed
Extract tiles into components
1 parent 8368b04 commit b4f2965

9 files changed

+57
-86
lines changed

Diff for: TODO.md

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
# TODO
22

3-
- CD: https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/
4-
- Put everyone's discards in front of their hand (suggested by Mom)
5-
- Bug: Undoing a win after a bot drew a tile hung bot (workaround: paused & unpaused bots)
3+
- Refactor: Convert Live View Components to regular Components
4+
- Slider for tile size (so users don't have to increase font size)
5+
- Real user accounts instead of just web sessions
66
- Shrink tile sizes on mobile
77
- Lobby not receiving bot player added
88
- Refactor: Denormalize seatno as a seat attribute
99
- Point out game menu on first load
10-
- Make seating less confusing
10+
- Make seating process less confusing
1111
- Sound
1212
- "Sort" button after deal (disappears if player moves any tile)
1313
- Indicate when deck is running low
1414
- Experiment with more CSS animations: dealing the tiles, etc.
15-
- Real user accounts instead of just web sessions
1615
- Exclude bots (e.g., PresidentCardGames uses phone numbers)
1716
- Support more Mahjong rule sets (flower tiles, no game wind, etc.)
1817
- Instructions
@@ -25,14 +24,14 @@
2524
- Add titles to tile images ("5 of bamboo"). good for game log where it's small
2625
- Add "Waiting for Mei..." to game log when waiting, then delete when no longer waiting
2726
- Make Pause button easier to click (click on board center?)
28-
- Slider for tile size (so users don't have to increase font size)
2927
- Animated "waiting" dots next to player name when waiting for them
3028
- Allow dragging from decktile to exposed tiles (adding onto a pong)
3129
- 2-click instead of drag & drop. First click will pause other players.
3230
- Display everyone's wind direction instead of staircase
3331
- Animate deal: 4 at a time goes into people's hand
3432
- Sanity check for (possible race condition) bug: rearranging hand leads to duplicate tiles. Last time it happened after peek tile got put into hand, and user drag & dropped that new tile.
3533
- Remember sorted hand in browser so it doesn't get reshuffled when losing internet connection
34+
- Put everyone's discards in front of their hand (suggested by Mom)
3635

3736
## Future rule enforcement
3837
- Winning tile was the last one picked up

Diff for: lib/mjw_web.ex

+3-1
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,10 @@ defmodule MjwWeb do
8484
quote do
8585
# HTML escaping functionality
8686
import Phoenix.HTML
87-
# Core UI components and translation
87+
# Phoenix Core UI components and translation
8888
import MjwWeb.CoreComponents
89+
# Our own custom components
90+
import MjwWeb.GameComponents
8991
import MjwWeb.Gettext
9092

9193
# Shortcut for generating JS commands

Diff for: lib/mjw_web/components/game_components.ex

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
defmodule MjwWeb.GameComponents do
2+
use Phoenix.Component
3+
4+
attr(:tile, :string, required: true)
5+
attr(:class, :string, default: nil)
6+
attr(:id, :string, default: nil)
7+
8+
def tile(assigns) do
9+
~H"""
10+
<img
11+
id={@id}
12+
src={"/images/tiles/#{Mjw.Tile.without_id(@tile)}.png"}
13+
alt=""
14+
class={["tile", @class]}
15+
/>
16+
"""
17+
end
18+
19+
attr(:class, :string, default: nil)
20+
attr(:rest, :global)
21+
22+
def concealed_tile(assigns) do
23+
~H"""
24+
<img src="/images/tiles/concealed.png" alt="" class={@class} {@rest} />
25+
"""
26+
end
27+
end

Diff for: lib/mjw_web/live/game_live/current_user_seat_component.html.heex

+4-24
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,14 @@
77
class={"hiddengong-tiles dropzone#{if @win_declared_seatno && @win_declared_seatno != @current_user_seatno && @seat.win_expose, do: " exposed-loser-hand"}"}
88
>
99
<%= for tile <- @seat.hiddengongs do %>
10-
<img
11-
id={tile}
12-
src={"/images/tiles/#{Mjw.Tile.without_id(tile)}.png"}
13-
alt=""
14-
class="tile draggable"
15-
/>
10+
<.tile id={tile} tile={tile} class="draggable" />
1611
<% end %>
1712
<div class="dropzone-description">Hidden gong</div>
1813
</div>
1914

2015
<div id="exposed-0" phx-hook="Drag" phx-target="#game" class="exposed-tiles dropzone">
2116
<%= for tile <- @seat.exposed do %>
22-
<img
23-
id={tile}
24-
src={"/images/tiles/#{Mjw.Tile.without_id(tile)}.png"}
25-
alt=""
26-
class="tile draggable"
27-
/>
17+
<.tile id={tile} tile={tile} class="draggable" />
2818
<% end %>
2919
<div class="dropzone-description">Exposed tiles</div>
3020
</div>
@@ -36,12 +26,7 @@
3626
class={"wintile-tiles#{if !@win_declared_seatno || @win_declared_seatno == @current_user_seatno, do: " dropzone"}"}
3727
>
3828
<%= if @seat.wintile do %>
39-
<img
40-
id={@seat.wintile}
41-
src={"/images/tiles/#{Mjw.Tile.without_id(@seat.wintile)}.png"}
42-
alt=""
43-
class="tile cursor-not-allowed"
44-
/>
29+
<.tile id={@seat.wintile} tile={@seat.wintile} class="cursor-not-allowed" />
4530
<% end %>
4631
<%= if !@win_declared_seatno || @win_declared_seatno == @current_user_seatno do %>
4732
<div class="dropzone-description">Winning tile</div>
@@ -57,12 +42,7 @@
5742
class={"concealed-tiles dropzone current-user-discarding-#{if @current_user_discarding, do: "t"} enable-pull-from-discards-#{if @available_discard_tile, do: "t"} concealed-loser-hand-#{if @concealed_loser_hand, do: "t"}"}
5843
>
5944
<%= for tile <- @seat.concealed do %>
60-
<img
61-
id={tile}
62-
src={"/images/tiles/#{Mjw.Tile.without_id(tile)}.png"}
63-
alt=""
64-
class="tile draggable"
65-
/>
45+
<.tile id={tile} tile={tile} class="draggable" />
6646
<% end %>
6747
</div>
6848
</div>

Diff for: lib/mjw_web/live/game_live/opponent_seat_component.html.heex

+6-15
Original file line numberDiff line numberDiff line change
@@ -38,22 +38,18 @@
3838

3939
<div class="exposed-tiles">
4040
<%= for tile <- @seat.exposed do %>
41-
<img id={tile} src={"/images/tiles/#{Mjw.Tile.without_id(tile)}.png"} alt="" class="tile" />
41+
<.tile id={tile} tile={tile} />
4242
<% end %>
4343
</div>
4444

4545
<div class="hiddengong-tiles">
4646
<%= if @seat.win_expose do %>
4747
<%= for tile <- @seat.hiddengongs do %>
48-
<img
49-
src={"/images/tiles/#{Mjw.Tile.without_id(tile)}.png"}
50-
alt=""
51-
class="tile opacity-50"
52-
/>
48+
<.tile tile={tile} class="opacity-50" />
5349
<% end %>
5450
<% else %>
5551
<%= for _tile <- @seat.hiddengongs do %>
56-
<img src="/images/tiles/concealed.png" alt="" class="tile" />
52+
<.concealed_tile class="tile" />
5753
<% end %>
5854
<% end %>
5955
</div>
@@ -63,23 +59,18 @@
6359
<div class="concealed-tiles">
6460
<%= if @seat.win_expose do %>
6561
<%= for tile <- @seat.concealed do %>
66-
<img src={"/images/tiles/#{Mjw.Tile.without_id(tile)}.png"} alt="" class="tile" />
62+
<.tile tile={tile} />
6763
<% end %>
6864
<% else %>
6965
<%= for _tile <- @seat.concealed do %>
70-
<img src="/images/tiles/concealed.png" alt="" class="tile" />
66+
<.concealed_tile class="tile" />
7167
<% end %>
7268
<% end %>
7369
</div>
7470

7571
<%= if @seat.wintile do %>
7672
<div class="wintile-tiles">
77-
<img
78-
id={@seat.wintile}
79-
src={"/images/tiles/#{Mjw.Tile.without_id(@seat.wintile)}.png"}
80-
alt=""
81-
class="tile ml-8"
82-
/>
73+
<.tile tile={@seat.wintile} class="ml-8" />
8374
</div>
8475
<% end %>
8576
</div>

Diff for: lib/mjw_web/live/game_live/show.html.heex

+7-29
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,7 @@
5858
class={"dglow-#{@available_discard_tile} discardedby-#{if @raw_event == :discarded, do: @discarded_by_relative_seatno} current-user-discarding-#{if @current_user_discarding, do: "t"} enable-pull-from-discards-#{if @available_discard_tile, do: "t"}"}
5959
>
6060
<%= for tile <- Enum.reverse(@game.discards) do %>
61-
<img
62-
id={tile}
63-
src={"/images/tiles/#{Mjw.Tile.without_id(tile)}.png"}
64-
alt=""
65-
class="tile draggable"
66-
/>
61+
<.tile id={tile} tile={tile} class="draggable" />
6762
<% end %>
6863
</div>
6964
<% end %>
@@ -74,11 +69,7 @@
7469
<span class="desc align-middle"><%= event %></span>
7570
<%= if icon do %>
7671
<%= if Mjw.Tile.tile_format?(icon) do %>
77-
<img
78-
src={"/images/tiles/#{Mjw.Tile.without_id(icon)}.png"}
79-
alt=""
80-
class="tile align-middle"
81-
/>
72+
<.tile tile={icon} class="align-middle" />
8273
<% else %>
8374
<span class="icon text-xl align-middle"><%= icon %></span>
8475
<% end %>
@@ -109,20 +100,13 @@
109100
<%= if @current_user_drawing || @current_user_seat.peektile do %>
110101
<div id="peektile-0" phx-hook="Drag" phx-target="#game">
111102
<%= if @current_user_seat.peektile do %>
112-
<img
103+
<.tile
113104
id={@current_user_seat.peektile}
114-
src={"/images/tiles/#{Mjw.Tile.without_id(@current_user_seat.peektile)}.png"}
115-
alt=""
116-
class="tile draggable"
105+
tile={@current_user_seat.peektile}
106+
class="draggable"
117107
/>
118108
<% else %>
119-
<img
120-
src="/images/tiles/concealed.png"
121-
alt=""
122-
class="tile cursor-pointer"
123-
phx-target="#game"
124-
phx-click="peek"
125-
/>
109+
<.concealed_tile class="tile cursor-pointer" phx-target="#game" phx-click="peek" />
126110
<% end %>
127111
</div>
128112
<% end %>
@@ -140,13 +124,7 @@
140124
<% end %>
141125
<%= if @show_correction_tile do %>
142126
<div id="correctiontiles" phx-hook="Drag" class="dropzone">
143-
<img
144-
id="decktile"
145-
alt=""
146-
title="Gong correction tile"
147-
src="/images/tiles/concealed.png"
148-
class="tile draggable"
149-
/>
127+
<.concealed_tile id="decktile" class="tile draggable" title="Gong correction tile" />
150128
</div>
151129
<% end %>
152130
<%= unless @show_wall do %>

Diff for: lib/mjw_web/live/game_live/wall_component.html.heex

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
<div class="tiles flex-wrap">
33
<div class="wall-tiles wall-tiles-1">
44
<%= for _ <- 0..15 do %>
5-
<img src="/images/tiles/concealed.png" alt="" class="walltile" />
5+
<.concealed_tile class="walltile" />
66
<% end %>
77
</div>
88
<div class="line-break"></div>
99
<div class="wall-tiles">
1010
<%= for _ <- 0..15 do %>
11-
<img src="/images/tiles/concealed.png" alt="" class="walltile" />
11+
<.concealed_tile class="walltile" />
1212
<% end %>
1313
</div>
1414
</div>

Diff for: lib/mjw_web/live/game_live/win_menu_component.html.heex

+1-6
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,7 @@
4040
<div class="flex flex-row flex-wrap text-left justify-start justify-items-start">
4141
<span class="pr-1 cursor-default" title="Next tile in the deck">&#8594;</span>
4242
<%= for tile <- @game.deck do %>
43-
<img
44-
id={tile}
45-
src={"/images/tiles/#{Mjw.Tile.without_id(tile)}.png"}
46-
alt=""
47-
class="tile"
48-
/>
43+
<.tile id={tile} tile={tile} />
4944
<% end %>
5045
</div>
5146
<% else %>

Diff for: lib/mjw_web/live/game_live/wind_pick_component.html.heex

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
<div class="windandname">
1313
<div class="windcontainer">
1414
<%= if wind_data[:picked_wind_idx] do %>
15-
<img
16-
src="/images/tiles/concealed.png"
15+
<.concealed_tile
1716
class="tile pickable-wind"
1817
phx-target="#game"
1918
phx-click="windpick"
@@ -24,7 +23,7 @@
2423
<%= if wind_data[:picked_by_name] do %>
2524
<img src={"/images/tiles/#{wind_data[:wind]}.png"} alt="" class="tile" />
2625
<% else %>
27-
<img src="/images/tiles/concealed.png" alt="" class="tile" />
26+
<.concealed_tile class="tile" />
2827
<% end %>
2928
<% end %>
3029
</div>

0 commit comments

Comments
 (0)