TBR croupier: Add GLOBAL support and new Arrange Players
(Sorry for combining 2 changes.)
GLOBAL support was added to the Makefile.
- If you say GLOBAL=1 when running, then you will mount on the global
mount table and use the proxy.
New Arrange Players
- Now, we primarily arrange players on the Table Device
- After being prompted (player vs table), we allow the Table to place
each player who joined the game.
- If there is no Table, the owner can still fallback to the old
Arrange Players behavior.
NOTE: Presubmit will not pass in the short term.
https://github.com/vanadium/issues/issues/1093
So I've had to prepend TBR to the front of this CL.
Change-Id: Ic0486554444819da991a52130143749fff3dc04d
diff --git a/Makefile b/Makefile
index 2dc7152..bc066e0 100644
--- a/Makefile
+++ b/Makefile
@@ -21,13 +21,20 @@
DEVICE_ID := $(shell adb devices | sed -n $(ANDROID_PLUS_ONE)p | awk '{ print $$1; }')
endif
+# The default mount table location. Note: May not always exist.
+MOUNTTABLE := /192.168.86.254:8101
+
+# If defined, use the proxy and global mount table.
+ifdef GLOBAL
+ PROXY_FLAG := --v23.proxy=/ns.dev.v.io:8101/proxy
+ MOUNTTABLE := /ns.dev.v.io:8101/tmp/croupier
+endif
+
ifdef ANDROID
MOJO_ANDROID_FLAGS := --android
SYNCBASE_MOJO_BIN_DIR := packages/syncbase/mojo_services/android
DISCOVERY_MOJO_BIN_DIR := packages/v23discovery/mojo_services/android
- # Location of mounttable on syncslides-alpha network.
- MOUNTTABLE := /192.168.86.254:8101
# Name to mount under.
SYNCBASE_NAME_FLAG := --name=$(MOUNTTABLE)/croupier-$(DEVICE_ID)
SYNCBASE_FLAGS += $(SYNCBASE_NAME_FLAG)
@@ -37,13 +44,8 @@
SYNCBASE_FLAGS += --logtostderr=true \
--root-dir=$(APP_HOME_DIR)/syncbase_data \
- --v23.credentials=$(ANDROID_CREDS_DIR)
-
-# If this is not the first mojo shell, then you must reuse the dev servers
-# to avoid a "port in use" error.
-ifneq ($(shell fuser 31841/tcp),)
- REUSE_FLAG := --reuse-servers
-endif
+ --v23.credentials=$(ANDROID_CREDS_DIR) \
+ $(PROXY_FLAG)
else
SYNCBASE_MOJO_BIN_DIR := packages/syncbase/mojo_services/linux_amd64
@@ -51,12 +53,18 @@
SYNCBASE_FLAGS += --root-dir=$(PWD)/tmp/syncbase_data --v23.credentials=$(PWD)/creds
endif
+# If this is not the first mojo shell, then you must reuse the dev servers
+# to avoid a "port in use" error.
+ifneq ($(shell fuser 31841/tcp),)
+ REUSE_FLAG := --reuse-servers
+endif
+
# We should consider combining these URLs and hosting our *.mojo files.
# https://github.com/vanadium/issues/issues/834
export SYNCBASE_SERVER_URL := https://mojo.v.io/syncbase_server.mojo
export DISCOVERY_SERVER_URL := https://mojo2.v.io/discovery.mojo
MOJO_SHELL_FLAGS := --enable-multiprocess \
- --map-origin="https://mojo2.v.io=$(DISCOVERY_MOJO_BIN_DIR)" --args-for="$(DISCOVERY_SERVER_URL) host$(DEVICE_ID) mdns" \
+ --map-origin="https://mojo2.v.io=$(DISCOVERY_MOJO_BIN_DIR)" --args-for="$(DISCOVERY_SERVER_URL) host$(DEVICE_ID)" \
--map-origin="https://mojo.v.io=$(SYNCBASE_MOJO_BIN_DIR)" --args-for="$(SYNCBASE_SERVER_URL) $(SYNCBASE_FLAGS)"
ifdef ANDROID
@@ -164,7 +172,7 @@
# Creates a shortcut on the phone that runs the hosted version of croupier.flx
# Does nothing if ANDROID is not defined.
define GENERATE_SHORTCUT_FILE
- sed -e "s;%DEVICE_ID%;$1;g" -e "s;%SYNCBASE_NAME_FLAG%;$2;g" \
+ sed -e "s;%DEVICE_ID%;$1;g" -e "s;%SYNCBASE_NAME_FLAG%;$2;g" -e "s;%PROXY_FLAG%;$3;g" \
shortcut_template > shortcut_commands
endef
diff --git a/lib/components/board.dart b/lib/components/board.dart
index 3ed6e9e..038e804 100644
--- a/lib/components/board.dart
+++ b/lib/components/board.dart
@@ -269,10 +269,8 @@
}
Widget _getProfile(int pNum, double sizeFactor) {
- return new CroupierProfileComponent(
- settings: config.croupier.settingsFromPlayerNumber(pNum),
- height: config.height * sizeFactor,
- width: config.height * sizeFactor * 1.5);
+ return new CroupierProfileComponent.horizontal(
+ settings: config.croupier.settingsFromPlayerNumber(pNum));
}
Widget _playerProfile(int pNum, double sizeFactor) {
@@ -365,12 +363,11 @@
top: 0.0,
left: 0.0,
child: new IgnorePointer(
- child: new CroupierProfileComponent(
+ child: new CroupierProfileComponent.mini(
settings:
config.croupier.settingsFromPlayerNumber(playerNumber),
height: config.cardHeight,
- width: config.cardWidth,
- isMini: true))));
+ width: config.cardWidth))));
}
return new Container(
@@ -396,8 +393,16 @@
? config.game.determineTrickWinner()
: config.game.whoseTurn;
+ // You can tap anywhere on the board to "Ask" or "Take Trick".
+ NoArgCb tapCb;
+ if (!config.game.asking && !config.game.allPlayed) {
+ tapCb = config.game.askUI;
+ } else if (config.game.allPlayed) {
+ tapCb = config.game.takeTrickUI;
+ }
+
return new GestureDetector(
- onTap: config.game.asking ? null : config.game.askUI,
+ onTap: tapCb,
child: new Container(
height: config.height,
width: config.width,
diff --git a/lib/components/croupier.dart b/lib/components/croupier.dart
index ffb5664..910e776 100644
--- a/lib/components/croupier.dart
+++ b/lib/components/croupier.dart
@@ -19,6 +19,7 @@
typedef void NoArgCb();
GlobalObjectKey _gameKey = new GlobalObjectKey("CroupierGameKey");
+GlobalObjectKey _gameArrangeKey = new GlobalObjectKey("CroupierGameArrangeKey");
class CroupierComponent extends StatefulComponent {
final logic_croupier.Croupier croupier;
@@ -61,8 +62,8 @@
: null),
new CroupierProfileComponent(
settings: config.croupier.settings,
- width: style.Size.settingsSize,
- height: style.Size.settingsSize)
+ width: style.Size.settingsWidth,
+ height: style.Size.settingsHeight)
]));
case logic_croupier.CroupierState.ChooseGame:
// in which we let them pick a game out of the many possible games... There aren't that many.
@@ -151,24 +152,23 @@
// shown if the person has not sat down yet.
Widget _buildPlayerProfiles(bool needsArrangement) {
List<Widget> profileWidgets = new List<Widget>();
- double size = style.Size.settingsSize;
config.croupier.players_found.forEach((int userID, int playerNumber) {
- if (!needsArrangement || playerNumber == null) {
- // Note: Even if cs is null, a placeholder will be shown instead.
- CroupierSettings cs = config.croupier.settings_everyone[userID];
- bool isMe = config.croupier.settings.userID == userID;
- Widget cpc = new Container(
- decoration: isMe ? style.Box.liveNow : null,
- child: new CroupierProfileComponent(
- settings: cs, height: size, width: size));
+ // Note: Even if cs is null, a placeholder will be shown instead.
+ CroupierSettings cs = config.croupier.settings_everyone[userID];
+ bool isMe = config.croupier.settings.userID == userID;
+ Widget cpc = new Container(
+ decoration: isMe ? style.Box.liveNow : null,
+ child: new CroupierProfileComponent(
+ settings: cs,
+ height: style.Size.settingsHeight,
+ width: style.Size.settingsWidth));
- // If the player profiles can be arranged, they should be draggable too.
- if (needsArrangement) {
- profileWidgets.add(new Draggable<CroupierSettings>(
- child: cpc, feedback: cpc, data: cs));
- } else {
- profileWidgets.add(cpc);
- }
+ // If the player profiles can be arranged, they should be draggable too.
+ if (needsArrangement) {
+ profileWidgets.add(new Draggable<CroupierSettings>(
+ child: cpc, feedback: cpc, data: cs));
+ } else {
+ profileWidgets.add(cpc);
}
});
@@ -177,7 +177,8 @@
child: new Row(profileWidgets),
scrollDirection: ScrollDirection.horizontal);
}
- return new MaxTileWidthGrid(profileWidgets, maxTileWidth: size);
+ return new MaxTileWidthGrid(profileWidgets,
+ maxTileWidth: style.Size.settingsWidth);
}
Widget _buildArrangePlayers() {
@@ -202,7 +203,8 @@
// Games that need arrangement can show their game arrange component.
allWidgets.add(component_game.createGameArrangeComponent(config.croupier,
width: ui.window.size.width * 0.90,
- height: ui.window.size.height * 0.50));
+ height: ui.window.size.height * 0.50,
+ key: _gameArrangeKey));
}
// Allow games that can start with these players to begin.
@@ -224,15 +226,10 @@
allWidgets.add(new Flexible(
flex: 0,
child: new Row([
- new Container(
- decoration: new BoxDecoration(
- backgroundColor: startCb != null
- ? style.theme.accentColor
- : Colors.grey[300]),
- padding: style.Spacing.smallPadding,
- child: new FlatButton(
- child: new Text("Start Game", style: style.Text.hugeStyle),
- onPressed: startCb))
+ new FlatButton(
+ child: new Text("Start Game", style: style.Text.hugeStyle),
+ onPressed: startCb,
+ color: style.theme.accentColor)
], justifyContent: FlexJustifyContent.spaceAround)));
}
allWidgets.add(new Flexible(
diff --git a/lib/components/croupier_game_advertisement.dart b/lib/components/croupier_game_advertisement.dart
index 545f028..07a960c 100644
--- a/lib/components/croupier_game_advertisement.dart
+++ b/lib/components/croupier_game_advertisement.dart
@@ -24,7 +24,11 @@
return new GestureDetector(
child: new Card(
child: new Row([
- new Card(child: new CroupierProfileComponent(settings: settings)),
+ new Card(
+ child: new CroupierProfileComponent(
+ settings: settings,
+ height: style.Size.settingsHeight,
+ width: style.Size.settingsWidth)),
new Text(game.gameTypeToString(gameStartData.gameType),
style: style.Text.hugeStyle),
])),
diff --git a/lib/components/croupier_profile.dart b/lib/components/croupier_profile.dart
index ffd0869..b406546 100644
--- a/lib/components/croupier_profile.dart
+++ b/lib/components/croupier_profile.dart
@@ -5,44 +5,93 @@
import 'package:flutter/material.dart';
import '../logic/croupier_settings.dart' show CroupierSettings;
+import '../styles/common.dart' as style;
+
+enum CroupierProfileComponentOrientation {
+ DEFAULT,
+ MINI,
+ HORIZONTAL,
+ TEXT_ONLY
+}
class CroupierProfileComponent extends StatelessComponent {
final CroupierSettings settings;
final double height;
final double width;
- final bool isMini;
+ final CroupierProfileComponentOrientation orientation;
static const double padAmount = 4.0;
CroupierProfileComponent(
- {CroupierSettings settings, this.height, this.width, this.isMini: false})
+ {CroupierSettings settings,
+ this.height,
+ this.width,
+ this.orientation: CroupierProfileComponentOrientation.DEFAULT})
: settings = settings ?? new CroupierSettings.placeholder();
+ CroupierProfileComponent.mini(
+ {CroupierSettings settings, double height, double width})
+ : this(
+ settings: settings,
+ height: height,
+ width: width,
+ orientation: CroupierProfileComponentOrientation.MINI);
+
+ CroupierProfileComponent.horizontal({CroupierSettings settings})
+ : this(
+ settings: settings,
+ orientation: CroupierProfileComponentOrientation.HORIZONTAL);
+
+ CroupierProfileComponent.textOnly({CroupierSettings settings})
+ : this(
+ settings: settings,
+ orientation: CroupierProfileComponentOrientation.TEXT_ONLY);
+
Widget build(BuildContext context) {
- if (!isMini) {
- return new Container(
- height: this.height,
- width: this.width,
- padding: const EdgeDims.all(padAmount),
- child: new Card(
- color: new Color(settings.color),
- child: new Column([
- new AssetImage(
- name: CroupierSettings.makeAvatarUrl(settings.avatar)),
- new Text(settings.name)
- ], justifyContent: FlexJustifyContent.spaceAround)));
- } else {
- return new Container(
- width: this.width,
- height: this.height,
- padding: const EdgeDims.all(padAmount),
- child: new Card(
- color: new Color(settings.color),
- child: new Row([
- new AssetImage(
- name: CroupierSettings.makeAvatarUrl(settings.avatar),
- fit: ImageFit.scaleDown)
- ], justifyContent: FlexJustifyContent.spaceAround)));
+ switch (orientation) {
+ case CroupierProfileComponentOrientation.DEFAULT:
+ return new Container(
+ height: this.height,
+ width: this.width,
+ padding: const EdgeDims.all(padAmount),
+ child: new Card(
+ color: new Color(settings.color),
+ child: new Column([
+ new AssetImage(
+ name: CroupierSettings.makeAvatarUrl(settings.avatar)),
+ new Text(settings.name, style: style.Text.largeStyle)
+ ], justifyContent: FlexJustifyContent.spaceAround)));
+ case CroupierProfileComponentOrientation.MINI:
+ return new Container(
+ width: this.width,
+ height: this.height,
+ padding: const EdgeDims.all(padAmount),
+ child: new Card(
+ color: new Color(settings.color),
+ child: new Row([
+ new AssetImage(
+ name: CroupierSettings.makeAvatarUrl(settings.avatar),
+ fit: ImageFit.scaleDown)
+ ], justifyContent: FlexJustifyContent.spaceAround)));
+ case CroupierProfileComponentOrientation.HORIZONTAL:
+ return new Card(
+ color: new Color(settings.color),
+ child: new Container(
+ padding: const EdgeDims.all(padAmount),
+ child: new Row([
+ new AssetImage(
+ name: CroupierSettings.makeAvatarUrl(settings.avatar),
+ fit: ImageFit.scaleDown),
+ new Text(settings.name, style: style.Text.hugeStyle)
+ ], justifyContent: FlexJustifyContent.collapse)));
+ case CroupierProfileComponentOrientation.TEXT_ONLY:
+ return new Card(
+ color: new Color(settings.color),
+ child: new Container(
+ padding: const EdgeDims.all(padAmount),
+ child: new Row(
+ [new Text(settings.name, style: style.Text.largeStyle)],
+ justifyContent: FlexJustifyContent.collapse)));
}
}
}
diff --git a/lib/components/game.dart b/lib/components/game.dart
index bbe1bcf..591c92e 100644
--- a/lib/components/game.dart
+++ b/lib/components/game.dart
@@ -222,18 +222,20 @@
}
}
-abstract class GameArrangeComponent extends StatelessComponent {
+abstract class GameArrangeComponent extends StatefulComponent {
final Croupier croupier;
final double width;
final double height;
- GameArrangeComponent(this.croupier, {this.width, this.height});
+ GameArrangeComponent(this.croupier, {this.width, this.height, Key key})
+ : super(key: key);
}
GameArrangeComponent createGameArrangeComponent(Croupier croupier,
- {double width, double height}) {
+ {double width, double height, Key key}) {
switch (croupier.game.gameType) {
case GameType.Hearts:
- return new HeartsArrangeComponent(croupier, width: width, height: height);
+ return new HeartsArrangeComponent(croupier,
+ width: width, height: height, key: key);
default:
// We can't arrange this game.
throw new UnimplementedError(
diff --git a/lib/components/hearts/hearts.part.dart b/lib/components/hearts/hearts.part.dart
index 066cbec..3120772 100644
--- a/lib/components/hearts/hearts.part.dart
+++ b/lib/components/hearts/hearts.part.dart
@@ -821,50 +821,196 @@
}
class HeartsArrangeComponent extends GameArrangeComponent {
- HeartsArrangeComponent(Croupier croupier, {double width, double height})
- : super(croupier, width: width, height: height);
+ HeartsArrangeComponent(Croupier croupier,
+ {double width, double height, Key key})
+ : super(croupier, width: width, height: height, key: key);
+
+ HeartsArrangeComponentState createState() =>
+ new HeartsArrangeComponentState();
+}
+
+class HeartsArrangeComponentState extends State<HeartsArrangeComponent> {
+ bool isTable = null; // Must first ask what kind of device this is.
+ bool fallback = false; // Set to true to switch to the old arrange players.
+
+ static final String personIcon = "social/person_outline";
+ static final String tableIcon = "hardware/tablet";
Widget build(BuildContext context) {
- int numAtTable = croupier.players_found.values
- .where((int playerNumber) => playerNumber == 4)
- .length;
+ if (isTable == null) {
+ return _buildAskDeviceType();
+ }
+ if (isTable) {
+ return _buildTableArrangePlayers();
+ }
+ if (fallback) {
+ return _buildFallbackArrangePlayers();
+ }
+ return _buildPlayerArrangePlayers();
+ }
+
+ Widget _buildAskDeviceType() {
+ return new Container(
+ decoration: style.Box.liveNow,
+ height: config.height,
+ width: config.width,
+ child: new Column([
+ new Text("Play Hearts as a...", style: style.Text.hugeStyle),
+ new FlatButton(
+ child: new Row([
+ new Icon(size: IconSize.s48, icon: personIcon),
+ new Text("Player", style: style.Text.largeStyle)
+ ], justifyContent: FlexJustifyContent.collapse),
+ color: style.secondaryTextColor, onPressed: () {
+ setState(() {
+ isTable = false;
+ });
+ }),
+ new FlatButton(
+ child: new Row([
+ new Icon(size: IconSize.s48, icon: tableIcon),
+ new Text("Table", style: style.Text.largeStyle)
+ ], justifyContent: FlexJustifyContent.collapse),
+ color: style.secondaryTextColor, onPressed: () {
+ setState(() {
+ isTable = true;
+ });
+ // Also sit at the table.
+ config.croupier.settings_manager.setPlayerNumber(
+ config.croupier.game.gameID,
+ config.croupier.settings.userID,
+ 4);
+ })
+ ], alignItems: FlexAlignItems.center));
+ }
+
+ int get numSitting => config.croupier.players_found.values.where((int index) {
+ return index != null && index >= 0 && index < 4;
+ }).length;
+
+ Widget _buildTableArrangePlayers() {
+ int arrangeID = null;
+ String status = "";
+ bool canStart = false;
+ if (numSitting < 4) {
+ // We still need people to sit.
+ // Only include non-table and non-sitting devices in this search.
+ // Note that this means it's possible arrangeID is null.
+ arrangeID = config.croupier.players_found.keys.firstWhere((int playerID) {
+ int index = config.croupier.players_found[playerID];
+ return index == null || index < 0;
+ }, orElse: () => null);
+ status = arrangeID != null ? "Tap to place" : "Waiting for players...";
+ } else {
+ status = "Play Hearts!";
+ canStart = true;
+ }
+
+ List<Widget> children = [new Text(status, style: style.Text.hugeStyle)];
+ // Also add the player's name (using a placeholder if that's not possible).
+ if (arrangeID != null) {
+ children.add(new CroupierProfileComponent.textOnly(
+ settings: config.croupier.settings_everyone[arrangeID]));
+ }
+
+ // You will need to show a Start Game button if the table isn't the creator.
+ // Replace the status text with a status button instead.
+ if (canStart && !config.croupier.game.isCreator) {
+ children = [
+ new FlatButton(
+ child: new Text(status, style: style.Text.hugeStyle),
+ color: style.theme.accentColor, onPressed: () {
+ config.croupier.settings_manager
+ .setGameStatus(config.croupier.game.gameID, "RUNNING");
+ })
+ ];
+ }
+ Widget firstChild =
+ new Row(children, justifyContent: FlexJustifyContent.collapse);
return new Container(
decoration: style.Box.liveNow,
- height: height,
- width: width,
+ height: config.height,
+ width: config.width,
child: new Column([
- new Flexible(
- flex: 1,
- child: new Row(
- [_buildEmptySlot(), _buildSlot("social/person_outline", 2), _buildEmptySlot()],
- justifyContent: FlexJustifyContent.spaceAround,
- alignItems: FlexAlignItems.stretch)),
- new Flexible(
- flex: 1,
- child: new Row([
- _buildSlot("social/person_outline", 1),
- _buildSlot("hardware/tablet", 4, extra: "x${numAtTable}"),
- _buildSlot("social/person_outline", 3)
- ],
- justifyContent: FlexJustifyContent.spaceAround,
- alignItems: FlexAlignItems.stretch)),
- new Flexible(
- flex: 1,
- child: new Row(
- [_buildEmptySlot(), _buildSlot("social/person_outline", 0), _buildEmptySlot()],
- justifyContent: FlexJustifyContent.spaceAround,
- alignItems: FlexAlignItems.stretch))
- ],
- justifyContent: FlexJustifyContent.spaceAround,
- alignItems: FlexAlignItems.stretch));
+ firstChild,
+ new Flexible(child: _buildArrangeTable(activeID: arrangeID))
+ ], alignItems: FlexAlignItems.center));
+ }
+
+ Widget _buildPlayerArrangePlayers() {
+ List<Widget> children = <Widget>[
+ new Text("Waiting for game setup...", style: style.Text.hugeStyle)
+ ];
+ if (config.croupier.game.isCreator) {
+ children.add(new FlatButton(
+ child: new Text("Manual Setup", style: style.Text.largeStyle),
+ color: style.theme.accentColor, onPressed: () {
+ setState(() {
+ fallback = true;
+ });
+ }));
+ }
+
+ return new Container(
+ decoration: style.Box.liveNow,
+ height: config.height,
+ width: config.width,
+ child: new Column(children, alignItems: FlexAlignItems.center));
+ }
+
+ Widget _buildFallbackArrangePlayers() {
+ return new Container(
+ decoration: style.Box.liveNow,
+ height: config.height,
+ width: config.width,
+ child: _buildArrangeTable(canDragTo: true));
+ }
+
+ Widget _buildArrangeTable({int activeID: null, bool canDragTo: false}) {
+ int numAtTable = config.croupier.players_found.values
+ .where((int playerNumber) => playerNumber == 4)
+ .length;
+ return new Column([
+ new Flexible(
+ flex: 1,
+ child: new Row([
+ _buildEmptySlot(),
+ _buildSlot(personIcon, 2, activeID, canDragTo),
+ _buildEmptySlot()
+ ],
+ justifyContent: FlexJustifyContent.spaceAround,
+ alignItems: FlexAlignItems.stretch)),
+ new Flexible(
+ flex: 1,
+ child: new Row([
+ _buildSlot(personIcon, 1, activeID, canDragTo),
+ _buildSlot(tableIcon, 4, activeID, canDragTo,
+ extra: "x${numAtTable}"),
+ _buildSlot(personIcon, 3, activeID, canDragTo)
+ ],
+ justifyContent: FlexJustifyContent.spaceAround,
+ alignItems: FlexAlignItems.stretch)),
+ new Flexible(
+ flex: 1,
+ child: new Row([
+ _buildEmptySlot(),
+ _buildSlot(personIcon, 0, activeID, canDragTo),
+ _buildEmptySlot()
+ ],
+ justifyContent: FlexJustifyContent.spaceAround,
+ alignItems: FlexAlignItems.stretch))
+ ],
+ justifyContent: FlexJustifyContent.spaceAround,
+ alignItems: FlexAlignItems.stretch);
}
Widget _buildEmptySlot() {
return new Flexible(flex: 1, child: new Text(""));
}
- Widget _buildSlot(String name, int index, {String extra: ""}) {
+ Widget _buildSlot(String name, int index, int activeID, bool canDragTo,
+ {String extra: ""}) {
Widget slotWidget = new Row([
new Icon(size: IconSize.s48, icon: name),
new Text(extra, style: style.Text.largeStyle)
@@ -872,29 +1018,36 @@
alignItems: FlexAlignItems.center,
justifyContent: FlexJustifyContent.center);
- bool isMe = croupier.game.playerNumber == index;
+ bool isMe = config.croupier.game.playerNumber == index;
bool isPlayerIndex = index >= 0 && index < 4;
bool isTableIndex = index == 4;
bool seatTaken = (isPlayerIndex || (isTableIndex && isMe)) &&
- croupier.players_found.containsValue(index);
+ config.croupier.players_found.containsValue(index);
if (seatTaken) {
// Note: If more than 1 person is in the seat, it may no longer show you.
- CroupierSettings cs = croupier.settingsFromPlayerNumber(index);
- CroupierProfileComponent cpc = new CroupierProfileComponent(settings: cs);
+ CroupierSettings cs = config.croupier.settingsFromPlayerNumber(index);
+ CroupierProfileComponent cpc =
+ new CroupierProfileComponent.horizontal(settings: cs);
slotWidget =
new Draggable<CroupierSettings>(child: cpc, feedback: cpc, data: cs);
}
Widget dragTarget = new DragTarget<CroupierSettings>(
builder: (BuildContext context, List<CroupierSettings> data, _) {
- return new Container(
- constraints: const BoxConstraints.expand(),
- decoration: isMe ? style.Box.liveBackground : style.Box.border,
- child: slotWidget);
+ return new GestureDetector(onTap: () {
+ if (activeID != null) {
+ config.croupier.settings_manager
+ .setPlayerNumber(config.croupier.game.gameID, activeID, index);
+ }
+ },
+ child: new Container(
+ constraints: const BoxConstraints.expand(),
+ decoration: isMe ? style.Box.liveBackground : style.Box.border,
+ child: new Center(child: slotWidget)));
}, onAccept: (CroupierSettings cs) {
- croupier.settings_manager
- .setPlayerNumber(croupier.game.gameID, cs.userID, index);
- }, onWillAccept: (_) => true);
+ config.croupier.settings_manager
+ .setPlayerNumber(config.croupier.game.gameID, cs.userID, index);
+ }, onWillAccept: (_) => canDragTo);
return new Flexible(flex: 1, child: dragTarget);
}
diff --git a/lib/components/main_route.dart b/lib/components/main_route.dart
index 0c402bd..2c4887f 100644
--- a/lib/components/main_route.dart
+++ b/lib/components/main_route.dart
@@ -81,8 +81,8 @@
child: new BlockBody([
new CroupierProfileComponent(
settings: config.croupier.settings,
- width: style.Size.settingsSize,
- height: style.Size.settingsSize),
+ width: style.Size.settingsWidth,
+ height: style.Size.settingsHeight),
new Text('Croupier', style: style.Text.titleStyle)
])),
new DrawerItem(
diff --git a/lib/logic/croupier.dart b/lib/logic/croupier.dart
index 5c33aa2..0970318 100644
--- a/lib/logic/croupier.dart
+++ b/lib/logic/croupier.dart
@@ -199,8 +199,6 @@
_advertiseFuture = settings_manager
.createGameSyncgroup(gameTypeToString(gt), game.gameID)
.then((GameStartData gsd) {
- // The game creator should always sit as player 0, at least initially.
- settings_manager.setPlayerNumber(gsd.gameID, settings.userID, 0);
// Only the game chooser should be advertising the game.
return settings_manager.advertiseSettings(gsd);
}); // don't wait for this future.
@@ -232,11 +230,7 @@
assert(sgName != null);
players_found[gsd.ownerID] = null;
- settings_manager.joinGameSyncgroup(sgName, gsd.gameID).then((_) {
- if (!game.gameArrangeData.needsArrangement) {
- settings_manager.setPlayerNumber(gsd.gameID, settings.userID, 0);
- }
- });
+ settings_manager.joinGameSyncgroup(sgName, gsd.gameID);
break;
case CroupierState.ArrangePlayers:
diff --git a/lib/logic/croupier_settings.dart b/lib/logic/croupier_settings.dart
index 0522fed..8f18c3a 100644
--- a/lib/logic/croupier_settings.dart
+++ b/lib/logic/croupier_settings.dart
@@ -151,7 +151,7 @@
int nameIndex = rng.nextInt(names.length);
int appIndex = rng.nextInt(appellations.length);
- return "${names[nameIndex]} the ${appellations[appIndex]}";
+ return "${names[nameIndex]} ${appellations[appIndex]}";
}
// Return something between 0x00000000 and 0xffffffff
diff --git a/lib/src/syncbase/settings_manager.dart b/lib/src/syncbase/settings_manager.dart
index a2170d1..336c38c 100644
--- a/lib/src/syncbase/settings_manager.dart
+++ b/lib/src/syncbase/settings_manager.dart
@@ -207,7 +207,10 @@
// Watch for the players in the game.
_gameSubscription = await _cc.watchEverything(
- db, util.tableNameGames, util.syncgamePrefix(gameID), _onGameChange);
+ db, util.tableNameGames, util.syncgamePrefix(gameID), _onGameChange,
+ sorter: (sc.WatchChange a, sc.WatchChange b) {
+ return a.rowKey.compareTo(b.rowKey);
+ });
await _cc.joinSyncgroup(sgName);
diff --git a/lib/src/syncbase/util.dart b/lib/src/syncbase/util.dart
index c6c8259..83ec86e 100644
--- a/lib/src/syncbase/util.dart
+++ b/lib/src/syncbase/util.dart
@@ -10,9 +10,6 @@
const String tableNameGames = 'games';
const String tableNameSettings = 'table_settings';
-// TODO(alexfandrianto): This may need to be the global mount table with a
-// proxy. Otherwise, it will be difficult for other users to run.
-// https://github.com/vanadium/issues/issues/782
String makeSgPrefix(String mounttable, String deviceID) {
return "${mounttable}/croupier-${deviceID}/%%sync";
}
diff --git a/lib/styles/common.dart b/lib/styles/common.dart
index 77caba5..f3ba93e 100644
--- a/lib/styles/common.dart
+++ b/lib/styles/common.dart
@@ -23,7 +23,8 @@
class Size {
static const double splashLogo = 75.0;
- static const double settingsSize = 125.0;
+ static const double settingsHeight = 125.0;
+ static const double settingsWidth = 175.0;
}
class Spacing {
diff --git a/pubspec.lock b/pubspec.lock
index f2e179a..0be2f9c 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -12,7 +12,7 @@
args:
description: args
source: hosted
- version: "0.13.2"
+ version: "0.13.3+1"
asn1lib:
description: asn1lib
source: hosted
@@ -20,7 +20,7 @@
async:
description: async
source: hosted
- version: "1.6.0"
+ version: "1.8.0"
barback:
description: barback
source: hosted
@@ -50,7 +50,7 @@
collection:
description: collection
source: hosted
- version: "1.2.0"
+ version: "1.4.0"
contrast:
description: contrast
source: hosted
@@ -102,11 +102,11 @@
github:
description: github
source: hosted
- version: "2.3.1"
+ version: "2.3.1+1"
glob:
description: glob
source: hosted
- version: "1.0.5"
+ version: "1.1.0"
html:
description: html
source: hosted
@@ -126,7 +126,7 @@
intl:
description: intl
source: hosted
- version: "0.12.5"
+ version: "0.12.6"
logging:
description: logging
source: hosted
@@ -184,7 +184,7 @@
petitparser:
description: petitparser
source: hosted
- version: "1.5.0"
+ version: "1.5.1"
plugin:
description: plugin
source: hosted
@@ -240,11 +240,11 @@
stack_trace:
description: stack_trace
source: hosted
- version: "1.5.1"
+ version: "1.6.0"
string_scanner:
description: string_scanner
source: hosted
- version: "0.1.4"
+ version: "0.1.4+1"
syncbase:
description: syncbase
source: hosted
@@ -268,7 +268,7 @@
vector_math:
description: vector_math
source: hosted
- version: "1.4.4"
+ version: "1.4.6"
watcher:
description: watcher
source: hosted
@@ -284,8 +284,8 @@
xml:
description: xml
source: hosted
- version: "2.4.0"
+ version: "2.4.1"
yaml:
description: yaml
source: hosted
- version: "2.1.7"
+ version: "2.1.8"
diff --git a/shortcut_template b/shortcut_template
index 015b1db..cb90797 100644
--- a/shortcut_template
+++ b/shortcut_template
@@ -6,6 +6,6 @@
--args-for=mojo:flutter --enable-checked-mode
--enable-multiprocess
--map-origin=https://mojo2.v.io=https://storage.googleapis.com/mojo_services/v23discovery/mojo_services/android/
---args-for=https://mojo2.v.io/discovery.mojo host%DEVICE_ID% mdns
+--args-for=https://mojo2.v.io/discovery.mojo host%DEVICE_ID%
--map-origin=https://mojo.v.io=https://storage.googleapis.com/mojo_services/syncbase/mojo_services/android/
---args-for=https://mojo.v.io/syncbase_server.mojo --v=0 --logtostderr=true --root-dir=/data/data/org.chromium.mojo.shell/app_home/syncbase_data --v23.credentials=/sdcard/v23creds %SYNCBASE_NAME_FLAG%
+--args-for=https://mojo.v.io/syncbase_server.mojo --v=0 --logtostderr=true --root-dir=/data/data/org.chromium.mojo.shell/app_home/syncbase_data --v23.credentials=/sdcard/v23creds %SYNCBASE_NAME_FLAG% %PROXY_FLAG%