1
0
mirror of https://github.com/flutter/samples.git synced 2025-11-11 23:39:14 +00:00

Update web/ samples to work with Flutter SDK (#134)

* add package:http dependency in dad_jokes

* add package:http dependency in filipino_cuisine

* don't build package:http demos until flutter/flutter#34858 is resolved

* update gallery

* update github_dataviz

* update particle_background

* don't build github_dataviz (uses package:http)

* update slide_puzzle

* update spinning_square

* update timeflow

* update vision_challenge

* update charts

* update dad_jokes

* update filipino cuisine

* ignore build output

* update timeflow and vision_challenge

* update slide_puzzle

* don't commit build/ directory

* move preview.png images to assets

* fix path url join

* update readme

* update web/readme.md
This commit is contained in:
John Ryan
2019-09-10 09:49:58 -07:00
committed by GitHub
parent 16fa475ff8
commit 317d459a58
746 changed files with 14607 additions and 61610 deletions

View File

@@ -1,93 +0,0 @@
include: package:pedantic/analysis_options.yaml
analyzer:
strong-mode:
implicit-casts: false
linter:
rules:
- always_declare_return_types
- annotate_overrides
- avoid_bool_literals_in_conditional_expressions
- avoid_classes_with_only_static_members
- avoid_empty_else
- avoid_function_literals_in_foreach_calls
- avoid_init_to_null
- avoid_null_checks_in_equality_operators
- avoid_relative_lib_imports
- avoid_renaming_method_parameters
- avoid_return_types_on_setters
- avoid_returning_null
- avoid_returning_null_for_future
- avoid_returning_null_for_void
- avoid_returning_this
- avoid_shadowing_type_parameters
- avoid_single_cascade_in_expression_statements
- avoid_types_as_parameter_names
- avoid_unused_constructor_parameters
- await_only_futures
- camel_case_types
- cancel_subscriptions
- cascade_invocations
- comment_references
- constant_identifier_names
- control_flow_in_finally
- directives_ordering
- empty_catches
- empty_constructor_bodies
- empty_statements
- file_names
- hash_and_equals
- implementation_imports
- invariant_booleans
- iterable_contains_unrelated_type
- join_return_with_assignment
- library_names
- library_prefixes
- list_remove_unrelated_type
- literal_only_boolean_expressions
- no_adjacent_strings_in_list
- no_duplicate_case_values
- non_constant_identifier_names
- null_closures
- omit_local_variable_types
- only_throw_errors
- overridden_fields
- package_api_docs
- package_names
- package_prefixed_library_names
- prefer_adjacent_string_concatenation
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_const_constructors
- prefer_contains
- prefer_equal_for_default_values
- prefer_final_fields
- prefer_final_locals
- prefer_generic_function_type_aliases
- prefer_initializing_formals
- prefer_interpolation_to_compose_strings
- prefer_is_empty
- prefer_is_not_empty
- prefer_null_aware_operators
- prefer_single_quotes
- prefer_typing_uninitialized_variables
- recursive_getters
- slash_for_doc_comments
- test_types_in_equals
- throw_in_finally
- type_init_formals
- unawaited_futures
- unnecessary_await_in_return
- unnecessary_brace_in_string_interps
- unnecessary_const
- unnecessary_getters_setters
- unnecessary_lambdas
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_parenthesis
- unnecessary_statements
- unnecessary_this
- unrelated_type_equality_checks
- use_function_type_syntax_for_parameters
- use_rethrow_when_possible
- valid_regexps
- void_checks

View File

@@ -0,0 +1,94 @@
Copyright (c) 2011 by Sorkin Type Co (www.sorkintype.com),
with Reserved Font Name "Plaster".
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 KiB

View File

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -1,9 +1,5 @@
// Copyright 2019 The Chromium 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 'src/core/puzzle_animator.dart';
import 'src/flutter.dart';
import 'src/puzzle_home_state.dart';
void main() => runApp(PuzzleApp());
@@ -25,7 +21,7 @@ class PuzzleApp extends StatelessWidget {
class _PuzzleHome extends StatefulWidget {
final int _rows, _columns;
const _PuzzleHome(this._rows, this._columns);
const _PuzzleHome(this._rows, this._columns, {Key key}) : super(key: key);
@override
PuzzleHomeState createState() =>

View File

@@ -1,13 +1,29 @@
// Copyright 2019 The Chromium 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_web/foundation.dart';
import 'core/puzzle_proxy.dart';
import 'core/puzzle_animator.dart';
import 'package:flutter/material.dart';
import 'shared_theme.dart';
abstract class AppState {
TabController get tabController;
Animation<Offset> get shuffleOffsetAnimation;
PuzzleProxy get puzzle;
Listenable get animationNotifier;
bool get autoPlay;
void setAutoPlay(bool newValue);
AnimationNotifier get animationNotifier;
Iterable<SharedTheme> get themeData;
SharedTheme get currentTheme;
set currentTheme(SharedTheme theme);
}
abstract class AnimationNotifier implements Listenable {
void animate();
void dispose();
}

View File

@@ -1,7 +1,3 @@
// Copyright 2019 The Chromium 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 'dart:math' show Point;
const zeroPoint = Point<double>(0, 0);

View File

@@ -1,7 +1,3 @@
// Copyright 2019 The Chromium 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 'dart:math' as math;
class Point extends math.Point<int> {

View File

@@ -1,7 +1,3 @@
// Copyright 2019 The Chromium 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 'dart:collection';
import 'dart:convert';
import 'dart:math' show Random, max;
@@ -127,7 +123,8 @@ abstract class Puzzle {
value += delta * delta;
}
}
return value * incorrectTiles;
value *= incorrectTiles;
return value;
}
Puzzle clickRandom({bool vertical}) {
@@ -140,8 +137,8 @@ abstract class Puzzle {
List<int> clickableValues({bool vertical}) {
final open = openPosition();
final doRow = vertical == null || vertical == false;
final doColumn = vertical == null || vertical;
final doRow = (vertical == null || vertical == false);
final doColumn = (vertical == null || vertical);
final values =
Uint8List((doRow ? (width - 1) : 0) + (doColumn ? (height - 1) : 0));

View File

@@ -1,13 +1,34 @@
// Copyright 2019 The Chromium 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 'dart:async';
import 'dart:math' show Point, Random;
import 'body.dart';
import 'puzzle.dart';
import 'puzzle_proxy.dart';
enum PuzzleEvent { click, reset, noop }
abstract class PuzzleProxy {
int get width;
int get height;
int get length;
bool get solved;
void reset();
void clickOrShake(int tileValue);
int get tileCount;
int get clickCount;
int get incorrectTiles;
Point<double> location(int index);
bool isCorrectPosition(int value);
}
class PuzzleAnimator implements PuzzleProxy {
final _rnd = Random();
@@ -36,10 +57,13 @@ class PuzzleAnimator implements PuzzleProxy {
@override
int get tileCount => _puzzle.tileCount;
@override
int get incorrectTiles => _puzzle.incorrectTiles;
@override
int get clickCount => _clickCount;
@override
void reset() => _resetCore();
Stream<PuzzleEvent> get onEvent => _controller.stream;
@@ -69,7 +93,7 @@ class PuzzleAnimator implements PuzzleProxy {
_puzzle = _puzzle.clickRandom(vertical: _nextRandomVertical);
_nextRandomVertical = !_nextRandomVertical;
_clickCount++;
_controller.add(PuzzleEvent.random);
_controller.add(PuzzleEvent.click);
}
@override
@@ -141,7 +165,7 @@ class PuzzleAnimator implements PuzzleProxy {
final delta = _puzzle.openPosition() - _puzzle.coordinatesOf(tileValue);
deltaDouble = Point(delta.x.toDouble(), delta.y.toDouble());
}
deltaDouble *= 0.5 / deltaDouble.magnitude;
deltaDouble *= (0.5 / deltaDouble.magnitude);
_locations[tileValue].kick(deltaDouble);
}

View File

@@ -1,25 +0,0 @@
// Copyright 2019 The Chromium 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 'dart:math' show Point;
enum PuzzleEvent { click, random, reset, noop }
abstract class PuzzleProxy {
int get width;
int get height;
int get length;
bool get solved;
void clickOrShake(int tileValue);
int get tileCount;
Point<double> location(int index);
bool isCorrectPosition(int value);
}

View File

@@ -1,7 +1,3 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of 'puzzle.dart';
class _PuzzleSimple extends Puzzle {

View File

@@ -1,7 +1,3 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
part of 'puzzle.dart';
mixin _SliceListMixin on ListMixin<int> {

View File

@@ -1,7 +1,3 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
void requireArgument(bool truth, String argName, [String message]) {
if (!truth) {
if (message == null || message.isEmpty) {

View File

@@ -1,7 +0,0 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
export 'package:flutter_web/material.dart';
export 'package:flutter_web/scheduler.dart' show Ticker;

View File

@@ -0,0 +1,63 @@
import 'dart:collection';
class FrameNanny {
static const _bufferSize = 200;
static const _maxFrameDuration = Duration(milliseconds: 34);
final _buffer = ListQueue<Duration>(_bufferSize);
final _watch = Stopwatch();
Duration tick(Duration source) {
_watch.start();
_buffer.add(source);
while (_buffer.length > _bufferSize) {
_buffer.removeFirst();
}
if (source > _maxFrameDuration) {
source = _maxFrameDuration;
}
if (_watch.elapsed > const Duration(seconds: 2)) {
var goodCount = 0;
var sum = const Duration();
Duration best, worst;
for (var e in _buffer) {
sum += e;
if (e <= _maxFrameDuration) {
goodCount++;
}
if (best == null || e < best) {
best = e;
}
if (worst == null || e > worst) {
worst = e;
}
}
_watch.reset();
print([
'**Nanny**',
'${(100 * goodCount / _buffer.length).toStringAsFixed(1)}%',
'<= ${_maxFrameDuration.inMilliseconds}ms',
'best:',
best?.inMilliseconds,
'avg:',
_safeDivide(sum, _buffer.length),
'worst',
worst?.inMilliseconds
].join(' '));
}
return source;
}
}
Object _safeDivide(Duration source, int divisor) {
if (divisor == 0) {
return double.nan;
}
return (source ~/ divisor).inMilliseconds;
}

View File

@@ -1,17 +0,0 @@
// Copyright 2019 The Chromium 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_web/foundation.dart';
abstract class PuzzleControls implements Listenable {
void reset();
int get clickCount;
int get incorrectTiles;
bool get autoPlay;
void Function(bool newValue) get setAutoPlayFunction;
}

View File

@@ -1,9 +1,5 @@
// Copyright 2019 The Chromium 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 'core/puzzle_proxy.dart';
import 'flutter.dart';
import 'core/puzzle_animator.dart';
import 'package:flutter/material.dart';
class PuzzleFlowDelegate extends FlowDelegate {
final Size _tileSize;

View File

@@ -1,84 +1,101 @@
// Copyright 2019 The Chromium 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 'dart:async';
import 'dart:math' as math;
import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'app_state.dart';
import 'core/puzzle_animator.dart';
import 'core/puzzle_proxy.dart';
import 'flutter.dart';
import 'puzzle_controls.dart';
import 'puzzle_flow_delegate.dart';
import 'frame_nanny.dart';
import 'shared_theme.dart';
import 'themes.dart';
import 'value_tab_controller.dart';
class _PuzzleControls extends ChangeNotifier implements PuzzleControls {
final PuzzleHomeState _parent;
_PuzzleControls(this._parent);
@override
bool get autoPlay => _parent._autoPlay;
void _notify() => notifyListeners();
@override
void Function(bool newValue) get setAutoPlayFunction {
if (_parent.puzzle.solved) {
return null;
}
return _parent._setAutoPlay;
}
@override
int get clickCount => _parent.puzzle.clickCount;
@override
int get incorrectTiles => _parent.puzzle.incorrectTiles;
@override
void reset() => _parent.puzzle.reset();
}
import 'theme_plaster.dart';
import 'theme_seattle.dart';
import 'theme_simple.dart';
class PuzzleHomeState extends State
with SingleTickerProviderStateMixin, AppState {
with TickerProviderStateMixin
implements AppState {
TabController _tabController;
AnimationController _controller;
Animation<Offset> _shuffleOffsetAnimation;
@override
Animation<Offset> get shuffleOffsetAnimation => _shuffleOffsetAnimation;
@override
final PuzzleAnimator puzzle;
@override
final _AnimationNotifier animationNotifier = _AnimationNotifier();
final animationNotifier = _AnimationNotifier();
@override
TabController get tabController => _tabController;
final _nanny = FrameNanny();
SharedTheme _currentTheme;
@override
SharedTheme get currentTheme => _currentTheme;
@override
set currentTheme(SharedTheme theme) {
setState(() {
_currentTheme = theme;
});
}
Duration _tickerTimeSinceLastEvent = Duration.zero;
Ticker _ticker;
Duration _lastElapsed;
StreamSubscription _puzzleEventSubscription;
StreamSubscription sub;
bool _autoPlay = false;
_PuzzleControls _autoPlayListenable;
@override
bool autoPlay = false;
PuzzleHomeState(this.puzzle) {
_puzzleEventSubscription = puzzle.onEvent.listen(_onPuzzleEvent);
sub = puzzle.onEvent.listen(_onPuzzleEvent);
_themeDataCache = List.unmodifiable([
ThemeSimple(this),
ThemeSeattle(this),
ThemePlaster(this),
]);
_currentTheme = themeData.first;
}
@override
void initState() {
super.initState();
_autoPlayListenable = _PuzzleControls(this);
_ticker ??= createTicker(_onTick);
_ensureTicking();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 200),
);
_shuffleOffsetAnimation = _controller.drive(const _Shake());
_tabController = TabController(vsync: this, length: _themeDataCache.length);
_tabController.addListener(() {
currentTheme = _themeDataCache[_tabController.index];
});
}
void _setAutoPlay(bool newValue) {
if (newValue != _autoPlay) {
List<SharedTheme> _themeDataCache;
@override
Iterable<SharedTheme> get themeData => _themeDataCache;
@override
void setAutoPlay(bool newValue) {
if (newValue != autoPlay) {
setState(() {
// Only allow enabling autoPlay if the puzzle is not solved
_autoPlayListenable._notify();
_autoPlay = newValue && !puzzle.solved;
if (_autoPlay) {
autoPlay = newValue && !puzzle.solved;
if (autoPlay) {
_ensureTicking();
}
});
@@ -86,46 +103,26 @@ class PuzzleHomeState extends State
}
@override
Widget build(BuildContext context) => MultiProvider(
providers: [
Provider<AppState>.value(value: this),
ListenableProvider<PuzzleControls>.value(
listenable: _autoPlayListenable,
)
],
child: Material(
child: Stack(
children: <Widget>[
const SizedBox.expand(
child: FittedBox(
fit: BoxFit.cover,
child: Image(
image: AssetImage('seattle.jpg'),
),
),
),
const LayoutBuilder(builder: _doBuild),
],
),
),
);
Widget build(BuildContext context) => _currentTheme.build(context);
@override
void dispose() {
animationNotifier.dispose();
_tabController.dispose();
_controller?.dispose();
_ticker?.dispose();
_autoPlayListenable?.dispose();
_puzzleEventSubscription.cancel();
sub.cancel();
super.dispose();
}
void _onPuzzleEvent(PuzzleEvent e) {
_autoPlayListenable._notify();
if (e != PuzzleEvent.random) {
_setAutoPlay(false);
}
_tickerTimeSinceLastEvent = Duration.zero;
_ensureTicking();
if (e == PuzzleEvent.noop) {
assert(e == PuzzleEvent.noop);
_controller.reset();
_controller.forward();
}
setState(() {
// noop
});
@@ -151,141 +148,40 @@ class PuzzleHomeState extends State
}
_tickerTimeSinceLastEvent += delta;
puzzle.update(delta > _maxFrameDuration ? _maxFrameDuration : delta);
puzzle.update(_nanny.tick(delta));
if (!puzzle.stable) {
animationNotifier.animate();
} else {
if (!_autoPlay) {
if (!autoPlay) {
_ticker.stop();
_lastElapsed = null;
}
}
if (_autoPlay &&
if (autoPlay &&
_tickerTimeSinceLastEvent > const Duration(milliseconds: 200)) {
puzzle.playRandom();
if (puzzle.solved) {
_setAutoPlay(false);
setAutoPlay(false);
}
}
}
}
class _AnimationNotifier extends ChangeNotifier {
class _Shake extends Animatable<Offset> {
const _Shake();
@override
Offset transform(double t) => Offset(0.01 * math.sin(t * math.pi * 3), 0);
}
class _AnimationNotifier extends ChangeNotifier implements AnimationNotifier {
_AnimationNotifier();
@override
void animate() {
notifyListeners();
}
}
const _maxFrameDuration = Duration(milliseconds: 34);
Widget _updateConstraints(
BoxConstraints constraints, Widget Function(bool small) builder) {
const _smallWidth = 580;
final constraintWidth =
constraints.hasBoundedWidth ? constraints.maxWidth : 1000.0;
final constraintHeight =
constraints.hasBoundedHeight ? constraints.maxHeight : 1000.0;
return builder(constraintWidth < _smallWidth || constraintHeight < 690);
}
Widget _doBuild(BuildContext _, BoxConstraints constraints) =>
_updateConstraints(constraints, _doBuildCore);
Widget _doBuildCore(bool small) => ValueTabController<SharedTheme>(
values: themes,
child: Consumer<SharedTheme>(
builder: (_, theme, __) => AnimatedContainer(
duration: puzzleAnimationDuration,
color: theme.puzzleThemeBackground,
child: Center(
child: theme.styledWrapper(
small,
SizedBox(
width: 580,
child: Consumer<AppState>(
builder: (context, appState, _) => Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.black26,
width: 1,
),
),
),
margin:
const EdgeInsets.symmetric(horizontal: 20),
child: TabBar(
controller: ValueTabController.of(context),
labelPadding:
const EdgeInsets.fromLTRB(0, 20, 0, 12),
labelColor: theme.puzzleAccentColor,
indicatorColor: theme.puzzleAccentColor,
indicatorWeight: 1.5,
unselectedLabelColor:
Colors.black.withOpacity(0.6),
tabs: themes
.map((st) => Text(
st.name.toUpperCase(),
style: const TextStyle(
letterSpacing: 0.5,
),
))
.toList(),
),
),
Flexible(
child: Container(
padding: const EdgeInsets.all(10),
child: Flow(
delegate: PuzzleFlowDelegate(
small
? const Size(90, 90)
: const Size(140, 140),
appState.puzzle,
appState.animationNotifier,
),
children: List<Widget>.generate(
appState.puzzle.length,
(i) => theme.tileButtonCore(
i, appState.puzzle, small),
),
),
),
),
Container(
decoration: const BoxDecoration(
border: Border(
top: BorderSide(
color: Colors.black26, width: 1),
),
),
padding: const EdgeInsets.only(
left: 10,
bottom: 6,
top: 2,
right: 10,
),
child: Consumer<PuzzleControls>(
builder: (_, controls, __) => Row(
children: theme.bottomControls(controls)),
),
)
],
),
),
),
),
),
),
),
);

View File

@@ -1,30 +1,30 @@
// Copyright 2019 The Chromium 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 'core/puzzle_proxy.dart';
import 'flutter.dart';
import 'puzzle_controls.dart';
import 'app_state.dart';
import 'core/puzzle_animator.dart';
import 'puzzle_flow_delegate.dart';
import 'widgets/material_interior_alt.dart';
final puzzleAnimationDuration = kThemeAnimationDuration * 3;
abstract class SharedTheme {
const SharedTheme();
SharedTheme(this._appState);
final AppState _appState;
PuzzleProxy get puzzle => _appState.puzzle;
String get name;
Color get puzzleThemeBackground;
RoundedRectangleBorder puzzleBorder(bool small);
RoundedRectangleBorder get puzzleBorder;
Color get puzzleBackgroundColor;
Color get puzzleAccentColor;
EdgeInsetsGeometry tilePadding(PuzzleProxy puzzle) => const EdgeInsets.all(6);
EdgeInsetsGeometry get tilePadding => const EdgeInsets.all(6);
Widget tileButton(int i, PuzzleProxy puzzle, bool small);
Widget tileButton(int i);
Ink createInk(
Widget child, {
@@ -40,57 +40,159 @@ abstract class SharedTheme {
);
Widget createButton(
PuzzleProxy puzzle,
bool small,
int tileValue,
Widget content, {
Color color,
RoundedRectangleBorder shape,
}) =>
AnimatedContainer(
duration: puzzleAnimationDuration,
padding: tilePadding(puzzle),
duration: _puzzleAnimationDuration,
padding: tilePadding,
child: RaisedButton(
elevation: 4,
clipBehavior: Clip.hardEdge,
animationDuration: puzzleAnimationDuration,
onPressed: () => puzzle.clickOrShake(tileValue),
shape: shape ?? puzzleBorder(small),
animationDuration: _puzzleAnimationDuration,
onPressed: () => _tilePress(tileValue),
shape: shape ?? puzzleBorder,
padding: const EdgeInsets.symmetric(),
child: content,
color: color,
),
);
Widget build(BuildContext context) => Material(
child: Stack(
children: <Widget>[
const SizedBox.expand(
child: FittedBox(
fit: BoxFit.cover,
child: Image(
image: AssetImage('asset/seattle.jpg'),
),
),
),
AnimatedContainer(
duration: _puzzleAnimationDuration,
color: puzzleThemeBackground,
child: Center(
child: _styledWrapper(
SizedBox(
width: 580,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
decoration: const BoxDecoration(
border: Border(
bottom: BorderSide(
color: Colors.black26,
width: 1,
),
),
),
margin: const EdgeInsets.symmetric(horizontal: 20),
child: TabBar(
controller: _appState.tabController,
labelPadding: const EdgeInsets.fromLTRB(0, 20, 0, 12),
labelColor: puzzleAccentColor,
indicatorColor: puzzleAccentColor,
indicatorWeight: 1.5,
unselectedLabelColor: Colors.black.withOpacity(0.6),
tabs: _appState.themeData
.map((st) => Text(
st.name.toUpperCase(),
style: const TextStyle(
letterSpacing: 0.5,
),
))
.toList(),
),
),
Container(
constraints: const BoxConstraints.tightForFinite(),
padding: const EdgeInsets.all(10),
child: Flow(
delegate: PuzzleFlowDelegate(
_tileSize,
puzzle,
_appState.animationNotifier,
),
children: List<Widget>.generate(
puzzle.length,
_tileButton,
),
),
),
Container(
decoration: const BoxDecoration(
border: Border(
top: BorderSide(color: Colors.black26, width: 1),
),
),
padding: const EdgeInsets.only(
left: 10,
bottom: 6,
top: 2,
right: 10,
),
child: Row(children: _bottomControls(context)),
)
],
),
),
),
),
)
],
));
Duration get _puzzleAnimationDuration => kThemeAnimationDuration * 3;
// Thought about using AnimatedContainer here, but it causes some weird
// resizing behavior
Widget styledWrapper(bool small, Widget child) => MaterialInterior(
duration: puzzleAnimationDuration,
shape: puzzleBorder(small),
Widget _styledWrapper(Widget child) => MaterialInterior(
duration: _puzzleAnimationDuration,
shape: puzzleBorder,
color: puzzleBackgroundColor,
child: child,
);
Size get _tileSize => const Size(140.0, 140.0);
void Function(bool newValue) get _setAutoPlay {
if (puzzle.solved) {
return null;
}
return _appState.setAutoPlay;
}
void _tilePress(int tileValue) {
_appState.setAutoPlay(false);
_appState.puzzle.clickOrShake(tileValue);
}
TextStyle get _infoStyle => TextStyle(
color: puzzleAccentColor,
fontWeight: FontWeight.bold,
);
List<Widget> bottomControls(PuzzleControls controls) => <Widget>[
List<Widget> _bottomControls(BuildContext context) => <Widget>[
IconButton(
onPressed: controls.reset,
onPressed: puzzle.reset,
icon: Icon(Icons.refresh, color: puzzleAccentColor),
//Icons.refresh,
),
Checkbox(
value: controls.autoPlay,
onChanged: controls.setAutoPlayFunction,
value: _appState.autoPlay,
onChanged: _setAutoPlay,
activeColor: puzzleAccentColor,
),
Expanded(
child: Container(),
),
Text(
controls.clickCount.toString(),
puzzle.clickCount.toString(),
textAlign: TextAlign.right,
style: _infoStyle,
),
@@ -98,7 +200,7 @@ abstract class SharedTheme {
SizedBox(
width: 28,
child: Text(
controls.incorrectTiles.toString(),
puzzle.incorrectTiles.toString(),
textAlign: TextAlign.right,
style: _infoStyle,
),
@@ -106,11 +208,11 @@ abstract class SharedTheme {
const Text(' Tiles left ')
];
Widget tileButtonCore(int i, PuzzleProxy puzzle, bool small) {
Widget _tileButton(int i) {
if (i == puzzle.tileCount && !puzzle.solved) {
return const Center();
}
return tileButton(i, puzzle, small);
return tileButton(i);
}
}

View File

@@ -1,9 +1,6 @@
// Copyright 2019 The Chromium 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 'core/puzzle_proxy.dart';
import 'flutter.dart';
import 'app_state.dart';
import 'shared_theme.dart';
const _yellowIsh = Color.fromARGB(255, 248, 244, 233);
@@ -14,7 +11,7 @@ class ThemePlaster extends SharedTheme {
@override
String get name => 'Plaster';
const ThemePlaster();
ThemePlaster(AppState baseTheme) : super(baseTheme);
@override
Color get puzzleThemeBackground => _chocolate;
@@ -26,18 +23,18 @@ class ThemePlaster extends SharedTheme {
Color get puzzleAccentColor => _orangeIsh;
@override
RoundedRectangleBorder puzzleBorder(bool small) => RoundedRectangleBorder(
side: const BorderSide(
RoundedRectangleBorder get puzzleBorder => const RoundedRectangleBorder(
side: BorderSide(
color: Color.fromARGB(255, 103, 103, 105),
width: 8,
),
borderRadius: BorderRadius.all(
Radius.circular(small ? 10 : 18),
Radius.circular(18),
),
);
@override
Widget tileButton(int i, PuzzleProxy puzzle, bool small) {
Widget tileButton(int i) {
final correctColumn = i % puzzle.width;
final correctRow = i ~/ puzzle.width;
@@ -45,10 +42,10 @@ class ThemePlaster extends SharedTheme {
if (i == puzzle.tileCount) {
assert(puzzle.solved);
return Center(
return const Center(
child: Icon(
Icons.thumb_up,
size: small ? 50 : 72,
size: 72,
color: _orangeIsh,
),
);
@@ -59,13 +56,11 @@ class ThemePlaster extends SharedTheme {
style: TextStyle(
color: primary ? _yellowIsh : _chocolate,
fontFamily: 'Plaster',
fontSize: small ? 40 : 77,
fontSize: 77,
),
);
return createButton(
puzzle,
small,
i,
content,
color: primary ? _orangeIsh : _yellowIsh,

View File

@@ -1,9 +1,6 @@
// Copyright 2019 The Chromium 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 'core/puzzle_proxy.dart';
import 'flutter.dart';
import 'app_state.dart';
import 'shared_theme.dart';
import 'widgets/decoration_image_plus.dart';
@@ -11,7 +8,7 @@ class ThemeSeattle extends SharedTheme {
@override
String get name => 'Seattle';
const ThemeSeattle();
ThemeSeattle(AppState proxy) : super(proxy);
@override
Color get puzzleThemeBackground => const Color.fromARGB(153, 90, 135, 170);
@@ -23,19 +20,18 @@ class ThemeSeattle extends SharedTheme {
Color get puzzleAccentColor => const Color(0xff000579f);
@override
RoundedRectangleBorder puzzleBorder(bool small) =>
const RoundedRectangleBorder(
RoundedRectangleBorder get puzzleBorder => const RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(1),
),
);
@override
EdgeInsetsGeometry tilePadding(PuzzleProxy puzzle) =>
EdgeInsetsGeometry get tilePadding =>
puzzle.solved ? const EdgeInsets.all(1) : const EdgeInsets.all(4);
@override
Widget tileButton(int i, PuzzleProxy puzzle, bool small) {
Widget tileButton(int i) {
if (i == puzzle.tileCount && !puzzle.solved) {
assert(puzzle.solved);
}
@@ -45,7 +41,7 @@ class ThemeSeattle extends SharedTheme {
puzzleHeight: puzzle.height,
pieceIndex: i,
fit: BoxFit.cover,
image: const AssetImage('seattle.jpg'));
image: const AssetImage('asset/seattle.jpg'));
final correctPosition = puzzle.isCorrectPosition(i);
final content = createInk(
@@ -62,14 +58,14 @@ class ThemeSeattle extends SharedTheme {
style: TextStyle(
fontWeight: FontWeight.normal,
color: correctPosition ? Colors.white : Colors.black,
fontSize: small ? 25 : 42,
fontSize: 42,
),
),
),
image: decorationImage,
padding: EdgeInsets.all(small ? 20 : 32),
padding: const EdgeInsets.all(32),
);
return createButton(puzzle, small, i, content);
return createButton(i, content);
}
}

View File

@@ -1,9 +1,6 @@
// Copyright 2019 The Chromium 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 'core/puzzle_proxy.dart';
import 'flutter.dart';
import 'app_state.dart';
import 'shared_theme.dart';
const _accentBlue = Color(0xff000579e);
@@ -12,7 +9,7 @@ class ThemeSimple extends SharedTheme {
@override
String get name => 'Simple';
const ThemeSimple();
ThemeSimple(AppState proxy) : super(proxy);
@override
Color get puzzleThemeBackground => Colors.white;
@@ -24,8 +21,7 @@ class ThemeSimple extends SharedTheme {
Color get puzzleAccentColor => _accentBlue;
@override
RoundedRectangleBorder puzzleBorder(bool small) =>
const RoundedRectangleBorder(
RoundedRectangleBorder get puzzleBorder => const RoundedRectangleBorder(
side: BorderSide(color: Colors.black26, width: 1),
borderRadius: BorderRadius.all(
Radius.circular(4),
@@ -33,7 +29,7 @@ class ThemeSimple extends SharedTheme {
);
@override
Widget tileButton(int i, PuzzleProxy puzzle, bool small) {
Widget tileButton(int i) {
if (i == puzzle.tileCount) {
assert(puzzle.solved);
return const Center(
@@ -54,15 +50,13 @@ class ThemeSimple extends SharedTheme {
style: TextStyle(
color: Colors.white,
fontWeight: correctPosition ? FontWeight.bold : FontWeight.normal,
fontSize: small ? 30 : 49,
fontSize: 49,
),
),
),
);
return createButton(
puzzle,
small,
i,
content,
color: const Color.fromARGB(255, 13, 87, 155),

View File

@@ -1,9 +0,0 @@
import 'theme_plaster.dart';
import 'theme_seattle.dart';
import 'theme_simple.dart';
const themes = [
ThemeSimple(),
ThemeSeattle(),
ThemePlaster(),
];

View File

@@ -1,88 +0,0 @@
import 'package:flutter_web/material.dart';
import 'package:provider/provider.dart';
class ValueTabController<T> extends StatefulWidget {
/// Creates a default tab controller for the given [child] widget.
const ValueTabController({
Key key,
@required this.child,
@required this.values,
}) : super(key: key);
/// The widget below this widget in the tree.
///
/// Typically a [Scaffold] whose [AppBar] includes a [TabBar].
///
/// {@macro flutter.widgets.child}
final Widget child;
final List<T> values;
/// The closest instance of this class that encloses the given context.
///
/// Typical usage:
///
/// ```dart
/// TabController controller = DefaultTabBarController.of(context);
/// ```
static TabController of(BuildContext context) {
final scope = context.inheritFromWidgetOfExactType(_ValueTabControllerScope)
as _ValueTabControllerScope;
return scope?.controller;
}
@override
_ValueTabControllerState<T> createState() => _ValueTabControllerState<T>();
}
class _ValueTabControllerState<T> extends State<ValueTabController<T>>
with SingleTickerProviderStateMixin {
final _notifier = ValueNotifier<T>(null);
TabController _controller;
@override
void initState() {
super.initState();
_controller = TabController(
vsync: this,
length: widget.values.length,
initialIndex: 0,
);
_notifier.value = widget.values.first;
_controller.addListener(() {
_notifier.value = widget.values[_controller.index];
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) => _ValueTabControllerScope(
controller: _controller,
enabled: TickerMode.of(context),
child: ValueListenableProvider.value(
valueListenable: _notifier,
child: widget.child,
),
);
}
class _ValueTabControllerScope extends InheritedWidget {
const _ValueTabControllerScope(
{Key key, this.controller, this.enabled, Widget child})
: super(key: key, child: child);
final TabController controller;
final bool enabled;
@override
bool updateShouldNotify(_ValueTabControllerScope old) =>
enabled != old.enabled || controller != old.controller;
}

View File

@@ -1,12 +1,8 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// ignore_for_file: omit_local_variable_types, annotate_overrides
import 'package:flutter_web_ui/ui.dart' as ui show Image;
import 'dart:ui' as ui show Image;
import '../flutter.dart';
import 'package:flutter/material.dart';
// A model on top of DecorationImage that supports slicing up the source image
// efficiently to draw it as tiles in the puzzle game
@@ -142,13 +138,13 @@ class DecorationImagePlus implements DecorationImage {
@override
String toString() {
final List<String> properties = <String>['$image'];
final List<String> properties = <String>[];
properties.add('$image');
if (colorFilter != null) properties.add('$colorFilter');
if (fit != null &&
!(fit == BoxFit.fill && centerSlice != null) &&
!(fit == BoxFit.scaleDown && centerSlice == null)) {
!(fit == BoxFit.scaleDown && centerSlice == null))
properties.add('$fit');
}
properties.add('$alignment');
if (centerSlice != null) properties.add('centerSlice: $centerSlice');
if (repeat != ImageRepeat.noRepeat) properties.add('$repeat');
@@ -170,13 +166,16 @@ class DecorationImagePlus implements DecorationImage {
/// longer needed.
class DecorationImagePainterPlus implements DecorationImagePainter {
DecorationImagePainterPlus._(this._details, this._onChanged)
: assert(_details != null);
: assert(_details != null) {
_imageStreamListener = ImageStreamListener(_imageListener);
}
final DecorationImagePlus _details;
final VoidCallback _onChanged;
ImageStream _imageStream;
ImageInfo _image;
ImageStreamListener _imageStreamListener;
/// Draw the image onto the given canvas.
///
@@ -218,15 +217,14 @@ class DecorationImagePainterPlus implements DecorationImagePainter {
final ImageStream newImageStream = _details.image.resolve(configuration);
if (newImageStream.key != _imageStream?.key) {
_imageStream?.removeListener(_imageListener);
_imageStream = newImageStream..addListener(_imageListener);
_imageStream?.removeListener(_imageStreamListener);
_imageStream = newImageStream..addListener(_imageStreamListener);
}
if (_image == null) return;
if (clipPath != null) {
canvas
..save()
..clipPath(clipPath);
canvas.save();
canvas.clipPath(clipPath);
}
_paintImage(
@@ -259,7 +257,7 @@ class DecorationImagePainterPlus implements DecorationImagePainter {
/// After this method has been called, the object is no longer usable.
@mustCallSuper
void dispose() {
_imageStream?.removeListener(_imageListener);
_imageStream?.removeListener(_imageStreamListener);
}
@override

View File

@@ -1,8 +1,4 @@
// Copyright 2019 The Chromium 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 '../flutter.dart';
import 'package:flutter/material.dart';
// Copied from
// https://github.com/flutter/flutter/blob/f5b02e3c05ed1ab31e890add84fb56e35de2d392/packages/flutter/lib/src/material/material.dart#L593-L715

View File

@@ -7,7 +7,7 @@ packages:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "0.37.0"
version: "0.36.0"
archive:
dependency: transitive
description:
@@ -29,83 +29,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.3.0"
bazel_worker:
boolean_selector:
dependency: transitive
description:
name: bazel_worker
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.21"
build:
dependency: transitive
description:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.5"
build_config:
dependency: transitive
description:
name: build_config
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.1"
build_daemon:
dependency: transitive
description:
name: build_daemon
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
build_modules:
dependency: transitive
description:
name: build_modules
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.1"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.6"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.5"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.7"
build_web_compilers:
dependency: "direct dev"
description:
name: build_web_compilers
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
built_collection:
dependency: transitive
description:
name: built_collection
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.2"
built_value:
dependency: transitive
description:
name: built_value
url: "https://pub.dartlang.org"
source: hosted
version: "6.7.0"
version: "1.0.5"
charcode:
dependency: transitive
description:
@@ -113,20 +43,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.2"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
code_builder:
dependency: transitive
description:
name: code_builder
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.0"
collection:
dependency: transitive
description:
@@ -147,45 +63,16 @@ packages:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
csslib:
dependency: transitive
description:
name: csslib
url: "https://pub.dartlang.org"
source: hosted
version: "0.16.1"
dart_style:
dependency: transitive
description:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.9"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.9"
flutter_web:
version: "2.1.2"
flutter:
dependency: "direct main"
description:
path: "packages/flutter_web"
ref: HEAD
resolved-ref: "88a6325290b75326c072ae63bf3016e15a08fccc"
url: "https://github.com/flutter/flutter_web"
source: git
description: flutter
source: sdk
version: "0.0.0"
flutter_web_ui:
dependency: "direct main"
description:
path: "packages/flutter_web_ui"
ref: HEAD
resolved-ref: "88a6325290b75326c072ae63bf3016e15a08fccc"
url: "https://github.com/flutter/flutter_web"
source: git
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
front_end:
dependency: transitive
@@ -193,7 +80,7 @@ packages:
name: front_end
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.20"
version: "0.1.15"
glob:
dependency: transitive
description:
@@ -201,20 +88,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.7"
graphs:
dependency: transitive
description:
name: graphs
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
html:
dependency: transitive
description:
name: html
url: "https://pub.dartlang.org"
source: hosted
version: "0.14.0+2"
http:
dependency: transitive
description:
@@ -228,7 +101,7 @@ packages:
name: http_multi_server
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
version: "2.0.5"
http_parser:
dependency: transitive
description:
@@ -236,13 +109,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.3"
intl:
image:
dependency: transitive
description:
name: intl
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "0.15.8"
version: "2.1.4"
io:
dependency: transitive
description:
@@ -257,27 +130,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.1+1"
json_annotation:
json_rpc_2:
dependency: transitive
description:
name: json_annotation
name: json_rpc_2
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
version: "2.0.10"
kernel:
dependency: transitive
description:
name: kernel
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.20"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "0.11.3+2"
version: "0.3.15"
matcher:
dependency: transitive
description:
@@ -298,7 +164,21 @@ packages:
name: mime
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.6+3"
version: "0.9.6+2"
multi_server_socket:
dependency: transitive
description:
name: multi_server_socket
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
node_preamble:
dependency: transitive
description:
name: node_preamble
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.4"
package_config:
dependency: transitive
description:
@@ -327,6 +207,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0+1"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
pool:
dependency: transitive
description:
@@ -334,22 +221,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
protobuf:
dependency: transitive
description:
name: protobuf
url: "https://pub.dartlang.org"
source: hosted
version: "0.13.15"
provider:
dependency: "direct main"
description:
path: "."
ref: "5cf4521d4d6"
resolved-ref: "5cf4521d4d635d7d7ca8ddbd6e28048a7f319ee0"
url: "https://github.com/kevmoo/provider"
source: git
version: "2.1.0"
pub_semver:
dependency: transitive
description:
@@ -357,27 +228,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.2"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
quiver:
dependency: transitive
description:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
scratch_space:
dependency: transitive
description:
name: scratch_space
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4"
version: "2.0.5"
shelf:
dependency: transitive
description:
@@ -385,13 +242,39 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.5"
shelf_packages_handler:
dependency: transitive
description:
name: shelf_packages_handler
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
shelf_static:
dependency: transitive
description:
name: shelf_static
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.8"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.3"
version: "0.2.2+5"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_map_stack_trace:
dependency: transitive
description:
name: source_map_stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.5"
source_maps:
dependency: transitive
description:
@@ -420,13 +303,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
stream_transform:
dependency: transitive
description:
name: stream_transform
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.19"
string_scanner:
dependency: transitive
description:
@@ -441,13 +317,27 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
timing:
dependency: transitive
test:
dependency: "direct dev"
description:
name: timing
name: test
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1+1"
version: "1.6.3"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.5"
test_core:
dependency: transitive
description:
name: test_core
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.5"
typed_data:
dependency: transitive
description:
@@ -462,26 +352,40 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.8"
vm_service_client:
dependency: transitive
description:
name: vm_service_client
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.6+1"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.7+12"
version: "0.9.7+10"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.14"
version: "1.0.12"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "3.5.0"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.16"
version: "2.1.15"
sdks:
dart: ">=2.3.0 <3.0.0"
dart: ">=2.4.0 <3.0.0"

View File

@@ -1,31 +1,27 @@
name: slide_puzzle
version: 1.0.0
environment:
sdk: ">=2.2.0 <3.0.0"
sdk: ">=2.0.0 <3.0.0"
dependencies:
flutter_web: any
flutter_web_ui: any
provider: any
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
pedantic: ^1.3.0
test: ^1.3.4
build_runner: any
build_web_compilers: any
flutter:
uses-material-design: true
assets:
- asset/
- preview.png
# flutter_web packages are not published to pub.dartlang.org
# These overrides tell the package tools to get them from GitHub
dependency_overrides:
flutter_web:
git:
url: https://github.com/flutter/flutter_web
path: packages/flutter_web
flutter_web_ui:
git:
url: https://github.com/flutter/flutter_web
path: packages/flutter_web_ui
provider:
git:
url: https://github.com/kevmoo/provider
ref: 5cf4521d4d6 # flutter_web, but v2
fonts:
- family: Plaster
fonts:
- asset: asset/fonts/plaster/Plaster-Regular.ttf

View File

@@ -1,18 +0,0 @@
[
{
"family": "MaterialIcons",
"fonts": [
{
"asset": "https://fonts.gstatic.com/s/materialicons/v47/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2"
}
]
},
{
"family": "Plaster",
"fonts": [
{
"asset": "https://fonts.gstatic.com/l/font?kit=DdTm79QatW80eRh4EitJPNLPUrnLdNiMw9JVKCON&skey=6748ccde38e8a5e5&v=v10"
}
]
}
]

View File

@@ -1,15 +0,0 @@
### Material Icon font
Via https://google.github.io/material-design-icons/#icon-font-for-the-web
Via https://fonts.googleapis.com/icon?family=Material+Icons
### Plaster font
Via https://fonts.google.com/specimen/Plaster
Via https://fonts.googleapis.com/css?family=Plaster&text=0123456789
*Note `text=` includes only the used characters 0-9.*
*HT to https://twitter.com/csswizardry/status/1139435442506469376*

Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 KiB

View File

@@ -1,11 +1,10 @@
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<script defer src="main.dart.js" type="application/javascript"></script>
<title>slide_puzzle</title>
</head>
<body>
<script src="main.dart.js" type="application/javascript"></script>
</body>
</html>

View File

@@ -1,11 +0,0 @@
// Copyright 2019 The Chromium 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_web_ui/ui.dart' as ui;
import 'package:slide_puzzle/main.dart' as app;
void main() async {
await ui.webOnlyInitializePlatform();
app.main();
}