{"action":"created","comment":{"url":"https://api.github.com/repos/flutter/flutter/pulls/comments/45284994","id":45284994,"diff_hunk":"@@ -77,46 +79,102 @@ class _ScaffoldLayout extends MultiChildLayoutDelegate {\n \n final _ScaffoldLayout _scaffoldLayout = new _ScaffoldLayout();\n \n-void _addIfNonNull(List<LayoutId> children, Widget child, Object childId) {\n-  if (child != null)\n-    children.add(new LayoutId(child: child, id: childId));\n-}\n-\n-class Scaffold extends StatelessComponent {\n+class Scaffold extends StatefulComponent {\n   Scaffold({\n     Key key,\n-    this.body,\n     this.toolBar,\n-    this.snackBar,\n-    this.floatingActionButton,\n-    this.bottomSheet\n+    this.body,\n+    this.bottomSheet,\n+    this.floatingActionButton\n   }) : super(key: key);\n \n-  final Widget body;\n   final ToolBar toolBar;\n-  final Widget snackBar;\n+  final Widget body;\n+  final Widget bottomSheet; // this is for non-modal bottom sheets\n   final Widget floatingActionButton;\n-  final Widget bottomSheet;\n+\n+  static ScaffoldState of(BuildContext context) => context.ancestorStateOfType(ScaffoldState);\n+\n+  ScaffoldState createState() => new ScaffoldState();\n+}\n+\n+class ScaffoldState extends State<Scaffold> {\n+\n+  List<SnackBar> _snackBars = <SnackBar>[];\n+  Performance _snackBarPerformance;\n+  Timer _snackBarTimer;\n+\n+  void showSnackBar(SnackBar snackbar) {\n+    _snackBarPerformance ??= SnackBar.createPerformance(_handleSnackBarStatusChange);\n+    setState(() {\n+      _snackBars.add(snackbar.withPerformance(_snackBarPerformance));\n+    });\n+  }\n+\n+  void _handleSnackBarStatusChange(PerformanceStatus status) {\n+    switch (status) {\n+      case PerformanceStatus.dismissed:\n+        assert(_snackBars.isNotEmpty);\n+        setState(() {\n+          _snackBars.removeAt(0);\n+        });\n+        break;\n+      case PerformanceStatus.completed:\n+        setState(() {\n+          assert(_snackBarTimer == null);\n+          // build will create a new timer if necessary to dismiss the snack bar\n+        });\n+        break;\n+      case PerformanceStatus.forward:\n+      case PerformanceStatus.reverse:\n+        break;\n+    }\n+  }\n+\n+  void _hideSnackBar() {\n+    _snackBarPerformance.reverse();\n+    _snackBarTimer = null;\n+  }\n+\n+  void dispose() {\n+    _snackBarPerformance?.stop();\n+    _snackBarTimer?.cancel();\n+    super.dispose();\n+  }\n+\n+  void _addIfNonNull(List<LayoutId> children, Widget child, Object childId) {\n+    if (child != null)\n+      children.add(new LayoutId(child: child, id: childId));\n+  }\n \n   Widget build(BuildContext context) {\n-    final Widget paddedToolBar = toolBar?.withPadding(new EdgeDims.only(top: ui.window.padding.top));\n-    final Widget materialBody = body != null ? new Material(child: body) : null;\n-    Widget constrainedSnackBar;\n-    if (snackBar != null) {\n-      // TODO(jackson): On tablet/desktop, minWidth = 288, maxWidth = 568\n-      constrainedSnackBar = new ConstrainedBox(\n-        constraints: const BoxConstraints(maxHeight: kSnackBarHeight),\n-        child: snackBar\n-      );\n+    final Widget paddedToolBar = config.toolBar?.withPadding(new EdgeDims.only(top: ui.window.padding.top));\n+    final Widget materialBody = config.body != null ? new Material(child: config.body) : null;\n+\n+    if (_snackBars.length > 0) {\n+print('build! ${_snackBars.length} ${ModalRoute.of(context).isCurrent}');\n+      if (_snackBarPerformance.isDismissed)\n+        _snackBarPerformance.forward();\n+      if (ModalRoute.of(context).isCurrent) {","path":"packages/flutter/lib/src/material/scaffold.dart","position":121,"original_position":121,"commit_id":"0131c8d6cca8828571c81bd3f551dc9d66851750","original_commit_id":"0131c8d6cca8828571c81bd3f551dc9d66851750","user":{"login":"abarth","id":112007,"avatar_url":"https://avatars.githubusercontent.com/u/112007?v=3","gravatar_id":"","url":"https://api.github.com/users/abarth","html_url":"https://github.com/abarth","followers_url":"https://api.github.com/users/abarth/followers","following_url":"https://api.github.com/users/abarth/following{/other_user}","gists_url":"https://api.github.com/users/abarth/gists{/gist_id}","starred_url":"https://api.github.com/users/abarth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/abarth/subscriptions","organizations_url":"https://api.github.com/users/abarth/orgs","repos_url":"https://api.github.com/users/abarth/repos","events_url":"https://api.github.com/users/abarth/events{/privacy}","received_events_url":"https://api.github.com/users/abarth/received_events","type":"User","site_admin":false},"body":"Should we handle the error of not finding the modal route?","created_at":"2015-11-19T00:48:50Z","updated_at":"2015-11-19T00:48:50Z","html_url":"https://github.com/flutter/flutter/pull/479#discussion_r45284994","pull_request_url":"https://api.github.com/repos/flutter/flutter/pulls/479","_links":{"self":{"href":"https://api.github.com/repos/flutter/flutter/pulls/comments/45284994"},"html":{"href":"https://github.com/flutter/flutter/pull/479#discussion_r45284994"},"pull_request":{"href":"https://api.github.com/repos/flutter/flutter/pulls/479"}}},"pull_request":{"url":"https://api.github.com/repos/flutter/flutter/pulls/479","id":51164901,"html_url":"https://github.com/flutter/flutter/pull/479","diff_url":"https://github.com/flutter/flutter/pull/479.diff","patch_url":"https://github.com/flutter/flutter/pull/479.patch","issue_url":"https://api.github.com/repos/flutter/flutter/issues/479","number":479,"state":"open","locked":false,"title":"Snackbar Refactor","user":{"login":"Hixie","id":551196,"avatar_url":"https://avatars.githubusercontent.com/u/551196?v=3","gravatar_id":"","url":"https://api.github.com/users/Hixie","html_url":"https://github.com/Hixie","followers_url":"https://api.github.com/users/Hixie/followers","following_url":"https://api.github.com/users/Hixie/following{/other_user}","gists_url":"https://api.github.com/users/Hixie/gists{/gist_id}","starred_url":"https://api.github.com/users/Hixie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Hixie/subscriptions","organizations_url":"https://api.github.com/users/Hixie/orgs","repos_url":"https://api.github.com/users/Hixie/repos","events_url":"https://api.github.com/users/Hixie/events{/privacy}","received_events_url":"https://api.github.com/users/Hixie/received_events","type":"User","site_admin":false},"body":"\"showSnackBar()\" is now a feature of a Scaffold. To get to a Scaffold\r\nyou either use a global key (`scaffoldKey.currentState.showSnackBar(...)`),\r\nor you use `Scaffold.of(context)`.\r\n\r\nSnack bars no longer have a route. They are entirely managed by the\r\nScaffold. Fixes #432.\r\n\r\nSnack bars now queue up when you have several of them. Fixes #374.\r\n\r\nSnack bars now auto-size themselves around their contents. This is step\r\none towards implementing multiline snack bars.\r\n\r\nSnack bars now self-dismiss after some per-snackbar configurable period.\r\n\r\nThe self-dismissing pauses while a dialog is up above the snackbar (or\r\nanything that uses ModalRoute). To enable this, there's now a\r\n`ModalRoute.of(context)` API that returns the current ModalRoute, and\r\nyou will be rebuilt if you asked for this and the route's \"current\"\r\nstatus changes. To implement this, the Navigator now rebuilds\r\nunconditionally any time it pushes or pops a route.\r\n\r\nSnack bars now use the curves that Android uses for snack bars.\r\n\r\nSnack bar contents now fade in.","created_at":"2015-11-19T00:41:04Z","updated_at":"2015-11-19T00:48:50Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5ac0b0034c0feb8e26bb53fe7fab4bfb5a3ac280","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/flutter/flutter/pulls/479/commits","review_comments_url":"https://api.github.com/repos/flutter/flutter/pulls/479/comments","review_comment_url":"https://api.github.com/repos/flutter/flutter/pulls/comments{/number}","comments_url":"https://api.github.com/repos/flutter/flutter/issues/479/comments","statuses_url":"https://api.github.com/repos/flutter/flutter/statuses/0131c8d6cca8828571c81bd3f551dc9d66851750","head":{"label":"Hixie:yak3-snackbar-PENDING","ref":"yak3-snackbar-PENDING","sha":"0131c8d6cca8828571c81bd3f551dc9d66851750","user":{"login":"Hixie","id":551196,"avatar_url":"https://avatars.githubusercontent.com/u/551196?v=3","gravatar_id":"","url":"https://api.github.com/users/Hixie","html_url":"https://github.com/Hixie","followers_url":"https://api.github.com/users/Hixie/followers","following_url":"https://api.github.com/users/Hixie/following{/other_user}","gists_url":"https://api.github.com/users/Hixie/gists{/gist_id}","starred_url":"https://api.github.com/users/Hixie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Hixie/subscriptions","organizations_url":"https://api.github.com/users/Hixie/orgs","repos_url":"https://api.github.com/users/Hixie/repos","events_url":"https://api.github.com/users/Hixie/events{/privacy}","received_events_url":"https://api.github.com/users/Hixie/received_events","type":"User","site_admin":false},"repo":{"id":45635647,"name":"flutter","full_name":"Hixie/flutter","owner":{"login":"Hixie","id":551196,"avatar_url":"https://avatars.githubusercontent.com/u/551196?v=3","gravatar_id":"","url":"https://api.github.com/users/Hixie","html_url":"https://github.com/Hixie","followers_url":"https://api.github.com/users/Hixie/followers","following_url":"https://api.github.com/users/Hixie/following{/other_user}","gists_url":"https://api.github.com/users/Hixie/gists{/gist_id}","starred_url":"https://api.github.com/users/Hixie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Hixie/subscriptions","organizations_url":"https://api.github.com/users/Hixie/orgs","repos_url":"https://api.github.com/users/Hixie/repos","events_url":"https://api.github.com/users/Hixie/events{/privacy}","received_events_url":"https://api.github.com/users/Hixie/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Hixie/flutter","description":"The Flutter framework","fork":true,"url":"https://api.github.com/repos/Hixie/flutter","forks_url":"https://api.github.com/repos/Hixie/flutter/forks","keys_url":"https://api.github.com/repos/Hixie/flutter/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Hixie/flutter/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Hixie/flutter/teams","hooks_url":"https://api.github.com/repos/Hixie/flutter/hooks","issue_events_url":"https://api.github.com/repos/Hixie/flutter/issues/events{/number}","events_url":"https://api.github.com/repos/Hixie/flutter/events","assignees_url":"https://api.github.com/repos/Hixie/flutter/assignees{/user}","branches_url":"https://api.github.com/repos/Hixie/flutter/branches{/branch}","tags_url":"https://api.github.com/repos/Hixie/flutter/tags","blobs_url":"https://api.github.com/repos/Hixie/flutter/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Hixie/flutter/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Hixie/flutter/git/refs{/sha}","trees_url":"https://api.github.com/repos/Hixie/flutter/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Hixie/flutter/statuses/{sha}","languages_url":"https://api.github.com/repos/Hixie/flutter/languages","stargazers_url":"https://api.github.com/repos/Hixie/flutter/stargazers","contributors_url":"https://api.github.com/repos/Hixie/flutter/contributors","subscribers_url":"https://api.github.com/repos/Hixie/flutter/subscribers","subscription_url":"https://api.github.com/repos/Hixie/flutter/subscription","commits_url":"https://api.github.com/repos/Hixie/flutter/commits{/sha}","git_commits_url":"https://api.github.com/repos/Hixie/flutter/git/commits{/sha}","comments_url":"https://api.github.com/repos/Hixie/flutter/comments{/number}","issue_comment_url":"https://api.github.com/repos/Hixie/flutter/issues/comments{/number}","contents_url":"https://api.github.com/repos/Hixie/flutter/contents/{+path}","compare_url":"https://api.github.com/repos/Hixie/flutter/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Hixie/flutter/merges","archive_url":"https://api.github.com/repos/Hixie/flutter/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Hixie/flutter/downloads","issues_url":"https://api.github.com/repos/Hixie/flutter/issues{/number}","pulls_url":"https://api.github.com/repos/Hixie/flutter/pulls{/number}","milestones_url":"https://api.github.com/repos/Hixie/flutter/milestones{/number}","notifications_url":"https://api.github.com/repos/Hixie/flutter/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Hixie/flutter/labels{/name}","releases_url":"https://api.github.com/repos/Hixie/flutter/releases{/id}","created_at":"2015-11-05T19:54:58Z","updated_at":"2015-11-05T19:54:59Z","pushed_at":"2015-11-19T00:40:53Z","git_url":"git://github.com/Hixie/flutter.git","ssh_url":"git@github.com:Hixie/flutter.git","clone_url":"https://github.com/Hixie/flutter.git","svn_url":"https://github.com/Hixie/flutter","homepage":"http://flutter.io","size":10223,"stargazers_count":0,"watchers_count":0,"language":"Dart","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"flutter:master","ref":"master","sha":"67b2ee3a3b4ed6355292fa62e202fcd2fbd68d8b","user":{"login":"flutter","id":14101776,"avatar_url":"https://avatars.githubusercontent.com/u/14101776?v=3","gravatar_id":"","url":"https://api.github.com/users/flutter","html_url":"https://github.com/flutter","followers_url":"https://api.github.com/users/flutter/followers","following_url":"https://api.github.com/users/flutter/following{/other_user}","gists_url":"https://api.github.com/users/flutter/gists{/gist_id}","starred_url":"https://api.github.com/users/flutter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flutter/subscriptions","organizations_url":"https://api.github.com/users/flutter/orgs","repos_url":"https://api.github.com/users/flutter/repos","events_url":"https://api.github.com/users/flutter/events{/privacy}","received_events_url":"https://api.github.com/users/flutter/received_events","type":"Organization","site_admin":false},"repo":{"id":31792824,"name":"flutter","full_name":"flutter/flutter","owner":{"login":"flutter","id":14101776,"avatar_url":"https://avatars.githubusercontent.com/u/14101776?v=3","gravatar_id":"","url":"https://api.github.com/users/flutter","html_url":"https://github.com/flutter","followers_url":"https://api.github.com/users/flutter/followers","following_url":"https://api.github.com/users/flutter/following{/other_user}","gists_url":"https://api.github.com/users/flutter/gists{/gist_id}","starred_url":"https://api.github.com/users/flutter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/flutter/subscriptions","organizations_url":"https://api.github.com/users/flutter/orgs","repos_url":"https://api.github.com/users/flutter/repos","events_url":"https://api.github.com/users/flutter/events{/privacy}","received_events_url":"https://api.github.com/users/flutter/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/flutter/flutter","description":"The Flutter framework","fork":false,"url":"https://api.github.com/repos/flutter/flutter","forks_url":"https://api.github.com/repos/flutter/flutter/forks","keys_url":"https://api.github.com/repos/flutter/flutter/keys{/key_id}","collaborators_url":"https://api.github.com/repos/flutter/flutter/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/flutter/flutter/teams","hooks_url":"https://api.github.com/repos/flutter/flutter/hooks","issue_events_url":"https://api.github.com/repos/flutter/flutter/issues/events{/number}","events_url":"https://api.github.com/repos/flutter/flutter/events","assignees_url":"https://api.github.com/repos/flutter/flutter/assignees{/user}","branches_url":"https://api.github.com/repos/flutter/flutter/branches{/branch}","tags_url":"https://api.github.com/repos/flutter/flutter/tags","blobs_url":"https://api.github.com/repos/flutter/flutter/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/flutter/flutter/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/flutter/flutter/git/refs{/sha}","trees_url":"https://api.github.com/repos/flutter/flutter/git/trees{/sha}","statuses_url":"https://api.github.com/repos/flutter/flutter/statuses/{sha}","languages_url":"https://api.github.com/repos/flutter/flutter/languages","stargazers_url":"https://api.github.com/repos/flutter/flutter/stargazers","contributors_url":"https://api.github.com/repos/flutter/flutter/contributors","subscribers_url":"https://api.github.com/repos/flutter/flutter/subscribers","subscription_url":"https://api.github.com/repos/flutter/flutter/subscription","commits_url":"https://api.github.com/repos/flutter/flutter/commits{/sha}","git_commits_url":"https://api.github.com/repos/flutter/flutter/git/commits{/sha}","comments_url":"https://api.github.com/repos/flutter/flutter/comments{/number}","issue_comment_url":"https://api.github.com/repos/flutter/flutter/issues/comments{/number}","contents_url":"https://api.github.com/repos/flutter/flutter/contents/{+path}","compare_url":"https://api.github.com/repos/flutter/flutter/compare/{base}...{head}","merges_url":"https://api.github.com/repos/flutter/flutter/merges","archive_url":"https://api.github.com/repos/flutter/flutter/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/flutter/flutter/downloads","issues_url":"https://api.github.com/repos/flutter/flutter/issues{/number}","pulls_url":"https://api.github.com/repos/flutter/flutter/pulls{/number}","milestones_url":"https://api.github.com/repos/flutter/flutter/milestones{/number}","notifications_url":"https://api.github.com/repos/flutter/flutter/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/flutter/flutter/labels{/name}","releases_url":"https://api.github.com/repos/flutter/flutter/releases{/id}","created_at":"2015-03-06T22:54:58Z","updated_at":"2015-11-18T20:29:03Z","pushed_at":"2015-11-19T00:41:04Z","git_url":"git://github.com/flutter/flutter.git","ssh_url":"git@github.com:flutter/flutter.git","clone_url":"https://github.com/flutter/flutter.git","svn_url":"https://github.com/flutter/flutter","homepage":"http://flutter.io","size":101753,"stargazers_count":2194,"watchers_count":2194,"language":"Dart","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":211,"mirror_url":null,"open_issues_count":273,"forks":211,"open_issues":273,"watchers":2194,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/flutter/flutter/pulls/479"},"html":{"href":"https://github.com/flutter/flutter/pull/479"},"issue":{"href":"https://api.github.com/repos/flutter/flutter/issues/479"},"comments":{"href":"https://api.github.com/repos/flutter/flutter/issues/479/comments"},"review_comments":{"href":"https://api.github.com/repos/flutter/flutter/pulls/479/comments"},"review_comment":{"href":"https://api.github.com/repos/flutter/flutter/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/flutter/flutter/pulls/479/commits"},"statuses":{"href":"https://api.github.com/repos/flutter/flutter/statuses/0131c8d6cca8828571c81bd3f551dc9d66851750"}}}}