1
0
mirror of https://github.com/flutter/samples.git synced 2025-11-11 07:18:15 +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,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)),
),
)
],
),
),
),
),
),
),
),
);