feat(meta): Cleanup
This commit is contained in:
129
lib/src/ui/widgets/dropdown.dart
Normal file
129
lib/src/ui/widgets/dropdown.dart
Normal file
@@ -0,0 +1,129 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SelectorItem<T> {
|
||||
const SelectorItem(this.value, this.text);
|
||||
|
||||
final T value;
|
||||
|
||||
final String text;
|
||||
}
|
||||
|
||||
class DropdownSelector<T> extends StatefulWidget {
|
||||
const DropdownSelector({
|
||||
required this.title,
|
||||
required this.onChanged,
|
||||
required this.values,
|
||||
required this.initialValue,
|
||||
super.key,
|
||||
});
|
||||
|
||||
/// The title of the dropdown
|
||||
final String title;
|
||||
|
||||
final List<SelectorItem<T>> values;
|
||||
|
||||
final T initialValue;
|
||||
|
||||
/// Called when the selection has changed
|
||||
final void Function(T) onChanged;
|
||||
|
||||
@override
|
||||
DropdownSelectorState<T> createState() => DropdownSelectorState<T>();
|
||||
}
|
||||
|
||||
class DropdownSelectorDialog<T> extends StatelessWidget {
|
||||
const DropdownSelectorDialog({
|
||||
required this.values,
|
||||
super.key,
|
||||
});
|
||||
|
||||
final List<SelectorItem<T>> values;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SafeArea(
|
||||
child: Material(
|
||||
color: Theme.of(context).scaffoldBackgroundColor,
|
||||
child: ListView.builder(
|
||||
itemCount: values.length,
|
||||
itemBuilder: (context, index) => InkWell(
|
||||
onTap: () {
|
||||
Navigator.of(context).pop(values[index].value);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(
|
||||
values[index].text,
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class DropdownSelectorState<T> extends State<DropdownSelector<T>> {
|
||||
late int index;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
index = widget.values.indexWhere((item) => item.value == widget.initialValue);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Card(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
final result = await showDialog<T>(
|
||||
context: context,
|
||||
builder: (context) => DropdownSelectorDialog<T>(
|
||||
values: widget.values.cast<SelectorItem<T>>(),
|
||||
),
|
||||
);
|
||||
|
||||
if (result == null) return;
|
||||
if (result == widget.values[index].value) return;
|
||||
|
||||
setState(() {
|
||||
index = widget.values.indexWhere((item) => item.value == result);
|
||||
});
|
||||
|
||||
widget.onChanged(result);
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
widget.title,
|
||||
style: Theme.of(context).textTheme.titleSmall,
|
||||
),
|
||||
Text(
|
||||
widget.values[index].text,
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ class AnimeCoverImage extends StatelessWidget {
|
||||
/// The URL to the cover image.
|
||||
final String url;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:anitrack/src/data/anime.dart';
|
||||
import 'package:anitrack/src/ui/widgets/image.dart';
|
||||
import 'package:anitrack/src/ui/widgets/swipe_icon.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -6,7 +5,7 @@ import 'package:swipeable_tile/swipeable_tile.dart';
|
||||
|
||||
/// A widget for displaying simple data about an anime in the listview
|
||||
class ListItem extends StatelessWidget {
|
||||
ListItem({
|
||||
const ListItem({
|
||||
required this.thumbnailUrl,
|
||||
required this.title,
|
||||
this.onLeftSwipe,
|
||||
@@ -42,14 +41,14 @@ class ListItem extends StatelessWidget {
|
||||
key: UniqueKey(),
|
||||
backgroundBuilder: (_, direction, __) {
|
||||
if (direction == SwipeDirection.endToStart) {
|
||||
return Align(
|
||||
return const Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: SwipeIcon(
|
||||
Icons.add,
|
||||
),
|
||||
);
|
||||
} else if (direction == SwipeDirection.startToEnd) {
|
||||
return Align(
|
||||
return const Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: SwipeIcon(
|
||||
Icons.remove,
|
||||
|
||||
Reference in New Issue
Block a user