diff --git a/INDEX.md b/INDEX.md index d57d4b65f..39959ac75 100644 --- a/INDEX.md +++ b/INDEX.md @@ -144,10 +144,10 @@ thread and into an isolate. ## Demos -#### [Shrine](material_studies/shrine) _(Flutter team)_ +#### [Shrine](gallery/gallery/lib/studies/shrine) _(Flutter team)_ The Shrine demo app from the Flutter team. It's designed to showcase how apps can put their own spin on the Material Design components and how to use ScopedModel to maintain app state across screens. -#### [Flutter Gallery](https://github.com/flutter/flutter/tree/master/examples/flutter_gallery) _(Flutter team)_ +#### [Flutter Gallery](gallery) _(Flutter team)_ The official Flutter Gallery. There's tons of stuff in here. Just tons. diff --git a/material_studies/rally/.gitignore b/material_studies/rally/.gitignore deleted file mode 100644 index 07488ba61..000000000 --- a/material_studies/rally/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# Visual Studio Code related -.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/material_studies/rally/README.md b/material_studies/rally/README.md deleted file mode 100644 index a1007b537..000000000 --- a/material_studies/rally/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Rally - -A Flutter sample app based on the Material study Rally (a hypothetical, personal finance app). It -showcases custom tabs, custom painted widgets, and custom animations. - -For info on the Rally Material Study, see: https://material.io/design/material-studies/rally.html - -## Goals - -* Show how to customize a tab bar. -* Show how to create reusable custom widgets with composition and custom painting. -* Show how to create an app with tabs and child navigation screens. - -## The important bits - -### `/charts/*` - -These are the custom charts. The circle chart and line chart are custom painters, -while the single vertical bar chart is a simple composition of boxes. - -### `/sections/*` - -These are the main sections for the tab views and the child screen with the details and line chart. -The financial entity is a reusable screen that is the base for the accounts, bills, and budgets -screens. - -## Questions/issues - -If you have a general question about any of the techniques you see in -the sample, the best places to go are: - -* [The FlutterDev Google Group](https://groups.google.com/forum/#!forum/flutter-dev) -* [The Flutter Gitter channel](https://gitter.im/flutter/flutter) -* [StackOverflow](https://stackoverflow.com/questions/tagged/flutter) - -If you run into an issue with the sample itself, please file an issue -in the [main Flutter repo](https://github.com/flutter/flutter/issues). diff --git a/material_studies/rally/analysis_options.yaml b/material_studies/rally/analysis_options.yaml deleted file mode 100644 index 8595cd0e8..000000000 --- a/material_studies/rally/analysis_options.yaml +++ /dev/null @@ -1,30 +0,0 @@ -include: package:pedantic/analysis_options.1.8.0.yaml - -analyzer: - strong-mode: - implicit-casts: false - implicit-dynamic: false - -linter: - rules: - - avoid_types_on_closure_parameters - - avoid_void_async - - await_only_futures - - camel_case_types - - cancel_subscriptions - - close_sinks - - constant_identifier_names - - control_flow_in_finally - - empty_statements - - hash_and_equals - - implementation_imports - - non_constant_identifier_names - - package_api_docs - - package_names - - package_prefixed_library_names - - test_types_in_equals - - throw_in_finally - - unnecessary_brace_in_string_interps - - unnecessary_getters_setters - - unnecessary_new - - unnecessary_statements diff --git a/material_studies/rally/assets/logo.png b/material_studies/rally/assets/logo.png deleted file mode 100644 index c718f3860..000000000 Binary files a/material_studies/rally/assets/logo.png and /dev/null differ diff --git a/material_studies/rally/assets/thumb.png b/material_studies/rally/assets/thumb.png deleted file mode 100644 index 4a495f08c..000000000 Binary files a/material_studies/rally/assets/thumb.png and /dev/null differ diff --git a/material_studies/rally/fonts/Eczar-Bold.ttf b/material_studies/rally/fonts/Eczar-Bold.ttf deleted file mode 100755 index 175210250..000000000 Binary files a/material_studies/rally/fonts/Eczar-Bold.ttf and /dev/null differ diff --git a/material_studies/rally/fonts/Eczar-Regular.ttf b/material_studies/rally/fonts/Eczar-Regular.ttf deleted file mode 100755 index 8eb92d975..000000000 Binary files a/material_studies/rally/fonts/Eczar-Regular.ttf and /dev/null differ diff --git a/material_studies/rally/fonts/Eczar-SemiBold.ttf b/material_studies/rally/fonts/Eczar-SemiBold.ttf deleted file mode 100755 index 2132b24c0..000000000 Binary files a/material_studies/rally/fonts/Eczar-SemiBold.ttf and /dev/null differ diff --git a/material_studies/rally/fonts/RobotoCondensed-Bold.ttf b/material_studies/rally/fonts/RobotoCondensed-Bold.ttf deleted file mode 100755 index 8c7a08be0..000000000 Binary files a/material_studies/rally/fonts/RobotoCondensed-Bold.ttf and /dev/null differ diff --git a/material_studies/rally/fonts/RobotoCondensed-Light.ttf b/material_studies/rally/fonts/RobotoCondensed-Light.ttf deleted file mode 100755 index 67e84089e..000000000 Binary files a/material_studies/rally/fonts/RobotoCondensed-Light.ttf and /dev/null differ diff --git a/material_studies/rally/fonts/RobotoCondensed-Regular.ttf b/material_studies/rally/fonts/RobotoCondensed-Regular.ttf deleted file mode 100755 index 533e3999c..000000000 Binary files a/material_studies/rally/fonts/RobotoCondensed-Regular.ttf and /dev/null differ diff --git a/material_studies/rally/lib/app.dart b/material_studies/rally/lib/app.dart deleted file mode 100644 index 964090a7e..000000000 --- a/material_studies/rally/lib/app.dart +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; - -import 'package:rally/colors.dart'; -import 'package:rally/home.dart'; -import 'package:rally/login.dart'; - -/// The RallyApp is a MaterialApp with a theme and 2 routes. -/// -/// The home route is the main page with tabs for sub pages. -/// The login route is the initial route. -class RallyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Rally', - theme: _buildRallyTheme(), - home: HomePage(), - initialRoute: '/login', - routes: {'/login': (context) => LoginPage()}, - ); - } - - ThemeData _buildRallyTheme() { - final ThemeData base = ThemeData.dark(); - return ThemeData( - scaffoldBackgroundColor: RallyColors.primaryBackground, - primaryColor: RallyColors.primaryBackground, - textTheme: _buildRallyTextTheme(base.textTheme), - inputDecorationTheme: InputDecorationTheme( - labelStyle: - TextStyle(color: RallyColors.gray, fontWeight: FontWeight.w500), - filled: true, - fillColor: RallyColors.inputBackground, - focusedBorder: InputBorder.none, - ), - ); - } - - TextTheme _buildRallyTextTheme(TextTheme base) { - return base - .copyWith( - body1: base.body1.copyWith( - fontFamily: 'Roboto Condensed', - fontSize: 14, - fontWeight: FontWeight.w400, - ), - body2: base.body2.copyWith( - fontFamily: 'Eczar', - fontSize: 40, - fontWeight: FontWeight.w400, - letterSpacing: 1.4, - ), - button: base.button.copyWith( - fontFamily: 'Roboto Condensed', - fontWeight: FontWeight.w700, - letterSpacing: 2.8, - ), - headline: base.body2.copyWith( - fontFamily: 'Eczar', - fontSize: 40, - fontWeight: FontWeight.w600, - letterSpacing: 1.4, - ), - ) - .apply( - displayColor: Colors.white, - bodyColor: Colors.white, - ); - } -} diff --git a/material_studies/rally/lib/charts/line_chart.dart b/material_studies/rally/lib/charts/line_chart.dart deleted file mode 100644 index 87e6c9d8e..000000000 --- a/material_studies/rally/lib/charts/line_chart.dart +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter/widgets.dart'; - -import 'package:rally/colors.dart'; -import 'package:rally/data.dart'; - -class RallyLineChart extends StatelessWidget { - RallyLineChart({this.events = const []}) : assert(events != null); - - final List events; - - @override - Widget build(BuildContext context) { - return CustomPaint(painter: RallyLineChartPainter(context, events)); - } -} - -class RallyLineChartPainter extends CustomPainter { - RallyLineChartPainter(this.context, this.events); - - final BuildContext context; - - // Events to plot on the line as points. - final List events; - - // Number of days to plot. - // This is hardcoded to reflect the dummy data, but would be dynamic in a real - // app. - final int numDays = 52; - - // Beginning of window. The end is this plus numDays. - // This is hardcoded to reflect the dummy data, but would be dynamic in a real - // app. - final DateTime startDate = DateTime.utc(2018, 12, 1); - - // Ranges uses to lerp the pixel points. - // This is hardcoded to reflect the dummy data, but would be dynamic in a real - // app. - final double maxAmount = 3000.0; // minAmount is assumed to be 0.0 - - // The number of milliseconds in a day. This is the inherit period fot the - // points in this line. - static const int millisInDay = 24 * 60 * 60 * 1000; - - // Amount to shift the tick drawing by so that the sunday ticks do not start - // on the edge. - final int tickShift = 3; - - // Arbitrary unit of space for absolute positioned painting. - final double space = 16.0; - - @override - void paint(Canvas canvas, Size size) { - double ticksTop = size.height - space * 5; - double labelsTop = size.height - space * 2; - _drawLine( - canvas, - Rect.fromLTWH(0.0, 0.0, size.width, ticksTop), - ); - _drawXAxisTicks( - canvas, - Rect.fromLTWH(0.0, ticksTop, size.width, labelsTop - ticksTop), - ); - _drawXAxisLabels( - canvas, - Rect.fromLTWH(0.0, labelsTop, size.width, size.height - labelsTop), - ); - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) { - return false; - } - - void _drawLine(Canvas canvas, Rect rect) { - final linePaint = Paint() - ..color = RallyColors.accountColor(2) - ..style = PaintingStyle.stroke - ..strokeWidth = 2.0; - - // Arbitrary value for the first point. In a real app, a wider range of - // points would be used that go beyond the boundaries of the screen. - double lastAmount = 800.0; - - // Try changing this value between 1, 7, 15, etc. - int smoothing = 7; - - // Align the points with equal deltas (1 day) as a cumulative sum. - int startMillis = startDate.millisecondsSinceEpoch; - final points = [ - Offset(0.0, (maxAmount - lastAmount) / maxAmount * rect.height) - ]; - for (int i = 0; i < numDays + smoothing; i++) { - int endMillis = startMillis + millisInDay * 1; - final filteredEvents = events.where((e) { - return startMillis <= e.date.millisecondsSinceEpoch && - e.date.millisecondsSinceEpoch <= endMillis; - }).toList(); - lastAmount += filteredEvents.fold(0.0, (sum, e) => sum + e.amount); - double x = i / numDays * rect.width; - double y = (maxAmount - lastAmount) / maxAmount * rect.height; - points.add(Offset(x, y)); - startMillis = endMillis; - } - - final Path path = Path(); - path.moveTo(points[0].dx, points[0].dy); - for (int i = 1; i < points.length - smoothing; i += smoothing) { - double x1 = points[i].dx; - double y1 = points[i].dy; - double x2 = (x1 + points[i + smoothing].dx) / 2; - double y2 = (y1 + points[i + smoothing].dy) / 2; - path.quadraticBezierTo(x1, y1, x2, y2); - } - canvas.drawPath(path, linePaint); - } - - /// Draw the X-axis increment markers at constant width intervals. - void _drawXAxisTicks(Canvas canvas, Rect rect) { - double dayTop = (rect.top + rect.bottom) / 2; - for (int i = 0; i < numDays; i++) { - double x = rect.width / numDays * i; - canvas.drawRect( - Rect.fromPoints( - Offset(x, i % 7 == tickShift ? rect.top : dayTop), - Offset(x, rect.bottom), - ), - Paint() - ..style = PaintingStyle.stroke - ..strokeWidth = 1.0 - ..color = RallyColors.gray25, - ); - } - } - - /// Set X-axis labels under the X-axis increment markers. - void _drawXAxisLabels(Canvas canvas, Rect rect) { - final selectedLabelStyle = Theme.of(context).textTheme.body1.copyWith( - fontWeight: FontWeight.w700, - ); - final unselectedLabelStyle = Theme.of(context).textTheme.body1.copyWith( - fontWeight: FontWeight.w700, - color: RallyColors.gray25, - ); - - final leftLabel = TextPainter( - text: TextSpan( - text: 'AUGUST 2019', - style: unselectedLabelStyle, - ), - textDirection: TextDirection.ltr, - ); - leftLabel.layout(); - leftLabel.paint(canvas, Offset(rect.left + space / 2, rect.center.dy)); - - final centerLabel = TextPainter( - text: TextSpan(text: 'SEPTEMBER 2019', style: selectedLabelStyle), - textDirection: TextDirection.ltr, - ); - centerLabel.layout(); - final double x = (rect.width - centerLabel.width) / 2; - final double y = rect.center.dy; - centerLabel.paint(canvas, Offset(x, y)); - - final rightLabel = TextPainter( - text: TextSpan( - text: 'OCTOBER 2019', - style: unselectedLabelStyle, - ), - textDirection: TextDirection.ltr, - ); - rightLabel.layout(); - rightLabel.paint( - canvas, - Offset(rect.right - centerLabel.width - space / 2, rect.center.dy), - ); - } -} diff --git a/material_studies/rally/lib/charts/pie_chart.dart b/material_studies/rally/lib/charts/pie_chart.dart deleted file mode 100644 index 87ef02a20..000000000 --- a/material_studies/rally/lib/charts/pie_chart.dart +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter/widgets.dart'; - -import 'package:rally/colors.dart'; -import 'package:rally/data.dart'; -import 'package:rally/formatters.dart'; - -/// A colored piece of the [RallyPieChart]. -class RallyPieChartSegment { - final Color color; - final double value; - - const RallyPieChartSegment({this.color, this.value}); -} - -List buildSegmentsFromAccountItems( - List items) { - return List.generate( - items.length, - (i) => RallyPieChartSegment( - color: RallyColors.accountColor(i), - value: items[i].primaryAmount, - ), - ); -} - -List buildSegmentsFromBillItems(List items) { - return List.generate( - items.length, - (i) => RallyPieChartSegment( - color: RallyColors.billColor(i), - value: items[i].primaryAmount, - ), - ); -} - -List buildSegmentsFromBudgetItems( - List items) { - return List.generate( - items.length, - (i) => RallyPieChartSegment( - color: RallyColors.budgetColor(i), - value: items[i].primaryAmount - items[i].amountUsed, - ), - ); -} - -/// An animated circular pie chart to represent pieces of a whole, which can -/// have empty space. -class RallyPieChart extends StatefulWidget { - RallyPieChart( - {this.heroLabel, this.heroAmount, this.wholeAmount, this.segments}); - - final String heroLabel; - final double heroAmount; - final double wholeAmount; - final List segments; - - _RallyPieChartState createState() => _RallyPieChartState(); -} - -class _RallyPieChartState extends State - with SingleTickerProviderStateMixin { - AnimationController controller; - Animation animation; - - @override - initState() { - super.initState(); - controller = AnimationController( - duration: const Duration(milliseconds: 600), vsync: this); - animation = CurvedAnimation( - parent: TweenSequence(>[ - TweenSequenceItem(tween: Tween(begin: 0.0, end: 0.0), weight: 1.0), - TweenSequenceItem(tween: Tween(begin: 0.0, end: 1.0), weight: 1.5), - ]).animate(controller), - curve: Curves.decelerate); - controller.forward(); - } - - dispose() { - controller.dispose(); - super.dispose(); - } - - Widget build(BuildContext context) { - return _AnimatedRallyPieChart( - animation: animation, - centerLabel: widget.heroLabel, - centerAmount: widget.heroAmount, - total: widget.wholeAmount, - segments: widget.segments, - ); - } -} - -class _AnimatedRallyPieChart extends AnimatedWidget { - _AnimatedRallyPieChart({ - Key key, - this.animation, - this.centerLabel, - this.centerAmount, - this.total, - this.segments, - }) : super(key: key, listenable: animation); - - final Animation animation; - final String centerLabel; - final double centerAmount; - final double total; - final List segments; - - Widget build(BuildContext context) { - final labelTextStyle = Theme.of(context) - .textTheme - .body1 - .copyWith(fontSize: 14.0, letterSpacing: 0.5); - - return DecoratedBox( - decoration: _RallyPieChartOutlineDecoration( - maxFraction: animation.value, total: total, segments: segments), - child: SizedBox( - height: 300.0, - child: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - centerLabel, - style: labelTextStyle, - ), - Text( - Formatters.usdWithSign.format(centerAmount), - style: Theme.of(context).textTheme.headline, - ), - ], - ), - ), - ), - ); - } -} - -class _RallyPieChartOutlineDecoration extends Decoration { - _RallyPieChartOutlineDecoration( - {this.maxFraction, this.total, this.segments}); - - final double maxFraction; - final double total; - final List segments; - - @override - BoxPainter createBoxPainter([onChanged]) { - return _RallyPieChartOutlineBoxPainter( - maxFraction: maxFraction, - wholeAmount: total, - segments: segments, - ); - } -} - -class _RallyPieChartOutlineBoxPainter extends BoxPainter { - _RallyPieChartOutlineBoxPainter( - {this.maxFraction, this.wholeAmount, this.segments}); - - final double maxFraction; - final double wholeAmount; - final List segments; - - @override - void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { - // Create two padded rects to draw arcs in: one for colored arcs and one for - // inner bg arc. - const double strokeWidth = 4.0; - final outerRadius = - min(configuration.size.width, configuration.size.height) / 2; - final outerRect = Rect.fromCircle( - center: configuration.size.center(Offset.zero), - radius: outerRadius - strokeWidth * 3.0); - final innerRect = Rect.fromCircle( - center: configuration.size.center(Offset.zero), - radius: outerRadius - strokeWidth * 4.0); - - // Paint each arc with spacing. - double cummulativeSpace = 0.0; - double cummulativeTotal = 0.0; - const double wholeRadians = (2.0 * pi); - const double spaceRadians = wholeRadians / 180.0; - final wholeMinusSpacesRadians = - wholeRadians - (segments.length * spaceRadians); - for (RallyPieChartSegment segment in segments) { - final paint = Paint()..color = segment.color; - final start = maxFraction * - ((cummulativeTotal / wholeAmount * wholeMinusSpacesRadians) + - cummulativeSpace) - - pi / 2.0; - final sweep = - maxFraction * (segment.value / wholeAmount * wholeMinusSpacesRadians); - canvas.drawArc(outerRect, start, sweep, true, paint); - cummulativeTotal += segment.value; - cummulativeSpace += spaceRadians; - } - - // Paint any remaining space black (e.g. budget amount remaining). - double remaining = wholeAmount - cummulativeTotal; - if (remaining > 0) { - final paint = Paint()..color = Colors.black; - final start = maxFraction * - ((cummulativeTotal / wholeAmount * wholeMinusSpacesRadians) + - spaceRadians * segments.length) - - pi / 2.0; - final sweep = maxFraction * - (remaining / wholeAmount * wholeMinusSpacesRadians - spaceRadians); - canvas.drawArc(outerRect, start, sweep, true, paint); - } - - // Paint a smaller inner circle to cover the painted arcs, so they are - // display as segments. - Paint bgPaint = Paint()..color = RallyColors.primaryBackground; - canvas.drawArc(innerRect, 0.0, 2.0 * pi, true, bgPaint); - } -} diff --git a/material_studies/rally/lib/charts/vertical_fraction_bar.dart b/material_studies/rally/lib/charts/vertical_fraction_bar.dart deleted file mode 100644 index 81b7308f8..000000000 --- a/material_studies/rally/lib/charts/vertical_fraction_bar.dart +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; - -class VerticalFractionBar extends StatelessWidget { - VerticalFractionBar({this.color, this.fraction}); - - final Color color; - final double fraction; - - @override - Widget build(BuildContext context) { - return SizedBox( - height: 32.0, - width: 4.0, - child: Column( - children: [ - SizedBox( - height: (1 - fraction) * 32.0, - child: Container( - color: Colors.black, - ), - ), - SizedBox( - height: fraction * 32.0, - child: Container(color: color), - ), - ], - ), - ); - } -} diff --git a/material_studies/rally/lib/colors.dart b/material_studies/rally/lib/colors.dart deleted file mode 100644 index 0c6b4d721..000000000 --- a/material_studies/rally/lib/colors.dart +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; - -/// Most color assignments in Rally are not like the the typical color -/// assignments that are common in other apps. Instead of primarily mapping to -/// component type and part, they are assigned round robin based on layout. -class RallyColors { - static const accountColors = [ - Color(0xFF005D57), - Color(0xFF04B97F), - Color(0xFF37EFBA), - Color(0xFF007D51), - ]; - - static const billColors = [ - Color(0xFFFFDC78), - Color(0xFFFF6951), - Color(0xFFFFD7D0), - Color(0xFFFFAC12), - ]; - - static const budgetColors = [ - Color(0xFFB2F2FF), - Color(0xFFB15DFF), - Color(0xFF72DEFF), - Color(0xFF0082FB), - ]; - - static const gray = Color(0xFFD8D8D8); - static const gray60 = Color(0x99D8D8D8); - static const gray25 = Color(0x40D8D8D8); - static const white60 = Color(0x99FFFFFF); - static const primaryBackground = Color(0xFF33333D); - static const inputBackground = Color(0xFF26282F); - static const cardBackground = Color(0x03FEFEFE); - - /// Convenience method to get a single account color with position i. - static Color accountColor(int i) { - return cycledColor(accountColors, i); - } - - /// Convenience method to get a single bill color with position i. - static Color billColor(int i) { - return cycledColor(billColors, i); - } - - /// Convenience method to get a single budget color with position i. - static Color budgetColor(int i) { - return cycledColor(budgetColors, i); - } - - /// Gets a color from a list that is considered to be infinitely repeating. - static Color cycledColor(List colors, int i) { - return colors[i % colors.length]; - } -} diff --git a/material_studies/rally/lib/data.dart b/material_studies/rally/lib/data.dart deleted file mode 100644 index c31daa1ac..000000000 --- a/material_studies/rally/lib/data.dart +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/// Calculates the sum of the primary amounts of a list of [AccountData]. -double sumAccountDataPrimaryAmount(List items) { - return items.fold( - 0, - (sum, next) => sum + next.primaryAmount, - ); -} - -/// Calculates the sum of the primary amounts of a list of [BillData]. -double sumBillDataPrimaryAmount(List items) { - return items.fold( - 0, - (sum, next) => sum + next.primaryAmount, - ); -} - -/// Calculates the sum of the primary amounts of a list of [BudgetData]. -double sumBudgetDataPrimaryAmount(List items) { - return items.fold( - 0, - (sum, next) => sum + next.primaryAmount, - ); -} - -/// Calculates the sum of the amounts used of a list of [BudgetData]. -double sumBudgetDataAmountUsed(List items) { - return items.fold( - 0.0, - (sum, next) => sum + next.amountUsed, - ); -} - -/// A data model for an account. -/// -/// The [primaryAmount] is the balance of the account in USD. -class AccountData { - const AccountData({this.name, this.primaryAmount, this.accountNumber}); - - /// The display name of this entity. - final String name; - - // The primary amount or value of this entity. - final double primaryAmount; - - /// The full displayable account number. - final String accountNumber; -} - -/// A data model for a bill. -/// -/// The [primaryAmount] is the amount due in USD. -class BillData { - const BillData({this.name, this.primaryAmount, this.dueDate}); - - /// The display name of this entity. - final String name; - - // The primary amount or value of this entity. - final double primaryAmount; - - /// The due date of this bill. - final String dueDate; -} - -/// A data model for a budget. -/// -/// The [primaryAmount] is the budget cap in USD. -class BudgetData { - const BudgetData({this.name, this.primaryAmount, this.amountUsed}); - - /// The display name of this entity. - final String name; - - // The primary amount or value of this entity. - final double primaryAmount; - - /// Amount of the budget that is consumed or used. - final double amountUsed; -} - -class DetailedEventData { - const DetailedEventData({ - this.title, - this.date, - this.amount, - }); - - final String title; - final DateTime date; - final double amount; -} - -/// Class to return dummy data lists. -/// -/// In a real app, this might be replaced with some asynchronous service. -class DummyDataService { - static List getAccountDataList() { - return [ - AccountData( - name: 'Checking', - primaryAmount: 2215.13, - accountNumber: '1234561234', - ), - AccountData( - name: 'Home Savings', - primaryAmount: 8678.88, - accountNumber: '8888885678', - ), - AccountData( - name: 'Car Savings', - primaryAmount: 987.48, - accountNumber: '8888889012', - ), - AccountData( - name: 'Vacation', - primaryAmount: 253.0, - accountNumber: '1231233456', - ), - ]; - } - - static List getDetailedEventItems() { - return [ - DetailedEventData( - title: 'Genoe', date: DateTime.utc(2019, 1, 24), amount: -16.54), - DetailedEventData( - title: 'Fortnightly Subscribe', - date: DateTime.utc(2019, 1, 5), - amount: -12.54), - DetailedEventData( - title: 'Circle Cash', date: DateTime.utc(2019, 1, 5), amount: 365.65), - DetailedEventData( - title: 'Crane Hospitality', - date: DateTime.utc(2019, 1, 4), - amount: -705.13), - DetailedEventData( - title: 'ABC Payroll', - date: DateTime.utc(2018, 12, 15), - amount: 1141.43), - DetailedEventData( - title: 'Shrine', date: DateTime.utc(2018, 12, 15), amount: -88.88), - DetailedEventData( - title: 'Foodmates', date: DateTime.utc(2018, 12, 4), amount: -11.69), - ]; - } - - static List getBillDataList() { - return [ - BillData( - name: 'RedPay Credit', - primaryAmount: 45.36, - dueDate: 'Jan 29', - ), - BillData( - name: 'Rent', - primaryAmount: 1200.0, - dueDate: 'Feb 9', - ), - BillData( - name: 'TabFine Credit', - primaryAmount: 87.33, - dueDate: 'Feb 22', - ), - BillData( - name: 'ABC Loans', - primaryAmount: 400.0, - dueDate: 'Feb 29', - ), - ]; - } - - static List getBudgetDataList() { - return [ - BudgetData( - name: 'Coffee Shops', - primaryAmount: 70.0, - amountUsed: 45.49, - ), - BudgetData( - name: 'Groceries', - primaryAmount: 170.0, - amountUsed: 16.45, - ), - BudgetData( - name: 'Restaurants', - primaryAmount: 170.0, - amountUsed: 123.25, - ), - BudgetData( - name: 'Clothing', - primaryAmount: 70.0, - amountUsed: 19.45, - ), - ]; - } - - static List getSettingsTitles() { - return [ - 'Manage Accounts', - 'Tax Documents', - 'Passcode and Touch ID', - 'Notifications', - 'Personal Information', - 'Paperless Settings', - 'Find ATMs', - 'Help', - ]; - } -} diff --git a/material_studies/rally/lib/finance.dart b/material_studies/rally/lib/finance.dart deleted file mode 100644 index ab82dd51e..000000000 --- a/material_studies/rally/lib/finance.dart +++ /dev/null @@ -1,344 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; - -import 'package:rally/charts/pie_chart.dart'; -import 'package:rally/charts/line_chart.dart'; -import 'package:rally/charts/vertical_fraction_bar.dart'; -import 'package:rally/colors.dart'; -import 'package:rally/data.dart'; -import 'package:rally/formatters.dart'; - -class FinancialEntityView extends StatelessWidget { - FinancialEntityView({ - this.heroLabel, - this.heroAmount, - this.wholeAmount, - this.segments, - this.financialEntityCards, - }) : assert(segments.length == financialEntityCards.length); - - /// The amounts to assign each item. - /// - /// This list must have the same length as [colors]. - final List segments; - final String heroLabel; - final double heroAmount; - final double wholeAmount; - final List financialEntityCards; - - @override - Widget build(BuildContext context) { - return Column( - children: [ - RallyPieChart( - heroLabel: heroLabel, - heroAmount: heroAmount, - wholeAmount: wholeAmount, - segments: segments, - ), - SizedBox( - height: 1.0, - child: Container( - color: Color(0xA026282F), - ), - ), - ListView(shrinkWrap: true, children: financialEntityCards) - ], - ); - } -} - -/// A reusable widget to show balance information of a single entity as a card. -class FinancialEntityCategoryView extends StatelessWidget { - const FinancialEntityCategoryView({ - @required this.indicatorColor, - @required this.indicatorFraction, - @required this.title, - @required this.subtitle, - @required this.amount, - @required this.suffix, - }); - - final Color indicatorColor; - final double indicatorFraction; - final String title; - final String subtitle; - final double amount; - final Widget suffix; - - @override - Widget build(BuildContext context) { - return FlatButton( - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (context) => FinancialEntityCategoryDetailsPage(), - ), - ); - }, - child: SizedBox( - height: 68, - child: Column( - children: [ - Expanded( - child: Row( - children: [ - Padding( - padding: EdgeInsets.only(left: 12, right: 12), - child: VerticalFractionBar( - color: indicatorColor, - fraction: indicatorFraction, - ), - ), - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - title, - style: Theme.of(context) - .textTheme - .body1 - .copyWith(fontSize: 16.0), - ), - Text( - subtitle, - style: Theme.of(context) - .textTheme - .body1 - .copyWith(color: RallyColors.gray60), - ), - ], - ), - Spacer(), - Text( - '\$ ' + Formatters.usd.format(amount), - style: Theme.of(context) - .textTheme - .body2 - .copyWith(fontSize: 20.0, color: RallyColors.gray), - ), - SizedBox(width: 32.0, child: suffix), - ], - ), - ), - Divider( - height: 1, - indent: 16, - endIndent: 16, - color: Color(0xAA282828), - ), - ], - ), - ), - ); - } -} - -/// Data model for [FinancialEntityCategoryView]. -class FinancialEntityCategoryModel { - final Color indicatorColor; - final double indicatorFraction; - final String title; - final String subtitle; - final double usdAmount; - final Widget suffix; - - const FinancialEntityCategoryModel( - this.indicatorColor, - this.indicatorFraction, - this.title, - this.subtitle, - this.usdAmount, - this.suffix, - ); -} - -FinancialEntityCategoryView buildFinancialEntityFromAccountData( - AccountData model, - int i, -) { - return FinancialEntityCategoryView( - suffix: Icon(Icons.chevron_right, color: Colors.grey), - title: model.name, - subtitle: '• • • • • • ${model.accountNumber.substring(6)}', - indicatorColor: RallyColors.accountColor(i), - indicatorFraction: 1.0, - amount: model.primaryAmount, - ); -} - -FinancialEntityCategoryView buildFinancialEntityFromBillData( - BillData model, - int i, -) { - return FinancialEntityCategoryView( - suffix: Icon(Icons.chevron_right, color: Colors.grey), - title: model.name, - subtitle: model.dueDate, - indicatorColor: RallyColors.billColor(i), - indicatorFraction: 1.0, - amount: model.primaryAmount, - ); -} - -FinancialEntityCategoryView buildFinancialEntityFromBudgetData( - BudgetData item, - int i, - BuildContext context, -) { - return FinancialEntityCategoryView( - suffix: Text(' LEFT', - style: Theme.of(context) - .textTheme - .body1 - .copyWith(color: RallyColors.gray60, fontSize: 10.0)), - title: item.name, - subtitle: Formatters.usdWithSign.format(item.amountUsed) + - ' / ' + - Formatters.usdWithSign.format(item.primaryAmount), - indicatorColor: RallyColors.budgetColor(i), - indicatorFraction: item.amountUsed / item.primaryAmount, - amount: item.primaryAmount - item.amountUsed, - ); -} - -List buildAccountDataListViews( - List items) { - return List.generate( - items.length, (i) => buildFinancialEntityFromAccountData(items[i], i)); -} - -List buildBillDataListViews(List items) { - return List.generate( - items.length, (i) => buildFinancialEntityFromBillData(items[i], i)); -} - -List buildBudgetDataListViews( - List items, BuildContext context) { - return [ - for (var i = 0; i < items.length; i++) - buildFinancialEntityFromBudgetData(items[i], i, context) - ]; -} - -class FinancialEntityCategoryDetailsPage extends StatelessWidget { - final List items = - DummyDataService.getDetailedEventItems(); - - @override - Widget build(BuildContext context) { - final List<_DetailedEventCard> cards = items - .map((i) => _DetailedEventCard( - title: i.title, - subtitle: Formatters.date.format(i.date), - amount: i.amount, - )) - .toList(); - - return Scaffold( - appBar: AppBar( - elevation: 0.0, - centerTitle: true, - title: Text( - 'Checking', - style: Theme.of(context).textTheme.body1.copyWith(fontSize: 18.0), - ), - ), - body: Column(children: [ - SizedBox( - height: 200.0, - width: double.infinity, - child: RallyLineChart(events: items)), - Flexible( - child: ListView(shrinkWrap: true, children: cards), - ) - ]), - ); - } -} - -class _DetailedEventCard extends StatelessWidget { - const _DetailedEventCard({ - @required this.title, - @required this.subtitle, - @required this.amount, - }); - - final String title; - final String subtitle; - final double amount; - - @override - Widget build(BuildContext context) { - return FlatButton( - onPressed: () {}, - child: SizedBox( - height: 68.0, - child: Column( - children: [ - SizedBox( - height: 67.0, - child: Row( - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - title, - style: Theme.of(context) - .textTheme - .body1 - .copyWith(fontSize: 16.0), - ), - Text( - subtitle, - style: Theme.of(context) - .textTheme - .body1 - .copyWith(color: RallyColors.gray60), - ) - ], - ), - Spacer(), - Text( - '\$${Formatters.usd.format(amount)}', - style: Theme.of(context) - .textTheme - .body2 - .copyWith(fontSize: 20.0, color: RallyColors.gray), - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: SizedBox( - height: 1.0, - child: Container( - color: Color(0xAA282828), - ), - ), - ) - ], - ), - ), - ); - } -} diff --git a/material_studies/rally/lib/formatters.dart b/material_studies/rally/lib/formatters.dart deleted file mode 100644 index 3d6f081c1..000000000 --- a/material_studies/rally/lib/formatters.dart +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:intl/intl.dart'; - -class Formatters { - static final NumberFormat usd = NumberFormat.currency(name: ''); - static final NumberFormat usdWithSign = NumberFormat.currency(name: '\$'); - static final DateFormat date = DateFormat('MM-dd-yy'); -} diff --git a/material_studies/rally/lib/home.dart b/material_studies/rally/lib/home.dart deleted file mode 100644 index bbb12bff2..000000000 --- a/material_studies/rally/lib/home.dart +++ /dev/null @@ -1,221 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:rally/tabs/accounts.dart'; -import 'package:rally/tabs/bills.dart'; -import 'package:rally/tabs/budgets.dart'; -import 'package:rally/tabs/overview.dart'; -import 'package:rally/tabs/settings.dart'; - -const int tabCount = 5; - -class HomePage extends StatefulWidget { - @override - _HomePageState createState() => _HomePageState(); -} - -class _HomePageState extends State - with SingleTickerProviderStateMixin { - TabController _tabController; - - _HomePageState() { - _tabController = TabController(length: tabCount, vsync: this); - } - - @override - void initState() { - super.initState(); - print('_HomePageState initState'); - - _tabController.addListener(() { - if (_tabController.indexIsChanging && - _tabController.previousIndex != _tabController.index) { - setState(() {}); - } - }); - } - - @override - dispose() { - _tabController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - - return Scaffold( - body: SafeArea( - child: Column( - children: [ - Theme( - // This theme effectively removes the default visual touch - // feedback for tapping a tab, which is replaced with a custom - // animation. - data: theme.copyWith( - splashColor: Colors.transparent, - highlightColor: Colors.transparent, - ), - child: TabBar( - // Setting isScrollable to true prevents the tabs from being - // wrapped in [Expanded] widgets, which allows for more - // flexible sizes and size animations among tabs. - isScrollable: true, - labelPadding: EdgeInsets.zero, - tabs: _buildTabs(theme), - controller: _tabController, - // This removes the tab indicator. - indicatorColor: Colors.transparent, - ), - ), - Expanded( - child: TabBarView( - controller: _tabController, - children: _buildTabViews(), - ), - ) - ], - ), - ), - ); - } - - List _buildTabs(ThemeData theme) { - return [ - _buildTab(theme, Icons.pie_chart, 'OVERVIEW', 0), - _buildTab(theme, Icons.attach_money, 'ACCOUNTS', 1), - _buildTab(theme, Icons.money_off, 'BILLS', 2), - _buildTab(theme, Icons.table_chart, 'BUDGETS', 3), - _buildTab(theme, Icons.settings, 'SETTINGS', 4), - ]; - } - - List _buildTabViews() { - return [ - OverviewView(), - AccountsView(), - BillsView(), - BudgetsView(), - SettingsView(), - ]; - } - - Widget _buildTab( - ThemeData theme, - IconData iconData, - String title, - int index, - ) { - return _RallyTab( - theme.textTheme.button, - Icon(iconData), - title, - _tabController.index == index, - ); - } -} - -class _RallyTab extends StatefulWidget { - final TextStyle style; - final Text titleText; - final Icon icon; - final bool isExpanded; - - _RallyTab(TextStyle style, Icon icon, String title, bool isExpanded) - : this.style = style, - this.titleText = Text(title, style: style), - this.icon = icon, - this.isExpanded = isExpanded; - - _RallyTabState createState() => _RallyTabState(); -} - -class _RallyTabState extends State<_RallyTab> - with SingleTickerProviderStateMixin { - Animation _titleSizeAnimation; - Animation _titleFadeAnimation; - Animation _iconFadeAnimation; - AnimationController _controller; - - @override - initState() { - super.initState(); - _controller = AnimationController( - duration: Duration(milliseconds: 200), - vsync: this, - ); - _titleSizeAnimation = _controller.view; - _titleFadeAnimation = _controller.drive(CurveTween(curve: Curves.easeOut)); - _iconFadeAnimation = _controller.drive(Tween(begin: 0.6, end: 1)); - if (widget.isExpanded) { - _controller.value = 1.0; - } - } - - @override - void didUpdateWidget(_RallyTab oldWidget) { - super.didUpdateWidget(oldWidget); - if (widget.isExpanded) { - _controller.forward(); - } else { - _controller.reverse(); - } - } - - Widget build(BuildContext context) { - // Calculate the width of each unexpanded tab by counting the number of - // units and dividing it into the screen width. Each unexpanded tab is 1 - // unit, and there is always 1 expanded tab which is 1 unit + any extra - // space determined by the multiplier. - final double width = MediaQuery.of(context).size.width; - final double expandedTitleWidthMultiplier = 2; - final double unitWidth = width / (tabCount + expandedTitleWidthMultiplier); - - return SizedBox( - height: 56, - child: Row( - children: [ - FadeTransition( - child: SizedBox( - width: unitWidth, - child: widget.icon, - ), - opacity: _iconFadeAnimation, - ), - FadeTransition( - child: SizeTransition( - child: SizedBox( - width: unitWidth * expandedTitleWidthMultiplier, - child: Center(child: widget.titleText), - ), - axis: Axis.horizontal, - axisAlignment: -1, - sizeFactor: _titleSizeAnimation, - ), - opacity: _titleFadeAnimation, - ), - ], - ), - ); - } - - @override - dispose() { - _controller.dispose(); - super.dispose(); - } -} diff --git a/material_studies/rally/lib/login.dart b/material_studies/rally/lib/login.dart deleted file mode 100644 index bf41a1071..000000000 --- a/material_studies/rally/lib/login.dart +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; - -class LoginPage extends StatefulWidget { - @override - _LoginPageState createState() => _LoginPageState(); -} - -class _LoginPageState extends State { - final _usernameController = TextEditingController(); - final _passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: SafeArea( - child: GestureDetector( - onTap: () { - Navigator.pop(context); - }, - child: ListView( - padding: EdgeInsets.symmetric(horizontal: 24), - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 64), - child: SizedBox( - height: 160, - child: Image.asset('assets/logo.png'), - ), - ), - TextField( - controller: _usernameController, - decoration: InputDecoration( - labelText: 'Username', - ), - ), - SizedBox(height: 12), - TextField( - controller: _passwordController, - decoration: InputDecoration( - labelText: 'Password', - ), - obscureText: true, - ), - SizedBox( - height: 120, - child: Image.asset('assets/thumb.png'), - ), - ], - ), - ), - ), - ); - } -} diff --git a/material_studies/rally/lib/main.dart b/material_studies/rally/lib/main.dart deleted file mode 100644 index c52246f5c..000000000 --- a/material_studies/rally/lib/main.dart +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:rally/app.dart'; - -void main() => runApp(RallyApp()); diff --git a/material_studies/rally/lib/tabs/accounts.dart b/material_studies/rally/lib/tabs/accounts.dart deleted file mode 100644 index 85797dd08..000000000 --- a/material_studies/rally/lib/tabs/accounts.dart +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; - -import 'package:rally/data.dart'; -import 'package:rally/finance.dart'; -import 'package:rally/charts/pie_chart.dart'; - -/// A page that shows a summary of accounts. -class AccountsView extends StatelessWidget { - final List items = DummyDataService.getAccountDataList(); - - @override - Widget build(BuildContext context) { - double balanceTotal = sumAccountDataPrimaryAmount(items); - return FinancialEntityView( - heroLabel: 'Total', - heroAmount: balanceTotal, - segments: buildSegmentsFromAccountItems(items), - wholeAmount: balanceTotal, - financialEntityCards: buildAccountDataListViews(items), - ); - } -} diff --git a/material_studies/rally/lib/tabs/bills.dart b/material_studies/rally/lib/tabs/bills.dart deleted file mode 100644 index 80ec924ca..000000000 --- a/material_studies/rally/lib/tabs/bills.dart +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; - -import 'package:rally/data.dart'; -import 'package:rally/finance.dart'; -import 'package:rally/charts/pie_chart.dart'; - -/// A page that shows a summary of bills. -class BillsView extends StatefulWidget { - @override - _BillsViewState createState() => _BillsViewState(); -} - -class _BillsViewState extends State - with SingleTickerProviderStateMixin { - final List items = DummyDataService.getBillDataList(); - - @override - Widget build(BuildContext context) { - double dueTotal = sumBillDataPrimaryAmount(items); - return FinancialEntityView( - heroLabel: 'Due', - heroAmount: dueTotal, - segments: buildSegmentsFromBillItems(items), - wholeAmount: dueTotal, - financialEntityCards: buildBillDataListViews(items), - ); - } -} diff --git a/material_studies/rally/lib/tabs/budgets.dart b/material_studies/rally/lib/tabs/budgets.dart deleted file mode 100644 index ccac509be..000000000 --- a/material_studies/rally/lib/tabs/budgets.dart +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; - -import 'package:rally/charts/pie_chart.dart'; -import 'package:rally/data.dart'; -import 'package:rally/finance.dart'; - -class BudgetsView extends StatefulWidget { - @override - _BudgetsViewState createState() => _BudgetsViewState(); -} - -class _BudgetsViewState extends State - with SingleTickerProviderStateMixin { - final List items = DummyDataService.getBudgetDataList(); - - @override - Widget build(BuildContext context) { - double capTotal = sumBudgetDataPrimaryAmount(items); - double usedTotal = sumBudgetDataAmountUsed(items); - return FinancialEntityView( - heroLabel: 'Left', - heroAmount: capTotal - usedTotal, - segments: buildSegmentsFromBudgetItems(items), - wholeAmount: capTotal, - financialEntityCards: buildBudgetDataListViews(items, context), - ); - } -} diff --git a/material_studies/rally/lib/tabs/overview.dart b/material_studies/rally/lib/tabs/overview.dart deleted file mode 100644 index 7861fc0d3..000000000 --- a/material_studies/rally/lib/tabs/overview.dart +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; - -import 'package:rally/colors.dart'; -import 'package:rally/data.dart'; -import 'package:rally/finance.dart'; -import 'package:rally/formatters.dart'; - -/// A page that shows a status overview. -class OverviewView extends StatefulWidget { - @override - _OverviewViewState createState() => _OverviewViewState(); -} - -class _OverviewViewState extends State { - @override - Widget build(BuildContext context) { - final accountDataList = DummyDataService.getAccountDataList(); - final billDataList = DummyDataService.getBillDataList(); - final budgetDataList = DummyDataService.getBudgetDataList(); - - return Padding( - padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: ListView(children: [ - _AlertsView(), - SizedBox(height: 16), - _FinancialView( - title: 'Accounts', - total: sumAccountDataPrimaryAmount(accountDataList), - financialItemViews: buildAccountDataListViews(accountDataList), - ), - SizedBox(height: 16), - _FinancialView( - title: 'Bills', - total: sumBillDataPrimaryAmount(billDataList), - financialItemViews: buildBillDataListViews(billDataList), - ), - SizedBox(height: 16), - _FinancialView( - title: 'Budgets', - total: sumBudgetDataPrimaryAmount(budgetDataList), - financialItemViews: buildBudgetDataListViews(budgetDataList, context), - ), - SizedBox(height: 16), - ]), - ); - } -} - -class _AlertsView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.only(left: 16, top: 4, bottom: 4), - color: RallyColors.cardBackground, - child: Column( - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text('Alerts'), - FlatButton( - onPressed: () {}, - child: Text('SEE ALL'), - textColor: Colors.white, - ), - ], - ), - Container(color: RallyColors.primaryBackground, height: 1), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - 'Heads up, you’ve used up 90% of your Shopping budget for ' - 'this month.'), - ), - SizedBox( - width: 100, - child: Align( - alignment: Alignment.topRight, - child: IconButton( - onPressed: () {}, - icon: Icon(Icons.sort, color: RallyColors.white60), - ), - ), - ), - ], - ) - ], - ), - ); - } -} - -class _FinancialView extends StatelessWidget { - _FinancialView({this.title, this.total, this.financialItemViews}); - - final String title; - final double total; - final List financialItemViews; - - @override - Widget build(BuildContext context) { - final theme = Theme.of(context); - return Container( - color: RallyColors.cardBackground, - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Padding( - padding: EdgeInsets.all(16), - child: Text(title), - ), - Padding( - padding: EdgeInsets.only(left: 16, right: 16), - child: Text( - Formatters.usdWithSign.format(total), - style: theme.textTheme.body2.copyWith( - fontSize: 44.0, - fontWeight: FontWeight.w600, - ), - ), - ), - ...financialItemViews.sublist(0, min(financialItemViews.length, 3)), - FlatButton( - child: Text('SEE ALL'), - textColor: Colors.white, - onPressed: () {}, - ), - ], - ), - ); - } -} diff --git a/material_studies/rally/lib/tabs/settings.dart b/material_studies/rally/lib/tabs/settings.dart deleted file mode 100644 index 757ef92e7..000000000 --- a/material_studies/rally/lib/tabs/settings.dart +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2019-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; - -import 'package:rally/data.dart'; - -class SettingsView extends StatefulWidget { - @override - _SettingsViewState createState() => _SettingsViewState(); -} - -class _SettingsViewState extends State { - List items = DummyDataService.getSettingsTitles() - .map((title) => _SettingsItem(title)) - .toList(); - - @override - Widget build(BuildContext context) { - return ListView(children: items); - } -} - -class _SettingsItem extends StatelessWidget { - _SettingsItem(this.title); - - final String title; - - @override - Widget build(BuildContext context) { - return FlatButton( - textColor: Colors.white, - child: SizedBox( - height: 60, - child: Row(children: [ - Text(title), - ]), - ), - onPressed: () {}, - ); - } -} diff --git a/material_studies/rally/pubspec.lock b/material_studies/rally/pubspec.lock deleted file mode 100644 index bd64e2335..000000000 --- a/material_studies/rally/pubspec.lock +++ /dev/null @@ -1,202 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.2" - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.11" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - intl: - dependency: "direct main" - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.15.8" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.4" - pedantic: - dependency: "direct dev" - description: - name: pedantic - 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" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.5" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.11" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.5.0" -sdks: - dart: ">=2.5.0 <3.0.0" diff --git a/material_studies/rally/pubspec.yaml b/material_studies/rally/pubspec.yaml deleted file mode 100644 index 701abb477..000000000 --- a/material_studies/rally/pubspec.yaml +++ /dev/null @@ -1,40 +0,0 @@ -name: rally -description: Rally -version: 1.0.0+1 - -environment: - sdk: ">=2.5.0 <3.0.0" - -dependencies: - flutter: - sdk: flutter - cupertino_icons: ^0.1.2 - intl: ^0.15.7 - -dev_dependencies: - flutter_test: - sdk: flutter - pedantic: ^1.8.0 - -flutter: - uses-material-design: true - assets: - - assets/logo.png - - assets/thumb.png - fonts: - - family: Roboto Condensed - fonts: - - asset: fonts/RobotoCondensed-Light.ttf - weight: 400 - - asset: fonts/RobotoCondensed-Regular.ttf - weight: 500 - - asset: fonts/RobotoCondensed-Bold.ttf - weight: 700 - - family: Eczar - fonts: - - asset: fonts/Eczar-Regular.ttf - weight: 400 - - asset: fonts/Eczar-SemiBold.ttf - weight: 600 - - asset: fonts/Eczar-Bold.ttf - weight: 700 diff --git a/material_studies/rally/test/widget_test.dart b/material_studies/rally/test/widget_test.dart deleted file mode 100644 index eac78b4f8..000000000 --- a/material_studies/rally/test/widget_test.dart +++ /dev/null @@ -1,18 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:rally/app.dart'; - -void main() { - testWidgets('Smoke test', (tester) async { - await tester.pumpWidget(RallyApp()); - expect(find.byType(MaterialApp), findsOneWidget); - }); -} diff --git a/material_studies/shrine/.gitignore b/material_studies/shrine/.gitignore deleted file mode 100644 index 808f1fc86..000000000 --- a/material_studies/shrine/.gitignore +++ /dev/null @@ -1,71 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# Visual Studio Code related -.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/material_studies/shrine/.metadata b/material_studies/shrine/.metadata deleted file mode 100644 index 82403edb5..000000000 --- a/material_studies/shrine/.metadata +++ /dev/null @@ -1,8 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: c7ea3ca377e909469c68f2ab878a5bc53d3cf66b - channel: beta diff --git a/material_studies/shrine/README.md b/material_studies/shrine/README.md deleted file mode 100644 index 1e725f425..000000000 --- a/material_studies/shrine/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Shrine - -A sample shopping app that uses Material Component widgets in its UI and -[`scoped_model`](https://pub.dartlang.org/packages/scoped_model) to -manage the state of its shopping cart. - -## Goals - -* Show how to customize Flutter's Material Component widgets to produce - a unique design for an app. -* Show how to use `scoped_model` to manage an app's state and access it - across different routes and in different widgets. - -This is a modified version of the app featured in Flutter's -[Material codelabs](https://codelabs.developers.google.com/?cat=Flutter). - -## The important bits - -### `/model/app_state_model.dart` - -The model object representing the state of the app. It holds the -available products as well as what's in the shopping cart. - -### `/supplemental` - -A bunch of widgets that customize Material to produce the look and feel -of the app. - -### `shopping_cart.dart` - -The shopping cart widgets. They access the app state model via -`ScopedModelDescendant`, display the contents of the shopping cart, and -allow the user to edit them. - -## Questions/issues - -If you have a general question about any of the techniques you see in -the sample, the best places to go are: - -* [The FlutterDev Google Group](https://groups.google.com/forum/#!forum/flutter-dev) -* [The Flutter Gitter channel](https://gitter.im/flutter/flutter) -* [StackOverflow](https://stackoverflow.com/questions/tagged/flutter) - -If you run into an issue with the sample itself, please file an issue -in the [main Flutter repo](https://github.com/flutter/flutter/issues). diff --git a/material_studies/shrine/analysis_options.yaml b/material_studies/shrine/analysis_options.yaml deleted file mode 100644 index 8595cd0e8..000000000 --- a/material_studies/shrine/analysis_options.yaml +++ /dev/null @@ -1,30 +0,0 @@ -include: package:pedantic/analysis_options.1.8.0.yaml - -analyzer: - strong-mode: - implicit-casts: false - implicit-dynamic: false - -linter: - rules: - - avoid_types_on_closure_parameters - - avoid_void_async - - await_only_futures - - camel_case_types - - cancel_subscriptions - - close_sinks - - constant_identifier_names - - control_flow_in_finally - - empty_statements - - hash_and_equals - - implementation_imports - - non_constant_identifier_names - - package_api_docs - - package_names - - package_prefixed_library_names - - test_types_in_equals - - throw_in_finally - - unnecessary_brace_in_string_interps - - unnecessary_getters_setters - - unnecessary_new - - unnecessary_statements diff --git a/material_studies/shrine/android/.gitignore b/material_studies/shrine/android/.gitignore deleted file mode 100644 index 65b7315af..000000000 --- a/material_studies/shrine/android/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.iml -*.class -.gradle -/local.properties -/.idea/workspace.xml -/.idea/libraries -.DS_Store -/build -/captures -GeneratedPluginRegistrant.java diff --git a/material_studies/shrine/android/app/build.gradle b/material_studies/shrine/android/app/build.gradle deleted file mode 100644 index 2c16fbafe..000000000 --- a/material_studies/shrine/android/app/build.gradle +++ /dev/null @@ -1,51 +0,0 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -apply plugin: 'com.android.application' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - -android { - compileSdkVersion 27 - - lintOptions { - disable 'InvalidPackage' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.flutter.shrine" - minSdkVersion 16 - targetSdkVersion 27 - versionCode 1 - versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - } - - buildTypes { - release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug - } - } -} - -flutter { - source '../..' -} - -dependencies { - testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' -} diff --git a/material_studies/shrine/android/app/src/main/AndroidManifest.xml b/material_studies/shrine/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index f288ca93f..000000000 --- a/material_studies/shrine/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/material_studies/shrine/android/app/src/main/java/com/example/flutter/shrine/MainActivity.java b/material_studies/shrine/android/app/src/main/java/com/example/flutter/shrine/MainActivity.java deleted file mode 100644 index f9c24edde..000000000 --- a/material_studies/shrine/android/app/src/main/java/com/example/flutter/shrine/MainActivity.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.example.flutter.shrine; - -import android.os.Bundle; -import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; - -public class MainActivity extends FlutterActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); - } -} diff --git a/material_studies/shrine/android/app/src/main/res/drawable/launch_background.xml b/material_studies/shrine/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f88..000000000 --- a/material_studies/shrine/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/material_studies/shrine/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/material_studies/shrine/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4b7..000000000 Binary files a/material_studies/shrine/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/material_studies/shrine/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/material_studies/shrine/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b79b..000000000 Binary files a/material_studies/shrine/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/material_studies/shrine/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/material_studies/shrine/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 09d439148..000000000 Binary files a/material_studies/shrine/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/material_studies/shrine/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/material_studies/shrine/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d34..000000000 Binary files a/material_studies/shrine/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/material_studies/shrine/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/material_studies/shrine/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372eeb..000000000 Binary files a/material_studies/shrine/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/material_studies/shrine/android/app/src/main/res/values/styles.xml b/material_studies/shrine/android/app/src/main/res/values/styles.xml deleted file mode 100644 index 00fa4417c..000000000 --- a/material_studies/shrine/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/material_studies/shrine/android/build.gradle b/material_studies/shrine/android/build.gradle deleted file mode 100644 index 447688755..000000000 --- a/material_studies/shrine/android/build.gradle +++ /dev/null @@ -1,29 +0,0 @@ -buildscript { - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' - } -} - -allprojects { - repositories { - google() - jcenter() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/material_studies/shrine/android/gradle.properties b/material_studies/shrine/android/gradle.properties deleted file mode 100644 index 8bd86f680..000000000 --- a/material_studies/shrine/android/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M diff --git a/material_studies/shrine/android/gradle/wrapper/gradle-wrapper.properties b/material_studies/shrine/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index aa901e1e0..000000000 --- a/material_studies/shrine/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Jun 23 08:50:38 CEST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/material_studies/shrine/android/settings.gradle b/material_studies/shrine/android/settings.gradle deleted file mode 100644 index 5a2f14fb1..000000000 --- a/material_studies/shrine/android/settings.gradle +++ /dev/null @@ -1,15 +0,0 @@ -include ':app' - -def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() - -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } -} - -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory -} diff --git a/material_studies/shrine/assets/2.0x/diamond.png b/material_studies/shrine/assets/2.0x/diamond.png deleted file mode 100644 index 602e2ea51..000000000 Binary files a/material_studies/shrine/assets/2.0x/diamond.png and /dev/null differ diff --git a/material_studies/shrine/assets/2.0x/slanted_menu.png b/material_studies/shrine/assets/2.0x/slanted_menu.png deleted file mode 100755 index 5958055e4..000000000 Binary files a/material_studies/shrine/assets/2.0x/slanted_menu.png and /dev/null differ diff --git a/material_studies/shrine/assets/3.0x/diamond.png b/material_studies/shrine/assets/3.0x/diamond.png deleted file mode 100644 index 78af7cd64..000000000 Binary files a/material_studies/shrine/assets/3.0x/diamond.png and /dev/null differ diff --git a/material_studies/shrine/assets/3.0x/slanted_menu.png b/material_studies/shrine/assets/3.0x/slanted_menu.png deleted file mode 100755 index 9b4920d4b..000000000 Binary files a/material_studies/shrine/assets/3.0x/slanted_menu.png and /dev/null differ diff --git a/material_studies/shrine/assets/diamond.png b/material_studies/shrine/assets/diamond.png deleted file mode 100644 index 1978a0a5a..000000000 Binary files a/material_studies/shrine/assets/diamond.png and /dev/null differ diff --git a/material_studies/shrine/assets/slanted_menu.png b/material_studies/shrine/assets/slanted_menu.png deleted file mode 100644 index c80d2d47e..000000000 Binary files a/material_studies/shrine/assets/slanted_menu.png and /dev/null differ diff --git a/material_studies/shrine/fonts/Rubik-Medium.ttf b/material_studies/shrine/fonts/Rubik-Medium.ttf deleted file mode 100755 index c0b7965f9..000000000 Binary files a/material_studies/shrine/fonts/Rubik-Medium.ttf and /dev/null differ diff --git a/material_studies/shrine/fonts/Rubik-Regular.ttf b/material_studies/shrine/fonts/Rubik-Regular.ttf deleted file mode 100755 index fb52c8eec..000000000 Binary files a/material_studies/shrine/fonts/Rubik-Regular.ttf and /dev/null differ diff --git a/material_studies/shrine/ios/.gitignore b/material_studies/shrine/ios/.gitignore deleted file mode 100644 index 79cc4da80..000000000 --- a/material_studies/shrine/ios/.gitignore +++ /dev/null @@ -1,45 +0,0 @@ -.idea/ -.vagrant/ -.sconsign.dblite -.svn/ - -.DS_Store -*.swp -profile - -DerivedData/ -build/ -GeneratedPluginRegistrant.h -GeneratedPluginRegistrant.m - -.generated/ - -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 - -!default.pbxuser -!default.mode1v3 -!default.mode2v3 -!default.perspectivev3 - -xcuserdata - -*.moved-aside - -*.pyc -*sync/ -Icon? -.tags* - -/Flutter/app.flx -/Flutter/app.zip -/Flutter/flutter_assets/ -/Flutter/App.framework -/Flutter/Flutter.framework -/Flutter/Generated.xcconfig -/ServiceDefinitions.json - -Pods/ -.symlinks/ diff --git a/material_studies/shrine/ios/Flutter/AppFrameworkInfo.plist b/material_studies/shrine/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 9367d483e..000000000 --- a/material_studies/shrine/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 8.0 - - diff --git a/material_studies/shrine/ios/Flutter/Debug.xcconfig b/material_studies/shrine/ios/Flutter/Debug.xcconfig deleted file mode 100644 index 592ceee85..000000000 --- a/material_studies/shrine/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "Generated.xcconfig" diff --git a/material_studies/shrine/ios/Flutter/Release.xcconfig b/material_studies/shrine/ios/Flutter/Release.xcconfig deleted file mode 100644 index 592ceee85..000000000 --- a/material_studies/shrine/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "Generated.xcconfig" diff --git a/material_studies/shrine/ios/Runner.xcodeproj/project.pbxproj b/material_studies/shrine/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index 62a37cf8c..000000000 --- a/material_studies/shrine/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,438 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; - 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */, - 3B80C3931E831B6300D905FE /* App.framework */, - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 97C146F21CF9000F007C117D /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0910; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 97C146F31CF9000F007C117D /* main.m in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = 1; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.flutter.shrine; - PRODUCT_NAME = "$(TARGET_NAME)"; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = 1; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.flutter.shrine; - PRODUCT_NAME = "$(TARGET_NAME)"; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/material_studies/shrine/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/material_studies/shrine/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16e..000000000 --- a/material_studies/shrine/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/material_studies/shrine/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/material_studies/shrine/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 1263ac84b..000000000 --- a/material_studies/shrine/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/material_studies/shrine/ios/Runner.xcworkspace/contents.xcworkspacedata b/material_studies/shrine/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16e..000000000 --- a/material_studies/shrine/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/material_studies/shrine/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/material_studies/shrine/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index 949b67898..000000000 --- a/material_studies/shrine/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - BuildSystemType - Original - - diff --git a/material_studies/shrine/ios/Runner/AppDelegate.h b/material_studies/shrine/ios/Runner/AppDelegate.h deleted file mode 100644 index 36e21bbf9..000000000 --- a/material_studies/shrine/ios/Runner/AppDelegate.h +++ /dev/null @@ -1,6 +0,0 @@ -#import -#import - -@interface AppDelegate : FlutterAppDelegate - -@end diff --git a/material_studies/shrine/ios/Runner/AppDelegate.m b/material_studies/shrine/ios/Runner/AppDelegate.m deleted file mode 100644 index 59a72e90b..000000000 --- a/material_studies/shrine/ios/Runner/AppDelegate.m +++ /dev/null @@ -1,13 +0,0 @@ -#include "AppDelegate.h" -#include "GeneratedPluginRegistrant.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application - didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; - // Override point for customization after application launch. - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -@end diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab2..000000000 --- a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index 3d43d11e6..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf030..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 2ccbfd967..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0b..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 4cde12118..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7e..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png deleted file mode 100644 index dcdc2306c..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png deleted file mode 100644 index 2ccbfd967..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f5..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b8609..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b8609..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164a..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d39..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png deleted file mode 100644 index 6a84f41e1..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index d0e1f5853..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json deleted file mode 100644 index 0bedcf2fd..000000000 --- a/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "LaunchImage.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "LaunchImage@3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png deleted file mode 100644 index 9da19eaca..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eaca..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eaca..000000000 Binary files a/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png and /dev/null differ diff --git a/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b7..000000000 --- a/material_studies/shrine/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/material_studies/shrine/ios/Runner/Base.lproj/LaunchScreen.storyboard b/material_studies/shrine/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7c..000000000 --- a/material_studies/shrine/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/material_studies/shrine/ios/Runner/Base.lproj/Main.storyboard b/material_studies/shrine/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516f..000000000 --- a/material_studies/shrine/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/material_studies/shrine/ios/Runner/Info.plist b/material_studies/shrine/ios/Runner/Info.plist deleted file mode 100644 index bff936f44..000000000 --- a/material_studies/shrine/ios/Runner/Info.plist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - shrine - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/material_studies/shrine/ios/Runner/main.m b/material_studies/shrine/ios/Runner/main.m deleted file mode 100644 index dff6597e4..000000000 --- a/material_studies/shrine/ios/Runner/main.m +++ /dev/null @@ -1,9 +0,0 @@ -#import -#import -#import "AppDelegate.h" - -int main(int argc, char* argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/material_studies/shrine/lib/app.dart b/material_studies/shrine/lib/app.dart deleted file mode 100644 index 97316f988..000000000 --- a/material_studies/shrine/lib/app.dart +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; - -import 'backdrop.dart'; -import 'category_menu_page.dart'; -import 'colors.dart'; -import 'home.dart'; -import 'login.dart'; -import 'expanding_bottom_sheet.dart'; -import 'supplemental/cut_corners_border.dart'; - -class ShrineApp extends StatefulWidget { - @override - _ShrineAppState createState() => _ShrineAppState(); -} - -class _ShrineAppState extends State - with SingleTickerProviderStateMixin { - // Controller to coordinate both the opening/closing of backdrop and sliding - // of expanding bottom sheet. - AnimationController _controller; - - @override - void initState() { - super.initState(); - _controller = AnimationController( - vsync: this, - duration: Duration(milliseconds: 450), - value: 1.0, - ); - } - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Shrine', - home: HomePage( - backdrop: Backdrop( - frontLayer: ProductPage(), - backLayer: - CategoryMenuPage(onCategoryTap: () => _controller.forward()), - frontTitle: Text('SHRINE'), - backTitle: Text('MENU'), - controller: _controller, - ), - expandingBottomSheet: ExpandingBottomSheet(hideController: _controller), - ), - initialRoute: '/login', - onGenerateRoute: _getRoute, - theme: _kShrineTheme, - ); - } -} - -Route _getRoute(RouteSettings settings) { - if (settings.name != '/login') { - return null; - } - - return MaterialPageRoute( - settings: settings, - builder: (context) => LoginPage(), - fullscreenDialog: true, - ); -} - -final ThemeData _kShrineTheme = _buildShrineTheme(); - -IconThemeData _customIconTheme(IconThemeData original) { - return original.copyWith(color: kShrineBrown900); -} - -ThemeData _buildShrineTheme() { - final ThemeData base = ThemeData.light(); - return base.copyWith( - colorScheme: kShrineColorScheme, - accentColor: kShrineBrown900, - primaryColor: kShrinePink100, - buttonColor: kShrinePink100, - scaffoldBackgroundColor: kShrineBackgroundWhite, - cardColor: kShrineBackgroundWhite, - textSelectionColor: kShrinePink100, - errorColor: kShrineErrorRed, - buttonTheme: const ButtonThemeData( - colorScheme: kShrineColorScheme, - textTheme: ButtonTextTheme.normal, - ), - primaryIconTheme: _customIconTheme(base.iconTheme), - inputDecorationTheme: - const InputDecorationTheme(border: CutCornersBorder()), - textTheme: _buildShrineTextTheme(base.textTheme), - primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme), - accentTextTheme: _buildShrineTextTheme(base.accentTextTheme), - iconTheme: _customIconTheme(base.iconTheme), - ); -} - -TextTheme _buildShrineTextTheme(TextTheme base) { - return base - .copyWith( - headline: base.headline.copyWith(fontWeight: FontWeight.w500), - title: base.title.copyWith(fontSize: 18.0), - caption: base.caption.copyWith( - fontWeight: FontWeight.w400, - fontSize: 14.0, - ), - body2: base.body2.copyWith( - fontWeight: FontWeight.w500, - fontSize: 16.0, - ), - button: base.button.copyWith( - fontWeight: FontWeight.w500, - fontSize: 14.0, - ), - ) - .apply( - fontFamily: 'Rubik', - displayColor: kShrineBrown900, - bodyColor: kShrineBrown900, - ); -} - -const ColorScheme kShrineColorScheme = ColorScheme( - primary: kShrinePink100, - primaryVariant: kShrineBrown900, - secondary: kShrinePink50, - secondaryVariant: kShrineBrown900, - surface: kShrineSurfaceWhite, - background: kShrineBackgroundWhite, - error: kShrineErrorRed, - onPrimary: kShrineBrown900, - onSecondary: kShrineBrown900, - onSurface: kShrineBrown900, - onBackground: kShrineBrown900, - onError: kShrineSurfaceWhite, - brightness: Brightness.light, -); diff --git a/material_studies/shrine/lib/backdrop.dart b/material_studies/shrine/lib/backdrop.dart deleted file mode 100644 index 7f6f1e68d..000000000 --- a/material_studies/shrine/lib/backdrop.dart +++ /dev/null @@ -1,332 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:meta/meta.dart'; - -import 'login.dart'; - -const Cubic _kAccelerateCurve = Cubic(0.548, 0.0, 0.757, 0.464); -const Cubic _kDecelerateCurve = Cubic(0.23, 0.94, 0.41, 1.0); -const double _kPeakVelocityTime = 0.248210; -const double _kPeakVelocityProgress = 0.379146; - -class _FrontLayer extends StatelessWidget { - const _FrontLayer({ - Key key, - this.onTap, - this.child, - }) : super(key: key); - - final VoidCallback onTap; - final Widget child; - - @override - Widget build(BuildContext context) { - return Material( - elevation: 16.0, - shape: BeveledRectangleBorder( - borderRadius: BorderRadius.only(topLeft: Radius.circular(46.0)), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Container( - height: 40.0, - alignment: AlignmentDirectional.centerStart, - ), - ), - Expanded( - child: child, - ), - ], - ), - ); - } -} - -class _BackdropTitle extends AnimatedWidget { - final VoidCallback onPress; - final Widget frontTitle; - final Widget backTitle; - - const _BackdropTitle({ - Key key, - Listenable listenable, - this.onPress, - @required this.frontTitle, - @required this.backTitle, - }) : assert(frontTitle != null), - assert(backTitle != null), - super(key: key, listenable: listenable); - - @override - Widget build(BuildContext context) { - final Animation animation = CurvedAnimation( - parent: this.listenable as Animation, - curve: Interval(0.0, 0.78), - ); - - return DefaultTextStyle( - style: Theme.of(context).primaryTextTheme.title, - softWrap: false, - overflow: TextOverflow.ellipsis, - child: Row(children: [ - // branded icon - SizedBox( - width: 72.0, - child: IconButton( - padding: EdgeInsets.only(right: 8.0), - onPressed: this.onPress, - icon: Stack(children: [ - Opacity( - opacity: animation.value, - child: ImageIcon(AssetImage('assets/slanted_menu.png')), - ), - FractionalTranslation( - translation: Tween( - begin: Offset.zero, - end: Offset(1.0, 0.0), - ).evaluate(animation), - child: ImageIcon(AssetImage('assets/diamond.png')), - ) - ]), - ), - ), - // Here, we do a custom cross fade between backTitle and frontTitle. - // This makes a smooth animation between the two texts. - Stack( - children: [ - Opacity( - opacity: CurvedAnimation( - parent: ReverseAnimation(animation), - curve: Interval(0.5, 1.0), - ).value, - child: FractionalTranslation( - translation: Tween( - begin: Offset.zero, - end: Offset(0.5, 0.0), - ).evaluate(animation), - child: backTitle, - ), - ), - Opacity( - opacity: CurvedAnimation( - parent: animation, - curve: Interval(0.5, 1.0), - ).value, - child: FractionalTranslation( - translation: Tween( - begin: Offset(-0.25, 0.0), - end: Offset.zero, - ).evaluate(animation), - child: frontTitle, - ), - ), - ], - ) - ]), - ); - } -} - -/// Builds a Backdrop. -/// -/// A Backdrop widget has two layers, front and back. The front layer is shown -/// by default, and slides down to show the back layer, from which a user -/// can make a selection. The user can also configure the titles for when the -/// front or back layer is showing. -class Backdrop extends StatefulWidget { - final Widget frontLayer; - final Widget backLayer; - final Widget frontTitle; - final Widget backTitle; - final AnimationController controller; - - const Backdrop({ - @required this.frontLayer, - @required this.backLayer, - @required this.frontTitle, - @required this.backTitle, - @required this.controller, - }) : assert(frontLayer != null), - assert(backLayer != null), - assert(frontTitle != null), - assert(backTitle != null), - assert(controller != null); - - @override - _BackdropState createState() => _BackdropState(); -} - -class _BackdropState extends State - with SingleTickerProviderStateMixin { - final GlobalKey _backdropKey = GlobalKey(debugLabel: 'Backdrop'); - AnimationController _controller; - Animation _layerAnimation; - - @override - void initState() { - super.initState(); - _controller = widget.controller; - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - bool get _frontLayerVisible { - final AnimationStatus status = _controller.status; - return status == AnimationStatus.completed || - status == AnimationStatus.forward; - } - - void _toggleBackdropLayerVisibility() { - // Call setState here to update layerAnimation if that's necessary - setState(() { - _frontLayerVisible ? _controller.reverse() : _controller.forward(); - }); - } - - // _layerAnimation animates the front layer between open and close. - // _getLayerAnimation adjusts the values in the TweenSequence so the - // curve and timing are correct in both directions. - Animation _getLayerAnimation(Size layerSize, double layerTop) { - Curve firstCurve; // Curve for first TweenSequenceItem - Curve secondCurve; // Curve for second TweenSequenceItem - double firstWeight; // Weight of first TweenSequenceItem - double secondWeight; // Weight of second TweenSequenceItem - Animation animation; // Animation on which TweenSequence runs - - if (_frontLayerVisible) { - firstCurve = _kAccelerateCurve; - secondCurve = _kDecelerateCurve; - firstWeight = _kPeakVelocityTime; - secondWeight = 1.0 - _kPeakVelocityTime; - animation = CurvedAnimation( - parent: _controller.view, - curve: Interval(0.0, 0.78), - ); - } else { - // These values are only used when the controller runs from t=1.0 to t=0.0 - firstCurve = _kDecelerateCurve.flipped; - secondCurve = _kAccelerateCurve.flipped; - firstWeight = 1.0 - _kPeakVelocityTime; - secondWeight = _kPeakVelocityTime; - animation = _controller.view; - } - - return TweenSequence( - >[ - TweenSequenceItem( - tween: RelativeRectTween( - begin: RelativeRect.fromLTRB( - 0.0, - layerTop, - 0.0, - layerTop - layerSize.height, - ), - end: RelativeRect.fromLTRB( - 0.0, - layerTop * _kPeakVelocityProgress, - 0.0, - (layerTop - layerSize.height) * _kPeakVelocityProgress, - ), - ).chain(CurveTween(curve: firstCurve)), - weight: firstWeight, - ), - TweenSequenceItem( - tween: RelativeRectTween( - begin: RelativeRect.fromLTRB( - 0.0, - layerTop * _kPeakVelocityProgress, - 0.0, - (layerTop - layerSize.height) * _kPeakVelocityProgress, - ), - end: RelativeRect.fill, - ).chain(CurveTween(curve: secondCurve)), - weight: secondWeight, - ), - ], - ).animate(animation); - } - - Widget _buildStack(BuildContext context, BoxConstraints constraints) { - const double layerTitleHeight = 48.0; - final Size layerSize = constraints.biggest; - final double layerTop = layerSize.height - layerTitleHeight; - - _layerAnimation = _getLayerAnimation(layerSize, layerTop); - - return Stack( - key: _backdropKey, - children: [ - widget.backLayer, - PositionedTransition( - rect: _layerAnimation, - child: _FrontLayer( - onTap: _toggleBackdropLayerVisibility, - child: widget.frontLayer, - ), - ), - ], - ); - } - - @override - Widget build(BuildContext context) { - var appBar = AppBar( - brightness: Brightness.light, - elevation: 0.0, - titleSpacing: 0.0, - title: _BackdropTitle( - listenable: _controller.view, - onPress: _toggleBackdropLayerVisibility, - frontTitle: widget.frontTitle, - backTitle: widget.backTitle, - ), - actions: [ - IconButton( - icon: const Icon(Icons.search, semanticLabel: 'login'), - onPressed: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => LoginPage()), - ); - }, - ), - IconButton( - icon: const Icon(Icons.tune, semanticLabel: 'login'), - onPressed: () { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => LoginPage()), - ); - }, - ), - ], - ); - return Scaffold( - appBar: appBar, - body: LayoutBuilder( - builder: _buildStack, - ), - ); - } -} diff --git a/material_studies/shrine/lib/category_menu_page.dart b/material_studies/shrine/lib/category_menu_page.dart deleted file mode 100644 index fbebb41b4..000000000 --- a/material_studies/shrine/lib/category_menu_page.dart +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:scoped_model/scoped_model.dart'; - -import 'colors.dart'; -import 'model/app_state_model.dart'; -import 'model/product.dart'; - -class CategoryMenuPage extends StatelessWidget { - final List _categories = Category.values; - final VoidCallback onCategoryTap; - - const CategoryMenuPage({ - Key key, - this.onCategoryTap, - }) : super(key: key); - - Widget _buildCategory(Category category, BuildContext context) { - final categoryString = - category.toString().replaceAll('Category.', '').toUpperCase(); - final ThemeData theme = Theme.of(context); - return ScopedModelDescendant( - builder: (context, child, model) => GestureDetector( - onTap: () { - model.setCategory(category); - if (onCategoryTap != null) onCategoryTap(); - }, - child: model.selectedCategory == category - ? Column( - children: [ - SizedBox(height: 16.0), - Text( - categoryString, - style: theme.textTheme.body2, - textAlign: TextAlign.center, - ), - SizedBox(height: 14.0), - Container( - width: 70.0, - height: 2.0, - color: kShrinePink400, - ), - ], - ) - : Padding( - padding: EdgeInsets.symmetric(vertical: 16.0), - child: Text( - categoryString, - style: theme.textTheme.body2 - .copyWith(color: kShrineBrown900.withAlpha(153)), - textAlign: TextAlign.center, - ), - ), - ), - ); - } - - @override - Widget build(BuildContext context) { - return Center( - child: Container( - padding: EdgeInsets.only(top: 40.0), - color: kShrinePink100, - child: ListView( - children: _categories.map((c) => _buildCategory(c, context)).toList(), - ), - ), - ); - } -} diff --git a/material_studies/shrine/lib/colors.dart b/material_studies/shrine/lib/colors.dart deleted file mode 100644 index 4af159310..000000000 --- a/material_studies/shrine/lib/colors.dart +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; - -const kShrinePink50 = Color(0xFFFEEAE6); -const kShrinePink100 = Color(0xFFFEDBD0); -const kShrinePink300 = Color(0xFFFBB8AC); -const kShrinePink400 = Color(0xFFEAA4A4); - -const kShrineBrown900 = Color(0xFF442B2D); -const kShrineBrown600 = Color(0xFF7D4F52); - -const kShrineErrorRed = Color(0xFFC5032B); - -const kShrineSurfaceWhite = Color(0xFFFFFBFA); -const kShrineBackgroundWhite = Colors.white; diff --git a/material_studies/shrine/lib/expanding_bottom_sheet.dart b/material_studies/shrine/lib/expanding_bottom_sheet.dart deleted file mode 100644 index ec5e0b504..000000000 --- a/material_studies/shrine/lib/expanding_bottom_sheet.dart +++ /dev/null @@ -1,670 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:meta/meta.dart'; -import 'package:scoped_model/scoped_model.dart'; - -import 'colors.dart'; -import 'model/app_state_model.dart'; -import 'model/product.dart'; -import 'shopping_cart.dart'; - -// These curves define the emphasized easing curve. -const Cubic _kAccelerateCurve = Cubic(0.548, 0.0, 0.757, 0.464); -const Cubic _kDecelerateCurve = Cubic(0.23, 0.94, 0.41, 1.0); -// The time at which the accelerate and decelerate curves switch off -const double _kPeakVelocityTime = 0.248210; -// Percent (as a decimal) of animation that should be completed at _peakVelocityTime -const double _kPeakVelocityProgress = 0.379146; -const double _kCartHeight = 56.0; -// Radius of the shape on the top left of the sheet. -const double _kCornerRadius = 24.0; -// Width for just the cart icon and no thumbnails. -const double _kWidthForCartIcon = 64.0; - -class ExpandingBottomSheet extends StatefulWidget { - const ExpandingBottomSheet({Key key, @required this.hideController}) - : assert(hideController != null), - super(key: key); - - final AnimationController hideController; - - @override - _ExpandingBottomSheetState createState() => _ExpandingBottomSheetState(); - - static _ExpandingBottomSheetState of(BuildContext context, - {bool isNullOk = false}) { - assert(isNullOk != null); - assert(context != null); - final _ExpandingBottomSheetState result = - context.findAncestorStateOfType<_ExpandingBottomSheetState>(); - if (isNullOk || result != null) { - return result; - } - throw FlutterError( - 'ExpandingBottomSheet.of() called with a context that does not contain a ExpandingBottomSheet.\n'); - } -} - -// Emphasized Easing is a motion curve that has an organic, exciting feeling. -// It's very fast to begin with and then very slow to finish. Unlike standard -// curves, like [Curves.fastOutSlowIn], it can't be expressed in a cubic bezier -// curve formula. It's quintic, not cubic. But it _can_ be expressed as one -// curve followed by another, which we do here. -Animation _getEmphasizedEasingAnimation( - {@required T begin, - @required T peak, - @required T end, - @required bool isForward, - @required Animation parent}) { - Curve firstCurve; - Curve secondCurve; - double firstWeight; - double secondWeight; - - if (isForward) { - firstCurve = _kAccelerateCurve; - secondCurve = _kDecelerateCurve; - firstWeight = _kPeakVelocityTime; - secondWeight = 1.0 - _kPeakVelocityTime; - } else { - firstCurve = _kDecelerateCurve.flipped; - secondCurve = _kAccelerateCurve.flipped; - firstWeight = 1.0 - _kPeakVelocityTime; - secondWeight = _kPeakVelocityTime; - } - - return TweenSequence( - >[ - TweenSequenceItem( - weight: firstWeight, - tween: Tween( - begin: begin, - end: peak, - ).chain(CurveTween(curve: firstCurve)), - ), - TweenSequenceItem( - weight: secondWeight, - tween: Tween( - begin: peak, - end: end, - ).chain(CurveTween(curve: secondCurve)), - ), - ], - ).animate(parent); -} - -// Calculates the value where two double Animations should be joined. Used by -// callers of _getEmphasisedEasing(). -double _getPeakPoint({double begin, double end}) { - return begin + (end - begin) * _kPeakVelocityProgress; -} - -class _ExpandingBottomSheetState extends State - with TickerProviderStateMixin { - final GlobalKey _expandingBottomSheetKey = - GlobalKey(debugLabel: 'Expanding bottom sheet'); - - // The width of the Material, calculated by _widthFor() & based on the number - // of products in the cart. 64.0 is the width when there are 0 products - // (_kWidthForZeroProducts) - double _width = _kWidthForCartIcon; - // Controller for the opening and closing of the ExpandingBottomSheet - AnimationController _controller; - // Animations for the opening and closing of the ExpandingBottomSheet - Animation _widthAnimation; - Animation _heightAnimation; - Animation _thumbnailOpacityAnimation; - Animation _cartOpacityAnimation; - Animation _shapeAnimation; - Animation _slideAnimation; - - @override - void initState() { - super.initState(); - _controller = AnimationController( - duration: const Duration(milliseconds: 500), - vsync: this, - ); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - Animation _getWidthAnimation(double screenWidth) { - if (_controller.status == AnimationStatus.forward) { - // Opening animation - return Tween(begin: _width, end: screenWidth).animate( - CurvedAnimation( - parent: _controller.view, - curve: Interval(0.0, 0.3, curve: Curves.fastOutSlowIn), - ), - ); - } else { - // Closing animation - return _getEmphasizedEasingAnimation( - begin: _width, - peak: _getPeakPoint(begin: _width, end: screenWidth), - end: screenWidth, - isForward: false, - parent: CurvedAnimation( - parent: _controller.view, curve: Interval(0.0, 0.87)), - ); - } - } - - Animation _getHeightAnimation(double screenHeight) { - if (_controller.status == AnimationStatus.forward) { - // Opening animation - - return _getEmphasizedEasingAnimation( - begin: _kCartHeight, - peak: _kCartHeight + - (screenHeight - _kCartHeight) * _kPeakVelocityProgress, - end: screenHeight, - isForward: true, - parent: _controller.view, - ); - } else { - // Closing animation - return Tween( - begin: _kCartHeight, - end: screenHeight, - ).animate( - CurvedAnimation( - parent: _controller.view, - curve: Interval(0.434, 1.0, curve: Curves.linear), // not used - // only the reverseCurve will be used - reverseCurve: - Interval(0.434, 1.0, curve: Curves.fastOutSlowIn.flipped), - ), - ); - } - } - - // Animation of the cut corner. It's cut when closed and not cut when open. - Animation _getShapeAnimation() { - if (_controller.status == AnimationStatus.forward) { - return Tween(begin: _kCornerRadius, end: 0.0).animate( - CurvedAnimation( - parent: _controller.view, - curve: Interval(0.0, 0.3, curve: Curves.fastOutSlowIn), - ), - ); - } else { - return _getEmphasizedEasingAnimation( - begin: _kCornerRadius, - peak: _getPeakPoint(begin: _kCornerRadius, end: 0.0), - end: 0.0, - isForward: false, - parent: _controller.view, - ); - } - } - - Animation _getThumbnailOpacityAnimation() { - return Tween(begin: 1.0, end: 0.0).animate( - CurvedAnimation( - parent: _controller.view, - curve: _controller.status == AnimationStatus.forward - ? Interval(0.0, 0.3) - : Interval(0.532, 0.766), - ), - ); - } - - Animation _getCartOpacityAnimation() { - return CurvedAnimation( - parent: _controller.view, - curve: _controller.status == AnimationStatus.forward - ? Interval(0.3, 0.6) - : Interval(0.766, 1.0), - ); - } - - // Returns the correct width of the ExpandingBottomSheet based on the number of - // products in the cart. - double _widthFor(int numProducts) { - switch (numProducts) { - case 0: - return _kWidthForCartIcon; - break; - case 1: - return 136.0; - break; - case 2: - return 192.0; - break; - case 3: - return 248.0; - break; - default: - return 278.0; - } - } - - // Returns true if the cart is open or opening and false otherwise. - bool get _isOpen { - final AnimationStatus status = _controller.status; - return status == AnimationStatus.completed || - status == AnimationStatus.forward; - } - - // Opens the ExpandingBottomSheet if it's closed, otherwise does nothing. - void open() { - if (!_isOpen) { - _controller.forward(); - } - } - - // Closes the ExpandingBottomSheet if it's open or opening, otherwise does nothing. - void close() { - if (_isOpen) { - _controller.reverse(); - } - } - - // Changes the padding between the start edge of the Material and the cart icon - // based on the number of products in the cart (padding increases when > 0 - // products.) - EdgeInsetsDirectional _cartPaddingFor(int numProducts) { - if (numProducts == 0) { - return EdgeInsetsDirectional.only(start: 20.0, end: 8.0); - } else { - return EdgeInsetsDirectional.only(start: 32.0, end: 8.0); - } - } - - bool get _cartIsVisible => _thumbnailOpacityAnimation.value == 0.0; - - Widget _buildThumbnails(int numProducts) { - return ExcludeSemantics( - child: Opacity( - opacity: _thumbnailOpacityAnimation.value, - child: Column(children: [ - Row(children: [ - AnimatedPadding( - padding: _cartPaddingFor(numProducts), - child: Icon(Icons.shopping_cart), - duration: Duration(milliseconds: 225), - ), - Container( - // Accounts for the overflow number - width: numProducts > 3 ? _width - 94.0 : _width - 64.0, - height: _kCartHeight, - padding: EdgeInsets.symmetric(vertical: 8.0), - child: ProductThumbnailRow(), - ), - ExtraProductsNumber() - ]), - ]), - ), - ); - } - - Widget _buildShoppingCartPage() { - return Opacity( - opacity: _cartOpacityAnimation.value, - child: ShoppingCartPage(), - ); - } - - Widget _buildCart(BuildContext context, Widget child) { - // numProducts is the number of different products in the cart (does not - // include multiples of the same product). - final AppStateModel model = ScopedModel.of(context); - final int numProducts = model.productsInCart.keys.length; - final int totalCartQuantity = model.totalCartQuantity; - final Size screenSize = MediaQuery.of(context).size; - final double screenWidth = screenSize.width; - final double screenHeight = screenSize.height; - - _width = _widthFor(numProducts); - _widthAnimation = _getWidthAnimation(screenWidth); - _heightAnimation = _getHeightAnimation(screenHeight); - _shapeAnimation = _getShapeAnimation(); - _thumbnailOpacityAnimation = _getThumbnailOpacityAnimation(); - _cartOpacityAnimation = _getCartOpacityAnimation(); - - return Semantics( - button: true, - value: 'Shopping cart, $totalCartQuantity items', - child: Container( - width: _widthAnimation.value, - height: _heightAnimation.value, - child: Material( - animationDuration: Duration(milliseconds: 0), - shape: BeveledRectangleBorder( - borderRadius: BorderRadius.only( - topLeft: Radius.circular(_shapeAnimation.value), - ), - ), - elevation: 4.0, - color: kShrinePink50, - child: _cartIsVisible - ? _buildShoppingCartPage() - : _buildThumbnails(numProducts), - ), - ), - ); - } - - // Builder for the hide and reveal animation when the backdrop opens and closes - Widget _buildSlideAnimation(BuildContext context, Widget child) { - _slideAnimation = _getEmphasizedEasingAnimation( - begin: Offset(1.0, 0.0), - peak: Offset(_kPeakVelocityProgress, 0.0), - end: Offset(0.0, 0.0), - isForward: widget.hideController.status == AnimationStatus.forward, - parent: widget.hideController, - ); - - return SlideTransition( - position: _slideAnimation, - child: child, - ); - } - - // Closes the cart if the cart is open, otherwise exits the app (this should - // only be relevant for Android). - Future _onWillPop() async { - if (!_isOpen) { - await SystemNavigator.pop(); - return true; - } - - close(); - return true; - } - - @override - Widget build(BuildContext context) { - return AnimatedSize( - key: _expandingBottomSheetKey, - duration: Duration(milliseconds: 225), - curve: Curves.easeInOut, - vsync: this, - alignment: FractionalOffset.topLeft, - child: WillPopScope( - onWillPop: _onWillPop, - child: AnimatedBuilder( - animation: widget.hideController, - builder: _buildSlideAnimation, - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: open, - child: ScopedModelDescendant( - builder: (context, child, model) { - return AnimatedBuilder( - builder: _buildCart, - animation: _controller, - ); - }, - ), - ), - ), - ), - ); - } -} - -class ProductThumbnailRow extends StatefulWidget { - @override - _ProductThumbnailRowState createState() => _ProductThumbnailRowState(); -} - -class _ProductThumbnailRowState extends State { - final GlobalKey _listKey = GlobalKey(); - // _list represents what's currently on screen. If _internalList updates, - // it will need to be updated to match it. - _ListModel _list; - // _internalList represents the list as it is updated by the AppStateModel. - List _internalList; - - @override - void initState() { - super.initState(); - _list = _ListModel( - listKey: _listKey, - initialItems: - ScopedModel.of(context).productsInCart.keys.toList(), - removedItemBuilder: _buildRemovedThumbnail, - ); - _internalList = List.from(_list.list); - } - - Product _productWithId(int productId) { - final AppStateModel model = ScopedModel.of(context); - final Product product = model.getProductById(productId); - assert(product != null); - return product; - } - - Widget _buildRemovedThumbnail( - int item, BuildContext context, Animation animation) { - return ProductThumbnail(animation, animation, _productWithId(item)); - } - - Widget _buildThumbnail( - BuildContext context, int index, Animation animation) { - Animation thumbnailSize = - Tween(begin: 0.8, end: 1.0).animate( - CurvedAnimation( - curve: Interval(0.33, 1.0, curve: Curves.easeIn), - parent: animation, - ), - ); - - Animation opacity = CurvedAnimation( - curve: Interval(0.33, 1.0, curve: Curves.linear), - parent: animation, - ); - - return ProductThumbnail( - thumbnailSize, opacity, _productWithId(_list[index])); - } - - // If the lists are the same length, assume nothing has changed. - // If the internalList is shorter than the ListModel, an item has been removed. - // If the internalList is longer, then an item has been added. - void _updateLists() { - // Update _internalList based on the model - _internalList = - ScopedModel.of(context).productsInCart.keys.toList(); - Set internalSet = Set.from(_internalList); - Set listSet = Set.from(_list.list); - - Set difference = internalSet.difference(listSet); - if (difference.isEmpty) { - return; - } - - difference.forEach((product) { - if (_internalList.length < _list.length) { - _list.remove(product); - } else if (_internalList.length > _list.length) { - _list.add(product); - } - }); - - while (_internalList.length != _list.length) { - int index = 0; - // Check bounds and that the list elements are the same - while (_internalList.isNotEmpty && - _list.length > 0 && - index < _internalList.length && - index < _list.length && - _internalList[index] == _list[index]) { - index++; - } - } - } - - Widget _buildAnimatedList() { - return AnimatedList( - key: _listKey, - shrinkWrap: true, - itemBuilder: _buildThumbnail, - initialItemCount: _list.length, - scrollDirection: Axis.horizontal, - physics: NeverScrollableScrollPhysics(), // Cart shouldn't scroll - ); - } - - @override - Widget build(BuildContext context) { - _updateLists(); - return ScopedModelDescendant( - builder: (context, child, model) => _buildAnimatedList(), - ); - } -} - -class ExtraProductsNumber extends StatelessWidget { - // Calculates the number to be displayed at the end of the row if there are - // more than three products in the cart. This calculates overflow products, - // including their duplicates (but not duplicates of products shown as - // thumbnails). - int _calculateOverflow(AppStateModel model) { - Map productMap = model.productsInCart; - // List created to be able to access products by index instead of ID. - // Order is guaranteed because productsInCart returns a LinkedHashMap. - List products = productMap.keys.toList(); - int overflow = 0; - int numProducts = products.length; - if (numProducts > 3) { - for (int i = 3; i < numProducts; i++) { - overflow += productMap[products[i]]; - } - } - return overflow; - } - - Widget _buildOverflow(AppStateModel model, BuildContext context) { - if (model.productsInCart.length > 3) { - int numOverflowProducts = _calculateOverflow(model); - // Maximum of 99 so padding doesn't get messy. - int displayedOverflowProducts = - numOverflowProducts <= 99 ? numOverflowProducts : 99; - return Container( - child: Text( - '+$displayedOverflowProducts', - style: Theme.of(context).primaryTextTheme.button, - ), - ); - } else { - return Container(); // build() can never return null. - } - } - - @override - Widget build(BuildContext context) { - return ScopedModelDescendant( - builder: (builder, child, model) => _buildOverflow(model, context), - ); - } -} - -class ProductThumbnail extends StatelessWidget { - final Animation animation; - final Animation opacityAnimation; - final Product product; - - ProductThumbnail(this.animation, this.opacityAnimation, this.product); - - @override - Widget build(BuildContext context) { - return FadeTransition( - opacity: opacityAnimation, - child: ScaleTransition( - scale: animation, - child: Container( - width: 40.0, - height: 40.0, - decoration: BoxDecoration( - image: DecorationImage( - image: ExactAssetImage( - product.assetName, // asset name - package: product.assetPackage, // asset package - ), - fit: BoxFit.cover, - ), - borderRadius: BorderRadius.all(Radius.circular(10.0)), - ), - margin: EdgeInsets.only(left: 16.0), - ), - ), - ); - } -} - -typedef RemovedItemBuilder = Widget Function( - int, BuildContext, Animation); - -// _ListModel manipulates an internal list and an AnimatedList -class _ListModel { - _ListModel( - {@required this.listKey, - @required this.removedItemBuilder, - Iterable initialItems}) - : assert(listKey != null), - assert(removedItemBuilder != null), - _items = List.from(initialItems ?? []); - - final GlobalKey listKey; - final RemovedItemBuilder removedItemBuilder; - final List _items; - - AnimatedListState get _animatedList => listKey.currentState; - - void add(int product) { - _insert(_items.length, product); - } - - void _insert(int index, int item) { - _items.insert(index, item); - _animatedList.insertItem(index, duration: Duration(milliseconds: 225)); - } - - void remove(int product) { - final int index = _items.indexOf(product); - if (index >= 0) { - _removeAt(index); - } - } - - void _removeAt(int index) { - final int removedItem = _items.removeAt(index); - if (removedItem != null) { - _animatedList.removeItem(index, (context, animation) { - return removedItemBuilder(removedItem, context, animation); - }); - } - } - - int get length => _items.length; - - int operator [](int index) => _items[index]; - - int indexOf(int item) => _items.indexOf(item); - - List get list => _items; -} diff --git a/material_studies/shrine/lib/home.dart b/material_studies/shrine/lib/home.dart deleted file mode 100644 index b73ca18ab..000000000 --- a/material_studies/shrine/lib/home.dart +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:scoped_model/scoped_model.dart'; - -import 'backdrop.dart'; -import 'expanding_bottom_sheet.dart'; -import 'model/app_state_model.dart'; -import 'model/product.dart'; -import 'supplemental/asymmetric_view.dart'; - -class ProductPage extends StatelessWidget { - final Category category; - - const ProductPage({this.category = Category.all}); - - @override - Widget build(BuildContext context) { - return ScopedModelDescendant( - builder: (context, child, model) { - return AsymmetricView( - products: model.getProducts(), - ); - }); - } -} - -class HomePage extends StatelessWidget { - final ExpandingBottomSheet expandingBottomSheet; - final Backdrop backdrop; - - const HomePage({Key key, this.expandingBottomSheet, this.backdrop}) - : super(key: key); - - @override - Widget build(BuildContext context) { - return Stack( - children: [ - backdrop, - Align(child: expandingBottomSheet, alignment: Alignment.bottomRight) - ], - ); - } -} diff --git a/material_studies/shrine/lib/login.dart b/material_studies/shrine/lib/login.dart deleted file mode 100644 index 5bab64042..000000000 --- a/material_studies/shrine/lib/login.dart +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; - -import 'colors.dart'; - -class LoginPage extends StatefulWidget { - @override - _LoginPageState createState() => _LoginPageState(); -} - -class _LoginPageState extends State { - final TextEditingController _usernameController = TextEditingController(); - final TextEditingController _passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: SafeArea( - child: ListView( - padding: const EdgeInsets.symmetric(horizontal: 24.0), - children: [ - const SizedBox(height: 80.0), - Column( - children: [ - Image.asset('assets/diamond.png'), - const SizedBox(height: 16.0), - Text( - 'SHRINE', - style: Theme.of(context).textTheme.headline, - ), - ], - ), - const SizedBox(height: 120.0), - PrimaryColorOverride( - color: kShrineBrown900, - child: TextField( - controller: _usernameController, - decoration: const InputDecoration( - labelText: 'Username', - ), - ), - ), - const SizedBox(height: 12.0), - PrimaryColorOverride( - color: kShrineBrown900, - child: TextField( - controller: _passwordController, - decoration: const InputDecoration( - labelText: 'Password', - ), - ), - ), - ButtonBar( - children: [ - FlatButton( - child: const Text('CANCEL'), - shape: const BeveledRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(7.0)), - ), - onPressed: () { - _usernameController.clear(); - _passwordController.clear(); - }, - ), - RaisedButton( - child: const Text('NEXT'), - elevation: 8.0, - shape: const BeveledRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(7.0)), - ), - onPressed: () { - Navigator.pop(context); - }, - ), - ], - ), - ], - ), - ), - ); - } -} - -class PrimaryColorOverride extends StatelessWidget { - const PrimaryColorOverride({Key key, this.color, this.child}) - : super(key: key); - - final Color color; - final Widget child; - - @override - Widget build(BuildContext context) { - return Theme( - child: child, - data: Theme.of(context).copyWith(primaryColor: color), - ); - } -} diff --git a/material_studies/shrine/lib/main.dart b/material_studies/shrine/lib/main.dart deleted file mode 100644 index 3cf5d0bdf..000000000 --- a/material_studies/shrine/lib/main.dart +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:scoped_model/scoped_model.dart'; - -import 'app.dart'; -import 'model/app_state_model.dart'; - -void main() { - SystemChrome.setPreferredOrientations( - [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]); - - AppStateModel model = AppStateModel(); - model.loadProducts(); - - runApp( - ScopedModel( - model: model, - child: ShrineApp(), - ), - ); -} diff --git a/material_studies/shrine/lib/model/app_state_model.dart b/material_studies/shrine/lib/model/app_state_model.dart deleted file mode 100644 index 7d86a044c..000000000 --- a/material_studies/shrine/lib/model/app_state_model.dart +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:scoped_model/scoped_model.dart'; - -import 'product.dart'; -import 'products_repository.dart'; - -double _salesTaxRate = 0.06; -double _shippingCostPerItem = 7.0; - -class AppStateModel extends Model { - // All the available products. - List _availableProducts; - - // The currently selected category of products. - Category _selectedCategory = Category.all; - - // The IDs and quantities of products currently in the cart. - Map _productsInCart = {}; - - Map get productsInCart => Map.from(_productsInCart); - - // Total number of items in the cart. - int get totalCartQuantity => _productsInCart.values.fold(0, (v, e) => v + e); - - Category get selectedCategory => _selectedCategory; - - // Totaled prices of the items in the cart. - double get subtotalCost => _productsInCart.keys - .map((id) => _availableProducts[id].price * _productsInCart[id]) - .fold(0.0, (sum, e) => sum + e); - - // Total shipping cost for the items in the cart. - double get shippingCost => - _shippingCostPerItem * - _productsInCart.values.fold(0.0, (sum, e) => sum + e); - - // Sales tax for the items in the cart - double get tax => subtotalCost * _salesTaxRate; - - // Total cost to order everything in the cart. - double get totalCost => subtotalCost + shippingCost + tax; - - // Returns a copy of the list of available products, filtered by category. - List getProducts() { - if (_availableProducts == null) return List(); - - if (_selectedCategory == Category.all) { - return List.from(_availableProducts); - } else { - return _availableProducts - .where((p) => p.category == _selectedCategory) - .toList(); - } - } - - // Adds a product to the cart. - void addProductToCart(int productId) { - if (!_productsInCart.containsKey(productId)) { - _productsInCart[productId] = 1; - } else { - _productsInCart[productId]++; - } - - notifyListeners(); - } - - // Removes an item from the cart. - void removeItemFromCart(int productId) { - if (_productsInCart.containsKey(productId)) { - if (_productsInCart[productId] == 1) { - _productsInCart.remove(productId); - } else { - _productsInCart[productId]--; - } - } - - notifyListeners(); - } - - // Returns the Product instance matching the provided id. - Product getProductById(int id) { - return _availableProducts.firstWhere((p) => p.id == id); - } - - // Removes everything from the cart. - void clearCart() { - _productsInCart.clear(); - notifyListeners(); - } - - // Loads the list of available products from the repo. - void loadProducts() { - _availableProducts = ProductsRepository.loadProducts(Category.all); - notifyListeners(); - } - - void setCategory(Category newCategory) { - _selectedCategory = newCategory; - notifyListeners(); - } -} diff --git a/material_studies/shrine/lib/model/product.dart b/material_studies/shrine/lib/model/product.dart deleted file mode 100644 index ffedcc321..000000000 --- a/material_studies/shrine/lib/model/product.dart +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/foundation.dart'; - -enum Category { - all, - accessories, - clothing, - home, -} - -class Product { - const Product({ - @required this.category, - @required this.id, - @required this.isFeatured, - @required this.name, - @required this.price, - }) : assert(category != null), - assert(id != null), - assert(isFeatured != null), - assert(name != null), - assert(price != null); - - final Category category; - final int id; - final bool isFeatured; - final String name; - final int price; - - String get assetName => '$id-0.jpg'; - String get assetPackage => 'shrine_images'; - - @override - String toString() => '$name (id=$id)'; -} diff --git a/material_studies/shrine/lib/model/products_repository.dart b/material_studies/shrine/lib/model/products_repository.dart deleted file mode 100644 index 9f4a1cd27..000000000 --- a/material_studies/shrine/lib/model/products_repository.dart +++ /dev/null @@ -1,293 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'product.dart'; - -class ProductsRepository { - static List loadProducts(Category category) { - const allProducts = [ - Product( - category: Category.accessories, - id: 0, - isFeatured: true, - name: 'Vagabond sack', - price: 120, - ), - Product( - category: Category.accessories, - id: 1, - isFeatured: true, - name: 'Stella sunglasses', - price: 58, - ), - Product( - category: Category.accessories, - id: 2, - isFeatured: false, - name: 'Whitney belt', - price: 35, - ), - Product( - category: Category.accessories, - id: 3, - isFeatured: true, - name: 'Garden strand', - price: 98, - ), - Product( - category: Category.accessories, - id: 4, - isFeatured: false, - name: 'Strut earrings', - price: 34, - ), - Product( - category: Category.accessories, - id: 5, - isFeatured: false, - name: 'Varsity socks', - price: 12, - ), - Product( - category: Category.accessories, - id: 6, - isFeatured: false, - name: 'Weave keyring', - price: 16, - ), - Product( - category: Category.accessories, - id: 7, - isFeatured: true, - name: 'Gatsby hat', - price: 40, - ), - Product( - category: Category.accessories, - id: 8, - isFeatured: true, - name: 'Shrug bag', - price: 198, - ), - Product( - category: Category.home, - id: 9, - isFeatured: true, - name: 'Gilt desk trio', - price: 58, - ), - Product( - category: Category.home, - id: 10, - isFeatured: false, - name: 'Copper wire rack', - price: 18, - ), - Product( - category: Category.home, - id: 11, - isFeatured: false, - name: 'Soothe ceramic set', - price: 28, - ), - Product( - category: Category.home, - id: 12, - isFeatured: false, - name: 'Hurrahs tea set', - price: 34, - ), - Product( - category: Category.home, - id: 13, - isFeatured: true, - name: 'Blue stone mug', - price: 18, - ), - Product( - category: Category.home, - id: 14, - isFeatured: true, - name: 'Rainwater tray', - price: 27, - ), - Product( - category: Category.home, - id: 15, - isFeatured: true, - name: 'Chambray napkins', - price: 16, - ), - Product( - category: Category.home, - id: 16, - isFeatured: true, - name: 'Succulent planters', - price: 16, - ), - Product( - category: Category.home, - id: 17, - isFeatured: false, - name: 'Quartet table', - price: 175, - ), - Product( - category: Category.home, - id: 18, - isFeatured: true, - name: 'Kitchen quattro', - price: 129, - ), - Product( - category: Category.clothing, - id: 19, - isFeatured: false, - name: 'Clay sweater', - price: 48, - ), - Product( - category: Category.clothing, - id: 20, - isFeatured: false, - name: 'Sea tunic', - price: 45, - ), - Product( - category: Category.clothing, - id: 21, - isFeatured: false, - name: 'Plaster tunic', - price: 38, - ), - Product( - category: Category.clothing, - id: 22, - isFeatured: false, - name: 'White pinstripe shirt', - price: 70, - ), - Product( - category: Category.clothing, - id: 23, - isFeatured: false, - name: 'Chambray shirt', - price: 70, - ), - Product( - category: Category.clothing, - id: 24, - isFeatured: true, - name: 'Seabreeze sweater', - price: 60, - ), - Product( - category: Category.clothing, - id: 25, - isFeatured: false, - name: 'Gentry jacket', - price: 178, - ), - Product( - category: Category.clothing, - id: 26, - isFeatured: false, - name: 'Navy trousers', - price: 74, - ), - Product( - category: Category.clothing, - id: 27, - isFeatured: true, - name: 'Walter henley (white)', - price: 38, - ), - Product( - category: Category.clothing, - id: 28, - isFeatured: true, - name: 'Surf and perf shirt', - price: 48, - ), - Product( - category: Category.clothing, - id: 29, - isFeatured: true, - name: 'Ginger scarf', - price: 98, - ), - Product( - category: Category.clothing, - id: 30, - isFeatured: true, - name: 'Ramona crossover', - price: 68, - ), - Product( - category: Category.clothing, - id: 31, - isFeatured: false, - name: 'Chambray shirt', - price: 38, - ), - Product( - category: Category.clothing, - id: 32, - isFeatured: false, - name: 'Classic white collar', - price: 58, - ), - Product( - category: Category.clothing, - id: 33, - isFeatured: true, - name: 'Cerise scallop tee', - price: 42, - ), - Product( - category: Category.clothing, - id: 34, - isFeatured: false, - name: 'Shoulder rolls tee', - price: 27, - ), - Product( - category: Category.clothing, - id: 35, - isFeatured: false, - name: 'Grey slouch tank', - price: 24, - ), - Product( - category: Category.clothing, - id: 36, - isFeatured: false, - name: 'Sunshirt dress', - price: 58, - ), - Product( - category: Category.clothing, - id: 37, - isFeatured: true, - name: 'Fine lines tee', - price: 58, - ), - ]; - if (category == Category.all) { - return allProducts; - } else { - return allProducts.where((p) => p.category == category).toList(); - } - } -} diff --git a/material_studies/shrine/lib/shopping_cart.dart b/material_studies/shrine/lib/shopping_cart.dart deleted file mode 100644 index 1f7b3fd32..000000000 --- a/material_studies/shrine/lib/shopping_cart.dart +++ /dev/null @@ -1,272 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; -import 'package:scoped_model/scoped_model.dart'; - -import 'colors.dart'; -import 'expanding_bottom_sheet.dart'; -import 'model/app_state_model.dart'; -import 'model/product.dart'; - -const _leftColumnWidth = 60.0; - -class ShoppingCartPage extends StatefulWidget { - @override - _ShoppingCartPageState createState() => _ShoppingCartPageState(); -} - -class _ShoppingCartPageState extends State { - List _createShoppingCartRows(AppStateModel model) { - return model.productsInCart.keys - .map( - (id) => ShoppingCartRow( - product: model.getProductById(id), - quantity: model.productsInCart[id], - onPressed: () { - model.removeItemFromCart(id); - }, - ), - ) - .toList(); - } - - @override - Widget build(BuildContext context) { - final localTheme = Theme.of(context); - - return Scaffold( - backgroundColor: kShrinePink50, - body: SafeArea( - child: Container( - child: ScopedModelDescendant( - builder: (context, child, model) { - return Stack( - children: [ - ListView( - children: [ - Row( - children: [ - SizedBox( - width: _leftColumnWidth, - child: IconButton( - icon: const Icon(Icons.keyboard_arrow_down), - onPressed: () => - ExpandingBottomSheet.of(context).close()), - ), - Text( - 'CART', - style: localTheme.textTheme.subhead - .copyWith(fontWeight: FontWeight.w600), - ), - const SizedBox(width: 16.0), - Text('${model.totalCartQuantity} ITEMS'), - ], - ), - const SizedBox(height: 16.0), - Column( - children: _createShoppingCartRows(model), - ), - ShoppingCartSummary(model: model), - const SizedBox(height: 100.0), - ], - ), - Positioned( - bottom: 16.0, - left: 16.0, - right: 16.0, - child: RaisedButton( - shape: const BeveledRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(7.0)), - ), - color: kShrinePink100, - splashColor: kShrineBrown600, - child: const Padding( - padding: EdgeInsets.symmetric(vertical: 12.0), - child: Text('CLEAR CART'), - ), - onPressed: () { - model.clearCart(); - ExpandingBottomSheet.of(context).close(); - }, - ), - ), - ], - ); - }, - ), - ), - ), - ); - } -} - -class ShoppingCartSummary extends StatelessWidget { - ShoppingCartSummary({this.model}); - - final AppStateModel model; - - @override - Widget build(BuildContext context) { - final smallAmountStyle = - Theme.of(context).textTheme.body1.copyWith(color: kShrineBrown600); - final largeAmountStyle = Theme.of(context).textTheme.display1; - final formatter = NumberFormat.simpleCurrency( - decimalDigits: 2, locale: Localizations.localeOf(context).toString()); - - return Row( - children: [ - SizedBox(width: _leftColumnWidth), - Expanded( - child: Padding( - padding: const EdgeInsets.only(right: 16.0), - child: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Expanded( - child: Text('TOTAL'), - ), - Text( - formatter.format(model.totalCost), - style: largeAmountStyle, - ), - ], - ), - const SizedBox(height: 16.0), - Row( - children: [ - const Expanded( - child: Text('Subtotal:'), - ), - Text( - formatter.format(model.subtotalCost), - style: smallAmountStyle, - ), - ], - ), - const SizedBox(height: 4.0), - Row( - children: [ - const Expanded( - child: Text('Shipping:'), - ), - Text( - formatter.format(model.shippingCost), - style: smallAmountStyle, - ), - ], - ), - const SizedBox(height: 4.0), - Row( - children: [ - const Expanded( - child: Text('Tax:'), - ), - Text( - formatter.format(model.tax), - style: smallAmountStyle, - ), - ], - ), - ], - ), - ), - ), - ], - ); - } -} - -class ShoppingCartRow extends StatelessWidget { - ShoppingCartRow( - {@required this.product, @required this.quantity, this.onPressed}); - - final Product product; - final int quantity; - final VoidCallback onPressed; - - @override - Widget build(BuildContext context) { - final formatter = NumberFormat.simpleCurrency( - decimalDigits: 0, locale: Localizations.localeOf(context).toString()); - final localTheme = Theme.of(context); - - return Padding( - padding: const EdgeInsets.only(bottom: 16.0), - child: Row( - key: ValueKey(product.id), - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - width: _leftColumnWidth, - child: IconButton( - icon: const Icon(Icons.remove_circle_outline), - onPressed: onPressed, - ), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.only(right: 16.0), - child: Column( - children: [ - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Image.asset( - product.assetName, - package: product.assetPackage, - fit: BoxFit.cover, - width: 75.0, - height: 75.0, - ), - const SizedBox(width: 16.0), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Expanded( - child: Text('Quantity: $quantity'), - ), - Text('x ${formatter.format(product.price)}'), - ], - ), - Text( - product.name, - style: localTheme.textTheme.subhead - .copyWith(fontWeight: FontWeight.w600), - ), - ], - ), - ), - ], - ), - const SizedBox(height: 16.0), - const Divider( - color: kShrineBrown900, - height: 10.0, - ), - ], - ), - ), - ), - ], - ), - ); - } -} diff --git a/material_studies/shrine/lib/supplemental/asymmetric_view.dart b/material_studies/shrine/lib/supplemental/asymmetric_view.dart deleted file mode 100644 index abb46b9f0..000000000 --- a/material_studies/shrine/lib/supplemental/asymmetric_view.dart +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; - -import '../model/product.dart'; -import 'product_columns.dart'; - -class AsymmetricView extends StatelessWidget { - final List products; - - const AsymmetricView({Key key, this.products}); - - List _buildColumns(BuildContext context) { - if (products == null || products.isEmpty) { - return const []; - } - - /// This will return a list of columns. It will oscillate between the two - /// kinds of columns. Even cases of the index (0, 2, 4, etc) will be - /// TwoProductCardColumn and the odd cases will be OneProductCardColumn. - /// - /// Each pair of columns will advance us 3 products forward (2 + 1). That's - /// some kinda awkward math so we use _evenCasesIndex and _oddCasesIndex as - /// helpers for creating the index of the product list that will correspond - /// to the index of the list of columns. - return List.generate(_listItemCount(products.length), (index) { - double width = .59 * MediaQuery.of(context).size.width; - Widget column; - if (index % 2 == 0) { - /// Even cases - int bottom = _evenCasesIndex(index); - column = TwoProductCardColumn( - bottom: products[bottom], - top: products.length - 1 >= bottom + 1 - ? products[bottom + 1] - : null); - width += 32.0; - } else { - /// Odd cases - column = OneProductCardColumn( - product: products[_oddCasesIndex(index)], - ); - } - return Container( - width: width, - child: Padding( - padding: EdgeInsets.symmetric(horizontal: 16.0), - child: column, - ), - ); - }).toList(); - } - - int _evenCasesIndex(int input) { - /// The operator ~/ is a cool one. It's the truncating division operator. It - /// divides the number and if there's a remainder / decimal, it cuts it off. - /// This is like dividing and then casting the result to int. Also, it's - /// functionally equivalent to floor() in this case. - return input ~/ 2 * 3; - } - - int _oddCasesIndex(int input) { - assert(input > 0); - return (input / 2).ceil() * 3 - 1; - } - - int _listItemCount(int totalItems) { - if (totalItems % 3 == 0) { - return totalItems ~/ 3 * 2; - } else { - return (totalItems / 3).ceil() * 2 - 1; - } - } - - @override - Widget build(BuildContext context) { - return ListView( - scrollDirection: Axis.horizontal, - padding: EdgeInsets.fromLTRB(0.0, 34.0, 16.0, 44.0), - children: _buildColumns(context), - physics: AlwaysScrollableScrollPhysics(), - ); - } -} diff --git a/material_studies/shrine/lib/supplemental/cut_corners_border.dart b/material_studies/shrine/lib/supplemental/cut_corners_border.dart deleted file mode 100644 index af7ab94e1..000000000 --- a/material_studies/shrine/lib/supplemental/cut_corners_border.dart +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'dart:ui' show lerpDouble; - -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; - -class CutCornersBorder extends OutlineInputBorder { - const CutCornersBorder({ - BorderSide borderSide = const BorderSide(), - BorderRadius borderRadius = const BorderRadius.all(Radius.circular(2.0)), - this.cut = 7.0, - double gapPadding = 2.0, - }) : super( - borderSide: borderSide, - borderRadius: borderRadius, - gapPadding: gapPadding); - - @override - CutCornersBorder copyWith({ - BorderSide borderSide, - BorderRadius borderRadius, - double gapPadding, - double cut, - }) { - return CutCornersBorder( - borderRadius: borderRadius ?? this.borderRadius, - borderSide: borderSide ?? this.borderSide, - cut: cut ?? this.cut, - gapPadding: gapPadding ?? this.gapPadding, - ); - } - - final double cut; - - @override - ShapeBorder lerpFrom(ShapeBorder a, double t) { - if (a is CutCornersBorder) { - final CutCornersBorder outline = a; - return CutCornersBorder( - borderRadius: BorderRadius.lerp(outline.borderRadius, borderRadius, t), - borderSide: BorderSide.lerp(outline.borderSide, borderSide, t), - cut: cut, - gapPadding: outline.gapPadding, - ); - } - return super.lerpFrom(a, t); - } - - @override - ShapeBorder lerpTo(ShapeBorder b, double t) { - if (b is CutCornersBorder) { - final CutCornersBorder outline = b; - return CutCornersBorder( - borderRadius: BorderRadius.lerp(borderRadius, outline.borderRadius, t), - borderSide: BorderSide.lerp(borderSide, outline.borderSide, t), - cut: cut, - gapPadding: outline.gapPadding, - ); - } - return super.lerpTo(b, t); - } - - Path _notchedCornerPath(Rect center, - [double start = 0.0, double extent = 0.0]) { - final Path path = Path(); - if (start > 0.0 || extent > 0.0) { - path.relativeMoveTo(extent + start, center.top); - _notchedSidesAndBottom(center, path); - path..lineTo(center.left + cut, center.top)..lineTo(start, center.top); - } else { - path.moveTo(center.left + cut, center.top); - _notchedSidesAndBottom(center, path); - path.lineTo(center.left + cut, center.top); - } - return path; - } - - Path _notchedSidesAndBottom(Rect center, Path path) { - return path - ..lineTo(center.right - cut, center.top) - ..lineTo(center.right, center.top + cut) - ..lineTo(center.right, center.top + center.height - cut) - ..lineTo(center.right - cut, center.top + center.height) - ..lineTo(center.left + cut, center.top + center.height) - ..lineTo(center.left, center.top + center.height - cut) - ..lineTo(center.left, center.top + cut); - } - - @override - void paint( - Canvas canvas, - Rect rect, { - double gapStart, - double gapExtent = 0.0, - double gapPercentage = 0.0, - TextDirection textDirection, - }) { - assert(gapExtent != null); - assert(gapPercentage >= 0.0 && gapPercentage <= 1.0); - - final Paint paint = borderSide.toPaint(); - final RRect outer = borderRadius.toRRect(rect); - if (gapStart == null || gapExtent <= 0.0 || gapPercentage == 0.0) { - canvas.drawPath(_notchedCornerPath(outer.middleRect), paint); - } else { - final double extent = - lerpDouble(0.0, gapExtent + gapPadding * 2.0, gapPercentage); - switch (textDirection) { - case TextDirection.rtl: - { - final Path path = _notchedCornerPath( - outer.middleRect, gapStart + gapPadding - extent, extent); - canvas.drawPath(path, paint); - break; - } - case TextDirection.ltr: - { - final Path path = _notchedCornerPath( - outer.middleRect, gapStart - gapPadding, extent); - canvas.drawPath(path, paint); - break; - } - } - } - } -} diff --git a/material_studies/shrine/lib/supplemental/product_card.dart b/material_studies/shrine/lib/supplemental/product_card.dart deleted file mode 100644 index 9eeb63223..000000000 --- a/material_studies/shrine/lib/supplemental/product_card.dart +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; -import 'package:scoped_model/scoped_model.dart'; - -import '../model/app_state_model.dart'; -import '../model/product.dart'; - -class ProductCard extends StatelessWidget { - ProductCard({this.imageAspectRatio = 33 / 49, this.product}) - : assert(imageAspectRatio == null || imageAspectRatio > 0); - - final double imageAspectRatio; - final Product product; - - static final kTextBoxHeight = 65.0; - - @override - Widget build(BuildContext context) { - final NumberFormat formatter = NumberFormat.simpleCurrency( - decimalDigits: 0, locale: Localizations.localeOf(context).toString()); - final ThemeData theme = Theme.of(context); - - final imageWidget = Image.asset( - product.assetName, - package: product.assetPackage, - fit: BoxFit.cover, - ); - - return ScopedModelDescendant( - builder: (context, child, model) => GestureDetector( - onTap: () { - model.addProductToCart(product.id); - // TODO: Add Snackbar - }, - child: child, - ), - child: Stack( - children: [ - Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - AspectRatio( - aspectRatio: imageAspectRatio, - child: imageWidget, - ), - SizedBox( - height: kTextBoxHeight * MediaQuery.of(context).textScaleFactor, - width: 121.0, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text( - product == null ? '' : product.name, - style: theme.textTheme.button, - softWrap: false, - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), - SizedBox(height: 4.0), - Text( - product == null ? '' : formatter.format(product.price), - style: theme.textTheme.caption, - ), - ], - ), - ), - ], - ), - Padding( - padding: const EdgeInsets.all(16.0), - child: Icon(Icons.add_shopping_cart), - ), - ], - ), - ); - } -} diff --git a/material_studies/shrine/lib/supplemental/product_columns.dart b/material_studies/shrine/lib/supplemental/product_columns.dart deleted file mode 100644 index 12c9a064b..000000000 --- a/material_studies/shrine/lib/supplemental/product_columns.dart +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2018-present the Flutter authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import 'package:flutter/material.dart'; - -import '../model/product.dart'; -import 'product_card.dart'; - -class TwoProductCardColumn extends StatelessWidget { - TwoProductCardColumn({ - this.bottom, - this.top, - }) : assert(bottom != null); - - final Product bottom, top; - - @override - Widget build(BuildContext context) { - return LayoutBuilder( - builder: (context, constraints) { - const spacerHeight = 44.0; - - double heightOfCards = - (constraints.biggest.height - spacerHeight) / 2.0; - double heightOfImages = heightOfCards - ProductCard.kTextBoxHeight; - double imageAspectRatio = (heightOfImages >= 0.0 && - constraints.biggest.width > heightOfImages) - ? constraints.biggest.width / heightOfImages - : 33 / 49; - - return ListView( - children: [ - Padding( - padding: EdgeInsetsDirectional.only(start: 28.0), - child: top != null - ? ProductCard( - imageAspectRatio: imageAspectRatio, - product: top, - ) - : SizedBox( - height: heightOfCards > 0 ? heightOfCards : spacerHeight, - ), - ), - SizedBox(height: spacerHeight), - Padding( - padding: EdgeInsetsDirectional.only(end: 28.0), - child: ProductCard( - imageAspectRatio: imageAspectRatio, - product: bottom, - ), - ), - ], - ); - }, - ); - } -} - -class OneProductCardColumn extends StatelessWidget { - OneProductCardColumn({this.product}); - - final Product product; - - @override - Widget build(BuildContext context) { - return ListView( - reverse: true, - children: [ - SizedBox( - height: 40.0, - ), - ProductCard( - product: product, - ), - ], - ); - } -} diff --git a/material_studies/shrine/pubspec.lock b/material_studies/shrine/pubspec.lock deleted file mode 100644 index eb2fd674c..000000000 --- a/material_studies/shrine/pubspec.lock +++ /dev/null @@ -1,216 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - archive: - dependency: transitive - description: - name: archive - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.2" - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.11" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - image: - dependency: transitive - description: - name: image - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - intl: - dependency: "direct main" - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.15.8" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.4" - pedantic: - dependency: "direct dev" - description: - name: pedantic - 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" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - scoped_model: - dependency: "direct main" - description: - name: scoped_model - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.0" - shrine_images: - dependency: "direct main" - description: - name: shrine_images - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.5" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.11" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" - xml: - dependency: transitive - description: - name: xml - url: "https://pub.dartlang.org" - source: hosted - version: "3.5.0" -sdks: - dart: ">=2.5.0 <3.0.0" diff --git a/material_studies/shrine/pubspec.yaml b/material_studies/shrine/pubspec.yaml deleted file mode 100644 index f1af36e49..000000000 --- a/material_studies/shrine/pubspec.yaml +++ /dev/null @@ -1,68 +0,0 @@ -name: Shrine -description: Take your design up a notch and learn to use our advanced component backdrop menu. -environment: - sdk: ">=2.5.0 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - cupertino_icons: ^0.1.2 - intl: ^0.15.7 - scoped_model: ^0.3.0 - shrine_images: ^1.0.0 - -dev_dependencies: - flutter_test: - sdk: flutter - pedantic: ^1.8.0 - -flutter: - uses-material-design: true - assets: - - assets/diamond.png - - assets/slanted_menu.png - - packages/shrine_images/0-0.jpg - - packages/shrine_images/1-0.jpg - - packages/shrine_images/2-0.jpg - - packages/shrine_images/3-0.jpg - - packages/shrine_images/4-0.jpg - - packages/shrine_images/5-0.jpg - - packages/shrine_images/6-0.jpg - - packages/shrine_images/7-0.jpg - - packages/shrine_images/8-0.jpg - - packages/shrine_images/9-0.jpg - - packages/shrine_images/10-0.jpg - - packages/shrine_images/11-0.jpg - - packages/shrine_images/12-0.jpg - - packages/shrine_images/13-0.jpg - - packages/shrine_images/14-0.jpg - - packages/shrine_images/15-0.jpg - - packages/shrine_images/16-0.jpg - - packages/shrine_images/17-0.jpg - - packages/shrine_images/18-0.jpg - - packages/shrine_images/19-0.jpg - - packages/shrine_images/20-0.jpg - - packages/shrine_images/21-0.jpg - - packages/shrine_images/22-0.jpg - - packages/shrine_images/23-0.jpg - - packages/shrine_images/24-0.jpg - - packages/shrine_images/25-0.jpg - - packages/shrine_images/26-0.jpg - - packages/shrine_images/27-0.jpg - - packages/shrine_images/28-0.jpg - - packages/shrine_images/29-0.jpg - - packages/shrine_images/30-0.jpg - - packages/shrine_images/31-0.jpg - - packages/shrine_images/32-0.jpg - - packages/shrine_images/33-0.jpg - - packages/shrine_images/34-0.jpg - - packages/shrine_images/35-0.jpg - - packages/shrine_images/36-0.jpg - - packages/shrine_images/37-0.jpg - fonts: - - family: Rubik - fonts: - - asset: fonts/Rubik-Regular.ttf - - asset: fonts/Rubik-Medium.ttf - weight: 500 diff --git a/material_studies/shrine/test/main_test.dart b/material_studies/shrine/test/main_test.dart deleted file mode 100644 index b0af11c4d..000000000 --- a/material_studies/shrine/test/main_test.dart +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2018 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:Shrine/app.dart'; -import 'package:Shrine/model/app_state_model.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:scoped_model/scoped_model.dart'; - -void main() { - testWidgets("smoke test", (tester) async { - AppStateModel model = AppStateModel(); - model.loadProducts(); - - await tester.pumpWidget(ScopedModel( - model: model, - child: ShrineApp(), - )); - - // Click through from the login screen. - await tester.tap(find.text("NEXT")); - await tester.pump(); - - // Ensure we populate the catalog page. - expect(find.text("Stella sunglasses"), findsOneWidget); - expect(find.text(r"$58"), findsOneWidget); - - // Buy a product. - await tester.tap(find.text("Stella sunglasses")); - await tester.pump(); - - // Go to the shopping cart. - await tester.tap(find.byIcon(Icons.shopping_cart)); - await tester.pumpAndSettle(); - - // Ensure that it appears, and that it computes total with tax and shipping. - expect(find.text("Subtotal:"), findsOneWidget); - expect(find.text(r"$68.48"), findsOneWidget); - }); -} diff --git a/travis_script.sh b/travis_script.sh index 6307e554c..67f5e2a38 100755 --- a/travis_script.sh +++ b/travis_script.sh @@ -24,8 +24,6 @@ declare -a PROJECT_NAMES=( "platform_view_swift" \ "provider_counter" \ "provider_shopper" \ - "material_studies/rally" \ - "material_studies/shrine" \ "veggieseasons" \ )