croupier: Show name of the game being advertised

Also tweaked a small issue with the "lost" part of the advertisements.

Change-Id: Id829b82291f504891079da31ff1fac5252f8a2c5
diff --git a/lib/components/croupier.dart b/lib/components/croupier.dart
index 211bd7b..415e8f7 100644
--- a/lib/components/croupier.dart
+++ b/lib/components/croupier.dart
@@ -10,6 +10,8 @@
 import '../logic/croupier_settings.dart' show CroupierSettings;
 import '../logic/game/game.dart' as logic_game;
 import '../styles/common.dart' as style;
+import 'croupier_game_advertisement.dart'
+    show CroupierGameAdvertisementComponent;
 import 'croupier_profile.dart' show CroupierProfileComponent;
 import 'game.dart' as component_game;
 
@@ -75,32 +77,34 @@
                       logic_croupier.CroupierState.Welcome))
             ], direction: FlexDirection.vertical));
       case logic_croupier.CroupierState.JoinGame:
-        // A stateful view, first showing the players that can be seen creating a game.
-        List<Widget> profileWidgets = new List<Widget>();
+        // A stateful view, showing the game ads discovered.
+        List<Widget> gameAdWidgets = new List<Widget>();
+        if (config.croupier.games_found.length == 0) {
+          gameAdWidgets.add(
+              new Text("Looking for Games...", style: style.Text.titleStyle));
+        } else {
+          gameAdWidgets
+              .add(new Text("Available Games", style: style.Text.titleStyle));
+        }
+
         config.croupier.games_found
             .forEach((String _, logic_game.GameStartData gsd) {
           CroupierSettings cs = config.croupier.settings_everyone[gsd.ownerID];
-          // cs could be null if this settings data hasn't synced yet.
-          // If so, a placeholder is shown instead.
-          profileWidgets.add(new GestureDetector(
-              child: new CroupierProfileComponent(settings: cs),
+          gameAdWidgets.add(new CroupierGameAdvertisementComponent(gsd,
               onTap: makeSetStateCallback(
-                  logic_croupier.CroupierState.ArrangePlayers, gsd)));
+                  logic_croupier.CroupierState.ArrangePlayers, gsd),
+              settings: cs));
         });
+
+        gameAdWidgets.add(new FlatButton(
+            child: new Text('Back', style: style.Text.subtitleStyle),
+            onPressed:
+                makeSetStateCallback(logic_croupier.CroupierState.Welcome)));
+
         // in which players wait for game invitations to arrive.
         return new Container(
             padding: new EdgeDims.only(top: ui.window.padding.top),
-            child: new Column([
-              profileWidgets.length == 0
-                  ? new Text("Looking for Games...",
-                      style: style.Text.titleStyle)
-                  : new Text("Available Games", style: style.Text.titleStyle),
-              new Grid(profileWidgets, maxChildExtent: 150.0),
-              new FlatButton(
-                  child: new Text('Back', style: style.Text.subtitleStyle),
-                  onPressed: makeSetStateCallback(
-                      logic_croupier.CroupierState.Welcome))
-            ]));
+            child: new Column(gameAdWidgets));
       case logic_croupier.CroupierState.ArrangePlayers:
         List<Widget> profileWidgets = new List<Widget>();
         config.croupier.players_found.forEach((int userID, _) {
diff --git a/lib/components/croupier_game_advertisement.dart b/lib/components/croupier_game_advertisement.dart
new file mode 100644
index 0000000..545f028
--- /dev/null
+++ b/lib/components/croupier_game_advertisement.dart
@@ -0,0 +1,33 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import 'package:flutter/material.dart';
+
+import 'croupier_profile.dart';
+import '../logic/croupier_settings.dart' show CroupierSettings;
+import '../logic/game/game.dart' as game;
+import '../styles/common.dart' as style;
+
+typedef void NoArgCb();
+
+class CroupierGameAdvertisementComponent extends StatelessComponent {
+  final CroupierSettings settings;
+  final game.GameStartData gameStartData;
+  final NoArgCb onTap;
+
+  CroupierGameAdvertisementComponent(this.gameStartData,
+      {CroupierSettings settings, this.onTap})
+      : settings = settings ?? new CroupierSettings.placeholder();
+
+  Widget build(BuildContext context) {
+    return new GestureDetector(
+        child: new Card(
+            child: new Row([
+          new Card(child: new CroupierProfileComponent(settings: settings)),
+          new Text(game.gameTypeToString(gameStartData.gameType),
+              style: style.Text.hugeStyle),
+        ])),
+        onTap: onTap);
+  }
+}
diff --git a/lib/src/syncbase/settings_manager.dart b/lib/src/syncbase/settings_manager.dart
index 297a363..8a5b88b 100644
--- a/lib/src/syncbase/settings_manager.dart
+++ b/lib/src/syncbase/settings_manager.dart
@@ -364,9 +364,7 @@
     // Looks like leave isn't actually implemented, so we can't do this.
     String addr = gameAddrs[instanceId];
     if (addr != null) {
-      List<String> parts = addr.split("-");
-      String gameID = parts[parts.length - 1];
-      updateGamesCallback(gameID, null);
+      updateGamesCallback(addr, null);
     }
     settingsAddrs.remove(instanceId);
     gameAddrs.remove(instanceId);