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 createState() => _EditCategoriesViewState(); } class _EditCategoriesViewState extends State { Wallet? selectedWallet; List wallets = []; @override void initState() { super.initState(); loadWallet(); } Future 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( 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( 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( 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, ), ), ], ), ); } }