2023-02-23 14:49:14 +00:00
|
|
|
import 'package:easy_localization/easy_localization.dart';
|
2022-05-16 22:41:00 +00:00
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
|
|
|
import 'package:ionicons/ionicons.dart';
|
2022-08-30 03:09:09 +00:00
|
|
|
import 'package:selfprivacy/logic/cubit/client_jobs/client_jobs_cubit.dart';
|
2022-05-16 22:41:00 +00:00
|
|
|
import 'package:selfprivacy/ui/components/jobs_content/jobs_content.dart';
|
|
|
|
|
|
|
|
class BrandFab extends StatefulWidget {
|
2023-02-23 14:49:14 +00:00
|
|
|
const BrandFab({
|
|
|
|
this.extended = false,
|
|
|
|
super.key,
|
|
|
|
});
|
|
|
|
|
|
|
|
final bool extended;
|
2022-05-16 22:41:00 +00:00
|
|
|
|
|
|
|
@override
|
2022-05-25 12:21:56 +00:00
|
|
|
State<BrandFab> createState() => _BrandFabState();
|
2022-05-16 22:41:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
class _BrandFabState extends State<BrandFab>
|
|
|
|
with SingleTickerProviderStateMixin {
|
|
|
|
late AnimationController _animationController;
|
|
|
|
late Animation _colorTween;
|
|
|
|
|
|
|
|
@override
|
|
|
|
void initState() {
|
2022-05-24 18:55:39 +00:00
|
|
|
_animationController = AnimationController(
|
2022-06-05 22:40:34 +00:00
|
|
|
vsync: this,
|
|
|
|
duration: const Duration(milliseconds: 800),
|
|
|
|
);
|
2022-05-16 22:41:00 +00:00
|
|
|
super.initState();
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
_animationController.dispose();
|
|
|
|
super.dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool wasPrevStateIsEmpty = true;
|
|
|
|
|
|
|
|
@override
|
2022-06-05 19:36:32 +00:00
|
|
|
Widget build(final BuildContext context) {
|
|
|
|
_colorTween = ColorTween(
|
|
|
|
begin: Theme.of(context).colorScheme.onPrimaryContainer,
|
|
|
|
end: Theme.of(context).colorScheme.primary,
|
|
|
|
).animate(_animationController);
|
|
|
|
|
2022-05-16 22:41:00 +00:00
|
|
|
return BlocListener<JobsCubit, JobsState>(
|
2022-06-05 19:36:32 +00:00
|
|
|
listener: (final BuildContext context, final JobsState state) {
|
2022-05-16 22:41:00 +00:00
|
|
|
if (wasPrevStateIsEmpty && state is! JobsStateEmpty) {
|
|
|
|
wasPrevStateIsEmpty = false;
|
|
|
|
_animationController.forward();
|
|
|
|
} else if (!wasPrevStateIsEmpty && state is JobsStateEmpty) {
|
|
|
|
wasPrevStateIsEmpty = true;
|
|
|
|
|
|
|
|
_animationController.reverse();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
child: FloatingActionButton(
|
|
|
|
onPressed: () {
|
2022-09-14 15:14:55 +00:00
|
|
|
// TODO: Make a hero animation to the screen
|
2023-03-31 14:17:22 +00:00
|
|
|
showModalBottomSheet(
|
2022-05-16 22:41:00 +00:00
|
|
|
context: context,
|
2023-06-29 09:53:13 +00:00
|
|
|
useRootNavigator: true,
|
|
|
|
isScrollControlled: true,
|
|
|
|
builder: (final BuildContext context) => DraggableScrollableSheet(
|
|
|
|
expand: false,
|
|
|
|
maxChildSize: 0.9,
|
|
|
|
minChildSize: 0.4,
|
|
|
|
initialChildSize: 0.6,
|
|
|
|
builder: (final context, final scrollController) =>
|
|
|
|
JobsContent(controller: scrollController),
|
|
|
|
),
|
2022-05-16 22:41:00 +00:00
|
|
|
);
|
|
|
|
},
|
2023-02-23 14:49:14 +00:00
|
|
|
isExtended: widget.extended,
|
|
|
|
child: Row(
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
children: [
|
|
|
|
AnimatedBuilder(
|
|
|
|
animation: _colorTween,
|
|
|
|
builder: (final BuildContext context, final Widget? child) {
|
|
|
|
final double v = _animationController.value;
|
|
|
|
final IconData icon =
|
|
|
|
v > 0.5 ? Ionicons.flash : Ionicons.flash_outline;
|
|
|
|
return Transform.scale(
|
|
|
|
scale: 1 + (v < 0.5 ? v : 1 - v) * 2,
|
|
|
|
child: Icon(
|
|
|
|
icon,
|
|
|
|
color: _colorTween.value,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
if (widget.extended)
|
|
|
|
const SizedBox(
|
|
|
|
width: 8,
|
|
|
|
),
|
|
|
|
if (widget.extended)
|
|
|
|
Text(
|
|
|
|
'jobs.title'.tr(),
|
2022-06-05 22:40:34 +00:00
|
|
|
),
|
2023-02-23 14:49:14 +00:00
|
|
|
],
|
2022-06-05 22:40:34 +00:00
|
|
|
),
|
2022-05-16 22:41:00 +00:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|