Compare commits

..

1 commit

Author SHA1 Message Date
23fabfc529 fix(deps): update dependency fl_chart to ^0.68.0 2024-06-14 14:12:06 +02:00
60 changed files with 248 additions and 765 deletions

@ -1 +1 @@
Subproject commit 2feea7a4071e25c1e3aac9c17016531bc4442f2a Subproject commit 312b9e81e93663b38f8e58d540be860fc75372b9

View file

@ -1,7 +1,3 @@
# newVersion
- Upgrade dependencies
- Use less `await`s in WalletManager class
# 1.1.1 # 1.1.1
- Removed deprecated code - Removed deprecated code
- Updated dependencies - Updated dependencies

View file

@ -9,9 +9,6 @@
# packages, and plugins designed to encourage good coding practices. # packages, and plugins designed to encourage good coding practices.
include: package:very_good_analysis/analysis_options.yaml include: package:very_good_analysis/analysis_options.yaml
analyzer:
exclude: [/**/*.g.dart]
linter: linter:
# The lint rules applied to this project can be customized in the # The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml` # section below to disable rules from the `package:flutter_lints/flutter.yaml`

View file

@ -52,7 +52,7 @@ android {
// You can update the following values to match your application needs. // You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 34 targetSdkVersion 33
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
} }

View file

@ -1,3 +0,0 @@
SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
SPDX-License-Identifier: AGPL-3.0-only

View file

@ -1,3 +0,0 @@
SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
SPDX-License-Identifier: AGPL-3.0-only

View file

@ -1,3 +0,0 @@
SPDX-FileCopyrightText: (C) 2024 Tesseract-OCR contributors
SPDX-License-Identifier: Apache-2.0

View file

@ -1,3 +0,0 @@
SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
SPDX-License-Identifier: AGPL-3.0-only

View file

@ -1,12 +1,7 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart'; import 'package:integration_test/integration_test.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
import 'package:path_provider/path_provider.dart';
import 'package:prasule/api/category.dart'; import 'package:prasule/api/category.dart';
import 'package:prasule/api/entry_data.dart'; import 'package:prasule/api/entry_data.dart';
import 'package:prasule/api/wallet.dart'; import 'package:prasule/api/wallet.dart';
@ -19,18 +14,15 @@ import 'package:prasule/pw/platformfield.dart';
void main() { void main() {
final logger = Logger(); final logger = Logger();
IntegrationTestWidgetsFlutterBinding.ensureInitialized(); IntegrationTestWidgetsFlutterBinding.ensureInitialized();
setUp(() async {
WalletManager.walletPath =
"${(await getApplicationDocumentsDirectory()).path}/wallets";
});
group("Test classes and API", () { group("Test classes and API", () {
test("Test wallet operations", () async { test("Test wallet operations", () async {
expect( expect(
WalletManager.listWallets().length, (await WalletManager.listWallets()).length,
equals(0), equals(0),
); // check that there are no other wallets ); // check that there are no other wallets
WalletManager.saveWallet(Wallet.empty); await WalletManager.saveWallet(Wallet.empty);
var w = WalletManager.listWallets().firstOrNull; var w = (await WalletManager.listWallets()).firstOrNull;
expect(w, isNotNull); // check that the wallet was successfully saved expect(w, isNotNull); // check that the wallet was successfully saved
expect(w!.categories.length, equals(1)); expect(w!.categories.length, equals(1));
w.categories.add( w.categories.add(
@ -51,8 +43,8 @@ void main() {
id: w.nextId, id: w.nextId,
), ),
); // create test entry ); // create test entry
WalletManager.saveWallet(w); // save again await WalletManager.saveWallet(w); // save again
w = WalletManager.loadWallet(w.name); // try loading manually w = await WalletManager.loadWallet(w.name); // try loading manually
final e = w.entries.where((element) => element.id == testId).firstOrNull; final e = w.entries.where((element) => element.id == testId).firstOrNull;
expect( expect(
e, e,
@ -63,9 +55,9 @@ void main() {
equals(1), equals(1),
); // check that the category exists too ); // check that the category exists too
WalletManager.deleteWallet(w); await WalletManager.deleteWallet(w);
expect( expect(
WalletManager.listWallets().length, (await WalletManager.listWallets()).length,
equals(0), equals(0),
); );
}); });
@ -74,7 +66,7 @@ void main() {
group("Test app functionality:", () { group("Test app functionality:", () {
testWidgets('First-time setup', (WidgetTester tester) async { testWidgets('First-time setup', (WidgetTester tester) async {
// Delete all data // Delete all data
WalletManager.deleteAllData(); await WalletManager.deleteAllData();
// Build our app and trigger a frame. // Build our app and trigger a frame.
await tester.pumpWidget( await tester.pumpWidget(
const MyApp( const MyApp(
@ -121,12 +113,13 @@ void main() {
testWidgets('Test rendering of entries', (WidgetTester tester) async { testWidgets('Test rendering of entries', (WidgetTester tester) async {
// Delete all data // Delete all data
WalletManager.deleteAllData(); await WalletManager.deleteAllData();
expect(WalletManager.listWallets().length, equals(0)); expect((await WalletManager.listWallets()).length, equals(0));
// Create test data // Create test data
Wallet.empty.createTestEntries(); final w = Wallet.empty;
expect(WalletManager.listWallets().length, equals(1)); await w.createTestEntries();
expect((await WalletManager.listWallets()).length, equals(1));
// Build our app and trigger a frame. // Build our app and trigger a frame.
await tester.pumpWidget( await tester.pumpWidget(

View file

@ -465,7 +465,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ARCHS = x86_64; ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
@ -647,7 +647,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = { buildSettings = {
ARCHS = x86_64; ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
@ -672,7 +672,7 @@
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = { buildSettings = {
ARCHS = x86_64; ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
part 'category.g.dart'; part 'category.g.dart';
@ -18,43 +14,25 @@ class WalletCategory {
required this.color, required this.color,
}); });
/// Generates a class instance from a Map /// Connects the generated fromJson method
factory WalletCategory.fromJson(Map<String, dynamic> json) => factory WalletCategory.fromJson(Map<String, dynamic> json) =>
_$WalletCategoryFromJson(json); _$WalletCategoryFromJson(json);
/// Default [WalletCategory] instance for json_serializable
factory WalletCategory.unknown() => WalletCategory(
name: "Unknown",
id: -1,
icon: Icons.question_mark,
color: Colors.green,
);
/// User-defined name /// User-defined name
@JsonKey(defaultValue: "Unknown")
String name; String name;
/// Unique identificator of the category /// Unique identificator of the category
@JsonKey(required: true, disallowNullValue: true)
final int id; final int id;
/// Selected Icon for the category /// Selected Icon for the category
@JsonKey( @JsonKey(fromJson: _iconDataFromJson, toJson: _iconDataToJson)
fromJson: _iconDataFromJson,
toJson: _iconDataToJson,
defaultValue: _defaultIcon,
)
IconData icon; IconData icon;
/// The color that will be displayed with entry /// The color that will be displayed with entry
@JsonKey( @JsonKey(fromJson: _colorFromJson, toJson: _colorToJson)
fromJson: _colorFromJson,
toJson: _colorToJson,
defaultValue: _defaultColor,
)
Color color; Color color;
/// Converts the data in this instance into a Map /// Connects the generated toJson method
Map<String, dynamic> toJson() => _$WalletCategoryToJson(this); Map<String, dynamic> toJson() => _$WalletCategoryToJson(this);
@override @override
@ -80,6 +58,3 @@ enum EntryType {
/// Income /// Income
income income
} }
IconData _defaultIcon() => Icons.question_mark;
Color _defaultColor() => Colors.green;

View file

@ -6,23 +6,13 @@ part of 'category.dart';
// JsonSerializableGenerator // JsonSerializableGenerator
// ************************************************************************** // **************************************************************************
WalletCategory _$WalletCategoryFromJson(Map<String, dynamic> json) { WalletCategory _$WalletCategoryFromJson(Map<String, dynamic> json) =>
$checkKeys( WalletCategory(
json, name: json['name'] as String,
requiredKeys: const ['id'], id: json['id'] as int,
disallowNullValues: const ['id'], icon: _iconDataFromJson(json['icon'] as Map<String, dynamic>),
color: _colorFromJson(json['color'] as int),
); );
return WalletCategory(
name: json['name'] as String? ?? 'Unknown',
id: (json['id'] as num).toInt(),
icon: json['icon'] == null
? _defaultIcon()
: _iconDataFromJson(json['icon'] as Map<String, dynamic>),
color: json['color'] == null
? _defaultColor()
: _colorFromJson((json['color'] as num).toInt()),
);
}
Map<String, dynamic> _$WalletCategoryToJson(WalletCategory instance) => Map<String, dynamic> _$WalletCategoryToJson(WalletCategory instance) =>
<String, dynamic>{ <String, dynamic>{

View file

@ -1,42 +0,0 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:prasule/api/debt_person.dart';
part 'debt_entry.g.dart';
/// Single transaction
///
/// The debt will be split between people who are not in [whoPayed]
@JsonSerializable()
class DebtEntry {
/// Single transaction
///
/// The debt will be split between people who are not in [whoPayed]
DebtEntry({
required this.id,
required this.amount,
required this.name,
required this.whoPayed,
}) : assert(whoPayed.isNotEmpty, "There has to be at least one payer");
/// Generates a class instance from a Map
factory DebtEntry.fromJson(Map<String, dynamic> json) =>
_$DebtEntryFromJson(json);
/// Converts the data in this instance into a Map
Map<String, dynamic> toJson() => _$DebtEntryToJson(this);
/// Unique identifier
@JsonKey(required: true, disallowNullValue: true)
final int id;
/// The payed amount
@JsonKey(defaultValue: 0)
int amount;
/// User-friendly identifier for the transaction
@JsonKey(defaultValue: "Unknown")
String name;
/// List of people who payed
@JsonKey(defaultValue: DebtPerson.unknownPerson)
List<DebtPerson> whoPayed;
}

View file

@ -1,31 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'debt_entry.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
DebtEntry _$DebtEntryFromJson(Map<String, dynamic> json) {
$checkKeys(
json,
requiredKeys: const ['id'],
disallowNullValues: const ['id'],
);
return DebtEntry(
id: (json['id'] as num).toInt(),
amount: (json['amount'] as num?)?.toInt() ?? 0,
name: json['name'] as String? ?? 'Unknown',
whoPayed: (json['whoPayed'] as List<dynamic>?)
?.map((e) => DebtPerson.fromJson(e as Map<String, dynamic>))
.toList() ??
DebtPerson.unknownPerson(),
);
}
Map<String, dynamic> _$DebtEntryToJson(DebtEntry instance) => <String, dynamic>{
'id': instance.id,
'amount': instance.amount,
'name': instance.name,
'whoPayed': instance.whoPayed,
};

View file

@ -1,28 +0,0 @@
import 'package:json_annotation/json_annotation.dart';
part 'debt_person.g.dart';
@JsonSerializable()
/// Represents a single person in a debt scenario
class DebtPerson {
/// Represents a single person in a debt scenario
DebtPerson({required this.id, required this.name});
/// Default [DebtPerson] instance for json_serializable
factory DebtPerson.unknownPerson() => DebtPerson(id: -1, name: "Unknown");
/// Generates a class instance from a Map
factory DebtPerson.fromJson(Map<String, dynamic> json) =>
_$DebtPersonFromJson(json);
/// Converts the data in this instance into a Map
Map<String, dynamic> toJson() => _$DebtPersonToJson(this);
/// Unique identifier
@JsonKey(required: true, disallowNullValue: true)
final int id;
/// Identifier that the user will see
@JsonKey(defaultValue: "Unknown")
String name;
}

View file

@ -1,25 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'debt_person.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
DebtPerson _$DebtPersonFromJson(Map<String, dynamic> json) {
$checkKeys(
json,
requiredKeys: const ['id'],
disallowNullValues: const ['id'],
);
return DebtPerson(
id: (json['id'] as num).toInt(),
name: json['name'] as String? ?? 'Unknown',
);
}
Map<String, dynamic> _$DebtPersonToJson(DebtPerson instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
};

View file

@ -1,46 +0,0 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:prasule/api/debt_entry.dart';
import 'package:prasule/api/debt_person.dart';
part 'debt_scenario.g.dart';
/// A folder for different entries and people
@JsonSerializable()
class DebtScenario {
/// A folder for different entries and people
DebtScenario({
required this.id,
required this.name,
required this.isArchived,
this.entries = const [],
this.people = const [],
});
/// Generates a class instance from a Map
factory DebtScenario.fromJson(Map<String, dynamic> json) =>
_$DebtScenarioFromJson(json);
/// Converts the data in this instance into a Map
Map<String, dynamic> toJson() => _$DebtScenarioToJson(this);
/// Unique identified
@JsonKey(disallowNullValue: true)
final int id;
/// User-friendly identifier
@JsonKey(defaultValue: "Unknown")
String name;
/// Whether this scenario should be shown under archived ones
@JsonKey(defaultValue: false)
bool isArchived;
/// All entries
@JsonKey(defaultValue: [])
List<DebtEntry> entries;
/// All people
@JsonKey(defaultValue: _defaultPeopleList)
List<DebtPerson> people;
}
List<DebtPerson> _defaultPeopleList() => [DebtPerson.unknownPerson()];

View file

@ -1,36 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'debt_scenario.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
DebtScenario _$DebtScenarioFromJson(Map<String, dynamic> json) {
$checkKeys(
json,
disallowNullValues: const ['id'],
);
return DebtScenario(
id: (json['id'] as num).toInt(),
name: json['name'] as String? ?? 'Unknown',
isArchived: json['isArchived'] as bool? ?? false,
entries: (json['entries'] as List<dynamic>?)
?.map((e) => DebtEntry.fromJson(e as Map<String, dynamic>))
.toList() ??
[],
people: (json['people'] as List<dynamic>?)
?.map((e) => DebtPerson.fromJson(e as Map<String, dynamic>))
.toList() ??
_defaultPeopleList(),
);
}
Map<String, dynamic> _$DebtScenarioToJson(DebtScenario instance) =>
<String, dynamic>{
'id': instance.id,
'name': instance.name,
'isArchived': instance.isArchived,
'entries': instance.entries,
'people': instance.people,
};

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
part 'entry_data.g.dart'; part 'entry_data.g.dart';
@ -11,25 +7,19 @@ class EntryData {
/// Contains raw data /// Contains raw data
EntryData({required this.name, required this.amount, this.description = ""}); EntryData({required this.name, required this.amount, this.description = ""});
/// Generates a class instance from a Map /// Connects the generated fromJson method
factory EntryData.fromJson(Map<String, dynamic> json) => factory EntryData.fromJson(Map<String, dynamic> json) =>
_$EntryDataFromJson(json); _$EntryDataFromJson(json);
/// [EntryData] instance used as a default value for json_serializable
factory EntryData.unknown() => EntryData(name: "Unknown", amount: 0);
/// Name of entry /// Name of entry
@JsonKey(defaultValue: "Unknown")
String name; String name;
/// Optional description, default is empty /// Optional description, default is empty
@JsonKey(defaultValue: "")
String description; String description;
/// Amount for entry /// Amount for entry
@JsonKey(defaultValue: 0)
double amount; double amount;
/// Converts the data in this instance into a Map /// Connects the generated toJson method
Map<String, dynamic> toJson() => _$EntryDataToJson(this); Map<String, dynamic> toJson() => _$EntryDataToJson(this);
} }

View file

@ -7,9 +7,9 @@ part of 'entry_data.dart';
// ************************************************************************** // **************************************************************************
EntryData _$EntryDataFromJson(Map<String, dynamic> json) => EntryData( EntryData _$EntryDataFromJson(Map<String, dynamic> json) => EntryData(
name: json['name'] as String? ?? 'Unknown', name: json['name'] as String,
amount: (json['amount'] as num?)?.toDouble() ?? 0, amount: (json['amount'] as num).toDouble(),
description: json['description'] as String? ?? '', description: json['description'] as String? ?? "",
); );
Map<String, dynamic> _$EntryDataToJson(EntryData instance) => <String, dynamic>{ Map<String, dynamic> _$EntryDataToJson(EntryData instance) => <String, dynamic>{

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:prasule/api/category.dart'; import 'package:prasule/api/category.dart';
import 'package:prasule/api/entry_data.dart'; import 'package:prasule/api/entry_data.dart';
@ -24,24 +20,21 @@ class RecurringWalletEntry extends WalletSingleEntry {
this.repeatAfter = 1, this.repeatAfter = 1,
}); });
/// Generates a class instance from a Map /// Connects the generated fromJson method
factory RecurringWalletEntry.fromJson(Map<String, dynamic> json) => factory RecurringWalletEntry.fromJson(Map<String, dynamic> json) =>
_$RecurringWalletEntryFromJson(json); _$RecurringWalletEntryFromJson(json);
/// Converts the data in this instance into a Map /// Connects the generated toJson method
@override @override
Map<String, dynamic> toJson() => _$RecurringWalletEntryToJson(this); Map<String, dynamic> toJson() => _$RecurringWalletEntryToJson(this);
/// Last date the recurring entry was added into the single entry list /// Last date the recurring entry was added into the single entry list
@JsonKey(defaultValue: DateTime.now)
DateTime lastRunDate; DateTime lastRunDate;
/// After how many {recurType} should the entry recur /// After how many {recurType} should the entry recur
@JsonKey(defaultValue: 1)
int repeatAfter; int repeatAfter;
/// What type of recurrence should happen /// What type of recurrence should happen
@JsonKey(defaultValue: RecurType.month)
RecurType recurType; RecurType recurType;
} }

View file

@ -6,33 +6,19 @@ part of 'recurring_entry.dart';
// JsonSerializableGenerator // JsonSerializableGenerator
// ************************************************************************** // **************************************************************************
RecurringWalletEntry _$RecurringWalletEntryFromJson(Map<String, dynamic> json) { RecurringWalletEntry _$RecurringWalletEntryFromJson(
$checkKeys( Map<String, dynamic> json) =>
json, RecurringWalletEntry(
requiredKeys: const ['id'], data: EntryData.fromJson(json['data'] as Map<String, dynamic>),
disallowNullValues: const ['id'], type: $enumDecode(_$EntryTypeEnumMap, json['type']),
date: DateTime.parse(json['date'] as String),
category:
WalletCategory.fromJson(json['category'] as Map<String, dynamic>),
id: json['id'] as int,
lastRunDate: DateTime.parse(json['lastRunDate'] as String),
repeatAfter: json['repeatAfter'] as int,
recurType: $enumDecode(_$RecurTypeEnumMap, json['recurType']),
); );
return RecurringWalletEntry(
data: json['data'] == null
? EntryData.unknown()
: EntryData.fromJson(json['data'] as Map<String, dynamic>),
type: $enumDecodeNullable(_$EntryTypeEnumMap, json['type']) ??
EntryType.expense,
date: json['date'] == null
? DateTime.now()
: DateTime.parse(json['date'] as String),
category: json['category'] == null
? WalletCategory.unknown()
: WalletCategory.fromJson(json['category'] as Map<String, dynamic>),
id: (json['id'] as num).toInt(),
lastRunDate: json['lastRunDate'] == null
? DateTime.now()
: DateTime.parse(json['lastRunDate'] as String),
recurType: $enumDecodeNullable(_$RecurTypeEnumMap, json['recurType']) ??
RecurType.month,
repeatAfter: (json['repeatAfter'] as num?)?.toInt() ?? 1,
);
}
Map<String, dynamic> _$RecurringWalletEntryToJson( Map<String, dynamic> _$RecurringWalletEntryToJson(
RecurringWalletEntry instance) => RecurringWalletEntry instance) =>

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:math'; import 'dart:math';
import 'package:currency_picker/currency_picker.dart'; import 'package:currency_picker/currency_picker.dart';
@ -34,39 +30,31 @@ class Wallet {
this.starterBalance = 0, this.starterBalance = 0,
}); });
/// Generates a class instance from a Map /// Connects the generated fromJson method
factory Wallet.fromJson(Map<String, dynamic> json) => _$WalletFromJson(json); factory Wallet.fromJson(Map<String, dynamic> json) => _$WalletFromJson(json);
/// A list of all [RecurringWalletEntry]s /// A list of all [RecurringWalletEntry]s
@JsonKey(defaultValue: [])
final List<RecurringWalletEntry> recurringEntries; final List<RecurringWalletEntry> recurringEntries;
/// Name of the wallet /// Name of the wallet
@JsonKey(defaultValue: "Unknown")
final String name; final String name;
/// A list of available categories /// A list of available categories
@JsonKey(defaultValue: _defaultWalletCategory)
final List<WalletCategory> categories; final List<WalletCategory> categories;
/// List of saved entries /// List of saved entries
@JsonKey(defaultValue: [])
final List<WalletSingleEntry> entries; final List<WalletSingleEntry> entries;
/// The starting balance of the wallet /// The starting balance of the wallet
/// ///
/// Used to calculate current balance /// Used to calculate current balance
@JsonKey(defaultValue: 0)
double starterBalance; double starterBalance;
/// Selected currency /// Selected currency
@JsonKey( @JsonKey(fromJson: _currencyFromJson)
fromJson: _currencyFromJson,
defaultValue: _defaultCurrency,
)
final Currency currency; final Currency currency;
/// Converts the data in this instance into a Map /// Connects the generated toJson method
Map<String, dynamic> toJson() => _$WalletToJson(this); 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
@ -159,7 +147,7 @@ class Wallet {
/// ///
/// All [WalletSingleEntry]s will have their category reassigned /// All [WalletSingleEntry]s will have their category reassigned
/// to the default *No category* /// to the default *No category*
void removeCategory(WalletCategory category) { Future<void> removeCategory(WalletCategory category) async {
// First remove the category from existing entries // First remove the category from existing entries
for (final entryToChange for (final entryToChange
in entries.where((element) => element.category.id == category.id)) { in entries.where((element) => element.category.id == category.id)) {
@ -169,7 +157,7 @@ class Wallet {
// Remove the category // Remove the category
categories.removeWhere((element) => element.id == category.id); categories.removeWhere((element) => element.id == category.id);
// Save // Save
WalletManager.saveWallet(this); await WalletManager.saveWallet(this);
} }
/// Returns the current balance /// Returns the current balance
@ -228,7 +216,7 @@ class Wallet {
); );
/// Creates test data used for debugging purposes /// Creates test data used for debugging purposes
void createTestEntries() { Future<void> createTestEntries() async {
entries.clear(); entries.clear();
recurringEntries.clear(); recurringEntries.clear();
final random = Random(); final random = Random();
@ -286,23 +274,6 @@ class Wallet {
); );
// save and reload // save and reload
WalletManager.saveWallet(this); await WalletManager.saveWallet(this);
} }
} }
List<WalletCategory> _defaultWalletCategory() => [WalletCategory.unknown()];
Currency _defaultCurrency() => Currency.from(
json: {
"code": "USD",
"name": "United States Dollar",
"symbol": r"$",
"flag": "USD",
"decimal_digits": 2,
"number": 840,
"name_plural": "US dollars",
"thousands_separator": ",",
"decimal_separator": ".",
"space_between_amount_and_symbol": false,
"symbol_on_left": true,
},
);

View file

@ -7,24 +7,22 @@ part of 'wallet.dart';
// ************************************************************************** // **************************************************************************
Wallet _$WalletFromJson(Map<String, dynamic> json) => Wallet( Wallet _$WalletFromJson(Map<String, dynamic> json) => Wallet(
name: json['name'] as String? ?? 'Unknown', name: json['name'] as String,
currency: json['currency'] == null currency: _currencyFromJson(json['currency'] as Map<String, dynamic>),
? _defaultCurrency()
: _currencyFromJson(json['currency'] as Map<String, dynamic>),
categories: (json['categories'] as List<dynamic>?) categories: (json['categories'] as List<dynamic>?)
?.map((e) => WalletCategory.fromJson(e as Map<String, dynamic>)) ?.map((e) => WalletCategory.fromJson(e as Map<String, dynamic>))
.toList() ?? .toList() ??
_defaultWalletCategory(), const [],
entries: (json['entries'] as List<dynamic>?) entries: (json['entries'] as List<dynamic>?)
?.map( ?.map(
(e) => WalletSingleEntry.fromJson(e as Map<String, dynamic>)) (e) => WalletSingleEntry.fromJson(e as Map<String, dynamic>))
.toList() ?? .toList() ??
[], const [],
recurringEntries: (json['recurringEntries'] as List<dynamic>?) recurringEntries: (json['recurringEntries'] as List<dynamic>?)
?.map((e) => ?.map((e) =>
RecurringWalletEntry.fromJson(e as Map<String, dynamic>)) RecurringWalletEntry.fromJson(e as Map<String, dynamic>))
.toList() ?? .toList() ??
[], const [],
starterBalance: (json['starterBalance'] as num?)?.toDouble() ?? 0, starterBalance: (json['starterBalance'] as num?)?.toDouble() ?? 0,
); );

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:prasule/api/category.dart'; import 'package:prasule/api/category.dart';
import 'package:prasule/api/entry_data.dart'; import 'package:prasule/api/entry_data.dart';
@ -21,30 +17,25 @@ class WalletSingleEntry {
required this.id, required this.id,
}); });
/// Generates a class instance from a Map /// Connects the generated fromJson method
factory WalletSingleEntry.fromJson(Map<String, dynamic> json) => factory WalletSingleEntry.fromJson(Map<String, dynamic> json) =>
_$WalletSingleEntryFromJson(json); _$WalletSingleEntryFromJson(json);
/// Expense or income /// Expense or income
@JsonKey(defaultValue: EntryType.expense)
EntryType type; EntryType type;
/// Actual entry data /// Actual entry data
@JsonKey(defaultValue: EntryData.unknown)
EntryData data; EntryData data;
/// Date of entry creation /// Date of entry creation
@JsonKey(defaultValue: DateTime.now)
DateTime date; DateTime date;
/// Selected category /// Selected category
@JsonKey(defaultValue: WalletCategory.unknown)
WalletCategory category; WalletCategory category;
/// Unique entry ID /// Unique entry ID
@JsonKey(required: true, disallowNullValue: true) int id;
final int id;
/// Converts the data in this instance into a Map /// Connects the generated toJson method
Map<String, dynamic> toJson() => _$WalletSingleEntryToJson(this); Map<String, dynamic> toJson() => _$WalletSingleEntryToJson(this);
} }

View file

@ -6,27 +6,15 @@ part of 'wallet_entry.dart';
// JsonSerializableGenerator // JsonSerializableGenerator
// ************************************************************************** // **************************************************************************
WalletSingleEntry _$WalletSingleEntryFromJson(Map<String, dynamic> json) { WalletSingleEntry _$WalletSingleEntryFromJson(Map<String, dynamic> json) =>
$checkKeys( WalletSingleEntry(
json, data: EntryData.fromJson(json['data'] as Map<String, dynamic>),
requiredKeys: const ['id'], type: $enumDecode(_$EntryTypeEnumMap, json['type']),
disallowNullValues: const ['id'], date: DateTime.parse(json['date'] as String),
category:
WalletCategory.fromJson(json['category'] as Map<String, dynamic>),
id: json['id'] as int,
); );
return WalletSingleEntry(
data: json['data'] == null
? EntryData.unknown()
: EntryData.fromJson(json['data'] as Map<String, dynamic>),
type: $enumDecodeNullable(_$EntryTypeEnumMap, json['type']) ??
EntryType.expense,
date: json['date'] == null
? DateTime.now()
: DateTime.parse(json['date'] as String),
category: json['category'] == null
? WalletCategory.unknown()
: WalletCategory.fromJson(json['category'] as Map<String, dynamic>),
id: (json['id'] as num).toInt(),
);
}
Map<String, dynamic> _$WalletSingleEntryToJson(WalletSingleEntry instance) => Map<String, dynamic> _$WalletSingleEntryToJson(WalletSingleEntry instance) =>
<String, dynamic>{ <String, dynamic>{

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
@ -15,28 +11,18 @@ import 'package:prasule/main.dart';
/// Used for [Wallet]-managing operations /// Used for [Wallet]-managing operations
class WalletManager { class WalletManager {
/// Currently selected wallet
static Wallet? selectedWallet;
/// Path to the directory with wallet files
///
/// Saved beforehand so we don't have to use async everywhere
static late String walletPath;
/// Returns a list of all [Wallet]s /// Returns a list of all [Wallet]s
static List<Wallet> listWallets() { static Future<List<Wallet>> listWallets() async {
final path = Directory(walletPath); final path =
Directory("${(await getApplicationDocumentsDirectory()).path}/wallets");
if (!path.existsSync()) { if (!path.existsSync()) {
path.createSync(); path.createSync();
} }
final wallets = <Wallet>[]; final wallets = <Wallet>[];
for (final w in path for (final w
.listSync() in path.listSync().map((e) => e.path.split("/").last).toList()) {
.whereType<File>()
.map((e) => e.path.split("/").last)
.toList()) {
try { try {
wallets.add(loadWallet(w)); wallets.add(await loadWallet(w));
} catch (e) { } catch (e) {
logger.e(e); logger.e(e);
// TODO: do something with unreadable wallets // TODO: do something with unreadable wallets
@ -46,8 +32,9 @@ class WalletManager {
} }
/// Deletes all [Wallet]s /// Deletes all [Wallet]s
static void deleteAllData() { static Future<void> deleteAllData() async {
final path = Directory(walletPath); final path =
Directory("${(await getApplicationDocumentsDirectory()).path}/wallets");
if (!path.existsSync()) { if (!path.existsSync()) {
return; return;
} }
@ -137,10 +124,10 @@ class WalletManager {
d = File(filePath).readAsStringSync(); d = File(filePath).readAsStringSync();
} }
final w = Wallet.fromJson(jsonDecode(d) as Map<String, dynamic>); final w = Wallet.fromJson(jsonDecode(d) as Map<String, dynamic>);
if (WalletManager.exists(w.name)) { if (await WalletManager.exists(w.name)) {
throw Exception("Wallet already exists!"); throw Exception("Wallet already exists!");
} }
WalletManager.saveWallet( await WalletManager.saveWallet(
w, w,
); );
} }
@ -179,14 +166,15 @@ class WalletManager {
} }
/// Loads and returns a single [Wallet] by name /// Loads and returns a single [Wallet] by name
static Wallet loadWallet(String name) { static Future<Wallet> loadWallet(String name) async {
final path = Directory(walletPath); final path =
Directory("${(await getApplicationDocumentsDirectory()).path}/wallets");
final wallet = File("${path.path}/$name"); final wallet = File("${path.path}/$name");
if (!path.existsSync()) { if (!path.existsSync()) {
path.createSync(); path.createSync();
} }
if (!wallet.existsSync()) { if (!wallet.existsSync()) {
throw Exception("Wallet does not exist"); return Future.error("Wallet does not exist");
} }
return Wallet.fromJson( return Wallet.fromJson(
jsonDecode(wallet.readAsStringSync()) as Map<String, dynamic>, jsonDecode(wallet.readAsStringSync()) as Map<String, dynamic>,
@ -194,26 +182,29 @@ class WalletManager {
} }
/// Converts [Wallet] to JSON and saves it to AppData /// Converts [Wallet] to JSON and saves it to AppData
static void saveWallet(Wallet w) { static Future<bool> saveWallet(Wallet w) async {
final path = Directory(walletPath); final path =
Directory("${(await getApplicationDocumentsDirectory()).path}/wallets");
final wallet = File("${path.path}/${w.name}"); final wallet = File("${path.path}/${w.name}");
if (!path.existsSync()) { if (!path.existsSync()) {
path.createSync(); path.createSync();
} }
// if (!wallet.existsSync()) return false; // if (!wallet.existsSync()) return false;
wallet.writeAsStringSync(jsonEncode(w.toJson())); wallet.writeAsStringSync(jsonEncode(w.toJson()));
return true;
} }
/// Deletes the corresponding [Wallet] file /// Deletes the corresponding [Wallet] file
static void deleteWallet(Wallet w) { static Future<void> deleteWallet(Wallet w) async {
final path = Directory(walletPath); final path =
Directory("${(await getApplicationDocumentsDirectory()).path}/wallets");
File("${path.path}/${w.name}").deleteSync(); File("${path.path}/${w.name}").deleteSync();
} }
/// Checks if the wallet exists /// Checks if the wallet exists
static bool exists(String name) { static Future<bool> exists(String name) async {
return File( return File(
"$walletPath/$name", "${(await getApplicationDocumentsDirectory()).path}/wallets/$name",
).existsSync(); ).existsSync();
} }
} }

View file

@ -1,3 +0,0 @@
SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
SPDX-License-Identifier: CC0-1.0

View file

@ -1,3 +0,0 @@
SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
SPDX-License-Identifier: CC0-1.0

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:io'; import 'dart:io';
import 'package:dynamic_color/dynamic_color.dart'; import 'package:dynamic_color/dynamic_color.dart';
@ -11,7 +7,7 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
import 'package:prasule/util/color_schemes.g.dart'; import 'package:prasule/util/color_schemes.g.dart';
import 'package:prasule/views/initialization_screen.dart'; import 'package:prasule/views/home.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
var _materialYou = false; var _materialYou = false;
@ -24,7 +20,6 @@ void main() async {
} }
_materialYou = s.getBool("useMaterialYou") ?? true; _materialYou = s.getBool("useMaterialYou") ?? true;
runApp(const MyApp()); runApp(const MyApp());
} }
@ -44,7 +39,6 @@ class MyApp extends StatelessWidget {
/// Override locale, used for testing /// Override locale, used for testing
final Locale? locale; final Locale? locale;
// This widget is the root of your application. // This widget is the root of your application.
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return (Platform.isAndroid) return (Platform.isAndroid)
@ -72,7 +66,7 @@ class MyApp extends StatelessWidget {
colorScheme: colorScheme:
_materialYou ? dark ?? darkColorScheme : darkColorScheme, _materialYou ? dark ?? darkColorScheme : darkColorScheme,
), ),
home: const InitializationScreen(), home: const HomeView(),
); );
}, },
) )
@ -91,7 +85,7 @@ class MyApp extends StatelessWidget {
...GlobalCupertinoLocalizations.delegates, ...GlobalCupertinoLocalizations.delegates,
], ],
title: 'Prašule', title: 'Prašule',
home: InitializationScreen(), home: HomeView(),
), ),
); );
} }

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:io'; import 'dart:io';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:io'; import 'dart:io';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
// ignore_for_file: public_member_api_docs // ignore_for_file: public_member_api_docs
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:prasule/pw/platformroute.dart'; import 'package:prasule/pw/platformroute.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
/// Extension to get last day of the month /// Extension to get last day of the month
extension LastDay on DateTime { extension LastDay on DateTime {
/// Returns the last day of the month as [int] /// Returns the last day of the month as [int]

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'package:currency_picker/currency_picker.dart'; import 'package:currency_picker/currency_picker.dart';
import 'package:dynamic_color/dynamic_color.dart'; import 'package:dynamic_color/dynamic_color.dart';
import 'package:fl_chart/fl_chart.dart'; import 'package:fl_chart/fl_chart.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'package:grouped_list/grouped_list.dart'; import 'package:grouped_list/grouped_list.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/// Used to add [calculateTextColor] to the [Color] class /// Used to add [calculateTextColor] to the [Color] class

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@ -240,8 +236,9 @@ class _CreateSingleEntryViewState extends State<CreateSingleEntryView> {
return; return;
} }
widget.w.entries.add(newEntry); widget.w.entries.add(newEntry);
WalletManager.saveWallet(widget.w); // TODO loading circle? WalletManager.saveWallet(widget.w).then(
Navigator.of(context).pop(widget.w); (value) => Navigator.of(context).pop(widget.w),
); // TODO loading circle?
}, },
), ),
], ],

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@ -327,8 +323,9 @@ class _CreateRecurringEntryViewState extends State<CreateRecurringEntryView> {
return; return;
} }
widget.w.recurringEntries.add(newEntry); widget.w.recurringEntries.add(newEntry);
WalletManager.saveWallet(widget.w); // TODO loading circle? WalletManager.saveWallet(widget.w).then(
Navigator.of(context).pop(widget.w); (value) => Navigator.of(context).pop(widget.w),
); // TODO loading circle?
}, },
), ),
], ],

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -71,8 +67,8 @@ class _GraphViewState extends State<GraphView> {
final availableYears = <WheelChoice<int>>[]; final availableYears = <WheelChoice<int>>[];
void loadWallet() { Future<void> loadWallet() async {
wallets = WalletManager.listWallets(); wallets = await WalletManager.listWallets();
if (wallets.isEmpty && mounted) { if (wallets.isEmpty && mounted) {
unawaited( unawaited(
Navigator.of(context) Navigator.of(context)
@ -228,7 +224,7 @@ class _GraphViewState extends State<GraphView> {
), ),
), ),
); );
wallets = WalletManager.listWallets(); wallets = await WalletManager.listWallets();
logger.i(wallets.length); logger.i(wallets.length);
selectedWallet = wallets.last; selectedWallet = wallets.last;
setState(() {}); setState(() {});
@ -254,7 +250,7 @@ class _GraphViewState extends State<GraphView> {
) )
.then((value) async { .then((value) async {
selectedWallet = selectedWallet =
WalletManager.loadWallet(selectedWallet!.name); await WalletManager.loadWallet(selectedWallet!.name);
final s = await SharedPreferences.getInstance(); final s = await SharedPreferences.getInstance();
chartType = s.getInt("monthlygraph") ?? 2; chartType = s.getInt("monthlygraph") ?? 2;
setState(() {}); setState(() {});

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:async'; import 'dart:async';
import 'package:dynamic_color/dynamic_color.dart'; import 'package:dynamic_color/dynamic_color.dart';
@ -67,8 +63,8 @@ class _HomeViewState extends State<HomeView> {
loadWallet(); loadWallet();
} }
void loadWallet() { Future<void> loadWallet() async {
wallets = WalletManager.listWallets(); wallets = await WalletManager.listWallets();
if (wallets.isEmpty && mounted) { if (wallets.isEmpty && mounted) {
unawaited( unawaited(
Navigator.of(context) Navigator.of(context)
@ -86,7 +82,7 @@ class _HomeViewState extends State<HomeView> {
return PopScope( return PopScope(
canPop: !_searchActive, // don't pop when we just want canPop: !_searchActive, // don't pop when we just want
// to deactivate searchfield // to deactivate searchfield
onPopInvokedWithResult: (b, d) { onPopInvoked: (b) {
if (b) return; if (b) return;
_searchActive = false; _searchActive = false;
_filter = ""; _filter = "";
@ -109,12 +105,13 @@ class _HomeViewState extends State<HomeView> {
onTap: () { onTap: () {
// debug option to quickly fill a wallet with data // debug option to quickly fill a wallet with data
if (selectedWallet == null) return; if (selectedWallet == null) return;
selectedWallet!.createTestEntries(); selectedWallet!.createTestEntries().then((_) {
Navigator.of(context).pushReplacement( Navigator.of(context).pushReplacement(
platformRoute( platformRoute(
(p0) => const HomeView(), (p0) => const HomeView(),
), ),
); );
});
}, },
), ),
SpeedDialChild( SpeedDialChild(
@ -197,7 +194,7 @@ class _HomeViewState extends State<HomeView> {
), ),
), ),
); );
wallets = WalletManager.listWallets(); wallets = await WalletManager.listWallets();
selectedWallet = wallets.last; selectedWallet = wallets.last;
setState(() {}); setState(() {});
return; return;
@ -251,9 +248,9 @@ class _HomeViewState extends State<HomeView> {
(context) => const SettingsView(), (context) => const SettingsView(),
), ),
) )
.then((value) { .then((value) async {
wallets = WalletManager.listWallets(); wallets = await WalletManager.listWallets();
selectedWallet = WalletManager.loadWallet( selectedWallet = await WalletManager.loadWallet(
selectedWallet!.name, selectedWallet!.name,
); );
setState(() {}); setState(() {});
@ -637,10 +634,7 @@ class _HomeViewState extends State<HomeView> {
(c) => const TessdataListView(), (c) => const TessdataListView(),
), ),
) )
.then((value) { .then((value) => Navigator.of(c).pop());
if (!c.mounted) return;
Navigator.of(c).pop();
});
}, },
), ),
PlatformButton( PlatformButton(
@ -747,7 +741,7 @@ class _HomeViewState extends State<HomeView> {
); );
if (newEntry == null) return; if (newEntry == null) return;
selectedWallet!.entries.add(newEntry); selectedWallet!.entries.add(newEntry);
WalletManager.saveWallet(selectedWallet!); await WalletManager.saveWallet(selectedWallet!);
setState(() {}); setState(() {});
}, },
child: const Text("Ok"), child: const Text("Ok"),

View file

@ -1,47 +0,0 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:prasule/api/wallet_manager.dart';
import 'package:prasule/pw/platformroute.dart';
import 'package:prasule/views/home.dart';
import 'package:prasule/views/setup.dart';
/// Intermediate screen used to initialize variables relying on context
class InitializationScreen extends StatefulWidget {
/// Intermediate screen used to initialize variables relying on context
const InitializationScreen({super.key});
@override
State<InitializationScreen> createState() => _InitializationScreenState();
}
class _InitializationScreenState extends State<InitializationScreen> {
@override
void initState() {
super.initState();
getApplicationDocumentsDirectory().then((v) {
WalletManager.walletPath = "${v.path}/wallets";
if (!mounted) return;
final wallets = WalletManager.listWallets();
if (wallets.isEmpty && mounted) {
Navigator.of(context)
.pushReplacement(platformRoute((c) => const SetupView()));
return;
}
Navigator.of(context)
.pushReplacement(platformRoute((c) => const HomeView()));
});
}
@override
Widget build(BuildContext context) {
return const Scaffold(
body: Align(
child: CircularProgressIndicator(),
),
);
}
}

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -48,8 +44,8 @@ class _RecurringEntriesViewState extends State<RecurringEntriesView> {
loadWallet(); loadWallet();
} }
void loadWallet() { Future<void> loadWallet() async {
wallets = WalletManager.listWallets(); wallets = await WalletManager.listWallets();
if (wallets.isEmpty && mounted) { if (wallets.isEmpty && mounted) {
unawaited( unawaited(
Navigator.of(context) Navigator.of(context)
@ -95,7 +91,7 @@ class _RecurringEntriesViewState extends State<RecurringEntriesView> {
), ),
), ),
); );
wallets = WalletManager.listWallets(); wallets = await WalletManager.listWallets();
selectedWallet = wallets.last; selectedWallet = wallets.last;
setState(() {}); setState(() {});
return; return;
@ -120,7 +116,7 @@ class _RecurringEntriesViewState extends State<RecurringEntriesView> {
) )
.then((value) async { .then((value) async {
selectedWallet = selectedWallet =
WalletManager.loadWallet(selectedWallet!.name); await WalletManager.loadWallet(selectedWallet!.name);
}); });
} else if (value == AppLocalizations.of(context).about) { } else if (value == AppLocalizations.of(context).about) {
showAbout(context); showAbout(context);

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
@ -43,7 +39,7 @@ class _EditCategoriesViewState extends State<EditCategoriesView> {
} }
Future<void> loadWallet() async { Future<void> loadWallet() async {
wallets = WalletManager.listWallets(); wallets = await WalletManager.listWallets();
if (wallets.isEmpty && mounted) { if (wallets.isEmpty && mounted) {
unawaited( unawaited(
Navigator.of(context) Navigator.of(context)
@ -86,7 +82,7 @@ class _EditCategoriesViewState extends State<EditCategoriesView> {
), ),
), ),
); );
wallets = WalletManager.listWallets(); wallets = await WalletManager.listWallets();
logger.i(wallets.length); logger.i(wallets.length);
selectedWallet = wallets.last; selectedWallet = wallets.last;
setState(() {}); setState(() {});
@ -126,7 +122,7 @@ class _EditCategoriesViewState extends State<EditCategoriesView> {
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
IconButton( IconButton(
onPressed: () { onPressed: () async {
selectedWallet!.categories.add( selectedWallet!.categories.add(
WalletCategory( WalletCategory(
name: AppLocalizations.of(context) name: AppLocalizations.of(context)
@ -141,7 +137,7 @@ class _EditCategoriesViewState extends State<EditCategoriesView> {
), ),
), ),
); );
WalletManager.saveWallet(selectedWallet!); await WalletManager.saveWallet(selectedWallet!);
setState(() {}); setState(() {});
}, },
icon: const Icon(Icons.add), icon: const Icon(Icons.add),
@ -210,7 +206,7 @@ class _EditCategoriesViewState extends State<EditCategoriesView> {
), ),
), ),
); );
WalletManager.saveWallet(selectedWallet!); await WalletManager.saveWallet(selectedWallet!);
setState(() {}); setState(() {});
}, },
child: Container( child: Container(
@ -230,8 +226,8 @@ class _EditCategoriesViewState extends State<EditCategoriesView> {
), ),
trailing: IconButton( trailing: IconButton(
icon: const Icon(Icons.cancel), icon: const Icon(Icons.cancel),
onPressed: () { onPressed: () async {
selectedWallet!.removeCategory( await selectedWallet!.removeCategory(
selectedWallet!.categories[i], selectedWallet!.categories[i],
); );
setState(() {}); setState(() {});
@ -247,11 +243,11 @@ class _EditCategoriesViewState extends State<EditCategoriesView> {
builder: (c) => AlertDialog.adaptive( builder: (c) => AlertDialog.adaptive(
actions: [ actions: [
TextButton( TextButton(
onPressed: () { onPressed: () async {
if (controller.text.isEmpty) return; if (controller.text.isEmpty) return;
selectedWallet!.categories[i].name = selectedWallet!.categories[i].name =
controller.text; controller.text;
WalletManager.saveWallet( await WalletManager.saveWallet(
selectedWallet!, selectedWallet!,
); );
if (!context.mounted) return; if (!context.mounted) return;

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:io'; import 'dart:io';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
@ -121,7 +117,7 @@ class _SettingsViewState extends State<SettingsView> {
description: description:
Text(AppLocalizations.of(context).exportSingleDesc), Text(AppLocalizations.of(context).exportSingleDesc),
onPressed: (ctx) async { onPressed: (ctx) async {
final all = WalletManager.listWallets(); final all = await WalletManager.listWallets();
if (!ctx.mounted) return; if (!ctx.mounted) return;
final w = await showAdaptiveDialog<String>( final w = await showAdaptiveDialog<String>(
context: ctx, context: ctx,

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';

View file

@ -1,7 +1,3 @@
// SPDX-FileCopyrightText: (C) 2024 Matyáš Caras
//
// SPDX-License-Identifier: AGPL-3.0-only
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
@ -135,7 +131,7 @@ class _SetupViewState extends State<SetupView> {
next: Text(AppLocalizations.of(context).next), next: Text(AppLocalizations.of(context).next),
back: Text(AppLocalizations.of(context).back), back: Text(AppLocalizations.of(context).back),
done: Text(AppLocalizations.of(context).finish), done: Text(AppLocalizations.of(context).finish),
onDone: () { onDone: () async {
if (_nameController.text.isEmpty) { if (_nameController.text.isEmpty) {
unawaited( unawaited(
showMessage( showMessage(
@ -145,7 +141,7 @@ class _SetupViewState extends State<SetupView> {
); );
return; return;
} }
if (WalletManager.exists(_nameController.text) && if (await WalletManager.exists(_nameController.text) &&
context.mounted) { context.mounted) {
unawaited( unawaited(
showMessage( showMessage(
@ -161,7 +157,7 @@ class _SetupViewState extends State<SetupView> {
categories: categories, categories: categories,
starterBalance: double.parse(_balanceController.text), starterBalance: double.parse(_balanceController.text),
); );
WalletManager.saveWallet(wallet); await WalletManager.saveWallet(wallet);
if (widget.newWallet && context.mounted) { if (widget.newWallet && context.mounted) {
Navigator.of(context).pop(); Navigator.of(context).pop();

View file

@ -5,31 +5,26 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: _fe_analyzer_shared name: _fe_analyzer_shared
sha256: "5aaf60d96c4cd00fe7f21594b5ad6a1b699c80a27420f8a837f4d68473ef09e3" sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "68.0.0" version: "67.0.0"
_macros:
dependency: transitive
description: dart
source: sdk
version: "0.1.5"
analyzer: analyzer:
dependency: transitive dependency: transitive
description: description:
name: analyzer name: analyzer
sha256: "21f1d3720fd1c70316399d5e2bccaebb415c434592d778cce8acb967b8578808" sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.5.0" version: "6.4.1"
archive: archive:
dependency: "direct main" dependency: "direct main"
description: description:
name: archive name: archive
sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d sha256: "22600aa1e926be775fa5fe7e6894e7fb3df9efda8891c73f70fb3262399a432d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.6.1" version: "3.4.10"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -74,10 +69,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: build_daemon name: build_daemon
sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" sha256: "0343061a33da9c5810b2d6cee51945127d8f4c060b7fbdd9d54917f0a3feaaa1"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.0.2" version: "4.0.1"
build_resolvers: build_resolvers:
dependency: transitive dependency: transitive
description: description:
@ -90,18 +85,18 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: build_runner name: build_runner
sha256: "644dc98a0f179b872f612d3eb627924b578897c629788e858157fa5e704ca0c7" sha256: "3ac61a79bfb6f6cc11f693591063a7f19a7af628dc52f141743edac5c16e8c22"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.11" version: "2.4.9"
build_runner_core: build_runner_core:
dependency: transitive dependency: transitive
description: description:
name: build_runner_core name: build_runner_core
sha256: e3c79f69a64bdfcd8a776a3c28db4eb6e3fb5356d013ae5eb2e52007706d5dbe sha256: "4ae8ffe5ac758da294ecf1802f2aff01558d8b1b00616aa7538ea9a8a5d50799"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "7.3.1" version: "7.3.0"
built_collection: built_collection:
dependency: transitive dependency: transitive
description: description:
@ -178,10 +173,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: coverage name: coverage
sha256: "3945034e86ea203af7a056d98e98e42a5518fff200d6e8e6647e1886b07e936e" sha256: "8acabb8306b57a409bf4c83522065672ee13179297a6bb0cb9ead73948df7c76"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.8.0" version: "1.7.2"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
@ -290,18 +285,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flex_color_picker name: flex_color_picker
sha256: "809af4ec82ede3b140ed0219b97d548de99e47aa4b99b14a10f705a2dbbcba5e" sha256: "5c846437069fb7afdd7ade6bf37e628a71d2ab0787095ddcb1253bf9345d5f3a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.5.1" version: "3.4.1"
flex_seed_scheme: flex_seed_scheme:
dependency: transitive dependency: transitive
description: description:
name: flex_seed_scheme name: flex_seed_scheme
sha256: "6c595e545b0678e1fe17e8eec3d1fbca7237482da194fadc20ad8607dc7a7f3d" sha256: "4cee2f1d07259f77e8b36f4ec5f35499d19e74e17c7dce5b819554914082bc01"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.0" version: "1.5.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -384,6 +379,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.13.1" version: "0.13.1"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "9e8c3858111da373efc5aa341de011d9bd23e2c5c5e0c62bccf32438e192d7b1"
url: "https://pub.dev"
source: hosted
version: "3.0.2"
flutter_localizations: flutter_localizations:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -409,10 +412,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_tesseract_ocr name: flutter_tesseract_ocr
sha256: c3af11e3a8803b36bd24f7ec8ff3e0e21168dac917407357ae177ddf9fe10180 sha256: "4a8d0e3f562ee01d94a464ff9d31d9e907b1e374aeff29bf696f979417c70bcf"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.26" version: "0.4.24"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -427,10 +430,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: fluttertoast name: fluttertoast
sha256: "7eae679e596a44fdf761853a706f74979f8dd3cd92cf4e23cae161fda091b847" sha256: "81b68579e23fcbcada2db3d50302813d2371664afe6165bc78148050ab94bf66"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "8.2.6" version: "8.2.5"
font_awesome_flutter: font_awesome_flutter:
dependency: transitive dependency: transitive
description: description:
@ -496,10 +499,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: image name: image
sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8" sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.2.0" version: "4.1.7"
integration_test: integration_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -509,10 +512,10 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: intl name: intl
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.19.0" version: "0.18.1"
introduction_screen: introduction_screen:
dependency: "direct main" dependency: "direct main"
description: description:
@ -541,34 +544,34 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: json_annotation name: json_annotation
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "4.9.0" version: "4.8.1"
json_serializable: json_serializable:
dependency: "direct main" dependency: "direct main"
description: description:
name: json_serializable name: json_serializable
sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b sha256: aa1f5a8912615733e0fdc7a02af03308933c93235bdc8d50d0b0c8a8ccb0b969
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.8.0" version: "6.7.1"
leak_tracker: leak_tracker:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker name: leak_tracker
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "10.0.5" version: "10.0.4"
leak_tracker_flutter_testing: leak_tracker_flutter_testing:
dependency: transitive dependency: transitive
description: description:
name: leak_tracker_flutter_testing name: leak_tracker_flutter_testing
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.5" version: "3.0.3"
leak_tracker_testing: leak_tracker_testing:
dependency: transitive dependency: transitive
description: description:
@ -577,14 +580,22 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.1" version: "3.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
url: "https://pub.dev"
source: hosted
version: "3.0.0"
logger: logger:
dependency: "direct main" dependency: "direct main"
description: description:
name: logger name: logger
sha256: af05cc8714f356fd1f3888fb6741cbe9fbe25cdb6eedbab80e1a6db21047d4a4 sha256: "8c94b8c219e7e50194efc8771cd0e9f10807d8d3e219af473d89b06cc2ee4e04"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.0" version: "2.2.0"
logging: logging:
dependency: transitive dependency: transitive
description: description:
@ -593,14 +604,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
macros:
dependency: transitive
description:
name: macros
sha256: a8403c89b36483b4cbf9f1fcd24562f483cb34a5c9bf101cf2b0d8a083cf1239
url: "https://pub.dev"
source: hosted
version: "0.1.0-main.5"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
@ -613,18 +616,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.11.1" version: "0.8.0"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
sha256: "25dfcaf170a0190f47ca6355bdd4552cb8924b430512ff0cafb8db9bd41fe33b" sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.14.0" version: "1.12.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@ -677,18 +680,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: path_provider_android name: path_provider_android
sha256: bca87b0165ffd7cdb9cad8edd22d18d2201e886d9a9f19b4fb3452ea7df3a72a sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.6" version: "2.2.4"
path_provider_foundation: path_provider_foundation:
dependency: transitive dependency: transitive
description: description:
name: path_provider_foundation name: path_provider_foundation
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16 sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.0" version: "2.3.2"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
@ -737,6 +740,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.8" version: "2.1.8"
pointycastle:
dependency: transitive
description:
name: pointycastle
sha256: "79fbafed02cfdbe85ef3fd06c7f4bc2cbcba0177e61b765264853d4253b21744"
url: "https://pub.dev"
source: hosted
version: "3.9.0"
pool: pool:
dependency: transitive dependency: transitive
description: description:
@ -773,10 +784,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: pubspec_parse name: pubspec_parse
sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.0" version: "1.2.3"
settings_ui: settings_ui:
dependency: "direct main" dependency: "direct main"
description: description:
@ -797,18 +808,18 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_android name: shared_preferences_android
sha256: "93d0ec9dd902d85f326068e6a899487d1f65ffcd5798721a95330b26c8131577" sha256: "1ee8bf911094a1b592de7ab29add6f826a7331fb854273d55918693d5364a1f2"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.3" version: "2.2.2"
shared_preferences_foundation: shared_preferences_foundation:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_foundation name: shared_preferences_foundation
sha256: "0a8a893bf4fd1152f93fec03a415d11c27c74454d96e2318a7ac38dd18683ab7" sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.0" version: "2.3.5"
shared_preferences_linux: shared_preferences_linux:
dependency: transitive dependency: transitive
description: description:
@ -869,10 +880,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: shelf_web_socket name: shelf_web_socket
sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.0" version: "1.0.4"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -970,26 +981,26 @@ packages:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: test name: test
sha256: d11b55850c68c1f6c0cf00eabded4e66c4043feaf6c0d7ce4a36785137df6331 sha256: "7ee446762c2c50b3bd4ea96fe13ffac69919352bd3b4b17bac3f3465edc58073"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.25.5" version: "1.25.2"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
sha256: "2419f20b0c8677b2d67c8ac4d1ac7372d862dc6c460cdbb052b40155408cd794" sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.7.1" version: "0.7.0"
test_core: test_core:
dependency: transitive dependency: transitive
description: description:
name: test_core name: test_core
sha256: "4d070a6bc36c1c4e89f20d353bfd71dc30cdf2bd0e14349090af360a029ab292" sha256: "2bc4b4ecddd75309300d8096f781c0e3280ca1ef85beda558d33fcbedc2eead4"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.2" version: "0.6.0"
timing: timing:
dependency: transitive dependency: transitive
description: description:
@ -1010,26 +1021,26 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: url_launcher name: url_launcher
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" sha256: "6ce1e04375be4eed30548f10a315826fd933c1e493206eab82eed01f438c8d2e"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.0" version: "6.2.6"
url_launcher_android: url_launcher_android:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_android name: url_launcher_android
sha256: ceb2625f0c24ade6ef6778d1de0b2e44f2db71fded235eb52295247feba8c5cf sha256: "360a6ed2027f18b73c8d98e159dda67a61b7f2e0f6ec26e86c3ada33b0621775"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.3" version: "6.3.1"
url_launcher_ios: url_launcher_ios:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_ios name: url_launcher_ios
sha256: "7068716403343f6ba4969b4173cbf3b84fc768042124bc2c011e5d782b24fe89" sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.0" version: "6.2.5"
url_launcher_linux: url_launcher_linux:
dependency: transitive dependency: transitive
description: description:
@ -1042,10 +1053,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_macos name: url_launcher_macos
sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de" sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.2.0" version: "3.1.0"
url_launcher_platform_interface: url_launcher_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -1090,10 +1101,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
sha256: "7475cb4dd713d57b6f7464c0e13f06da0d535d8b2067e188962a59bac2cf280b" sha256: a2662fb1f114f4296cf3f5a50786a2d888268d7776cf681aa17d660ffa23b246
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "14.2.2" version: "14.0.0"
watcher: watcher:
dependency: transitive dependency: transitive
description: description:
@ -1110,22 +1121,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "0.5.1" version: "0.5.1"
web_socket:
dependency: transitive
description:
name: web_socket
sha256: "24301d8c293ce6fe327ffe6f59d8fd8834735f0ec36e4fd383ec7ff8a64aa078"
url: "https://pub.dev"
source: hosted
version: "0.1.5"
web_socket_channel: web_socket_channel:
dependency: transitive dependency: transitive
description: description:
name: web_socket_channel name: web_socket_channel
sha256: a2d56211ee4d35d9b344d9d4ce60f362e4f5d1aafb988302906bd732bc731276 sha256: "58c6666b342a38816b2e7e50ed0f1e261959630becd4c879c4f26bfa14aa5a42"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.0" version: "2.4.5"
webdriver: webdriver:
dependency: transitive dependency: transitive
description: description:
@ -1154,10 +1157,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4 sha256: "0a989dc7ca2bb51eac91e8fd00851297cfffd641aa7538b165c62637ca0eaa4a"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "5.5.1" version: "5.4.0"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
@ -1183,5 +1186,5 @@ packages:
source: hosted source: hosted
version: "3.1.2" version: "3.1.2"
sdks: sdks:
dart: ">=3.4.0 <4.0.0" dart: ">=3.3.0 <4.0.0"
flutter: ">=3.22.0" flutter: ">=3.19.0"

View file

@ -28,7 +28,7 @@ dependencies:
sdk: flutter sdk: flutter
flutter_slidable: ^3.0.0 flutter_slidable: ^3.0.0
flutter_speed_dial: ^7.0.0 flutter_speed_dial: ^7.0.0
flutter_tesseract_ocr: ^0.4.26 flutter_tesseract_ocr: ^0.4.23
fluttertoast: ^8.2.4 fluttertoast: ^8.2.4
grouped_list: ^5.1.2 grouped_list: ^5.1.2
intl: any intl: any
@ -51,6 +51,7 @@ dev_dependencies:
# activated in the `analysis_options.yaml` file located at the root of your # activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint # package. See that file for information about deactivating specific lint
# rules and activating additional ones. # rules and activating additional ones.
flutter_lints: ^3.0.0
flutter_test: flutter_test:
sdk: flutter sdk: flutter
integration_test: integration_test:

View file

@ -1,6 +0,0 @@
sonar.projectKey=prasule
sonar.sources=lib,pubspec.yaml
sonar.tests=test
sonar.dart.analyzer.mode=MANUAL
sonar.dart.analyzer.options.override=true
sonar.host.url=https://sq.mnau.xyz

View file

@ -1,3 +0,0 @@
import 'package:integration_test/integration_test_driver.dart';
Future<void> main() => integrationDriver();