powergrid-viewer 2.0.8 → 2.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "powergrid-viewer",
3
- "version": "2.0.8",
3
+ "version": "2.0.9",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/boardgamers/powergrid.git",
@@ -142,13 +142,21 @@
142
142
  </template>
143
143
  </g>
144
144
 
145
+ <g v-if="stacked" ref="slotResourceView" :transform="slotT('resourceView')">
146
+ <ResourceViewButton :showTrack="showResourceTrack" @select="setResourceView($event)" />
147
+ </g>
148
+
145
149
  <g ref="slotResources" :transform="slotT('resources')">
146
150
  <!-- On a phone the printed price track is a strip of unreadable
147
- columns, so the stacked layout swaps it for one box per buyable
148
- source. Landscape and desktop keep the printed board exactly as
149
- it was this is an either/or, never an overlay. -->
151
+ columns, so the stacked layout defaults to one box per buyable
152
+ source. It is still only a default: the switch above this row
153
+ puts the printed track back, because the boxes deliberately
154
+ throw away the price ladder and that ladder is most of what
155
+ there is to know about uranium. Landscape and desktop keep the
156
+ printed board exactly as it was — an either/or, never an
157
+ overlay. -->
150
158
  <ResourceBoxes
151
- v-if="stacked"
159
+ v-if="stacked && !showResourceTrack"
152
160
  :transform="`translate(${G.map.supplyPosition[0]}, ${G.map.supplyPosition[1]})`"
153
161
  :gameState="G"
154
162
  :player="player"
@@ -744,6 +752,7 @@ import {
744
752
  HelpButton,
745
753
  RulesButton,
746
754
  LayoutButton,
755
+ ResourceViewButton,
747
756
  } from './buttons';
748
757
  import PlayerBoard from './PlayerBoard.vue';
749
758
  import Calculator from './Calculator.vue';
@@ -771,6 +780,9 @@ const STACK_ROWS: string[][] = [
771
780
  // the draw pile and the round readout are things you glance at.
772
781
  ['buttons', 'roundInfo', 'powerPlantDeck'],
773
782
  ['powerPlantMarket'],
783
+ // The resource-display switch sits between the two markets rather than in the
784
+ // icon column: it belongs to the row it changes, and reads as that row's header.
785
+ ['resourceView'],
774
786
  ['resources'],
775
787
  ['uraniumMines'],
776
788
  ['freeJump'],
@@ -814,6 +826,9 @@ const STACK_SLOT_MAX_WIDTH: Record<string, number> = {
814
826
  // The box market is one tall stack of full-width buttons; run edge to edge it
815
827
  // reads as though it had been cropped rather than laid out.
816
828
  resources: 0.94,
829
+ // Matched to `resources` on purpose: equal budgets render equal widths, so the
830
+ // switch and the market below it line up instead of nearly lining up.
831
+ resourceView: 0.94,
817
832
  };
818
833
 
819
834
  /**
@@ -883,6 +898,7 @@ const round = (n: number, digits = 2) => Number(n.toFixed(digits));
883
898
  HelpButton,
884
899
  RulesButton,
885
900
  LayoutButton,
901
+ ResourceViewButton,
886
902
  Button,
887
903
  Calculator,
888
904
  PowerPlantMarket,
@@ -2121,6 +2137,43 @@ export default class Game extends Vue {
2121
2137
  this.relayout();
2122
2138
  }
2123
2139
 
2140
+ /**
2141
+ * Only ever consulted inside the stacked layout — landscape and desktop draw the
2142
+ * printed board regardless, so this preference cannot reach them.
2143
+ */
2144
+ get showResourceTrack(): boolean {
2145
+ return this.preferences.portraitResourceTrack === true;
2146
+ }
2147
+
2148
+ setResourceView(showTrack: boolean) {
2149
+ if (showTrack === this.showResourceTrack) {
2150
+ return;
2151
+ }
2152
+
2153
+ this.emitter.emit('update:preference', { name: 'portraitResourceTrack', value: showTrack });
2154
+ this.preferences.portraitResourceTrack = showTrack;
2155
+ }
2156
+
2157
+ /**
2158
+ * The two resource displays are different shapes, so switching between them
2159
+ * invalidates the row heights the last layout solved for — the same trap as
2160
+ * entering the stacked layout at all. Measure again once the swap has landed.
2161
+ */
2162
+ @Watch('showResourceTrack')
2163
+ onResourceViewChanged() {
2164
+ this.$nextTick(() => {
2165
+ // The printed track fills itself imperatively and `createPieces` only ever
2166
+ // runs on a state update, so a track switched on mid-turn would draw an
2167
+ // EMPTY market until the next move landed — a display that lies. Fill it
2168
+ // before measuring: the cubes are what give the group its size.
2169
+ if (this.G) {
2170
+ this.resources?.createPieces(this.G);
2171
+ }
2172
+
2173
+ this.scheduleRelayout();
2174
+ });
2175
+ }
2176
+
2124
2177
  relayout() {
2125
2178
  if (!this.viewportIsMeasurable()) {
2126
2179
  // Still hidden. Whoever reveals us triggers the observer below.
@@ -0,0 +1,68 @@
1
+ <template>
2
+ <!--
3
+ Which resource display the portrait layout shows. A labelled either/or rather
4
+ than an icon: this changes what the whole row below it *is*, and no picture of
5
+ "boxes" or "a track" is recognisable before you tap it.
6
+
7
+ Authored 620x72 so that, held to the same 0.94 width budget as the box market
8
+ underneath, the two line up edge to edge and each half clears the 44px tap
9
+ guideline on a 414px-wide phone.
10
+ -->
11
+ <g class="resourceView">
12
+ <g class="button enabled" @click="$emit('select', false)">
13
+ <rect
14
+ x="0"
15
+ y="0"
16
+ width="306"
17
+ height="72"
18
+ rx="6"
19
+ :fill="showTrack ? 'gainsboro' : '#333'"
20
+ stroke="black"
21
+ stroke-width="3"
22
+ />
23
+ <text
24
+ x="153"
25
+ y="47"
26
+ text-anchor="middle"
27
+ font-weight="700"
28
+ :fill="showTrack ? 'black' : 'white'"
29
+ style="font-size: 30px"
30
+ >
31
+ Buy boxes
32
+ </text>
33
+ <title>One box per buyable source: the price you pay, and the whole box is the tap target</title>
34
+ </g>
35
+ <g class="button enabled" @click="$emit('select', true)">
36
+ <rect
37
+ x="314"
38
+ y="0"
39
+ width="306"
40
+ height="72"
41
+ rx="6"
42
+ :fill="showTrack ? '#333' : 'gainsboro'"
43
+ stroke="black"
44
+ stroke-width="3"
45
+ />
46
+ <text
47
+ x="467"
48
+ y="47"
49
+ text-anchor="middle"
50
+ font-weight="700"
51
+ :fill="showTrack ? 'white' : 'black'"
52
+ style="font-size: 30px"
53
+ >
54
+ Price track
55
+ </text>
56
+ <title>The printed market board, so the whole price track is visible at once</title>
57
+ </g>
58
+ </g>
59
+ </template>
60
+ <script lang="ts">
61
+ import { Vue, Component, Prop } from 'vue-property-decorator';
62
+
63
+ @Component
64
+ export default class ResourceViewButton extends Vue {
65
+ @Prop()
66
+ showTrack?: boolean;
67
+ }
68
+ </script>
@@ -4,7 +4,18 @@ import LayoutButton from './LayoutButton.vue';
4
4
  import LogButton from './LogButton.vue';
5
5
  import PassButton from './PassButton.vue';
6
6
  import SoundButton from './SoundButton.vue';
7
+ import ResourceViewButton from './ResourceViewButton.vue';
7
8
  import RulesButton from './RulesButton.vue';
8
9
  import UndoButton from './UndoButton.vue';
9
10
 
10
- export { Button, HelpButton, LayoutButton, LogButton, PassButton, SoundButton, RulesButton, UndoButton };
11
+ export {
12
+ Button,
13
+ HelpButton,
14
+ LayoutButton,
15
+ LogButton,
16
+ PassButton,
17
+ ResourceViewButton,
18
+ SoundButton,
19
+ RulesButton,
20
+ UndoButton,
21
+ };
package/src/launch.ts CHANGED
@@ -26,6 +26,7 @@ function launch(selector: string) {
26
26
  undoWholeTurn: true,
27
27
  fitToScreen: true,
28
28
  stackOnPortrait: true,
29
+ portraitResourceTrack: false,
29
30
  }),
30
31
  avatars: [],
31
32
  };
@@ -13,6 +13,11 @@ export type Preferences = {
13
13
  // Portrait phones stack the board into full-width rows. Per player, not per
14
14
  // game: it describes the screen you are holding, not the rules being played.
15
15
  stackOnPortrait: boolean;
16
+ // Within the stacked layout, show the printed price track instead of the box
17
+ // market. The boxes are the buying surface; the track is the reading surface --
18
+ // it is the only place the whole price ladder is visible at once, which matters
19
+ // most for uranium, where the cubes are few and the prices far apart.
20
+ portraitResourceTrack: boolean;
16
21
  };
17
22
 
18
23
  export interface Piece {