aves/lib/widgets/common/app_bar/quick_choosers/rate_chooser.dart
Thibault Deckers 9fcebd26f6 #406 quick rate
2022-11-29 12:03:18 +01:00

93 lines
2.6 KiB
Dart

import 'dart:async';
import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/dialogs/aves_dialog.dart';
import 'package:flutter/material.dart';
class RateQuickChooser extends StatefulWidget {
final ValueNotifier<int?> ratingNotifier;
final Stream<LongPressMoveUpdateDetails> moveUpdates;
const RateQuickChooser({
super.key,
required this.ratingNotifier,
required this.moveUpdates,
});
@override
State<RateQuickChooser> createState() => _RateQuickChooserState();
}
class _RateQuickChooserState extends State<RateQuickChooser> {
final List<StreamSubscription> _subscriptions = [];
@override
void initState() {
super.initState();
_registerWidget(widget);
}
@override
void didUpdateWidget(covariant RateQuickChooser oldWidget) {
super.didUpdateWidget(oldWidget);
_unregisterWidget(oldWidget);
_registerWidget(widget);
}
@override
void dispose() {
_unregisterWidget(widget);
super.dispose();
}
void _registerWidget(RateQuickChooser widget) {
_subscriptions.add(widget.moveUpdates.map((event) => event.globalPosition).listen(_onPointerMove));
}
void _unregisterWidget(RateQuickChooser widget) {
_subscriptions
..forEach((sub) => sub.cancel())
..clear();
}
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8),
child: Material(
shape: AvesDialog.shape(context),
child: Padding(
padding: const EdgeInsets.all(8),
child: ValueListenableBuilder<int?>(
valueListenable: widget.ratingNotifier,
builder: (context, rating, child) {
final _rating = rating ?? 0;
return Row(
mainAxisSize: MainAxisSize.min,
children: [
...List.generate(5, (i) {
final thisRating = i + 1;
return Padding(
padding: const EdgeInsets.all(4),
child: Icon(
_rating < thisRating ? AIcons.rating : AIcons.ratingFull,
color: _rating < thisRating ? Colors.grey : Colors.amber,
),
);
})
],
);
},
),
),
),
);
}
void _onPointerMove(Offset globalPosition) {
final rowBox = context.findRenderObject() as RenderBox;
final rowSize = rowBox.size;
final local = rowBox.globalToLocal(globalPosition);
widget.ratingNotifier.value = (5 * local.dx / rowSize.width).ceil().clamp(0, 5);
}
}