fix: make edit_categories actually edit categories
Also make sure home loads the wallet again after exiting settings. Also removed 'type' from Category, because I don't know what it was supposed to do there.
This commit is contained in:
parent
480c4e2538
commit
238caf9203
13 changed files with 275 additions and 216 deletions
|
@ -1,6 +1,7 @@
|
|||
# 1.0.0-alpha+3
|
||||
- Add settings view for editing wallet categories
|
||||
- Change code according to more aggressive linting
|
||||
- Create a default "no category" category, mainly to store entries with removed categories
|
||||
# 1.0.0-alpha+2
|
||||
- Fixed localization issues
|
||||
- Added graphs for expenses and income per month/year
|
||||
|
|
|
@ -9,19 +9,14 @@ class WalletCategory {
|
|||
/// Represents a category in a user's wallet
|
||||
WalletCategory({
|
||||
required this.name,
|
||||
required this.type,
|
||||
required this.id,
|
||||
required this.icon,
|
||||
});
|
||||
|
||||
/// Connect the generated [_$WalletEntry] function to the `fromJson`
|
||||
/// factory.
|
||||
/// Connects generated fromJson method
|
||||
factory WalletCategory.fromJson(Map<String, dynamic> json) =>
|
||||
_$WalletCategoryFromJson(json);
|
||||
|
||||
/// Expense or income
|
||||
final EntryType type;
|
||||
|
||||
/// User-defined name
|
||||
String name;
|
||||
|
||||
|
@ -32,7 +27,7 @@ class WalletCategory {
|
|||
@JsonKey(fromJson: _iconDataFromJson, toJson: _iconDataToJson)
|
||||
IconData icon;
|
||||
|
||||
/// Connect the generated [_$PersonToJson] function to the `toJson` method.
|
||||
/// Connects generated toJson method
|
||||
Map<String, dynamic> toJson() => _$WalletCategoryToJson(this);
|
||||
|
||||
@override
|
||||
|
|
|
@ -9,20 +9,13 @@ part of 'category.dart';
|
|||
WalletCategory _$WalletCategoryFromJson(Map<String, dynamic> json) =>
|
||||
WalletCategory(
|
||||
name: json['name'] as String,
|
||||
type: $enumDecode(_$EntryTypeEnumMap, json['type']),
|
||||
id: json['id'] as int,
|
||||
icon: _iconDataFromJson(json['icon'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$WalletCategoryToJson(WalletCategory instance) =>
|
||||
<String, dynamic>{
|
||||
'type': _$EntryTypeEnumMap[instance.type]!,
|
||||
'name': instance.name,
|
||||
'id': instance.id,
|
||||
'icon': _iconDataToJson(instance.icon),
|
||||
};
|
||||
|
||||
const _$EntryTypeEnumMap = {
|
||||
EntryType.expense: 'expense',
|
||||
EntryType.income: 'income',
|
||||
};
|
||||
|
|
|
@ -7,7 +7,7 @@ class EntryData {
|
|||
/// Contains raw data
|
||||
EntryData({required this.name, required this.amount, this.description = ""});
|
||||
|
||||
/// Connects generated fromJson function
|
||||
/// Connects generated fromJson method
|
||||
factory EntryData.fromJson(Map<String, dynamic> json) =>
|
||||
_$EntryDataFromJson(json);
|
||||
|
||||
|
@ -20,6 +20,6 @@ class EntryData {
|
|||
/// Amount for entry
|
||||
double amount;
|
||||
|
||||
/// Connects generated toJson function
|
||||
/// Connects generated toJson method
|
||||
Map<String, dynamic> toJson() => _$EntryDataToJson(this);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'package:currency_picker/currency_picker.dart';
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:prasule/api/category.dart';
|
||||
import 'package:prasule/api/walletentry.dart';
|
||||
import 'package:prasule/api/walletmanager.dart';
|
||||
part 'wallet.g.dart';
|
||||
|
||||
Currency _currencyFromJson(Map<String, dynamic> data) =>
|
||||
|
@ -13,14 +14,15 @@ Currency _currencyFromJson(Map<String, dynamic> data) =>
|
|||
@JsonSerializable()
|
||||
class Wallet {
|
||||
/// A wallet stores [WalletSingleEntry]s categorized under [WalletCategory]s
|
||||
Wallet(
|
||||
{required this.name,
|
||||
required this.currency,
|
||||
this.categories = const [],
|
||||
this.entries = const [],
|
||||
this.starterBalance = 0,});
|
||||
Wallet({
|
||||
required this.name,
|
||||
required this.currency,
|
||||
this.categories = const [],
|
||||
this.entries = const [],
|
||||
this.starterBalance = 0,
|
||||
});
|
||||
|
||||
/// Connects generated fromJson function
|
||||
/// Connects generated fromJson method
|
||||
factory Wallet.fromJson(Map<String, dynamic> json) => _$WalletFromJson(json);
|
||||
|
||||
/// Name of the wallet
|
||||
|
@ -41,10 +43,10 @@ class Wallet {
|
|||
@JsonKey(fromJson: _currencyFromJson)
|
||||
final Currency currency;
|
||||
|
||||
/// Connects generated toJson function
|
||||
/// Connects generated toJson method
|
||||
Map<String, dynamic> toJson() => _$WalletToJson(this);
|
||||
|
||||
/// Getter for the next unused unique number ID in the wallet's entry list
|
||||
/// Getter for the next unused unique number ID in the wallet's **entry** list
|
||||
int get nextId {
|
||||
var id = 1;
|
||||
while (entries.where((element) => element.id == id).isNotEmpty) {
|
||||
|
@ -53,6 +55,33 @@ class Wallet {
|
|||
return id;
|
||||
}
|
||||
|
||||
/// Getter for the next unused unique number ID in the wallet's **category**
|
||||
/// list
|
||||
int get nextCategoryId {
|
||||
var id = 0;
|
||||
while (categories.where((element) => element.id == id).isNotEmpty) {
|
||||
id++; // create unique ID
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/// Removes the specified category.
|
||||
///
|
||||
/// All [WalletSingleEntry]s will have their category reassigned
|
||||
/// to the default *No category*
|
||||
Future<void> removeCategory(WalletCategory category) async {
|
||||
// First remove the category from existing entries
|
||||
for (final entryToChange
|
||||
in entries.where((element) => element.category.id == category.id)) {
|
||||
entryToChange.category =
|
||||
categories.where((element) => element.id == 0).first;
|
||||
}
|
||||
// Remove the category
|
||||
categories.removeWhere((element) => element.id == category.id);
|
||||
// Save
|
||||
await WalletManager.saveWallet(this);
|
||||
}
|
||||
|
||||
/// Empty wallet used for placeholders
|
||||
static final Wallet empty = Wallet(
|
||||
name: "Empty",
|
||||
|
|
|
@ -9,14 +9,15 @@ part 'walletentry.g.dart';
|
|||
/// This is an entry containing a single item
|
||||
class WalletSingleEntry {
|
||||
/// This is an entry containing a single item
|
||||
WalletSingleEntry(
|
||||
{required this.data,
|
||||
required this.type,
|
||||
required this.date,
|
||||
required this.category,
|
||||
required this.id,});
|
||||
WalletSingleEntry({
|
||||
required this.data,
|
||||
required this.type,
|
||||
required this.date,
|
||||
required this.category,
|
||||
required this.id,
|
||||
});
|
||||
|
||||
/// Connects generated fromJson function
|
||||
/// Connects generated fromJson method
|
||||
factory WalletSingleEntry.fromJson(Map<String, dynamic> json) =>
|
||||
_$WalletSingleEntryFromJson(json);
|
||||
|
||||
|
@ -35,6 +36,6 @@ class WalletSingleEntry {
|
|||
/// Unique entry ID
|
||||
int id;
|
||||
|
||||
/// Connects generated toJson function
|
||||
/// Connects generated toJson method
|
||||
Map<String, dynamic> toJson() => _$WalletSingleEntryToJson(this);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,6 @@ class WalletManager {
|
|||
}
|
||||
// if (!wallet.existsSync()) return false;
|
||||
wallet.writeAsStringSync(jsonEncode(w.toJson()));
|
||||
logger.i(wallet.existsSync());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,6 +76,8 @@
|
|||
"enableYou":"Povolit Material You (Může vyžadovat restart aplikace)",
|
||||
"enableYouDesc":"Aplikace použije barevné schéma z vaší tapety",
|
||||
"editCategories":"Upravit kategorie",
|
||||
"editCategoriesDesc":"Přidat, upravit nebo odebrat kategorii z peněženky"
|
||||
"editCategoriesDesc":"Přidat, upravit nebo odebrat kategorii z peněženky",
|
||||
"wallet":"Peněženka",
|
||||
"noCategory":"Žádná kategorie"
|
||||
|
||||
}
|
|
@ -156,5 +156,7 @@
|
|||
"enableYou":"Enable Material You (May require an app restart)",
|
||||
"enableYouDesc":"The app will use a color scheme from your wallpaper",
|
||||
"editCategories":"Edit categories",
|
||||
"editCategoriesDesc":"Add, edit or remove categories from a wallet"
|
||||
"editCategoriesDesc":"Add, edit or remove categories from a wallet",
|
||||
"wallet":"Wallet",
|
||||
"noCategory":"No category"
|
||||
}
|
|
@ -198,11 +198,16 @@ class _HomeViewState extends State<HomeView> {
|
|||
].map((e) => PopupMenuItem(value: e, child: Text(e))).toList(),
|
||||
onSelected: (value) {
|
||||
if (value == AppLocalizations.of(context).settings) {
|
||||
Navigator.of(context).push(
|
||||
Navigator.of(context)
|
||||
.push(
|
||||
platformRoute(
|
||||
(context) => const SettingsView(),
|
||||
),
|
||||
);
|
||||
)
|
||||
.then((value) async {
|
||||
selectedWallet =
|
||||
await WalletManager.loadWallet(selectedWallet!.name);
|
||||
});
|
||||
} else if (value == AppLocalizations.of(context).about) {
|
||||
showAboutDialog(
|
||||
context: context,
|
||||
|
|
|
@ -27,7 +27,6 @@ class EditCategoriesView extends StatefulWidget {
|
|||
class _EditCategoriesViewState extends State<EditCategoriesView> {
|
||||
Wallet? selectedWallet;
|
||||
List<Wallet> wallets = [];
|
||||
List<WalletCategory> categories = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
@ -45,7 +44,7 @@ class _EditCategoriesViewState extends State<EditCategoriesView> {
|
|||
return;
|
||||
}
|
||||
selectedWallet = wallets.first;
|
||||
categories = selectedWallet!.categories;
|
||||
logger.i(selectedWallet!.categories);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
|
@ -115,109 +114,130 @@ class _EditCategoriesViewState extends State<EditCategoriesView> {
|
|||
),
|
||||
body: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
AppLocalizations.of(context).setupCategoriesEditHint,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
SizedBox(
|
||||
height: MediaQuery.of(context).size.height * 0.64,
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (context, i) => ListTile(
|
||||
leading: GestureDetector(
|
||||
onTap: () async {
|
||||
final icon =
|
||||
await FlutterIconPicker.showIconPicker(context);
|
||||
if (icon == null) return;
|
||||
categories[i].icon = icon;
|
||||
setState(() {});
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Icon(
|
||||
categories[i].icon,
|
||||
color: Theme.of(context).colorScheme.onSecondary,
|
||||
),
|
||||
),
|
||||
children: selectedWallet == null
|
||||
? [const CircularProgressIndicator()]
|
||||
: [
|
||||
Text(
|
||||
AppLocalizations.of(context).setupCategoriesEditHint,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
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 FlutterIconPicker.showIconPicker(
|
||||
context,
|
||||
);
|
||||
if (icon == null) return;
|
||||
selectedWallet!.categories[i].icon = icon;
|
||||
await WalletManager.saveWallet(selectedWallet!);
|
||||
setState(() {});
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color:
|
||||
Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Icon(
|
||||
selectedWallet!.categories[i].icon,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSecondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
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,
|
||||
);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (c) => PlatformDialog(
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
if (controller.text.isEmpty) return;
|
||||
selectedWallet!.categories[i].name =
|
||||
controller.text;
|
||||
await WalletManager.saveWallet(
|
||||
selectedWallet!,
|
||||
);
|
||||
if (!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: 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,
|
||||
),
|
||||
),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.cancel),
|
||||
onPressed: () {
|
||||
categories.removeAt(i);
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
title: GestureDetector(
|
||||
onTap: () {
|
||||
final controller =
|
||||
TextEditingController(text: categories[i].name);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (c) => PlatformDialog(
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
if (controller.text.isEmpty) return;
|
||||
categories[i].name = controller.text;
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(AppLocalizations.of(context).ok),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(AppLocalizations.of(context).cancel),
|
||||
),
|
||||
],
|
||||
title: AppLocalizations.of(context)
|
||||
.setupCategoriesEditingName,
|
||||
content: SizedBox(
|
||||
width: 400,
|
||||
child: PlatformField(controller: controller),
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
selectedWallet!.categories.add(
|
||||
WalletCategory(
|
||||
name: AppLocalizations.of(context)
|
||||
.setupWalletNamePlaceholder,
|
||||
id: selectedWallet!.nextCategoryId,
|
||||
icon: IconData(
|
||||
Icons.question_mark.codePoint,
|
||||
fontFamily: 'MaterialIcons',
|
||||
),
|
||||
),
|
||||
);
|
||||
await WalletManager.saveWallet(selectedWallet!);
|
||||
setState(() {});
|
||||
},
|
||||
child: Text(
|
||||
categories[i].name,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
icon: const Icon(Icons.add),
|
||||
),
|
||||
),
|
||||
itemCount: categories.length,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
var id = 1;
|
||||
while (
|
||||
categories.where((element) => element.id == id).isNotEmpty) {
|
||||
id++; // create unique ID
|
||||
}
|
||||
categories.add(
|
||||
WalletCategory(
|
||||
name: AppLocalizations.of(context).setupWalletNamePlaceholder,
|
||||
type: EntryType.expense,
|
||||
id: id,
|
||||
icon: IconData(
|
||||
Icons.question_mark.codePoint,
|
||||
fontFamily: 'MaterialIcons',
|
||||
),
|
||||
),
|
||||
);
|
||||
setState(() {});
|
||||
},
|
||||
icon: const Icon(Icons.add),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ class _SettingsViewState extends State<SettingsView> {
|
|||
),
|
||||
sections: [
|
||||
SettingsSection(
|
||||
title: Text(AppLocalizations.of(context).wallet),
|
||||
tiles: [
|
||||
SettingsTile.navigation(
|
||||
title: Text(AppLocalizations.of(context).editCategories),
|
||||
|
|
|
@ -51,9 +51,16 @@ class _SetupViewState extends State<SetupView> {
|
|||
super.didChangeDependencies();
|
||||
if (categories.isEmpty) {
|
||||
categories = [
|
||||
WalletCategory(
|
||||
name: AppLocalizations.of(context).noCategory,
|
||||
id: 0,
|
||||
icon: IconData(
|
||||
Icons.payments.codePoint,
|
||||
fontFamily: 'MaterialIcons',
|
||||
),
|
||||
),
|
||||
WalletCategory(
|
||||
name: AppLocalizations.of(context).categoryHealth,
|
||||
type: EntryType.expense,
|
||||
id: 1,
|
||||
icon: IconData(
|
||||
Icons.medical_information.codePoint,
|
||||
|
@ -62,21 +69,18 @@ class _SetupViewState extends State<SetupView> {
|
|||
),
|
||||
WalletCategory(
|
||||
name: AppLocalizations.of(context).categoryCar,
|
||||
type: EntryType.expense,
|
||||
id: 2,
|
||||
icon:
|
||||
IconData(Icons.car_repair.codePoint, fontFamily: 'MaterialIcons'),
|
||||
),
|
||||
WalletCategory(
|
||||
name: AppLocalizations.of(context).categoryFood,
|
||||
type: EntryType.expense,
|
||||
id: 3,
|
||||
icon:
|
||||
IconData(Icons.restaurant.codePoint, fontFamily: 'MaterialIcons'),
|
||||
),
|
||||
WalletCategory(
|
||||
name: AppLocalizations.of(context).categoryTravel,
|
||||
type: EntryType.expense,
|
||||
id: 4,
|
||||
icon: IconData(Icons.train.codePoint, fontFamily: 'MaterialIcons'),
|
||||
),
|
||||
|
@ -269,90 +273,98 @@ class _SetupViewState extends State<SetupView> {
|
|||
height: MediaQuery.of(context).size.height * 0.64,
|
||||
child: ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemBuilder: (context, i) => ListTile(
|
||||
leading: GestureDetector(
|
||||
onTap: () async {
|
||||
final icon =
|
||||
await FlutterIconPicker.showIconPicker(
|
||||
context,
|
||||
);
|
||||
if (icon == null) return;
|
||||
categories[i].icon = icon;
|
||||
setState(() {});
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Icon(
|
||||
categories[i].icon,
|
||||
color:
|
||||
Theme.of(context).colorScheme.onSecondary,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.cancel),
|
||||
onPressed: () {
|
||||
categories.removeAt(i);
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
title: GestureDetector(
|
||||
onTap: () {
|
||||
final controller = TextEditingController(
|
||||
text: categories[i].name,
|
||||
);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (c) => PlatformDialog(
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
if (controller.text.isEmpty) return;
|
||||
categories[i].name = controller.text;
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context).ok,
|
||||
itemBuilder: (context, i) => (i == 0)
|
||||
? const SizedBox()
|
||||
: ListTile(
|
||||
leading: GestureDetector(
|
||||
onTap: () async {
|
||||
final icon =
|
||||
await FlutterIconPicker.showIconPicker(
|
||||
context,
|
||||
);
|
||||
if (icon == null) return;
|
||||
categories[i].icon = icon;
|
||||
setState(() {});
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.secondary,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Icon(
|
||||
categories[i].icon,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSecondary,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context).cancel,
|
||||
),
|
||||
),
|
||||
],
|
||||
title: AppLocalizations.of(context)
|
||||
.setupCategoriesEditingName,
|
||||
content: SizedBox(
|
||||
width: 400,
|
||||
child:
|
||||
PlatformField(controller: controller),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
categories[i].name,
|
||||
style:
|
||||
const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
trailing: IconButton(
|
||||
icon: const Icon(Icons.cancel),
|
||||
onPressed: () {
|
||||
categories.removeAt(i);
|
||||
setState(() {});
|
||||
},
|
||||
),
|
||||
title: GestureDetector(
|
||||
onTap: () {
|
||||
final controller = TextEditingController(
|
||||
text: categories[i].name,
|
||||
);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (c) => PlatformDialog(
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
if (controller.text.isEmpty)
|
||||
return;
|
||||
categories[i].name =
|
||||
controller.text;
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context).ok,
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: Text(
|
||||
AppLocalizations.of(context)
|
||||
.cancel,
|
||||
),
|
||||
),
|
||||
],
|
||||
title: AppLocalizations.of(context)
|
||||
.setupCategoriesEditingName,
|
||||
content: SizedBox(
|
||||
width: 400,
|
||||
child: PlatformField(
|
||||
controller: controller),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
categories[i].name,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
),
|
||||
itemCount: categories.length,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
var id = 1;
|
||||
var id = 0;
|
||||
while (categories
|
||||
.where((element) => element.id == id)
|
||||
.isNotEmpty) {
|
||||
|
@ -362,7 +374,6 @@ class _SetupViewState extends State<SetupView> {
|
|||
WalletCategory(
|
||||
name: AppLocalizations.of(context)
|
||||
.setupWalletNamePlaceholder,
|
||||
type: EntryType.expense,
|
||||
id: id,
|
||||
icon: IconData(
|
||||
Icons.question_mark.codePoint,
|
||||
|
|
Loading…
Reference in a new issue