finished animations and started reveal/share

This commit is contained in:
kima 2023-06-23 00:54:56 +02:00
parent 87842de421
commit 5034af2fb4
6 changed files with 194 additions and 30 deletions

View File

@ -65,6 +65,7 @@ dependencies:
background_fetch: ^1.1.5 background_fetch: ^1.1.5
flutter_local_notifications: ^14.1.0 flutter_local_notifications: ^14.1.0
package_info_plus: ^4.0.2 package_info_plus: ^4.0.2
screenshot: ^2.1.0
dev_dependencies: dev_dependencies:
flutter_lints: ^2.0.1 flutter_lints: ^2.0.1

View File

@ -0,0 +1,68 @@
import 'package:dotted_border/dotted_border.dart';
import 'package:flutter/material.dart';
class EmptyCard extends StatefulWidget {
const EmptyCard({
Key? key,
required this.text,
}) : super(key: key);
final String text;
@override
State<EmptyCard> createState() => _EmptyCardState();
}
class _EmptyCardState extends State<EmptyCard> {
bool hold = false;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onLongPressDown: (_) => setState(() => hold = true),
onLongPressEnd: (_) => setState(() => hold = false),
onLongPressCancel: () => setState(() => hold = false),
child: AnimatedScale(
scale: hold ? 1.018 : 1.0,
curve: Curves.easeInOutBack,
duration: const Duration(milliseconds: 300),
child: Container(
height: 444,
padding:
const EdgeInsets.only(top: 12, bottom: 12, left: 12, right: 12),
decoration: BoxDecoration(
color: const Color(0x280008FF),
borderRadius: const BorderRadius.all(Radius.circular(5)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.08),
offset: const Offset(0, 5),
blurRadius: 20,
spreadRadius: 10,
),
],
),
child: DottedBorder(
color: Colors.black.withOpacity(0.9),
dashPattern: const [12, 12],
padding:
const EdgeInsets.only(top: 20, bottom: 20, left: 20, right: 20),
child: Center(
child: Text(
widget.text,
style: TextStyle(
color: Colors.white.withOpacity(0.9),
),
),
),
),
),
),
);
}
}

View File

@ -27,6 +27,7 @@ class _AllSumBodyState extends State<AllSumBody> {
late List<Widget> lastSixTiles = []; late List<Widget> lastSixTiles = [];
int avgDropValue = 0; int avgDropValue = 0;
bool animation = false;
List<Grade> getSubjectGrades(Subject subject, {int days = 0}) => gradeProvider List<Grade> getSubjectGrades(Subject subject, {int days = 0}) => gradeProvider
.grades .grades
@ -45,6 +46,12 @@ class _AllSumBodyState extends State<AllSumBody> {
homeworkProvider = Provider.of<HomeworkProvider>(context, listen: false); homeworkProvider = Provider.of<HomeworkProvider>(context, listen: false);
absenceProvider = Provider.of<AbsenceProvider>(context, listen: false); absenceProvider = Provider.of<AbsenceProvider>(context, listen: false);
//timetableProvider = Provider.of<TimetableProvider>(context, listen: false); //timetableProvider = Provider.of<TimetableProvider>(context, listen: false);
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
setState(() {
animation = true;
});
});
} }
void getGrades() { void getGrades() {
@ -176,7 +183,11 @@ class _AllSumBodyState extends State<AllSumBody> {
const SizedBox( const SizedBox(
height: 45, height: 45,
), ),
SizedBox( AnimatedContainer(
curve: Curves.easeInOut,
duration: const Duration(milliseconds: 420),
transform: Matrix4.translationValues(
animation ? 0 : MediaQuery.of(context).size.width, 0, 0),
height: 250, height: 250,
child: GridView.count( child: GridView.count(
crossAxisCount: 3, crossAxisCount: 3,
@ -188,7 +199,11 @@ class _AllSumBodyState extends State<AllSumBody> {
const SizedBox( const SizedBox(
height: 30, height: 30,
), ),
SizedBox( AnimatedContainer(
curve: Curves.easeInOut,
duration: const Duration(milliseconds: 420),
transform: Matrix4.translationValues(
animation ? 0 : -MediaQuery.of(context).size.width, 0, 0),
height: 250, height: 250,
child: GridView.count( child: GridView.count(
crossAxisCount: 3, crossAxisCount: 3,

View File

@ -45,6 +45,7 @@ class _GradesBodyState extends State<GradesBody> {
List<Widget> subjectTiles1 = []; List<Widget> subjectTiles1 = [];
int avgDropValue = 0; int avgDropValue = 0;
bool animation = false;
List<Grade> getSubjectGrades(Subject subject, {int days = 0}) => gradeProvider List<Grade> getSubjectGrades(Subject subject, {int days = 0}) => gradeProvider
.grades .grades
@ -61,6 +62,12 @@ class _GradesBodyState extends State<GradesBody> {
gradeProvider = Provider.of<GradeProvider>(context, listen: false); gradeProvider = Provider.of<GradeProvider>(context, listen: false);
settings = Provider.of<SettingsProvider>(context, listen: false); settings = Provider.of<SettingsProvider>(context, listen: false);
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
setState(() {
animation = true;
});
});
} }
void generateTiles({required int filter}) { void generateTiles({required int filter}) {
@ -73,37 +80,46 @@ class _GradesBodyState extends State<GradesBody> {
Map<Subject, double> subjectAvgs = {}; Map<Subject, double> subjectAvgs = {};
var count = 1;
for (Subject subject in subjects) { for (Subject subject in subjects) {
List<Grade> subjectGrades = getSubjectGrades(subject); List<Grade> subjectGrades = getSubjectGrades(subject);
double avg = AverageHelper.averageEvals(subjectGrades); double avg = AverageHelper.averageEvals(subjectGrades);
if (avg != 0) subjectAvgs[subject] = avg; if (avg != 0) subjectAvgs[subject] = avg;
Widget widget = Row( Widget widget = AnimatedContainer(
children: [ curve: Curves.easeInOut,
GradeValueWidget( duration: Duration(milliseconds: 300 + (count * 120)),
GradeValue(avg.round(), '', '', 100), transform: Matrix4.translationValues(
fill: true, animation ? 0 : MediaQuery.of(context).size.width, 0, 0),
size: 28.0, child: Row(
), children: [
const SizedBox(width: 8), GradeValueWidget(
Text( GradeValue(avg.round(), '', '', 100),
subject.renamedTo ?? subject.name.capital(), fill: true,
maxLines: 2, size: 28.0,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0,
color: Colors.white.withOpacity(0.98),
fontStyle: settings.renamedSubjectsItalics && subject.isRenamed
? FontStyle.italic
: null,
), ),
) const SizedBox(width: 8),
], Text(
subject.renamedTo ?? subject.name.capital(),
maxLines: 2,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0,
color: Colors.white.withOpacity(0.98),
fontStyle: settings.renamedSubjectsItalics && subject.isRenamed
? FontStyle.italic
: null,
),
)
],
),
); );
if (avg.round() == filter) { if (avg.round() == filter) {
tiles.add(widget); tiles.add(widget);
count++;
} }
} }
@ -175,7 +191,9 @@ class _GradesBodyState extends State<GradesBody> {
children: [ children: [
SizedBox( SizedBox(
height: ((100 * subjectTiles5.length) / height: ((100 * subjectTiles5.length) /
(subjectTiles5[0].runtimeType == Row ? 1.95 : 1.2)) (subjectTiles5[0].runtimeType == AnimatedContainer
? 1.95
: 1.2))
.toDouble(), .toDouble(),
child: ListView.builder( child: ListView.builder(
padding: const EdgeInsets.only(left: 5), padding: const EdgeInsets.only(left: 5),
@ -186,7 +204,7 @@ class _GradesBodyState extends State<GradesBody> {
EdgeInsetsGeometry panelPadding = EdgeInsetsGeometry panelPadding =
const EdgeInsets.symmetric(horizontal: 24.0); const EdgeInsets.symmetric(horizontal: 24.0);
if (subjectTiles5[index].runtimeType == Row) { if (subjectTiles5[index].runtimeType == AnimatedContainer) {
return Padding( return Padding(
padding: const EdgeInsets.only(top: 8), padding: const EdgeInsets.only(top: 8),
child: subjectTiles5[index]); child: subjectTiles5[index]);
@ -212,7 +230,9 @@ class _GradesBodyState extends State<GradesBody> {
const SizedBox(height: 12.0), const SizedBox(height: 12.0),
SizedBox( SizedBox(
height: ((100 * subjectTiles3.length) / height: ((100 * subjectTiles3.length) /
(subjectTiles3[0].runtimeType == Row ? 1.95 : 1.2)) (subjectTiles3[0].runtimeType == AnimatedContainer
? 1.95
: 1.2))
.toDouble(), .toDouble(),
child: ListView.builder( child: ListView.builder(
padding: const EdgeInsets.only(left: 5), padding: const EdgeInsets.only(left: 5),
@ -223,7 +243,7 @@ class _GradesBodyState extends State<GradesBody> {
EdgeInsetsGeometry panelPadding = EdgeInsetsGeometry panelPadding =
const EdgeInsets.symmetric(horizontal: 24.0); const EdgeInsets.symmetric(horizontal: 24.0);
if (subjectTiles3[index].runtimeType == Row) { if (subjectTiles3[index].runtimeType == AnimatedContainer) {
return Padding( return Padding(
padding: const EdgeInsets.only(top: 8), padding: const EdgeInsets.only(top: 8),
child: subjectTiles3[index]); child: subjectTiles3[index]);
@ -249,7 +269,9 @@ class _GradesBodyState extends State<GradesBody> {
const SizedBox(height: 12.0), const SizedBox(height: 12.0),
SizedBox( SizedBox(
height: ((100 * subjectTiles1.length) / height: ((100 * subjectTiles1.length) /
(subjectTiles1[0].runtimeType == Row ? 1.95 : 1.2)) (subjectTiles1[0].runtimeType == AnimatedContainer
? 1.95
: 1.2))
.toDouble(), .toDouble(),
child: ListView.builder( child: ListView.builder(
padding: const EdgeInsets.only(left: 5), padding: const EdgeInsets.only(left: 5),
@ -260,7 +282,7 @@ class _GradesBodyState extends State<GradesBody> {
EdgeInsetsGeometry panelPadding = EdgeInsetsGeometry panelPadding =
const EdgeInsets.symmetric(horizontal: 24.0); const EdgeInsets.symmetric(horizontal: 24.0);
if (subjectTiles1[index].runtimeType == Row) { if (subjectTiles1[index].runtimeType == AnimatedContainer) {
return Padding( return Padding(
padding: const EdgeInsets.only(top: 8), padding: const EdgeInsets.only(top: 8),
child: subjectTiles1[index]); child: subjectTiles1[index]);

View File

@ -1,7 +1,14 @@
import 'dart:io';
import 'package:filcnaplo/api/providers/user_provider.dart'; import 'package:filcnaplo/api/providers/user_provider.dart';
import 'package:filcnaplo_mobile_ui/common/personality_card/empty_card.dart';
import 'package:filcnaplo_mobile_ui/common/personality_card/personality_card.dart'; import 'package:filcnaplo_mobile_ui/common/personality_card/personality_card.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:screenshot/screenshot.dart';
import 'package:share_plus/share_plus.dart';
import 'package:path_provider/path_provider.dart';
class PersonalityBody extends StatefulWidget { class PersonalityBody extends StatefulWidget {
const PersonalityBody({Key? key}) : super(key: key); const PersonalityBody({Key? key}) : super(key: key);
@ -13,6 +20,25 @@ class PersonalityBody extends StatefulWidget {
class _PersonalityBodyState extends State<PersonalityBody> { class _PersonalityBodyState extends State<PersonalityBody> {
late UserProvider user; late UserProvider user;
bool isRevealed = false;
ScreenshotController screenshotController = ScreenshotController();
sharePersonality() async {
await screenshotController.capture().then((image) async {
if (image != null) {
final directory = await getApplicationDocumentsDirectory();
final imagePath =
await File('${directory.path}/refilc_personality.png').create();
await imagePath.writeAsBytes(image);
await Share.shareXFiles([XFile(imagePath.path)]);
}
}).catchError((err) {
throw err;
});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
user = Provider.of<UserProvider>(context); user = Provider.of<UserProvider>(context);
@ -22,8 +48,39 @@ class _PersonalityBodyState extends State<PersonalityBody> {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [ children: [
const SizedBox(height: 60), const SizedBox(height: 60),
PersonalityCard( AnimatedCrossFade(
user: user, duration: const Duration(milliseconds: 1000),
sizeCurve: Curves.easeInToLinear,
firstChild: Screenshot(
controller: screenshotController,
child: PersonalityCard(user: user),
),
secondChild: GestureDetector(
onTap: () => setState(() {
isRevealed = true;
}),
child: const EmptyCard(text: 'Kattints a felfedéshez...'),
),
crossFadeState: isRevealed
? CrossFadeState.showFirst
: CrossFadeState.showSecond,
),
const SizedBox(height: 40),
Center(
child: IconButton(
onPressed: () async {
await sharePersonality();
},
icon: const Icon(
FeatherIcons.share2,
color: Colors.white,
size: 20,
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.white.withOpacity(0.5)),
),
),
), ),
const SizedBox(height: 60), const SizedBox(height: 60),
]); ]);

View File

@ -41,6 +41,7 @@ dependencies:
wtf_sliding_sheet: ^1.0.0 wtf_sliding_sheet: ^1.0.0
package_info_plus: ^4.0.2 package_info_plus: ^4.0.2
dotted_border: ^2.0.0+3 dotted_border: ^2.0.0+3
screenshot: ^2.1.0
dev_dependencies: dev_dependencies:
flutter_lints: ^1.0.0 flutter_lints: ^1.0.0