fixed most reported bugs
This commit is contained in:
@@ -57,7 +57,8 @@ class _HeroScrollViewState extends State<HeroScrollView> {
|
||||
Widget build(BuildContext context) {
|
||||
return NestedScrollView(
|
||||
controller: _scrollController,
|
||||
physics: const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
|
||||
physics:
|
||||
const BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
|
||||
headerSliverBuilder: (context, _) => [
|
||||
SliverAppBar(
|
||||
pinned: true,
|
||||
@@ -70,7 +71,8 @@ class _HeroScrollViewState extends State<HeroScrollView> {
|
||||
opacity: showBarTitle ? 1.0 : 0.0,
|
||||
child: Row(
|
||||
children: [
|
||||
Icon(widget.icon, color: AppColors.of(context).text.withOpacity(.8)),
|
||||
Icon(widget.icon,
|
||||
color: AppColors.of(context).text.withOpacity(.8)),
|
||||
const SizedBox(width: 8.0),
|
||||
Expanded(
|
||||
child: Text(
|
||||
@@ -78,7 +80,9 @@ class _HeroScrollViewState extends State<HeroScrollView> {
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 2,
|
||||
style: TextStyle(
|
||||
color: AppColors.of(context).text, fontWeight: FontWeight.w500, fontStyle: widget.italic ? FontStyle.italic : null),
|
||||
color: AppColors.of(context).text,
|
||||
fontWeight: FontWeight.w500,
|
||||
fontStyle: widget.italic ? FontStyle.italic : null),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -94,7 +98,7 @@ class _HeroScrollViewState extends State<HeroScrollView> {
|
||||
}
|
||||
}),
|
||||
actions: widget.navBarItems,
|
||||
expandedHeight: 124.0,
|
||||
expandedHeight: 145.69,
|
||||
stretch: true,
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
background: Stack(
|
||||
|
||||
@@ -29,16 +29,18 @@ import 'package:flutter_expandable_fab/flutter_expandable_fab.dart';
|
||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'grades_page.i18n.dart';
|
||||
// import 'package:filcnaplo_premium/ui/mobile/goalplanner/new_goal.dart';
|
||||
// import 'package:filcnaplo_premium/ui/mobile/goal_planner/new_goal.dart';
|
||||
|
||||
class GradeSubjectView extends StatefulWidget {
|
||||
const GradeSubjectView(this.subject, {Key? key, this.groupAverage = 0.0}) : super(key: key);
|
||||
const GradeSubjectView(this.subject, {Key? key, this.groupAverage = 0.0})
|
||||
: super(key: key);
|
||||
|
||||
final Subject subject;
|
||||
final double groupAverage;
|
||||
|
||||
void push(BuildContext context, {bool root = false}) {
|
||||
Navigator.of(context, rootNavigator: root).push(CupertinoPageRoute(builder: (context) => this));
|
||||
Navigator.of(context, rootNavigator: root)
|
||||
.push(CupertinoPageRoute(builder: (context) => this));
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -73,7 +75,8 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
final gradeDates = subjectGrades.map((e) => e.date.millisecondsSinceEpoch);
|
||||
final maxGradeDate = gradeDates.fold(0, max);
|
||||
final minGradeDate = gradeDates.fold(0, min);
|
||||
if (maxGradeDate - minGradeDate < const Duration(days: 5).inMilliseconds) return false; // naplo/#78
|
||||
if (maxGradeDate - minGradeDate < const Duration(days: 5).inMilliseconds)
|
||||
return false; // naplo/#78
|
||||
|
||||
return subjectGrades.where((e) => e.type == GradeType.midYear).length > 1;
|
||||
}
|
||||
@@ -139,7 +142,8 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
),
|
||||
);
|
||||
|
||||
tiles.add(Padding(padding: EdgeInsets.only(bottom: !gradeCalcMode ? 24.0 : 250.0)));
|
||||
tiles.add(Padding(
|
||||
padding: EdgeInsets.only(bottom: !gradeCalcMode ? 24.0 : 250.0)));
|
||||
gradeTiles = List.castFrom(tiles);
|
||||
}
|
||||
|
||||
@@ -152,7 +156,10 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
average = AverageHelper.averageEvals(subjectGrades);
|
||||
final prevAvg = subjectGrades.isNotEmpty
|
||||
? AverageHelper.averageEvals(subjectGrades
|
||||
.where((e) => e.date.isBefore(subjectGrades.reduce((v, e) => e.date.isAfter(v.date) ? e : v).date.subtract(const Duration(days: 30))))
|
||||
.where((e) => e.date.isBefore(subjectGrades
|
||||
.reduce((v, e) => e.date.isAfter(v.date) ? e : v)
|
||||
.date
|
||||
.subtract(const Duration(days: 30))))
|
||||
.toList())
|
||||
: 0.0;
|
||||
|
||||
@@ -163,12 +170,14 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("annual_average".i18n),
|
||||
if (average != prevAvg) TrendDisplay(current: average, previous: prevAvg),
|
||||
if (average != prevAvg)
|
||||
TrendDisplay(current: average, previous: prevAvg),
|
||||
],
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(top: 16.0, right: 12.0),
|
||||
child: GradeGraph(subjectGrades, dayThreshold: 5, classAvg: widget.groupAverage),
|
||||
child: GradeGraph(subjectGrades,
|
||||
dayThreshold: 5, classAvg: widget.groupAverage),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -176,7 +185,9 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
if (!gradeCalcMode) {
|
||||
buildTiles(subjectGrades);
|
||||
} else {
|
||||
List<Grade> ghostGrades = calculatorProvider.ghosts.where((e) => e.subject == widget.subject).toList();
|
||||
List<Grade> ghostGrades = calculatorProvider.ghosts
|
||||
.where((e) => e.subject == widget.subject)
|
||||
.toList();
|
||||
buildTiles(ghostGrades);
|
||||
}
|
||||
|
||||
@@ -184,7 +195,10 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
key: _scaffoldKey,
|
||||
floatingActionButtonLocation: ExpandableFab.location,
|
||||
floatingActionButton: Visibility(
|
||||
visible: !gradeCalcMode && subjectGrades.where((e) => e.type == GradeType.midYear).isNotEmpty,
|
||||
visible: !gradeCalcMode &&
|
||||
subjectGrades
|
||||
.where((e) => e.type == GradeType.midYear)
|
||||
.isNotEmpty,
|
||||
child: ExpandableFab(
|
||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||
type: ExpandableFabType.up,
|
||||
@@ -204,14 +218,19 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
child: const Icon(FeatherIcons.flag, size: 20.0),
|
||||
backgroundColor: Theme.of(context).colorScheme.secondary,
|
||||
onPressed: () {
|
||||
if (!Provider.of<PremiumProvider>(context, listen: false).hasScope(PremiumScopes.goalPlanner)) {
|
||||
PremiumLockedFeatureUpsell.show(context: context, feature: PremiumFeature.goalplanner);
|
||||
if (!Provider.of<PremiumProvider>(context, listen: false)
|
||||
.hasScope(PremiumScopes.goalPlanner)) {
|
||||
PremiumLockedFeatureUpsell.show(
|
||||
context: context, feature: PremiumFeature.goalplanner);
|
||||
return;
|
||||
}
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("Hamarosan...")));
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(content: Text("Hamarosan...")));
|
||||
|
||||
// Navigator.of(context).push(CupertinoPageRoute(builder: (context) => PremiumGoalplannerNewGoalScreen(subject: widget.subject)));
|
||||
//Navigator.of(context).push(CupertinoPageRoute(
|
||||
//builder: (context) => PremiumGoalplannerNewGoalScreen(
|
||||
// subject: widget.subject)));
|
||||
},
|
||||
),
|
||||
],
|
||||
@@ -230,12 +249,17 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
},
|
||||
navBarItems: [
|
||||
const SizedBox(width: 6.0),
|
||||
if (widget.groupAverage != 0) Center(child: AverageDisplay(average: widget.groupAverage, border: true)),
|
||||
if (widget.groupAverage != 0)
|
||||
Center(
|
||||
child: AverageDisplay(
|
||||
average: widget.groupAverage, border: true)),
|
||||
const SizedBox(width: 6.0),
|
||||
if (average != 0) Center(child: AverageDisplay(average: average)),
|
||||
if (average != 0)
|
||||
Center(child: AverageDisplay(average: average)),
|
||||
const SizedBox(width: 12.0),
|
||||
],
|
||||
icon: SubjectIcon.resolveVariant(subject: widget.subject, context: context),
|
||||
icon: SubjectIcon.resolveVariant(
|
||||
subject: widget.subject, context: context),
|
||||
scrollController: _scrollController,
|
||||
title: widget.subject.renamedTo ?? widget.subject.name.capital(),
|
||||
italic: widget.subject.isRenamed,
|
||||
@@ -255,13 +279,15 @@ class _GradeSubjectViewState extends State<GradeSubjectView> {
|
||||
|
||||
void gradeCalc(BuildContext context) {
|
||||
// Scroll to the top of the page
|
||||
_scrollController.animateTo(75, duration: const Duration(milliseconds: 500), curve: Curves.ease);
|
||||
_scrollController.animateTo(75,
|
||||
duration: const Duration(milliseconds: 500), curve: Curves.ease);
|
||||
|
||||
calculatorProvider.clear();
|
||||
calculatorProvider.addAllGrades(gradeProvider.grades);
|
||||
|
||||
_sheetController = _scaffoldKey.currentState?.showBottomSheet(
|
||||
(context) => RoundedBottomSheet(child: GradeCalculator(widget.subject), borderRadius: 14.0),
|
||||
(context) => RoundedBottomSheet(
|
||||
child: GradeCalculator(widget.subject), borderRadius: 14.0),
|
||||
backgroundColor: const Color(0x00000000),
|
||||
elevation: 12.0,
|
||||
);
|
||||
|
||||
@@ -5,7 +5,8 @@ class NavItem {
|
||||
final Widget icon;
|
||||
final Widget activeIcon;
|
||||
|
||||
const NavItem({required this.title, required this.icon, required this.activeIcon});
|
||||
const NavItem(
|
||||
{required this.title, required this.icon, required this.activeIcon});
|
||||
}
|
||||
|
||||
class NavbarItem extends StatelessWidget {
|
||||
@@ -25,14 +26,16 @@ class NavbarItem extends StatelessWidget {
|
||||
final Widget icon = active ? item.activeIcon : item.icon;
|
||||
|
||||
return SafeArea(
|
||||
child: InkWell(
|
||||
child: GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 12.0, horizontal: 6.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
decoration: BoxDecoration(
|
||||
color: active ? Theme.of(context).colorScheme.secondary.withOpacity(.4) : null,
|
||||
color: active
|
||||
? Theme.of(context).colorScheme.secondary.withOpacity(.4)
|
||||
: null,
|
||||
borderRadius: BorderRadius.circular(14.0),
|
||||
),
|
||||
child: Stack(
|
||||
@@ -45,7 +48,9 @@ class NavbarItem extends StatelessWidget {
|
||||
),
|
||||
IconTheme(
|
||||
data: IconThemeData(
|
||||
color: Theme.of(context).brightness == Brightness.light ? Colors.black.withOpacity(.5) : Colors.white.withOpacity(.3),
|
||||
color: Theme.of(context).brightness == Brightness.light
|
||||
? Colors.black.withOpacity(.5)
|
||||
: Colors.white.withOpacity(.3),
|
||||
),
|
||||
child: icon,
|
||||
),
|
||||
|
||||
@@ -6,7 +6,10 @@ import 'settings_screen.i18n.dart';
|
||||
class PrivacyView extends StatelessWidget {
|
||||
const PrivacyView({Key? key}) : super(key: key);
|
||||
|
||||
static void show(BuildContext context) => showDialog(context: context, builder: (context) => const PrivacyView(), barrierDismissible: true);
|
||||
static void show(BuildContext context) => showDialog(
|
||||
context: context,
|
||||
builder: (context) => const PrivacyView(),
|
||||
barrierDismissible: true);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
@@ -54,6 +54,9 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
int devmodeCountdown = 3;
|
||||
bool __ss = false; // secret settings
|
||||
|
||||
late Future<Map> futureRelease =
|
||||
Provider.of<UpdateProvider>(context).installedVersion();
|
||||
|
||||
late UserProvider user;
|
||||
late UpdateProvider updateProvider;
|
||||
late SettingsProvider settings;
|
||||
@@ -150,6 +153,7 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
futureRelease = Provider.of<UpdateProvider>(context).installedVersion();
|
||||
_hideContainersController = AnimationController(
|
||||
vsync: this, duration: const Duration(milliseconds: 200));
|
||||
}
|
||||
@@ -877,9 +881,36 @@ class _SettingsScreenState extends State<SettingsScreen>
|
||||
top: false,
|
||||
child: Center(
|
||||
child: GestureDetector(
|
||||
child: const Panel(
|
||||
title: Text("v" +
|
||||
String.fromEnvironment("APPVER", defaultValue: "?"))),
|
||||
child: FutureBuilder<Map>(
|
||||
future: futureRelease,
|
||||
builder: (context, release) {
|
||||
if (release.hasData) {
|
||||
return DefaultTextStyle(
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(0.65)),
|
||||
child: Text("v${release.data!['version']}"),
|
||||
);
|
||||
} else {
|
||||
return DefaultTextStyle(
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleMedium!
|
||||
.copyWith(
|
||||
fontWeight: FontWeight.w600,
|
||||
color: AppColors.of(context)
|
||||
.text
|
||||
.withOpacity(0.65)),
|
||||
child: const Text("v?"),
|
||||
);
|
||||
}
|
||||
},
|
||||
),
|
||||
onTap: () {
|
||||
if (devmodeCountdown > 0) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
|
||||
@@ -41,7 +41,8 @@ extension SettingsLocalization on String {
|
||||
"done": "Done",
|
||||
"reset": "Reset",
|
||||
"open": "Open",
|
||||
"data_collected": "Data collected: Platform (eg. Android), App version (eg. 3.0.0), Unique Install Identifier",
|
||||
"data_collected":
|
||||
"Data collected: Platform (eg. Android), App version (eg. 3.0.0), Unique Install Identifier",
|
||||
"Analytics": "Analytics",
|
||||
"Anonymous Usage Analytics": "Anonymous Usage Analytics",
|
||||
"graph_class_avg": "Class average on graph",
|
||||
@@ -92,7 +93,7 @@ extension SettingsLocalization on String {
|
||||
"about": "Névjegy",
|
||||
"supporters": "Támogatók",
|
||||
"privacy": "Adatvédelmi irányelvek",
|
||||
"licenses": "Licenszek",
|
||||
"licenses": "Licencek",
|
||||
"vibrate": "Rezgés",
|
||||
"voff": "Kikapcsolás",
|
||||
"vlight": "Alacsony",
|
||||
@@ -102,7 +103,8 @@ extension SettingsLocalization on String {
|
||||
"done": "Kész",
|
||||
"reset": "Visszaállítás",
|
||||
"open": "Megnyitás",
|
||||
"data_collected": "Gyűjtött adat: Platform (pl. Android), App verzió (pl. 3.0.0), Egyedi telepítési azonosító",
|
||||
"data_collected":
|
||||
"Gyűjtött adat: Platform (pl. Android), App verzió (pl. 3.0.0), Egyedi telepítési azonosító",
|
||||
"Analytics": "Analitika",
|
||||
"Anonymous Usage Analytics": "Névtelen használati analitika",
|
||||
"graph_class_avg": "Osztályátlag a grafikonon",
|
||||
@@ -163,7 +165,8 @@ extension SettingsLocalization on String {
|
||||
"done": "Fertig",
|
||||
"reset": "Zurücksetzen",
|
||||
"open": "Öffnen",
|
||||
"data_collected": "Erhobene Daten: Plattform (z.B. Android), App version (z.B. 3.0.0), Eindeutige Installationskennung",
|
||||
"data_collected":
|
||||
"Erhobene Daten: Plattform (z.B. Android), App version (z.B. 3.0.0), Eindeutige Installationskennung",
|
||||
"Analytics": "Analytik",
|
||||
"Anonymous Usage Analytics": "Anonyme Nutzungsanalyse",
|
||||
"graph_class_avg": "Klassendurchschnitt in der Grafik",
|
||||
|
||||
@@ -39,6 +39,7 @@ dependencies:
|
||||
flutter_svg: ^1.1.6
|
||||
background_fetch: ^1.1.5
|
||||
wtf_sliding_sheet: ^1.0.0
|
||||
package_info_plus: ^3.1.2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^1.0.0
|
||||
|
||||
Reference in New Issue
Block a user