WT 1.1.5+2 remote images for menu
This commit is contained in:
+32
-17
@@ -5,6 +5,7 @@ import 'package:aitrainer_app/localization/app_localization.dart';
|
||||
import 'package:aitrainer_app/model/cache.dart';
|
||||
import 'package:aitrainer_app/repository/exercise_repository.dart';
|
||||
import 'package:aitrainer_app/util/common.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
@@ -12,6 +13,8 @@ import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:percent_indicator/linear_percent_indicator.dart';
|
||||
import 'package:rainbow_color/rainbow_color.dart';
|
||||
|
||||
import 'dialog_html.dart';
|
||||
|
||||
class AppBarNav extends StatefulWidget implements PreferredSizeWidget {
|
||||
final MenuBloc menuBloc;
|
||||
final bool isMenu;
|
||||
@@ -146,6 +149,9 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin, C
|
||||
percent = 0;
|
||||
}
|
||||
}
|
||||
if (percent == null) {
|
||||
percent = 0;
|
||||
}
|
||||
int sizeExerciseList = Cache().getExercises() == null ? 0 : Cache().getExercises().length;
|
||||
if (sizeExerciseList == 0) {
|
||||
String text = AppLocalizations.of(context).translate("Make your first test");
|
||||
@@ -155,29 +161,38 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin, C
|
||||
text,
|
||||
style: TextStyle(fontSize: fontSize, color: colorAnim.value, shadows: [Shadow(color: Colors.purple, blurRadius: 15)]),
|
||||
),
|
||||
//TestProgress(animation: sizeAnim),
|
||||
]);
|
||||
} else {
|
||||
return Stack(
|
||||
alignment: Alignment.topLeft,
|
||||
children: [
|
||||
LinearPercentIndicator(
|
||||
width: cWidth / 4,
|
||||
lineHeight: 14.0,
|
||||
percent: percent,
|
||||
center: Text(
|
||||
(percent * 100).toStringAsFixed(0) + "% " + AppLocalizations.of(context).translate("finished"),
|
||||
style: new TextStyle(fontSize: 10.0),
|
||||
GestureDetector(
|
||||
onTap: () => showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return DialogHTML(
|
||||
title: AppLocalizations.of(context).translate("Progressindicator for the tests"),
|
||||
htmlData: AppLocalizations.of(context).translate("Progressindicator_desc"),
|
||||
);
|
||||
}),
|
||||
child: LinearPercentIndicator(
|
||||
width: cWidth / 4,
|
||||
lineHeight: 14.0,
|
||||
percent: percent,
|
||||
center: Text(
|
||||
(percent * 100).toStringAsFixed(0) + "% " + AppLocalizations.of(context).translate("finished"),
|
||||
style: new TextStyle(fontSize: 10.0),
|
||||
),
|
||||
trailing: Icon(
|
||||
percent > 0.6 ? Icons.mood : Icons.mood_bad,
|
||||
color: colorAnim.value,
|
||||
),
|
||||
linearStrokeCap: LinearStrokeCap.roundAll,
|
||||
backgroundColor: colorAnim.value,
|
||||
progressColor: Color(0xff73e600),
|
||||
animation: true,
|
||||
),
|
||||
trailing: Icon(
|
||||
percent > 0.6 ? Icons.mood : Icons.mood_bad,
|
||||
color: colorAnim.value,
|
||||
),
|
||||
linearStrokeCap: LinearStrokeCap.roundAll,
|
||||
backgroundColor: colorAnim.value,
|
||||
progressColor: Color(0xff73e600),
|
||||
animation: true,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -172,6 +172,13 @@ class _BMIState extends State<BMI> with Trans {
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontSize: 20,
|
||||
color: Colors.orange[200],
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 5.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
)),
|
||||
Text(
|
||||
t("Bodyweight") +
|
||||
@@ -183,16 +190,37 @@ class _BMIState extends State<BMI> with Trans {
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontSize: 20,
|
||||
color: Colors.orange[200],
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 5.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
)),
|
||||
Text("BMI" + " " + t("goal") + ": " + widget.exerciseBloc.goalBMI.toStringAsFixed(1),
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontSize: 20,
|
||||
color: Colors.orange[500],
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 5.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
)),
|
||||
Text(t("Bodyweight") + " " + t("goal") + ": " + widget.exerciseBloc.goalWeight.toStringAsFixed(0) + " kg",
|
||||
style: GoogleFonts.archivoBlack(
|
||||
fontSize: 20,
|
||||
color: Colors.orange[500],
|
||||
shadows: <Shadow>[
|
||||
Shadow(
|
||||
offset: Offset(2.0, 2.0),
|
||||
blurRadius: 5.0,
|
||||
color: Colors.black54,
|
||||
),
|
||||
],
|
||||
)),
|
||||
]))))));
|
||||
}
|
||||
|
||||
@@ -141,6 +141,17 @@ class _BMRState extends State<BMR> with Trans {
|
||||
fontSize: 30,
|
||||
color: Colors.orange[300],
|
||||
)),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 65, right: 65),
|
||||
alignment: Alignment.center,
|
||||
child:
|
||||
Text(t("Resting metabolic rate is the rate at which your body burns energy when it is at complete rest."),
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 16,
|
||||
color: Colors.yellow[200],
|
||||
)),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 35, right: 35),
|
||||
@@ -189,7 +200,7 @@ class _BMRState extends State<BMR> with Trans {
|
||||
child: TextFormField(
|
||||
focusNode: _nodeText2,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
|
||||
contentPadding: EdgeInsets.only(left: 10, top: 5, bottom: 5),
|
||||
labelText: AppLocalizations.of(context).translate("Actual Height"),
|
||||
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
|
||||
fillColor: Colors.black38,
|
||||
@@ -216,7 +227,7 @@ class _BMRState extends State<BMR> with Trans {
|
||||
child: TextFormField(
|
||||
focusNode: _nodeText3,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
|
||||
contentPadding: EdgeInsets.only(left: 10, top: 5, bottom: 5),
|
||||
labelText: AppLocalizations.of(context).translate("Birth Year"),
|
||||
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
|
||||
fillColor: Colors.black38,
|
||||
@@ -338,7 +349,7 @@ class _BMRState extends State<BMR> with Trans {
|
||||
child: TextFormField(
|
||||
focusNode: _nodeText1,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: EdgeInsets.only(left: 15, top: 5, bottom: 5),
|
||||
contentPadding: EdgeInsets.only(left: 10, top: 5, bottom: 5),
|
||||
labelText: AppLocalizations.of(context).translate("Actual Weight"),
|
||||
labelStyle: GoogleFonts.inter(fontSize: 16, color: Colors.yellow[50]),
|
||||
fillColor: Colors.black38,
|
||||
|
||||
@@ -40,7 +40,7 @@ class _DialogPremiumState extends State<DialogHTML> with Trans {
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
boxShadow: [BoxShadow(color: Colors.black, offset: Offset(0, 10), blurRadius: 10)],
|
||||
image: DecorationImage(
|
||||
image: AssetImage('asset/image/WT_black_G_background.png'),
|
||||
image: AssetImage('asset/image/WT_results_background.jpg'),
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.center,
|
||||
),
|
||||
|
||||
@@ -256,7 +256,11 @@ class _DialogPremiumState extends State<DialogPremium> with Trans {
|
||||
list.add(TextSpan(text: t(" ")));
|
||||
list.add(
|
||||
TextSpan(
|
||||
text: widget.unlockRound == 1 ? t("the first") : t("the second"),
|
||||
text: widget.unlockRound == 1
|
||||
? t("the first")
|
||||
: widget.unlockRound == 2
|
||||
? t("the second")
|
||||
: t("the third"),
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
||||
@@ -89,6 +89,5 @@ class _HomePageState extends State<AitrainerHome> with Logging {
|
||||
@override
|
||||
void dispose() async {
|
||||
super.dispose();
|
||||
//await PlatformPurchaseApi().close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:aitrainer_app/bloc/menu/menu_bloc.dart';
|
||||
@@ -10,12 +10,16 @@ import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||
import 'package:aitrainer_app/service/logging.dart';
|
||||
import 'package:aitrainer_app/util/trans.dart';
|
||||
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
||||
import 'package:auto_animated/auto_animated.dart';
|
||||
import 'package:badges/badges.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/painting.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:transparent_image/transparent_image.dart';
|
||||
import 'package:aitrainer_app/library/image_cache.dart' as wt;
|
||||
|
||||
import 'dialog_html.dart';
|
||||
import 'menu_info_widget.dart';
|
||||
@@ -35,35 +39,33 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
final double baseHeight = 675.2;
|
||||
bool isFirst = true;
|
||||
bool wait = false;
|
||||
Timer _timer, _waitTimer;
|
||||
MenuBloc menuBloc;
|
||||
final scrollController = ScrollController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
isFirst = true;
|
||||
_timer = Timer.periodic(
|
||||
Duration(milliseconds: 800),
|
||||
(Timer timer) => setState(() {
|
||||
if (!wait) {
|
||||
isFirst = !isFirst;
|
||||
//wait = true;
|
||||
}
|
||||
}));
|
||||
_waitTimer = Timer.periodic(
|
||||
Duration(milliseconds: 5000),
|
||||
(Timer timer) => setState(() {
|
||||
wait = !wait;
|
||||
}));
|
||||
|
||||
/// We require the initializers to run after the loading screen is rendered
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) {
|
||||
menuBloc.add(MenuCreate());
|
||||
});
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
MenuBloc menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||
menuBloc = BlocProvider.of<MenuBloc>(context);
|
||||
setContext(context);
|
||||
double cWidth = MediaQuery.of(context).size.width;
|
||||
double cHeight = MediaQuery.of(context).size.height;
|
||||
|
||||
return CustomScrollView(scrollDirection: Axis.vertical, slivers: buildMenuColumn(widget.parent, context, menuBloc, cWidth, cHeight));
|
||||
return CustomScrollView(
|
||||
// Must add scrollController to sliver root
|
||||
controller: scrollController,
|
||||
scrollDirection: Axis.vertical,
|
||||
slivers: buildMenuColumn(widget.parent, context, menuBloc, cWidth, cHeight));
|
||||
}
|
||||
|
||||
List<Widget> buildMenuColumn(int parent, BuildContext context, MenuBloc menuBloc, double cWidth, double cHeight) {
|
||||
@@ -90,8 +92,8 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
menuBloc.getFilteredBranch(menuBloc.parent).forEach((treeName, value) {
|
||||
WorkoutMenuTree workoutTree = value;
|
||||
_columnChildren.add(Container(
|
||||
padding: EdgeInsets.only(top: 15.0, left: 15, right: 15),
|
||||
height: 225, //cHeight / 3 * distortionHeight,
|
||||
padding: EdgeInsets.only(top: 15.0, left: cWidth * 0.04, right: cWidth * 0.04),
|
||||
height: (cHeight / 3) - cWidth * 0.16,
|
||||
child: Badge(
|
||||
padding: EdgeInsets.all(8),
|
||||
position: BadgePosition.bottomEnd(end: 0),
|
||||
@@ -141,9 +143,16 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
])))));
|
||||
});
|
||||
}
|
||||
|
||||
SliverList sliverList = SliverList(
|
||||
delegate: SliverChildListDelegate(_columnChildren),
|
||||
//delegate: SliverChildListDelegate(_columnChildren),
|
||||
LiveSliverList sliverList = LiveSliverList(
|
||||
itemCount: _columnChildren.length,
|
||||
reAnimateOnVisibility: false,
|
||||
showItemDuration: Duration(milliseconds: 250),
|
||||
itemBuilder: (BuildContext context, int index, Animation<double> animation) => FadeTransition(
|
||||
opacity: animation,
|
||||
child: _columnChildren[index],
|
||||
),
|
||||
controller: scrollController,
|
||||
);
|
||||
|
||||
slivers.add(sliverList);
|
||||
@@ -332,33 +341,51 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
}
|
||||
|
||||
Widget _getButtonImage(WorkoutMenuTree workoutTree, double cWidth, double cHeight) {
|
||||
Widget image;
|
||||
|
||||
if (workoutTree.imageName.startsWith('https')) {
|
||||
image = ClipRRect(
|
||||
//print("_getButtonImage " + workoutTree.imageName);
|
||||
String imageString = menuBloc.getImage(workoutTree.id, workoutTree.imageName);
|
||||
Widget widget;
|
||||
if (imageString != null) {
|
||||
print(" -- get Image from MEMORY " + workoutTree.imageName);
|
||||
widget = ClipRRect(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
child: Container(
|
||||
color: Colors.black87,
|
||||
color: Colors.transparent,
|
||||
child: FadeInImage(
|
||||
image: NetworkImage(workoutTree.imageName),
|
||||
placeholder: AssetImage("asset/image/dots.gif"),
|
||||
fadeInDuration: Duration(milliseconds: 100),
|
||||
image: MemoryImage(base64Decode(imageString)),
|
||||
placeholder: MemoryImage(kTransparentImage),
|
||||
),
|
||||
));
|
||||
} else {
|
||||
image = Container(
|
||||
//width: cWidth - 30,
|
||||
//height: 210.0,
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
fit: BoxFit.cover,
|
||||
image: AssetImage(workoutTree.imageName),
|
||||
),
|
||||
borderRadius: BorderRadius.all(Radius.circular(24.0)),
|
||||
),
|
||||
);
|
||||
if (workoutTree.imageName.contains("https")) {
|
||||
if (!wt.ImageCache().existsImageInMap(workoutTree.id, workoutTree.imageName)) {
|
||||
print(" -- get Image from network " + workoutTree.imageName);
|
||||
widget = ClipRRect(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: FadeInImage(
|
||||
fadeInDuration: Duration(milliseconds: 500),
|
||||
image: NetworkImage(workoutTree.imageName),
|
||||
placeholder: MemoryImage(kTransparentImage),
|
||||
),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
//print(" -- get Image from asset " + workoutTree.imageName);
|
||||
widget = ClipRRect(
|
||||
borderRadius: BorderRadius.circular(24.0),
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: FadeInImage(
|
||||
fadeInDuration: Duration(milliseconds: 200),
|
||||
image: AssetImage(workoutTree.imageName),
|
||||
placeholder: MemoryImage(kTransparentImage),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
return widget;
|
||||
}
|
||||
|
||||
Widget badgedIcon(WorkoutMenuTree workoutMenuTree, double cWidth, double cHeight) {
|
||||
@@ -380,7 +407,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
)),
|
||||
child: buttonImage == null
|
||||
? Container(
|
||||
color: Colors.red,
|
||||
color: Colors.transparent,
|
||||
)
|
||||
: buttonImage,
|
||||
);
|
||||
@@ -388,8 +415,6 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_timer.cancel();
|
||||
_waitTimer.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user