prasule/lib/views/settings/edit_categories.dart
2024-02-26 22:59:08 +01:00

297 lines
13 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:flex_color_picker/flex_color_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_iconpicker/flutter_iconpicker.dart';
import 'package:prasule/api/category.dart';
import 'package:prasule/api/wallet.dart';
import 'package:prasule/api/wallet_manager.dart';
import 'package:prasule/main.dart';
import 'package:prasule/pw/platformbutton.dart';
import 'package:prasule/pw/platformfield.dart';
import 'package:prasule/pw/platformroute.dart';
import 'package:prasule/util/text_color.dart';
import 'package:prasule/util/utils.dart';
import 'package:prasule/views/settings/settings.dart';
import 'package:prasule/views/setup.dart';
import 'package:shared_preferences/shared_preferences.dart';
/// Allows adding, editing or removing [WalletCategory]s
class EditCategoriesView extends StatefulWidget {
/// Allows adding, editing or removing [WalletCategory]s
const EditCategoriesView({super.key});
@override
State<EditCategoriesView> createState() => _EditCategoriesViewState();
}
class _EditCategoriesViewState extends State<EditCategoriesView> {
Wallet? selectedWallet;
List<Wallet> wallets = [];
@override
void initState() {
super.initState();
loadWallet();
}
Future<void> loadWallet() async {
wallets = await WalletManager.listWallets();
if (wallets.isEmpty && mounted) {
unawaited(
Navigator.of(context)
.pushReplacement(platformRoute((c) => const SetupView())),
);
return;
}
selectedWallet = wallets.first;
logger.i(selectedWallet!.categories);
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: DropdownButton<int>(
value:
(selectedWallet == null) ? -1 : wallets.indexOf(selectedWallet!),
items: [
...wallets.map(
(e) => DropdownMenuItem(
value: wallets.indexOf(
e,
),
child: Text(e.name),
),
),
DropdownMenuItem(
value: -1,
child: Text(AppLocalizations.of(context).newWallet),
),
],
onChanged: (v) async {
if (v == null || v == -1) {
await Navigator.of(context).push(
platformRoute(
(c) => const SetupView(
newWallet: true,
),
),
);
wallets = await WalletManager.listWallets();
logger.i(wallets.length);
selectedWallet = wallets.last;
setState(() {});
return;
}
selectedWallet = wallets[v];
setState(() {});
},
),
actions: [
PopupMenuButton(
itemBuilder: (context) => [
AppLocalizations.of(context).settings,
AppLocalizations.of(context).about,
].map((e) => PopupMenuItem(value: e, child: Text(e))).toList(),
onSelected: (value) {
if (value == AppLocalizations.of(context).settings) {
Navigator.of(context).push(
platformRoute(
(context) => const SettingsView(),
),
);
} else if (value == AppLocalizations.of(context).about) {
showAbout(context);
}
},
),
],
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: selectedWallet == null
? [const CircularProgressIndicator()]
: [
Text(
AppLocalizations.of(context).setupCategoriesEditHint,
textAlign: TextAlign.center,
),
IconButton(
onPressed: () async {
selectedWallet!.categories.add(
WalletCategory(
name: AppLocalizations.of(context)
.setupWalletNamePlaceholder,
id: selectedWallet!.nextCategoryId,
icon: IconData(
Icons.question_mark.codePoint,
fontFamily: 'MaterialIcons',
),
color: Colors.blueGrey.harmonizeWith(
Theme.of(context).colorScheme.primary,
),
),
);
await WalletManager.saveWallet(selectedWallet!);
setState(() {});
},
icon: const Icon(Icons.add),
),
SizedBox(
height: MediaQuery.of(context).size.height * 0.64,
child: ListView.builder(
shrinkWrap: true,
itemBuilder: (context, i) => (i == 0)
? const SizedBox()
: ListTile(
leading: GestureDetector(
onTap: () async {
final icon = await showIconPicker(
context,
iconPackModes: [
if (!Platform.isIOS && !Platform.isMacOS)
IconPack.material,
if (Platform.isIOS || Platform.isMacOS)
IconPack.cupertino,
],
// adaptiveDialog: true,
);
if (icon != null) {
selectedWallet!.categories[i].icon = icon;
}
final materialEnabled =
(await SharedPreferences.getInstance())
.getBool("useMaterialYou") ??
false;
if (!context.mounted) return;
await showAdaptiveDialog<void>(
context: context,
builder: (c) => AlertDialog.adaptive(
actions: [
PlatformButton(
text: AppLocalizations.of(context).done,
onPressed: () {
Navigator.of(c).pop();
},
),
],
title: Text(
AppLocalizations.of(context).pickColor,
),
content: Column(
children: [
ColorPicker(
pickersEnabled: {
ColorPickerType.wheel: true,
ColorPickerType.primary: false,
ColorPickerType.custom: false,
ColorPickerType.bw: false,
ColorPickerType.accent:
materialEnabled,
},
color: selectedWallet!
.categories[i].color,
onColorChanged: (color) {
selectedWallet!
.categories[i].color = color;
setState(() {});
},
),
],
),
),
);
await WalletManager.saveWallet(selectedWallet!);
setState(() {});
},
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
color: selectedWallet!.categories[i].color,
),
child: Padding(
padding: const EdgeInsets.all(8),
child: Icon(
selectedWallet!.categories[i].icon,
color: selectedWallet!.categories[i].color
.calculateTextColor(),
),
),
),
),
trailing: IconButton(
icon: const Icon(Icons.cancel),
onPressed: () async {
await selectedWallet!.removeCategory(
selectedWallet!.categories[i],
);
setState(() {});
},
),
title: GestureDetector(
onTap: () {
final controller = TextEditingController(
text: selectedWallet!.categories[i].name,
);
showAdaptiveDialog<void>(
context: context,
builder: (c) => AlertDialog.adaptive(
actions: [
TextButton(
onPressed: () async {
if (controller.text.isEmpty) return;
selectedWallet!.categories[i].name =
controller.text;
await WalletManager.saveWallet(
selectedWallet!,
);
if (!context.mounted) return;
Navigator.of(context).pop();
},
child: Text(
AppLocalizations.of(context).ok,
),
),
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text(
AppLocalizations.of(context).cancel,
),
),
],
title: Text(
AppLocalizations.of(context)
.setupCategoriesEditingName,
),
content: SizedBox(
width: 400,
child:
PlatformField(controller: controller),
),
),
);
},
child: Text(
selectedWallet!.categories[i].name,
style: const TextStyle(
fontWeight: FontWeight.bold,
),
),
),
),
itemCount: selectedWallet!.categories.length,
),
),
],
),
);
}
}