Delete the filipino_cuisine web sample (#923)
* Delete the `filipino_cuisine` web sample * Drop `filipino_cuisine` from sample index
46
web/filipino_cuisine/.gitignore
vendored
@@ -1,46 +0,0 @@
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
**/ios/Flutter/.last_build_id
|
||||
.dart_tool/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
.packages
|
||||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
|
||||
# Web related
|
||||
lib/generated_plugin_registrant.dart
|
||||
|
||||
# Symbolication related
|
||||
app.*.symbols
|
||||
|
||||
# Obfuscation related
|
||||
app.*.map.json
|
||||
|
||||
# Android Studio will place build artifacts here
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
@@ -1,10 +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: ffb2ecea5223acdd139a5039be2f9c796962833d
|
||||
channel: stable
|
||||
|
||||
project_type: app
|
||||
@@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2019 John Mark Grancapal
|
||||
|
||||
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.
|
||||
@@ -1,31 +0,0 @@
|
||||
A sample that shows a visual recipe catalog for Filipino food.
|
||||
|
||||
Contributed as part of the Flutter Create 5K challenge by John Mark Grancapal.
|
||||
Original source at
|
||||
[github.com/markgrancapal/filipino_cuisine](https://github.com/markgrancapal/filipino_cuisine).
|
||||
|
||||
|
||||
**Asset License**: All images used on this app are under the "CC0 - Creative Commons" license
|
||||
|
||||
|
||||
## Developed By
|
||||
|
||||
John Mark Grancapal <mark.grancapal@gmail.com>
|
||||
Homepage: https://github.com/markgrancapal
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Copyright 2019 John Mark Grancapal
|
||||
|
||||
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.
|
||||
@@ -1,19 +0,0 @@
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
analyzer:
|
||||
strong-mode:
|
||||
implicit-casts: false
|
||||
implicit-dynamic: false
|
||||
|
||||
linter:
|
||||
rules:
|
||||
avoid_types_on_closure_parameters: true
|
||||
avoid_void_async: true
|
||||
cancel_subscriptions: true
|
||||
close_sinks: true
|
||||
directives_ordering: true
|
||||
package_api_docs: true
|
||||
package_prefixed_library_names: true
|
||||
test_types_in_equals: true
|
||||
throw_in_finally: true
|
||||
unnecessary_statements: true
|
||||
|
Before Width: | Height: | Size: 202 KiB |
|
Before Width: | Height: | Size: 385 KiB |
|
Before Width: | Height: | Size: 302 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 164 KiB |
|
Before Width: | Height: | Size: 493 KiB |
|
Before Width: | Height: | Size: 455 KiB |
|
Before Width: | Height: | Size: 203 KiB |
|
Before Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 320 KiB |
|
Before Width: | Height: | Size: 290 KiB |
|
Before Width: | Height: | Size: 442 KiB |
|
Before Width: | Height: | Size: 389 KiB |
|
Before Width: | Height: | Size: 384 KiB |
|
Before Width: | Height: | Size: 226 KiB |
|
Before Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 305 KiB |
|
Before Width: | Height: | Size: 224 KiB |
|
Before Width: | Height: | Size: 433 KiB |
|
Before Width: | Height: | Size: 541 KiB |
|
Before Width: | Height: | Size: 648 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 352 KiB |
|
Before Width: | Height: | Size: 175 KiB |
|
Before Width: | Height: | Size: 267 KiB |
|
Before Width: | Height: | Size: 390 KiB |
|
Before Width: | Height: | Size: 310 KiB |
|
Before Width: | Height: | Size: 424 KiB |
|
Before Width: | Height: | Size: 634 KiB |
|
Before Width: | Height: | Size: 281 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 387 KiB |
|
Before Width: | Height: | Size: 280 KiB |
|
Before Width: | Height: | Size: 400 KiB |
|
Before Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 357 KiB |
|
Before Width: | Height: | Size: 747 KiB |
|
Before Width: | Height: | Size: 514 KiB |
|
Before Width: | Height: | Size: 364 KiB |
|
Before Width: | Height: | Size: 348 KiB |
@@ -1,65 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Cook extends StatefulWidget {
|
||||
final List<String> dr;
|
||||
final String? img;
|
||||
final String? nme;
|
||||
|
||||
const Cook(this.dr, this.img, this.nme, {Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
CState createState() => CState();
|
||||
}
|
||||
|
||||
class CState extends State<Cook> {
|
||||
late List<bool?> cb;
|
||||
|
||||
@override
|
||||
initState() {
|
||||
super.initState();
|
||||
cb = [];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(context) {
|
||||
List<String> dr = widget.dr;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
backgroundColor: Colors.red,
|
||||
title: const Text("INSTRUCTIONS"),
|
||||
centerTitle: true),
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
Container(
|
||||
child: ListTile(
|
||||
leading: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
child: Hero(
|
||||
tag: widget.nme!,
|
||||
child: Image.asset(widget.img!,
|
||||
fit: BoxFit.cover, width: 100, height: 100))),
|
||||
title: Text(widget.nme!,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.headline3!
|
||||
.copyWith(fontFamily: 'ark', color: Colors.black))),
|
||||
margin: const EdgeInsets.only(top: 40, bottom: 30, left: 20)),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: dr.length,
|
||||
padding: const EdgeInsets.all(10),
|
||||
itemBuilder: (ct, i) {
|
||||
cb.add(false);
|
||||
return ListTile(
|
||||
title: Text(dr[i]),
|
||||
trailing: Checkbox(
|
||||
value: cb[i],
|
||||
onChanged: (v) => setState(() => cb[i] = v)));
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,344 +0,0 @@
|
||||
// Package flutter_page_indicator:
|
||||
// https://pub.dartlang.org/packages/flutter_page_indicator
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class WarmPainter extends BasePainter {
|
||||
WarmPainter(PageIndicator widget, double page, int index, Paint paint)
|
||||
: super(widget, page, index, paint);
|
||||
|
||||
@override
|
||||
void draw(Canvas canvas, double space, double size, double radius) {
|
||||
double progress = page - index;
|
||||
double distance = size + space;
|
||||
double start = index * (size + space);
|
||||
|
||||
if (progress > 0.5) {
|
||||
double right = start + size + distance;
|
||||
//progress=>0.5-1.0
|
||||
//left:0.0=>distance
|
||||
|
||||
double left = index * distance + distance * (progress - 0.5) * 2;
|
||||
canvas.drawRRect(
|
||||
RRect.fromLTRBR(left, 0.0, right, size, Radius.circular(radius)),
|
||||
_paint);
|
||||
} else {
|
||||
double right = start + size + distance * progress * 2;
|
||||
|
||||
canvas.drawRRect(
|
||||
RRect.fromLTRBR(start, 0.0, right, size, Radius.circular(radius)),
|
||||
_paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DropPainter extends BasePainter {
|
||||
DropPainter(PageIndicator widget, double page, int index, Paint paint)
|
||||
: super(widget, page, index, paint);
|
||||
|
||||
@override
|
||||
void draw(Canvas canvas, double space, double size, double radius) {
|
||||
double progress = page - index;
|
||||
double dropHeight = widget.dropHeight;
|
||||
double rate = (0.5 - progress).abs() * 2;
|
||||
double scale = widget.scale;
|
||||
|
||||
//lerp(begin, end, progress)
|
||||
|
||||
canvas.drawCircle(
|
||||
Offset(radius + ((page) * (size + space)),
|
||||
radius - dropHeight * (1 - rate)),
|
||||
radius * (scale + rate * (1.0 - scale)),
|
||||
_paint);
|
||||
}
|
||||
}
|
||||
|
||||
class NonePainter extends BasePainter {
|
||||
NonePainter(PageIndicator widget, double page, int index, Paint paint)
|
||||
: super(widget, page, index, paint);
|
||||
|
||||
@override
|
||||
void draw(Canvas canvas, double space, double size, double radius) {
|
||||
double progress = page - index;
|
||||
double secondOffset = index == widget.count - 1
|
||||
? radius
|
||||
: radius + ((index + 1) * (size + space));
|
||||
|
||||
if (progress > 0.5) {
|
||||
canvas.drawCircle(Offset(secondOffset, radius), radius, _paint);
|
||||
} else {
|
||||
canvas.drawCircle(
|
||||
Offset(radius + (index * (size + space)), radius), radius, _paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SlidePainter extends BasePainter {
|
||||
SlidePainter(PageIndicator widget, double page, int index, Paint paint)
|
||||
: super(widget, page, index, paint);
|
||||
|
||||
@override
|
||||
void draw(Canvas canvas, double space, double size, double radius) {
|
||||
canvas.drawCircle(
|
||||
Offset(radius + (page * (size + space)), radius), radius, _paint);
|
||||
}
|
||||
}
|
||||
|
||||
class ScalePainter extends BasePainter {
|
||||
ScalePainter(PageIndicator widget, double page, int index, Paint paint)
|
||||
: super(widget, page, index, paint);
|
||||
|
||||
// 连续的两个点,含有最后一个和第一个
|
||||
@override
|
||||
bool _shouldSkip(int index) {
|
||||
if (super.index == widget.count - 1) {
|
||||
return index == 0 || index == super.index;
|
||||
}
|
||||
return (index == super.index || index == super.index + 1);
|
||||
}
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
_paint.color = widget.color;
|
||||
double space = widget.space;
|
||||
double size = widget.size;
|
||||
double radius = size / 2;
|
||||
for (int i = 0, c = widget.count; i < c; ++i) {
|
||||
if (_shouldSkip(i)) {
|
||||
continue;
|
||||
}
|
||||
canvas.drawCircle(Offset(i * (size + space) + radius, radius),
|
||||
radius * widget.scale, _paint);
|
||||
}
|
||||
|
||||
_paint.color = widget.activeColor;
|
||||
draw(canvas, space, size, radius);
|
||||
}
|
||||
|
||||
@override
|
||||
void draw(Canvas canvas, double space, double size, double radius) {
|
||||
double secondOffset = index == widget.count - 1
|
||||
? radius
|
||||
: radius + ((index + 1) * (size + space));
|
||||
|
||||
double progress = page - index;
|
||||
_paint.color = Color.lerp(widget.activeColor, widget.color, progress)!;
|
||||
//last
|
||||
canvas.drawCircle(Offset(radius + (index * (size + space)), radius),
|
||||
lerp(radius, radius * widget.scale, progress), _paint);
|
||||
//first
|
||||
_paint.color = Color.lerp(widget.color, widget.activeColor, progress)!;
|
||||
canvas.drawCircle(Offset(secondOffset, radius),
|
||||
lerp(radius * widget.scale, radius, progress), _paint);
|
||||
}
|
||||
}
|
||||
|
||||
class ColorPainter extends BasePainter {
|
||||
ColorPainter(PageIndicator widget, double page, int index, Paint paint)
|
||||
: super(widget, page, index, paint);
|
||||
|
||||
// 连续的两个点,含有最后一个和第一个
|
||||
@override
|
||||
bool _shouldSkip(int index) {
|
||||
if (super.index == widget.count - 1) {
|
||||
return index == 0 || index == super.index;
|
||||
}
|
||||
return (index == super.index || index == super.index + 1);
|
||||
}
|
||||
|
||||
@override
|
||||
void draw(Canvas canvas, double space, double size, double radius) {
|
||||
double progress = page - index;
|
||||
double secondOffset = index == widget.count - 1
|
||||
? radius
|
||||
: radius + ((index + 1) * (size + space));
|
||||
|
||||
_paint.color = Color.lerp(widget.activeColor, widget.color, progress)!;
|
||||
//left
|
||||
canvas.drawCircle(
|
||||
Offset(radius + (index * (size + space)), radius), radius, _paint);
|
||||
//right
|
||||
_paint.color = Color.lerp(widget.color, widget.activeColor, progress)!;
|
||||
canvas.drawCircle(Offset(secondOffset, radius), radius, _paint);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class BasePainter extends CustomPainter {
|
||||
final PageIndicator widget;
|
||||
final double page;
|
||||
final int index;
|
||||
final Paint _paint;
|
||||
|
||||
double lerp(double begin, double end, double progress) {
|
||||
return begin + (end - begin) * progress;
|
||||
}
|
||||
|
||||
BasePainter(this.widget, this.page, this.index, this._paint);
|
||||
|
||||
void draw(Canvas canvas, double space, double size, double radius);
|
||||
|
||||
bool _shouldSkip(int index) {
|
||||
return false;
|
||||
}
|
||||
//double secondOffset = index == widget.count-1 ? radius : radius + ((index + 1) * (size + space));
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
_paint.color = widget.color;
|
||||
double space = widget.space;
|
||||
double size = widget.size;
|
||||
double radius = size / 2;
|
||||
for (int i = 0, c = widget.count; i < c; ++i) {
|
||||
if (_shouldSkip(i)) {
|
||||
continue;
|
||||
}
|
||||
canvas.drawCircle(
|
||||
Offset(i * (size + space) + radius, radius), radius, _paint);
|
||||
}
|
||||
|
||||
double page = this.page;
|
||||
if (page < index) {
|
||||
page = 0.0;
|
||||
}
|
||||
_paint.color = widget.activeColor;
|
||||
draw(canvas, space, size, radius);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(BasePainter oldDelegate) {
|
||||
return oldDelegate.page != page;
|
||||
}
|
||||
}
|
||||
|
||||
class _PageIndicatorState extends State<PageIndicator> {
|
||||
int index = 0;
|
||||
final Paint _paint = Paint();
|
||||
|
||||
BasePainter _createPainer() {
|
||||
switch (widget.layout) {
|
||||
case PageIndicatorLayout.NONE:
|
||||
return NonePainter(
|
||||
widget, widget.controller.page ?? 0.0, index, _paint);
|
||||
case PageIndicatorLayout.SLIDE:
|
||||
return SlidePainter(
|
||||
widget, widget.controller.page ?? 0.0, index, _paint);
|
||||
case PageIndicatorLayout.WARM:
|
||||
return WarmPainter(
|
||||
widget, widget.controller.page ?? 0.0, index, _paint);
|
||||
case PageIndicatorLayout.COLOR:
|
||||
return ColorPainter(
|
||||
widget, widget.controller.page ?? 0.0, index, _paint);
|
||||
case PageIndicatorLayout.SCALE:
|
||||
return ScalePainter(
|
||||
widget, widget.controller.page ?? 0.0, index, _paint);
|
||||
case PageIndicatorLayout.DROP:
|
||||
return DropPainter(
|
||||
widget, widget.controller.page ?? 0.0, index, _paint);
|
||||
default:
|
||||
throw Exception("Not a valid layout");
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget child = SizedBox(
|
||||
width: widget.count * widget.size + (widget.count - 1) * widget.space,
|
||||
height: widget.size,
|
||||
child: CustomPaint(
|
||||
painter: _createPainer(),
|
||||
),
|
||||
);
|
||||
|
||||
if (widget.layout == PageIndicatorLayout.SCALE ||
|
||||
widget.layout == PageIndicatorLayout.COLOR) {
|
||||
child = ClipRect(
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
return IgnorePointer(
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
|
||||
void _onController() {
|
||||
double page = widget.controller.page ?? 0.0;
|
||||
index = page.floor();
|
||||
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
widget.controller.addListener(_onController);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(PageIndicator oldWidget) {
|
||||
if (widget.controller != oldWidget.controller) {
|
||||
oldWidget.controller.removeListener(_onController);
|
||||
widget.controller.addListener(_onController);
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
widget.controller.removeListener(_onController);
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: constant_identifier_names
|
||||
enum PageIndicatorLayout { NONE, SLIDE, WARM, COLOR, SCALE, DROP }
|
||||
|
||||
class PageIndicator extends StatefulWidget {
|
||||
/// size of the dots
|
||||
final double size;
|
||||
|
||||
/// space between dots.
|
||||
final double space;
|
||||
|
||||
/// count of dots
|
||||
final int count;
|
||||
|
||||
/// active color
|
||||
final Color activeColor;
|
||||
|
||||
/// normal color
|
||||
final Color color;
|
||||
|
||||
/// layout of the dots,default is [PageIndicatorLayout.SLIDE]
|
||||
final PageIndicatorLayout? layout;
|
||||
|
||||
// Only valid when layout==PageIndicatorLayout.scale
|
||||
final double scale;
|
||||
|
||||
// Only valid when layout==PageIndicatorLayout.drop
|
||||
final double dropHeight;
|
||||
|
||||
final PageController controller;
|
||||
|
||||
final double activeSize;
|
||||
|
||||
const PageIndicator(
|
||||
{Key? key,
|
||||
this.size = 20.0,
|
||||
this.space = 5.0,
|
||||
required this.count,
|
||||
this.activeSize = 20.0,
|
||||
required this.controller,
|
||||
this.color = Colors.white30,
|
||||
this.layout = PageIndicatorLayout.SLIDE,
|
||||
this.activeColor = Colors.white,
|
||||
this.scale = 0.6,
|
||||
this.dropHeight = 20.0})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _PageIndicatorState();
|
||||
}
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import 'cook.dart';
|
||||
import 'flutter_swiper.dart';
|
||||
|
||||
void main() => runApp(const MyApp());
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
const MyApp({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(context) {
|
||||
final _themeData = ThemeData(
|
||||
brightness: Brightness.light,
|
||||
iconTheme: const IconThemeData(color: Colors.red),
|
||||
);
|
||||
return MaterialApp(
|
||||
theme: _themeData.copyWith(
|
||||
colorScheme: _themeData.colorScheme.copyWith(
|
||||
secondary: Colors.red,
|
||||
),
|
||||
),
|
||||
title: "Filipino Cuisine",
|
||||
home: const Home());
|
||||
}
|
||||
}
|
||||
|
||||
class Home extends StatefulWidget {
|
||||
const Home({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
HState createState() => HState();
|
||||
}
|
||||
|
||||
class HState extends State<Home> {
|
||||
Map<String, dynamic>? fd;
|
||||
Map<String, dynamic>? fi;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
getData();
|
||||
}
|
||||
|
||||
Future<void> getData() async {
|
||||
http.Response r = await http.get(Uri.parse(
|
||||
'https://flutter.github.io/samples/web/filipino_cuisine/data.json'));
|
||||
fd = json.decode(r.body) as Map<String, dynamic>?;
|
||||
setState(() => fi = fd!['0'] as Map<String, dynamic>?);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(context) {
|
||||
if (fd == null) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
var t = Theme.of(context).textTheme;
|
||||
return Scaffold(
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
flex: 5,
|
||||
child: Swiper(
|
||||
onIndexChanged: (n) =>
|
||||
setState(() => fi = fd!['$n'] as Map<String, dynamic>?),
|
||||
itemCount:
|
||||
fd!.keys.where((key) => int.tryParse(key) != null).length,
|
||||
itemBuilder: (cx, i) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(top: 40, bottom: 24),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
child: Hero(
|
||||
tag: fd!['$i']['fn'] as Object,
|
||||
child: Image.asset(fd!['$i']['pf'] as String,
|
||||
fit: BoxFit.cover)),
|
||||
));
|
||||
},
|
||||
viewportFraction: .85,
|
||||
scale: .9)),
|
||||
Text(fi!['fn'] as String,
|
||||
style: t.headline2!
|
||||
.copyWith(fontFamily: 'ark', color: Colors.black)),
|
||||
Container(
|
||||
child: Text(fi!['cn'] as String,
|
||||
style:
|
||||
t.subtitle1!.apply(color: Colors.red, fontFamily: 'opb')),
|
||||
margin: const EdgeInsets.only(top: 10, bottom: 30),
|
||||
),
|
||||
Container(
|
||||
child: Text(fi!['dc'] as String,
|
||||
textAlign: TextAlign.center,
|
||||
style: t.subtitle1!.copyWith(fontFamily: 'opr')),
|
||||
margin: const EdgeInsets.only(left: 10, right: 10)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: ListView.builder(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: fi!['ig'].length as int?,
|
||||
itemBuilder: (cx, i) {
|
||||
return Row(children: <Widget>[
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 10),
|
||||
height: 60,
|
||||
child: Image.asset(fi!['ig'][i]['p'] as String,
|
||||
fit: BoxFit.contain)),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 5, right: 10),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(fi!['ig'][i]['n'] as String,
|
||||
style: t.subtitle2!
|
||||
.copyWith(fontFamily: 'opb')),
|
||||
Text(fi!['ig'][i]['c'] as String,
|
||||
style:
|
||||
t.caption!.copyWith(fontFamily: 'opr'))
|
||||
]))
|
||||
]);
|
||||
}))
|
||||
],
|
||||
),
|
||||
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
|
||||
floatingActionButton: FloatingActionButton(
|
||||
child: const Icon(Icons.restaurant_menu),
|
||||
onPressed: () => Navigator.push<void>(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (cx) => Cook(
|
||||
(fi!['in'] as List).cast(),
|
||||
fi!['pf'] as String?,
|
||||
fi!['fn'] as String?,
|
||||
))),
|
||||
),
|
||||
bottomNavigationBar: BottomAppBar(
|
||||
shape: const CircularNotchedRectangle(),
|
||||
notchMargin: 4.0,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
IconButton(
|
||||
icon: Icon(fi!['fv'] as bool
|
||||
? Icons.favorite
|
||||
: Icons.favorite_border),
|
||||
onPressed: () =>
|
||||
setState(() => fi!['fv'] = !(fi!['fv'] as bool))),
|
||||
IconButton(icon: const Icon(Icons.share), onPressed: () {})
|
||||
])),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,805 +0,0 @@
|
||||
// Package transformer_page_view:
|
||||
// https://pub.dartlang.org/packages/transformer_page_view
|
||||
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class IndexController extends ChangeNotifier {
|
||||
// ignore: constant_identifier_names
|
||||
static const int NEXT = 1;
|
||||
// ignore: constant_identifier_names
|
||||
static const int PREVIOUS = -1;
|
||||
// ignore: constant_identifier_names
|
||||
static const int MOVE = 0;
|
||||
|
||||
late Completer<void> _completer;
|
||||
|
||||
int? index;
|
||||
bool? animation;
|
||||
int? event;
|
||||
|
||||
Future move(int index, {bool? animation = true}) {
|
||||
this.animation = animation ?? true;
|
||||
this.index = index;
|
||||
event = MOVE;
|
||||
_completer = Completer();
|
||||
notifyListeners();
|
||||
return _completer.future;
|
||||
}
|
||||
|
||||
Future next({bool? animation = true}) {
|
||||
event = NEXT;
|
||||
this.animation = animation ?? true;
|
||||
_completer = Completer();
|
||||
notifyListeners();
|
||||
return _completer.future;
|
||||
}
|
||||
|
||||
Future previous({bool? animation = true}) {
|
||||
event = PREVIOUS;
|
||||
this.animation = animation ?? true;
|
||||
_completer = Completer();
|
||||
notifyListeners();
|
||||
return _completer.future;
|
||||
}
|
||||
|
||||
void complete() {
|
||||
if (!_completer.isCompleted) {
|
||||
_completer.complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef PaintCallback = void Function(Canvas canvas, Size siz);
|
||||
|
||||
class ColorPainter extends CustomPainter {
|
||||
final Paint _paint;
|
||||
final TransformInfo info;
|
||||
final List<Color> colors;
|
||||
|
||||
ColorPainter(this._paint, this.info, this.colors);
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
int index = info.fromIndex!;
|
||||
_paint.color = colors[index];
|
||||
canvas.drawRect(Rect.fromLTWH(0.0, 0.0, size.width, size.height), _paint);
|
||||
if (info.done!) {
|
||||
return;
|
||||
}
|
||||
int alpha;
|
||||
int color;
|
||||
double opacity;
|
||||
double? position = info.position;
|
||||
if (info.forward!) {
|
||||
if (index < colors.length - 1) {
|
||||
color = colors[index + 1].value & 0x00ffffff;
|
||||
opacity = (position! <= 0
|
||||
? (-position / info.viewportFraction!)
|
||||
: 1 - position / info.viewportFraction!);
|
||||
if (opacity > 1) {
|
||||
opacity -= 1.0;
|
||||
}
|
||||
if (opacity < 0) {
|
||||
opacity += 1.0;
|
||||
}
|
||||
alpha = (0xff * opacity).toInt();
|
||||
|
||||
_paint.color = Color((alpha << 24) | color);
|
||||
canvas.drawRect(
|
||||
Rect.fromLTWH(0.0, 0.0, size.width, size.height), _paint);
|
||||
}
|
||||
} else {
|
||||
if (index > 0) {
|
||||
color = colors[index - 1].value & 0x00ffffff;
|
||||
opacity = (position! > 0
|
||||
? position / info.viewportFraction!
|
||||
: (1 + position / info.viewportFraction!));
|
||||
if (opacity > 1) {
|
||||
opacity -= 1.0;
|
||||
}
|
||||
if (opacity < 0) {
|
||||
opacity += 1.0;
|
||||
}
|
||||
alpha = (0xff * opacity).toInt();
|
||||
|
||||
_paint.color = Color((alpha << 24) | color);
|
||||
canvas.drawRect(
|
||||
Rect.fromLTWH(0.0, 0.0, size.width, size.height), _paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(ColorPainter oldDelegate) {
|
||||
return oldDelegate.info != info;
|
||||
}
|
||||
}
|
||||
|
||||
class _ParallaxColorState extends State<ParallaxColor> {
|
||||
Paint paint = Paint();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return CustomPaint(
|
||||
painter: ColorPainter(paint, widget.info, widget.colors),
|
||||
child: widget.child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ParallaxColor extends StatefulWidget {
|
||||
final Widget child;
|
||||
|
||||
final List<Color> colors;
|
||||
|
||||
final TransformInfo info;
|
||||
|
||||
const ParallaxColor({
|
||||
required this.colors,
|
||||
required this.info,
|
||||
required this.child,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _ParallaxColorState();
|
||||
}
|
||||
}
|
||||
|
||||
class ParallaxContainer extends StatelessWidget {
|
||||
final Widget child;
|
||||
final double position;
|
||||
final double translationFactor;
|
||||
final double opacityFactor;
|
||||
|
||||
const ParallaxContainer(
|
||||
{required this.child,
|
||||
required this.position,
|
||||
this.translationFactor = 100.0,
|
||||
this.opacityFactor = 1.0,
|
||||
Key? key})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Opacity(
|
||||
opacity: (1 - position.abs()).clamp(0.0, 1.0) * opacityFactor,
|
||||
child: Transform.translate(
|
||||
offset: Offset(position * translationFactor, 0.0),
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ParallaxImage extends StatelessWidget {
|
||||
final Image image;
|
||||
final double imageFactor;
|
||||
|
||||
ParallaxImage.asset(String name,
|
||||
{required double position, this.imageFactor = 0.3, Key? key})
|
||||
: image = Image.asset(name,
|
||||
fit: BoxFit.cover,
|
||||
alignment: FractionalOffset(
|
||||
0.5 + position * imageFactor,
|
||||
0.5,
|
||||
)),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// NOTICE::
|
||||
///
|
||||
/// In order to make package smaller,currently we're not supporting any build-in page transformers
|
||||
/// You can find build in transforms here:
|
||||
///
|
||||
///
|
||||
///
|
||||
|
||||
const int kMaxValue = 2000000000;
|
||||
const int kMiddleValue = 1000000000;
|
||||
|
||||
/// Default auto play transition duration (in millisecond)
|
||||
const int kDefaultTransactionDuration = 300;
|
||||
|
||||
class TransformInfo {
|
||||
/// The `width` of the `TransformerPageView`
|
||||
final double? width;
|
||||
|
||||
/// The `height` of the `TransformerPageView`
|
||||
final double? height;
|
||||
|
||||
/// The `position` of the widget pass to [PageTransformer.transform]
|
||||
/// A `position` describes how visible the widget is.
|
||||
/// The widget in the center of the screen' which is full visible, position is 0.0.
|
||||
/// The widge in the left ,may be hidden, of the screen's position is less than 0.0, -1.0 when out of the screen.
|
||||
/// The widge in the right ,may be hidden, of the screen's position is greater than 0.0, 1.0 when out of the screen
|
||||
///
|
||||
///
|
||||
final double? position;
|
||||
|
||||
/// The `index` of the widget pass to [PageTransformer.transform]
|
||||
final int? index;
|
||||
|
||||
/// The `activeIndex` of the PageView
|
||||
final int? activeIndex;
|
||||
|
||||
/// The `activeIndex` of the PageView, from user start to swipe
|
||||
/// It will change when user end drag
|
||||
final int? fromIndex;
|
||||
|
||||
/// Next `index` is greater than this `index`
|
||||
final bool? forward;
|
||||
|
||||
/// User drag is done.
|
||||
final bool? done;
|
||||
|
||||
/// Same as [TransformerPageView.viewportFraction]
|
||||
final double? viewportFraction;
|
||||
|
||||
/// Copy from [TransformerPageView.scrollDirection]
|
||||
final Axis? scrollDirection;
|
||||
|
||||
TransformInfo(
|
||||
{this.index,
|
||||
this.position,
|
||||
this.width,
|
||||
this.height,
|
||||
this.activeIndex,
|
||||
this.fromIndex,
|
||||
this.forward,
|
||||
this.done,
|
||||
this.viewportFraction,
|
||||
this.scrollDirection});
|
||||
}
|
||||
|
||||
abstract class PageTransformer {
|
||||
///
|
||||
final bool reverse;
|
||||
|
||||
PageTransformer({this.reverse = false});
|
||||
|
||||
/// Return a transformed widget, based on child and TransformInfo
|
||||
Widget transform(Widget child, TransformInfo info);
|
||||
}
|
||||
|
||||
typedef PageTransformerBuilderCallback = Widget Function(
|
||||
Widget child, TransformInfo info);
|
||||
|
||||
class PageTransformerBuilder extends PageTransformer {
|
||||
final PageTransformerBuilderCallback builder;
|
||||
|
||||
PageTransformerBuilder({bool reverse = false, required this.builder})
|
||||
: super(reverse: reverse);
|
||||
|
||||
@override
|
||||
Widget transform(Widget child, TransformInfo info) {
|
||||
return builder(child, info);
|
||||
}
|
||||
}
|
||||
|
||||
class TransformerPageController extends PageController {
|
||||
final bool loop;
|
||||
final int? itemCount;
|
||||
final bool reverse;
|
||||
|
||||
TransformerPageController({
|
||||
int? initialPage = 0,
|
||||
bool keepPage = true,
|
||||
double viewportFraction = 1.0,
|
||||
this.loop = false,
|
||||
this.itemCount,
|
||||
this.reverse = false,
|
||||
}) : super(
|
||||
initialPage: TransformerPageController._getRealIndexFromRenderIndex(
|
||||
initialPage ?? 0, loop, itemCount, reverse)!,
|
||||
keepPage: keepPage,
|
||||
viewportFraction: viewportFraction);
|
||||
|
||||
int getRenderIndexFromRealIndex(int? index) {
|
||||
return _getRenderIndexFromRealIndex(index, loop, itemCount, reverse);
|
||||
}
|
||||
|
||||
int? getRealItemCount() {
|
||||
if (itemCount == 0) return 0;
|
||||
return loop ? itemCount! + kMaxValue : itemCount;
|
||||
}
|
||||
|
||||
static int _getRenderIndexFromRealIndex(
|
||||
int? index, bool loop, int? itemCount, bool reverse) {
|
||||
if (itemCount == 0) return 0;
|
||||
int? renderIndex;
|
||||
if (loop) {
|
||||
renderIndex = index! - kMiddleValue;
|
||||
renderIndex = renderIndex % itemCount!;
|
||||
if (renderIndex < 0) {
|
||||
renderIndex += itemCount;
|
||||
}
|
||||
} else {
|
||||
renderIndex = index;
|
||||
}
|
||||
if (reverse) {
|
||||
renderIndex = itemCount! - renderIndex! - 1;
|
||||
}
|
||||
|
||||
return renderIndex!;
|
||||
}
|
||||
|
||||
double? get realPage {
|
||||
double? page;
|
||||
|
||||
page = super.page;
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
static double _getRenderPageFromRealPage(
|
||||
double? page, bool loop, int? itemCount, bool reverse) {
|
||||
double? renderPage;
|
||||
if (loop) {
|
||||
renderPage = page! - kMiddleValue;
|
||||
renderPage = renderPage % itemCount!;
|
||||
if (renderPage < 0) {
|
||||
renderPage += itemCount;
|
||||
}
|
||||
} else {
|
||||
renderPage = page;
|
||||
}
|
||||
if (reverse) {
|
||||
renderPage = itemCount! - renderPage! - 1;
|
||||
}
|
||||
|
||||
return renderPage!;
|
||||
}
|
||||
|
||||
@override
|
||||
double? get page {
|
||||
return loop
|
||||
? _getRenderPageFromRealPage(realPage, loop, itemCount, reverse)
|
||||
: realPage;
|
||||
}
|
||||
|
||||
int? getRealIndexFromRenderIndex(int? index) {
|
||||
return _getRealIndexFromRenderIndex(index, loop, itemCount, reverse);
|
||||
}
|
||||
|
||||
static int? _getRealIndexFromRenderIndex(
|
||||
int? index, bool loop, int? itemCount, bool reverse) {
|
||||
int? result = reverse ? (itemCount! - index! - 1) : index;
|
||||
if (loop) {
|
||||
result = result! + kMiddleValue;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class TransformerPageView extends StatefulWidget {
|
||||
/// Create a `transformed` widget base on the widget that has been passed to the [PageTransformer.transform].
|
||||
/// See [TransformInfo]
|
||||
///
|
||||
final PageTransformer? transformer;
|
||||
|
||||
/// Same as [PageView.scrollDirection]
|
||||
///
|
||||
/// Defaults to [Axis.horizontal].
|
||||
final Axis scrollDirection;
|
||||
|
||||
/// Same as [PageView.physics]
|
||||
final ScrollPhysics? physics;
|
||||
|
||||
/// Set to false to disable page snapping, useful for custom scroll behavior.
|
||||
/// Same as [PageView.pageSnapping]
|
||||
final bool pageSnapping;
|
||||
|
||||
/// Called whenever the page in the center of the viewport changes.
|
||||
/// Same as [PageView.onPageChanged]
|
||||
final ValueChanged<int>? onPageChanged;
|
||||
|
||||
final IndexedWidgetBuilder? itemBuilder;
|
||||
|
||||
// See [IndexController.mode],[IndexController.next],[IndexController.previous]
|
||||
final IndexController? controller;
|
||||
|
||||
/// Animation duration
|
||||
final Duration duration;
|
||||
|
||||
/// Animation curve
|
||||
final Curve? curve;
|
||||
|
||||
final TransformerPageController? pageController;
|
||||
|
||||
/// Set true to open infinity loop mode.
|
||||
final bool loop;
|
||||
|
||||
/// This value is only valid when `pageController` is not set,
|
||||
final int itemCount;
|
||||
|
||||
/// This value is only valid when `pageController` is not set,
|
||||
final double viewportFraction;
|
||||
|
||||
/// If not set, it is controlled by this widget.
|
||||
final int? index;
|
||||
|
||||
/// Creates a scrollable list that works page by page using widgets that are
|
||||
/// created on demand.
|
||||
///
|
||||
/// This constructor is appropriate for page views with a large (or infinite)
|
||||
/// number of children because the builder is called only for those children
|
||||
/// that are actually visible.
|
||||
///
|
||||
/// Providing a non-null [itemCount] lets the [PageView] compute the maximum
|
||||
/// scroll extent.
|
||||
///
|
||||
/// [itemBuilder] will be called only with indices greater than or equal to
|
||||
/// zero and less than [itemCount].
|
||||
const TransformerPageView({
|
||||
Key? key,
|
||||
this.index,
|
||||
Duration? duration,
|
||||
this.curve = Curves.ease,
|
||||
this.viewportFraction = 1.0,
|
||||
this.loop = false,
|
||||
this.scrollDirection = Axis.horizontal,
|
||||
this.physics,
|
||||
this.pageSnapping = true,
|
||||
this.onPageChanged,
|
||||
this.controller,
|
||||
this.transformer,
|
||||
this.itemBuilder,
|
||||
this.pageController,
|
||||
required this.itemCount,
|
||||
}) : assert(itemCount == 0 || itemBuilder != null || transformer != null),
|
||||
duration = duration ??
|
||||
const Duration(milliseconds: kDefaultTransactionDuration),
|
||||
super(key: key);
|
||||
|
||||
factory TransformerPageView.children(
|
||||
{Key? key,
|
||||
int? index,
|
||||
Duration? duration,
|
||||
Curve curve = Curves.ease,
|
||||
double viewportFraction = 1.0,
|
||||
bool loop = false,
|
||||
Axis scrollDirection = Axis.horizontal,
|
||||
ScrollPhysics? physics,
|
||||
bool pageSnapping = true,
|
||||
ValueChanged<int>? onPageChanged,
|
||||
IndexController? controller,
|
||||
PageTransformer? transformer,
|
||||
required List<Widget> children,
|
||||
TransformerPageController? pageController}) {
|
||||
return TransformerPageView(
|
||||
itemCount: children.length,
|
||||
itemBuilder: (context, index) {
|
||||
return children[index];
|
||||
},
|
||||
pageController: pageController,
|
||||
transformer: transformer,
|
||||
pageSnapping: pageSnapping,
|
||||
key: key,
|
||||
index: index,
|
||||
duration: duration,
|
||||
curve: curve,
|
||||
viewportFraction: viewportFraction,
|
||||
scrollDirection: scrollDirection,
|
||||
physics: physics,
|
||||
onPageChanged: onPageChanged,
|
||||
controller: controller,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _TransformerPageViewState();
|
||||
}
|
||||
|
||||
static int? getRealIndexFromRenderIndex(
|
||||
{required bool reverse, int? index, int? itemCount, required bool loop}) {
|
||||
int? initPage = reverse ? (itemCount! - index! - 1) : index;
|
||||
if (loop) {
|
||||
initPage = initPage! + kMiddleValue;
|
||||
}
|
||||
return initPage;
|
||||
}
|
||||
|
||||
static PageController createPageController(
|
||||
{required bool reverse,
|
||||
int? index,
|
||||
int? itemCount,
|
||||
required bool loop,
|
||||
required double viewportFraction}) {
|
||||
return PageController(
|
||||
initialPage: getRealIndexFromRenderIndex(
|
||||
reverse: reverse, index: index, itemCount: itemCount, loop: loop)!,
|
||||
viewportFraction: viewportFraction);
|
||||
}
|
||||
}
|
||||
|
||||
class _TransformerPageViewState extends State<TransformerPageView> {
|
||||
Size? _size;
|
||||
int? _activeIndex;
|
||||
double? _currentPixels;
|
||||
bool _done = false;
|
||||
|
||||
///This value will not change until user end drag.
|
||||
int? _fromIndex;
|
||||
|
||||
PageTransformer? _transformer;
|
||||
|
||||
TransformerPageController? _pageController;
|
||||
|
||||
Widget _buildItemNormal(BuildContext context, int index) {
|
||||
int renderIndex = _pageController!.getRenderIndexFromRealIndex(index);
|
||||
Widget child = widget.itemBuilder!(context, renderIndex);
|
||||
return child;
|
||||
}
|
||||
|
||||
Widget _buildItem(BuildContext context, int index) {
|
||||
return AnimatedBuilder(
|
||||
animation: _pageController!,
|
||||
builder: (c, w) {
|
||||
int renderIndex = _pageController!.getRenderIndexFromRealIndex(index);
|
||||
Widget? child;
|
||||
if (widget.itemBuilder != null) {
|
||||
child = widget.itemBuilder!(context, renderIndex);
|
||||
}
|
||||
child ??= Container();
|
||||
if (_size == null) {
|
||||
return child;
|
||||
}
|
||||
|
||||
double position;
|
||||
|
||||
double? page = _pageController!.realPage;
|
||||
|
||||
if (_transformer!.reverse) {
|
||||
position = page! - index;
|
||||
} else {
|
||||
position = index - page!;
|
||||
}
|
||||
position *= widget.viewportFraction;
|
||||
|
||||
TransformInfo info = TransformInfo(
|
||||
index: renderIndex,
|
||||
width: _size!.width,
|
||||
height: _size!.height,
|
||||
position: position.clamp(-1.0, 1.0),
|
||||
activeIndex:
|
||||
_pageController!.getRenderIndexFromRealIndex(_activeIndex),
|
||||
fromIndex: _fromIndex,
|
||||
forward: _pageController!.position.pixels - _currentPixels! >= 0,
|
||||
done: _done,
|
||||
scrollDirection: widget.scrollDirection,
|
||||
viewportFraction: widget.viewportFraction);
|
||||
return _transformer!.transform(child, info);
|
||||
});
|
||||
}
|
||||
|
||||
double? _calcCurrentPixels() {
|
||||
_currentPixels =
|
||||
_pageController!.getRenderIndexFromRealIndex(_activeIndex) *
|
||||
_pageController!.position.viewportDimension *
|
||||
widget.viewportFraction;
|
||||
|
||||
// print("activeIndex:$_activeIndex , pix:$_currentPixels");
|
||||
|
||||
return _currentPixels;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
IndexedWidgetBuilder builder =
|
||||
_transformer == null ? _buildItemNormal : _buildItem;
|
||||
Widget child = PageView.builder(
|
||||
itemBuilder: builder,
|
||||
itemCount: _pageController!.getRealItemCount(),
|
||||
onPageChanged: _onIndexChanged,
|
||||
controller: _pageController,
|
||||
scrollDirection: widget.scrollDirection,
|
||||
physics: widget.physics,
|
||||
pageSnapping: widget.pageSnapping,
|
||||
reverse: _pageController!.reverse,
|
||||
);
|
||||
if (_transformer == null) {
|
||||
return child;
|
||||
}
|
||||
return NotificationListener(
|
||||
// ignore: avoid_types_on_closure_parameters
|
||||
onNotification: (ScrollNotification notification) {
|
||||
if (notification is ScrollStartNotification) {
|
||||
_calcCurrentPixels();
|
||||
_done = false;
|
||||
_fromIndex = _activeIndex;
|
||||
} else if (notification is ScrollEndNotification) {
|
||||
_calcCurrentPixels();
|
||||
_fromIndex = _activeIndex;
|
||||
_done = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
child: child);
|
||||
}
|
||||
|
||||
void _onIndexChanged(int index) {
|
||||
_activeIndex = index;
|
||||
if (widget.onPageChanged != null) {
|
||||
widget
|
||||
.onPageChanged!(_pageController!.getRenderIndexFromRealIndex(index));
|
||||
}
|
||||
}
|
||||
|
||||
void _onGetSize(dynamic _) {
|
||||
Size? size;
|
||||
RenderObject? renderObject = context.findRenderObject();
|
||||
if (renderObject != null) {
|
||||
Rect bounds = renderObject.paintBounds;
|
||||
size = bounds.size;
|
||||
}
|
||||
_calcCurrentPixels();
|
||||
onGetSize(size);
|
||||
}
|
||||
|
||||
void onGetSize(Size? size) {
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_size = size;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_transformer = widget.transformer;
|
||||
// int index = widget.index ?? 0;
|
||||
_pageController = widget.pageController;
|
||||
_pageController ??= TransformerPageController(
|
||||
initialPage: widget.index,
|
||||
itemCount: widget.itemCount,
|
||||
loop: widget.loop,
|
||||
reverse:
|
||||
widget.transformer == null ? false : widget.transformer!.reverse);
|
||||
// int initPage = _getRealIndexFromRenderIndex(index);
|
||||
// _pageController = new PageController(initialPage: initPage,viewportFraction: widget.viewportFraction);
|
||||
_fromIndex = _activeIndex = _pageController!.initialPage;
|
||||
|
||||
_controller = getNotifier();
|
||||
if (_controller != null) {
|
||||
_controller!.addListener(onChangeNotifier);
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(TransformerPageView oldWidget) {
|
||||
_transformer = widget.transformer;
|
||||
int index = widget.index ?? 0;
|
||||
bool created = false;
|
||||
if (_pageController != widget.pageController) {
|
||||
if (widget.pageController != null) {
|
||||
_pageController = widget.pageController;
|
||||
} else {
|
||||
created = true;
|
||||
_pageController = TransformerPageController(
|
||||
initialPage: widget.index,
|
||||
itemCount: widget.itemCount,
|
||||
loop: widget.loop,
|
||||
reverse: widget.transformer == null
|
||||
? false
|
||||
: widget.transformer!.reverse);
|
||||
}
|
||||
}
|
||||
|
||||
if (_pageController!.getRenderIndexFromRealIndex(_activeIndex) != index) {
|
||||
_fromIndex = _activeIndex = _pageController!.initialPage;
|
||||
if (!created) {
|
||||
int initPage = _pageController!.getRealIndexFromRenderIndex(index)!;
|
||||
_pageController!.animateToPage(initPage,
|
||||
duration: widget.duration, curve: widget.curve!);
|
||||
}
|
||||
}
|
||||
if (_transformer != null) {
|
||||
WidgetsBinding.instance!.addPostFrameCallback(_onGetSize);
|
||||
}
|
||||
|
||||
if (_controller != getNotifier()) {
|
||||
if (_controller != null) {
|
||||
_controller!.removeListener(onChangeNotifier);
|
||||
}
|
||||
_controller = getNotifier();
|
||||
if (_controller != null) {
|
||||
_controller!.addListener(onChangeNotifier);
|
||||
}
|
||||
}
|
||||
super.didUpdateWidget(oldWidget);
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
if (_transformer != null) {
|
||||
WidgetsBinding.instance!.addPostFrameCallback(_onGetSize);
|
||||
}
|
||||
super.didChangeDependencies();
|
||||
}
|
||||
|
||||
ChangeNotifier? getNotifier() {
|
||||
return widget.controller;
|
||||
}
|
||||
|
||||
int _calcNextIndex(bool next) {
|
||||
int? currentIndex = _activeIndex;
|
||||
if (_pageController!.reverse) {
|
||||
if (next) {
|
||||
currentIndex = currentIndex! - 1;
|
||||
} else {
|
||||
currentIndex = currentIndex! + 1;
|
||||
}
|
||||
} else {
|
||||
if (next) {
|
||||
currentIndex = currentIndex! + 1;
|
||||
} else {
|
||||
currentIndex = currentIndex! - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_pageController!.loop) {
|
||||
if (currentIndex >= _pageController!.itemCount!) {
|
||||
currentIndex = 0;
|
||||
} else if (currentIndex < 0) {
|
||||
currentIndex = _pageController!.itemCount! - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
void onChangeNotifier() {
|
||||
int? event = widget.controller!.event;
|
||||
int? index;
|
||||
switch (event) {
|
||||
case IndexController.MOVE:
|
||||
{
|
||||
index = _pageController!
|
||||
.getRealIndexFromRenderIndex(widget.controller!.index);
|
||||
}
|
||||
break;
|
||||
case IndexController.PREVIOUS:
|
||||
case IndexController.NEXT:
|
||||
{
|
||||
index = _calcNextIndex(event == IndexController.NEXT);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//ignore this event
|
||||
return;
|
||||
}
|
||||
if (widget.controller!.animation!) {
|
||||
_pageController!
|
||||
.animateToPage(index!,
|
||||
duration: widget.duration, curve: widget.curve ?? Curves.ease)
|
||||
.whenComplete(widget.controller!.complete);
|
||||
} else {
|
||||
_pageController!.jumpToPage(index!);
|
||||
widget.controller!.complete();
|
||||
}
|
||||
}
|
||||
|
||||
ChangeNotifier? _controller;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
if (_controller != null) {
|
||||
_controller!.removeListener(onChangeNotifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.8.2"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
flutter_page_indicator:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_page_indicator
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.3"
|
||||
flutter_swiper:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_swiper
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.6"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.13.4"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
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.8.1"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
transformer_page_view:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: transformer_page_view
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.6"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
sdks:
|
||||
dart: ">=2.14.0 <3.0.0"
|
||||
flutter: ">=0.1.4"
|
||||
@@ -1,66 +0,0 @@
|
||||
name: filipino_cuisine
|
||||
|
||||
environment:
|
||||
sdk: '>=2.12.0 <3.0.0'
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
flutter_swiper: ^1.1.6
|
||||
http: ^0.13.4
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^1.0.0
|
||||
|
||||
flutter_icons:
|
||||
android: "launcher_icon"
|
||||
ios: true
|
||||
image_path: "assets/icon/fc_icon.png"
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
assets:
|
||||
- calamares.jpg
|
||||
- beef_caldereta.jpg
|
||||
- pochero.jpg
|
||||
- pork_sisig.jpg
|
||||
- embutido.jpg
|
||||
- black_pepper.png
|
||||
- butter.png
|
||||
- chili.png
|
||||
- egg.png
|
||||
- flour.png
|
||||
- garlic.png
|
||||
- lemon.png
|
||||
- oil.png
|
||||
- onion.png
|
||||
- pork.png
|
||||
- salt.png
|
||||
- squid.png
|
||||
- tomato.png
|
||||
- banana.png
|
||||
- cabbage.png
|
||||
- bokchoy.png
|
||||
- green_beans.png
|
||||
- potato.png
|
||||
- red_pepper.png
|
||||
- yellow_onion.png
|
||||
- red_bell.png
|
||||
- green_bell.png
|
||||
- carrot.png
|
||||
- beef.png
|
||||
- cheese.png
|
||||
- raisins.png
|
||||
- ground_pork.png
|
||||
- sausage.png
|
||||
- preview.png
|
||||
fonts:
|
||||
- family: opr
|
||||
fonts:
|
||||
- asset: fonts/OpenSans-Regular.ttf
|
||||
- family: opb
|
||||
fonts:
|
||||
- asset: fonts/OpenSans-Bold.ttf
|
||||
- family: ark
|
||||
fonts:
|
||||
- asset: fonts/Arkipelago.otf
|
||||
@@ -1,366 +0,0 @@
|
||||
{
|
||||
"0":{
|
||||
"cn":"120 Gr 85 Kcal 13 Min",
|
||||
"ct":"3 minutes",
|
||||
"dc":"Calamares is the Filipino version of the Mediterranean breaded fried squid dish, Calamari. ",
|
||||
"fn":"Calamares",
|
||||
"fv":false,
|
||||
"ig":[
|
||||
{
|
||||
"c":"1/2 lb",
|
||||
"n":"Squid",
|
||||
"p":"squid.png"
|
||||
},
|
||||
{
|
||||
"c":"3/4 cup",
|
||||
"n":"Flour",
|
||||
"p":"flour.png"
|
||||
},
|
||||
{
|
||||
"c":"1 pc",
|
||||
"n":"Egg",
|
||||
"p":"egg.png"
|
||||
},
|
||||
{
|
||||
"c":"1 tsp",
|
||||
"n":"Salt",
|
||||
"p":"salt.png"
|
||||
},
|
||||
{
|
||||
"c":"1/2 tsp",
|
||||
"n":"Black Pepper",
|
||||
"p":"black_pepper.png"
|
||||
},
|
||||
{
|
||||
"c":"2 cups",
|
||||
"n":"Cooking Oil",
|
||||
"p":"oil.png"
|
||||
}
|
||||
],
|
||||
"in":[
|
||||
"Combine squid, salt, and ground black pepper then mix well. Let stand for 10 minutes",
|
||||
"Heat a cooking pot the pour-in cooking oil",
|
||||
"Dredge the squid in flour then dip in beaten egg and roll over",
|
||||
"When the oil is hot enough, deep-fry the squid until the color of the coating turns brown",
|
||||
"Remove the fried squid from the cooking pot and transfer in a plate lined with paper towels",
|
||||
"Serve with sinamak or Asian dipping sauce"
|
||||
],
|
||||
"pf":"calamares.jpg",
|
||||
"pt":"10 minutes",
|
||||
"sv":"3",
|
||||
"tt":"13 MIN"
|
||||
},
|
||||
"1":{
|
||||
"cn":"260 Gr 293 Kcal 1 Hour 42 Min",
|
||||
"ct":"1 hour 30 minutes",
|
||||
"dc":"Sisig is a popular Filipino dish. It is composed of minced pork, chopped onion, and mayonnaise.",
|
||||
"fn":"Pork Sisig",
|
||||
"fv":false,
|
||||
"ig":[
|
||||
{
|
||||
"c":"1 1/2 lb",
|
||||
"n":"Pork Meat",
|
||||
"p":"pork.png"
|
||||
},
|
||||
{
|
||||
"c":"1 pc",
|
||||
"n":"Onion",
|
||||
"p":"onion.png"
|
||||
},
|
||||
{
|
||||
"c":"3 tsp",
|
||||
"n":"Chili",
|
||||
"p":"chili.png"
|
||||
},
|
||||
{
|
||||
"c":"1/2 tsp",
|
||||
"n":"Garlic",
|
||||
"p":"garlic.png"
|
||||
},
|
||||
{
|
||||
"c":"1/4 tsp",
|
||||
"n":"Black Pepper",
|
||||
"p":"black_pepper.png"
|
||||
},
|
||||
{
|
||||
"c":"1 pc",
|
||||
"n":"Lemon",
|
||||
"p":"lemon.png"
|
||||
},
|
||||
{
|
||||
"c":"1/2 cup",
|
||||
"n":"Butter",
|
||||
"p":"butter.png"
|
||||
},
|
||||
{
|
||||
"c":"1/2 tsp",
|
||||
"n":"Salt",
|
||||
"p":"salt.png"
|
||||
},
|
||||
{
|
||||
"c":"1 pc",
|
||||
"n":"Egg",
|
||||
"p":"egg.png"
|
||||
}
|
||||
],
|
||||
"in":[
|
||||
"Pour the water in a pan and bring to a boil Add salt and pepper",
|
||||
"Put-in the pork meat then simmer for 40 minutes to 1 hour (or until tender)",
|
||||
"Grill the boiled pork meat until done",
|
||||
"Chop the pork meat into fine pieces",
|
||||
"In a wide pan, melt the butter. Add the onions. Cook until onions are soft.",
|
||||
"Put-in the ginger and cook for 2 minutes",
|
||||
"Add the pork meat. Cook for 10 to 12 minutes",
|
||||
"Put-in the soy sauce, garlic powder, and chili. Mix well",
|
||||
"Add salt and pepper to taste",
|
||||
"Put-in the mayonnaise and mix with the other ingredients",
|
||||
"Transfer to a serving plate. Top with chopped green onions and raw egg",
|
||||
"Add the lemon before eating"
|
||||
],
|
||||
"pf":"pork_sisig.jpg",
|
||||
"pt":"12 minutes",
|
||||
"sv":"6",
|
||||
"tt":"1 hour 42 minutes"
|
||||
},
|
||||
"2":{
|
||||
"cn":"120 Gr 168 Kcal 1 Hour 10 Min",
|
||||
"ct":"3 minutes",
|
||||
"dc":"Pochero or Puchero is a well-loved Filipino stew. Made with meat, tomatoes, and saba bananas. ",
|
||||
"fn":"Pochero",
|
||||
"fv":false,
|
||||
"ig":[
|
||||
{
|
||||
"c":"1 large",
|
||||
"n":"Banana",
|
||||
"p":"banana.png"
|
||||
},
|
||||
{
|
||||
"c":"2 pcs",
|
||||
"n":"Tomato",
|
||||
"p":"tomato.png"
|
||||
},
|
||||
{
|
||||
"c":"1 lb",
|
||||
"n":"Pork Meat",
|
||||
"p":"pork.png"
|
||||
},
|
||||
{
|
||||
"c":"1 pc",
|
||||
"n":"Onion",
|
||||
"p":"onion.png"
|
||||
},
|
||||
{
|
||||
"c":"1 tsp",
|
||||
"n":"Garlic",
|
||||
"p":"garlic.png"
|
||||
},
|
||||
{
|
||||
"c":"1 tbsp",
|
||||
"n":"Peppercorn",
|
||||
"p":"black_pepper.png"
|
||||
},
|
||||
{
|
||||
"c":"1 medium",
|
||||
"n":"Potato",
|
||||
"p":"potato.png"
|
||||
},
|
||||
{
|
||||
"c":"1 small",
|
||||
"n":"Cabbage",
|
||||
"p":"cabbage.png"
|
||||
},
|
||||
{
|
||||
"c":"1 bunch",
|
||||
"n":"Bok Choy",
|
||||
"p":"bokchoy.png"
|
||||
},
|
||||
{
|
||||
"c":"1/4 lb",
|
||||
"n":"Green Beans",
|
||||
"p":"green_beans.png"
|
||||
},
|
||||
{
|
||||
"c":"2 tbsp",
|
||||
"n":"Cooking Oil",
|
||||
"p":"oil.png"
|
||||
}
|
||||
],
|
||||
"in":[
|
||||
"Heat cooking oil in a cooking pot",
|
||||
"Sauté garlic, onions, and tomatoes",
|
||||
"Add pork and cook until the color turns light brown",
|
||||
"Put-in fish sauce, whole pepper corn, and tomato sauce. Stir.",
|
||||
"Add water and let boil. Simmer until pork is tender (about 30 to 40 minutes)",
|
||||
"Put-in potato, plantain, and chick peas. Cook for 5 to 7 minutes.",
|
||||
"Add cabbage and long green beans. Cook for 5 minutes",
|
||||
"Stir-in the bok choy. Cover the pot and turn off the heat",
|
||||
"Let the residual heat cook the bok choy (about 5 minutes)",
|
||||
"Transfer to a serving plate and serve"
|
||||
],
|
||||
"pf":"pochero.jpg",
|
||||
"pt":"10 minutes",
|
||||
"sv":"3",
|
||||
"tt":"13 MIN"
|
||||
},
|
||||
"3":{
|
||||
"cn":"140 Gr 250 Kcal 1 Hour 30 Min",
|
||||
"ct":"3 minutes",
|
||||
"dc":"A type of Filipino Beef Stew. This dish is cooked in a tomato-based sauce with vegetables such as potato, carrot, and bell pepper.",
|
||||
"fn":"Beef Caldereta",
|
||||
"fv":false,
|
||||
"ig":[
|
||||
{
|
||||
"c":"1/2 lb",
|
||||
"n":"Beef",
|
||||
"p":"beef.png"
|
||||
},
|
||||
{
|
||||
"c":"2 medium",
|
||||
"n":"Carrot",
|
||||
"p":"carrot.png"
|
||||
},
|
||||
{
|
||||
"c":"1 large",
|
||||
"n":"Potato",
|
||||
"p":"potato.png"
|
||||
},
|
||||
{
|
||||
"c":"1 small",
|
||||
"n":"Green Bell Pepper",
|
||||
"p":"green_bell.png"
|
||||
},
|
||||
{
|
||||
"c":"1 small",
|
||||
"n":"Red Bell Pepper",
|
||||
"p":"red_bell.png"
|
||||
},
|
||||
{
|
||||
"c":"2 Cloves",
|
||||
"n":"Garlic",
|
||||
"p":"garlic.png"
|
||||
},
|
||||
{
|
||||
"c":"1 medium",
|
||||
"n":"Yellow Onion",
|
||||
"p":"yellow_onion.png"
|
||||
},
|
||||
{
|
||||
"c":"1 tsp",
|
||||
"n":"Salt",
|
||||
"p":"salt.png"
|
||||
},
|
||||
{
|
||||
"c":"6 tbsp",
|
||||
"n":"Cooking oil",
|
||||
"p":"oil.png"
|
||||
},
|
||||
{
|
||||
"c":"1 tsp",
|
||||
"n":"Peppercorn",
|
||||
"p":"black_pepper.png"
|
||||
},
|
||||
{
|
||||
"c":"1 tsp",
|
||||
"n":"Red Pepper",
|
||||
"p":"chili.png"
|
||||
}
|
||||
],
|
||||
"in":[
|
||||
"Heat a pan or wok and then pour 3 tablespoons cooking oil. Stir-fry the bell peppers for 3 minutes. Remove the bell peppers and put in a plate. Set aside",
|
||||
"Using the oil in the pan (add more if necessary), pan fry the carrots and potato for 3 to 5 minutes. Put these in a plate and then set aside",
|
||||
"Heat the remaining 3 tablespoons of oil in a clean pot",
|
||||
"Sauté the garlic and onion",
|
||||
"Add the beef. Cook until it turns light brown",
|
||||
"Pour –in tomato sauce and water. Let boil",
|
||||
"Continue to cook in low heat for 60 minutes or until the beef gets tender. Add more water if needed",
|
||||
"Stir-in the liver spread and then add some salt and pepper",
|
||||
"Put the pan-fried potato and carrots in the pot. Stir. Add the bell peppers",
|
||||
"Cover the pot. Continue to cook for 5 minutes",
|
||||
"Add the red pepper flakes. Stir and cook for 3 minutes more",
|
||||
"Transfer to a serving plate. Serve"
|
||||
],
|
||||
"pf":"beef_caldereta.jpg",
|
||||
"pt":"10 minutes",
|
||||
"sv":"3",
|
||||
"tt":"13 MIN"
|
||||
},
|
||||
"4":{
|
||||
"cn":"90 Gr 130 Kcal 1 Hour 15 Min",
|
||||
"ct":"3 minutes",
|
||||
"dc":"Pork Embutido is a Filipino-style meatloaf made with a festive mixture of ground pork, carrots, and raisins wrapped around slices of eggs and sausage.",
|
||||
"fn":"Embutido",
|
||||
"fv":false,
|
||||
"ig":[
|
||||
{
|
||||
"c":"2 lbs",
|
||||
"n":"Ground pork",
|
||||
"p":"ground_pork.png"
|
||||
},
|
||||
{
|
||||
"c":"12 pcs",
|
||||
"n":"Sausage",
|
||||
"p":"sausage.png"
|
||||
},
|
||||
{
|
||||
"c":"3 pcs",
|
||||
"n":"Egg",
|
||||
"p":"egg.png"
|
||||
},
|
||||
{
|
||||
"c":"2 cups",
|
||||
"n":"Cheese",
|
||||
"p":"cheese.png"
|
||||
},
|
||||
{
|
||||
"c":"1 cup",
|
||||
"n":"Red Bell Pepper",
|
||||
"p":"red_bell.png"
|
||||
},
|
||||
{
|
||||
"c":"1 cup",
|
||||
"n":"Green Bell Pepper",
|
||||
"p":"green_bell.png"
|
||||
},
|
||||
{
|
||||
"c":"1/2 cup",
|
||||
"n":"Raisins",
|
||||
"p":"raisins.png"
|
||||
},
|
||||
{
|
||||
"c":"1/2 cup",
|
||||
"n":"Carrot",
|
||||
"p":"carrot.png"
|
||||
},
|
||||
{
|
||||
"c":"1/2 cup",
|
||||
"n":"Onion",
|
||||
"p":"onion.png"
|
||||
},
|
||||
{
|
||||
"c":"2 tbsp",
|
||||
"n":"Salt",
|
||||
"p":"salt.png"
|
||||
},
|
||||
{
|
||||
"c":"1 tbsp",
|
||||
"n":"Peppercorn",
|
||||
"p":"black_pepper.png"
|
||||
}
|
||||
],
|
||||
"in":[
|
||||
"Place the ground pork in a large container",
|
||||
"Add the bread crumbs then break the raw eggs and add it in. Mix well",
|
||||
"Put-in the carrots, bell pepper (red and green), onion, pickle relish, and cheddar cheese. Mix thoroughly",
|
||||
"Add the raisins, tomato sauce, salt, and pepper then mix well.",
|
||||
"Put in the sliced vienna sausage and sliced boiled eggs alternately on the middle of the flat meat mixture.",
|
||||
"Roll the foil to form a cylinder — locking the sausage and egg in the middle if the meat mixture. Once done, lock the edges of the foil.",
|
||||
"Place in a steamer and let cook for 1 hour.",
|
||||
"Place inside the refrigerator until temperature turns cold",
|
||||
"Slice and serve"
|
||||
],
|
||||
"pf":"embutido.jpg",
|
||||
"pt":"10 minutes",
|
||||
"sv":"3",
|
||||
"tt":"13 MIN"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 917 B |
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 20 KiB |
@@ -1,101 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!--
|
||||
If you are serving your web app in a path other than the root, change the
|
||||
href value below to reflect the base path you are serving from.
|
||||
|
||||
The path provided below has to start and end with a slash "/" in order for
|
||||
it to work correctly.
|
||||
|
||||
For more details:
|
||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
|
||||
|
||||
This is a placeholder for base href that will be replaced by the value of
|
||||
the `--base-href` argument provided to `flutter build`.
|
||||
-->
|
||||
<base href="$FLUTTER_BASE_HREF">
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
||||
<meta name="description" content="A new Flutter project.">
|
||||
|
||||
<!-- iOS meta tags & icons -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="filipino_cuisine">
|
||||
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||
|
||||
<title>filipino_cuisine</title>
|
||||
<link rel="manifest" href="manifest.json">
|
||||
</head>
|
||||
<body>
|
||||
<!-- This script installs service_worker.js to provide PWA functionality to
|
||||
application. For more information, see:
|
||||
https://developers.google.com/web/fundamentals/primers/service-workers -->
|
||||
<script>
|
||||
var serviceWorkerVersion = null;
|
||||
var scriptLoaded = false;
|
||||
function loadMainDartJs() {
|
||||
if (scriptLoaded) {
|
||||
return;
|
||||
}
|
||||
scriptLoaded = true;
|
||||
var scriptTag = document.createElement('script');
|
||||
scriptTag.src = 'main.dart.js';
|
||||
scriptTag.type = 'application/javascript';
|
||||
document.body.append(scriptTag);
|
||||
}
|
||||
|
||||
if ('serviceWorker' in navigator) {
|
||||
// Service workers are supported. Use them.
|
||||
window.addEventListener('load', function () {
|
||||
// Wait for registration to finish before dropping the <script> tag.
|
||||
// Otherwise, the browser will load the script multiple times,
|
||||
// potentially different versions.
|
||||
var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
|
||||
navigator.serviceWorker.register(serviceWorkerUrl)
|
||||
.then((reg) => {
|
||||
function waitForActivation(serviceWorker) {
|
||||
serviceWorker.addEventListener('statechange', () => {
|
||||
if (serviceWorker.state == 'activated') {
|
||||
console.log('Installed new service worker.');
|
||||
loadMainDartJs();
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!reg.active && (reg.installing || reg.waiting)) {
|
||||
// No active web worker and we have installed or are installing
|
||||
// one for the first time. Simply wait for it to activate.
|
||||
waitForActivation(reg.installing || reg.waiting);
|
||||
} else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
|
||||
// When the app updates the serviceWorkerVersion changes, so we
|
||||
// need to ask the service worker to update.
|
||||
console.log('New service worker available.');
|
||||
reg.update();
|
||||
waitForActivation(reg.installing);
|
||||
} else {
|
||||
// Existing service worker is still good.
|
||||
console.log('Loading app from service worker.');
|
||||
loadMainDartJs();
|
||||
}
|
||||
});
|
||||
|
||||
// If service worker doesn't succeed in a reasonable amount of time,
|
||||
// fallback to plaint <script> tag.
|
||||
setTimeout(() => {
|
||||
if (!scriptLoaded) {
|
||||
console.warn(
|
||||
'Failed to load app from service worker. Falling back to plain <script> tag.',
|
||||
);
|
||||
loadMainDartJs();
|
||||
}
|
||||
}, 4000);
|
||||
});
|
||||
} else {
|
||||
// Service workers not supported. Just drop the <script> tag.
|
||||
loadMainDartJs();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,35 +0,0 @@
|
||||
{
|
||||
"name": "filipino_cuisine",
|
||||
"short_name": "filipino_cuisine",
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"background_color": "#0175C2",
|
||||
"theme_color": "#0175C2",
|
||||
"description": "A new Flutter project.",
|
||||
"orientation": "portrait-primary",
|
||||
"prefer_related_applications": false,
|
||||
"icons": [
|
||||
{
|
||||
"src": "icons/Icon-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "icons/Icon-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "icons/Icon-maskable-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "icons/Icon-maskable-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -485,23 +485,6 @@ samples:
|
||||
web: web/charts
|
||||
type: demo
|
||||
|
||||
- name: Filipino Cuisine
|
||||
author: github.com/markgrancapal
|
||||
screenshots:
|
||||
- url: images/filipino_cuisine1.png
|
||||
alt: Filipino Cuisine screenshot
|
||||
source: https://github.com/markgrancapal/filipino_cuisine
|
||||
description: >
|
||||
Flutter Create challenge entry
|
||||
difficulty: intermediate
|
||||
widgets: []
|
||||
packages: []
|
||||
platforms: ['web']
|
||||
links: []
|
||||
tags: ['demo', 'flutter create']
|
||||
web: web/filipino_cuisine
|
||||
type: demo
|
||||
|
||||
- name: GitHub Dataviz
|
||||
author: Larva Labs
|
||||
screenshots:
|
||||
|
||||
|
Before Width: | Height: | Size: 1.8 MiB |