diff --git a/.flutter b/.flutter new file mode 160000 index 0000000..4d9e56e --- /dev/null +++ b/.flutter @@ -0,0 +1 @@ +Subproject commit 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf diff --git a/.gitignore b/.gitignore index 3a83c2f..a87b4d2 100644 --- a/.gitignore +++ b/.gitignore @@ -4,8 +4,6 @@ .dart_tool/ .packages build/ -# If you're building an application, you may want to check-in your pubspec.lock -pubspec.lock # Directory created by dartdoc # If you don't generate documentation locally you can remove this line. diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..4cb5eda --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule ".flutter"] + path = .flutter + url = https://github.com/flutter/flutter diff --git a/android/app/build.gradle b/android/app/build.gradle index f06a416..6b24362 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -49,7 +49,7 @@ android { defaultConfig { applicationId "cat.naval.florae" - minSdkVersion 21 + minSdkVersion 16 targetSdkVersion rootProject.ext.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName diff --git a/android/build.gradle b/android/build.gradle index cfb7fcc..c04a866 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -20,6 +20,8 @@ allprojects { repositories { google() mavenCentral() + // for FDroid + mavenLocal() maven { // [required] background_fetch url "${project(':background_fetch').projectDir}/libs" diff --git a/lib/data/box.dart b/lib/data/box.dart deleted file mode 100644 index 474c0dc..0000000 --- a/lib/data/box.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'dart:io'; - -import 'package:florae/data/plant.dart'; -import 'package:objectbox_flutter_libs/objectbox_flutter_libs.dart'; -import 'package:path_provider/path_provider.dart'; -import '../objectbox.g.dart'; - -class ObjectBox { - /// The Store of this app. - late final Store store; - - /// A Box of notes. - late final Box plantBox; - - late final Box careBox; - - ObjectBox._create(this.store) { - plantBox = Box(store); - careBox = Box(store); - // Add any additional setup code, e.g. build queries. - } - - /// Create an instance of ObjectBox to use throughout the app. - static Future create() async { - // Future openStore() {...} is defined in the generated objectbox.g.dart - - Directory? dbPath = (await getExternalStorageDirectory()); - - dbPath ??= (await defaultStoreDirectory()); - - Store store; - - if (Store.isOpen(dbPath.path)) { - store = Store.attach(getObjectBoxModel(), dbPath.path); - } - else{ - store = await openStore(directory: dbPath.path); - } - return ObjectBox._create(store); - } - - int addPlant(Plant plant) => store.box().put(plant); - - Future removePlant(Plant plant) => - store.runInTransactionAsync(TxMode.write, _removePlantInTx, plant.id); - - /// Note: due to [dart-lang/sdk#36983](https://github.com/dart-lang/sdk/issues/36983) - /// not using a closure as it may capture more objects than expected. - /// These might not be send-able to an isolate. See Store.runAsync for details. - static void _removePlantInTx(Store store, int id) { - // Perform ObjectBox operations that take longer than a few milliseconds - // here. To keep it simple, this example just puts a single object. - - store.box().remove(id); - } -} diff --git a/lib/data/care.dart b/lib/data/care.dart new file mode 100644 index 0000000..d2b586f --- /dev/null +++ b/lib/data/care.dart @@ -0,0 +1,21 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'care.g.dart'; + +@JsonSerializable() +class Care { + int id = 0; + String name; + int cycles = 0; + DateTime? effected; + + Care( + {required this.name, + required this.cycles, + required this.effected, + required this.id}); + + factory Care.fromJson(Map json) => _$CareFromJson(json); + + Map toJson() => _$CareToJson(this); +} diff --git a/lib/data/care.g.dart b/lib/data/care.g.dart new file mode 100644 index 0000000..e832416 --- /dev/null +++ b/lib/data/care.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'care.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Care _$CareFromJson(Map json) => Care( + name: json['name'] as String, + cycles: json['cycles'] as int, + effected: json['effected'] == null + ? null + : DateTime.parse(json['effected'] as String), + id: json['id'] as int, + ); + +Map _$CareToJson(Care instance) => { + 'id': instance.id, + 'name': instance.name, + 'cycles': instance.cycles, + 'effected': instance.effected?.toIso8601String(), + }; diff --git a/lib/data/garden.dart b/lib/data/garden.dart new file mode 100644 index 0000000..384ba6c --- /dev/null +++ b/lib/data/garden.dart @@ -0,0 +1,83 @@ +import 'dart:convert'; +import 'package:florae/data/plant.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class Garden { + late final SharedPreferences store; + + Garden(this.store); + + static Future load() async { + var store = await SharedPreferences.getInstance(); + + await store.reload(); + + return (Garden(store)); + } + + Future> getAllPlants() async { + List allPlants = []; + var rawPlants = store.getString("plants"); + if (rawPlants != null) { + Iterable l = json.decode(rawPlants); + allPlants = List.from(l.map((model) => Plant.fromJson(model))); + } + return allPlants; + } + + // Returns true if update + // Return false if create + Future addOrUpdatePlant(Plant plant) async { + List allPlants = await getAllPlants(); + bool status; + + var plantIndex = + allPlants.indexWhere((element) => element.name == plant.name); + if (plantIndex == -1) { + allPlants.add(plant); + status = false; + } else { + allPlants[allPlants.indexWhere((element) => element.name == plant.name)] = + plant; + status = true; + } + String jsonPlants = jsonEncode(allPlants); + await store.setString("plants", jsonPlants); + + return status; + } + + Future deletePlant(Plant plant) async { + List allPlants = await getAllPlants(); + + var plantIndex = + allPlants.indexWhere((element) => element.name == plant.name); + if (plantIndex != -1) { + allPlants.removeAt(plantIndex); + + String jsonPlants = jsonEncode(allPlants); + await store.setString("plants", jsonPlants); + + return true; + } else { + return false; + } + } + + Future updatePlant(Plant plant) async { + List allPlants = await getAllPlants(); + + var plantIndex = + allPlants.indexWhere((element) => element.name == plant.name); + if (plantIndex != -1) { + allPlants[allPlants.indexWhere((element) => element.name == plant.name)] = + plant; + + String jsonPlants = jsonEncode(allPlants); + await store.setString("plants", jsonPlants); + return true; + } else { + return false; + } + } +} diff --git a/lib/data/plant.dart b/lib/data/plant.dart index 8fc348d..1b5bec1 100644 --- a/lib/data/plant.dart +++ b/lib/data/plant.dart @@ -1,33 +1,17 @@ -import 'package:objectbox/objectbox.dart'; +import 'package:json_annotation/json_annotation.dart'; +import 'care.dart'; -@Entity() -class Care { - int id = 0; - String name; - int cycles = 0; - @Property(type: PropertyType.date) - DateTime? effected; - - Care({required this.name, required this.cycles, required this.effected}); - - factory Care.fromJson(Map json) => Care( - cycles: json["cycles"], effected: json["effected"], name: json["name"]); +part 'plant.g.dart'; - Map toJson() => - {"cycles": cycles, "effected": effected, "name": name}; -} - -@Entity() +@JsonSerializable(explicitToJson: true) class Plant { int id = 0; String name; String? location; String description; - @Property(type: PropertyType.date) DateTime createdAt; String? picture; - - final cares = ToMany(); + List cares = []; Plant( {required this.name, @@ -35,21 +19,10 @@ class Plant { this.location, this.description = "", required this.createdAt, - this.picture}); + this.picture, + required this.cares}); - factory Plant.fromJson(Map json) => Plant( - name: json["name"], - location: json["location"], - description: json["description"], - createdAt: json["createdAt"], - picture: json["picture"], - ); + factory Plant.fromJson(Map json) => _$PlantFromJson(json); - Map toJson() => { - "name": name, - "location": location, - "description": description, - "createdAt": createdAt, - "picture": picture, - }; + Map toJson() => _$PlantToJson(this); } diff --git a/lib/data/plant.g.dart b/lib/data/plant.g.dart new file mode 100644 index 0000000..0d8c1ae --- /dev/null +++ b/lib/data/plant.g.dart @@ -0,0 +1,29 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'plant.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Plant _$PlantFromJson(Map json) => Plant( + name: json['name'] as String, + id: json['id'] as int? ?? 0, + location: json['location'] as String?, + description: json['description'] as String? ?? "", + createdAt: DateTime.parse(json['createdAt'] as String), + picture: json['picture'] as String?, + cares: (json['cares'] as List) + .map((e) => Care.fromJson(e as Map)) + .toList(), + ); + +Map _$PlantToJson(Plant instance) => { + 'id': instance.id, + 'name': instance.name, + 'location': instance.location, + 'description': instance.description, + 'createdAt': instance.createdAt.toIso8601String(), + 'picture': instance.picture, + 'cares': instance.cares.map((e) => e.toJson()).toList(), + }; diff --git a/lib/main.dart b/lib/main.dart index b242b0b..8633140 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,22 +1,22 @@ import 'dart:io'; - import 'package:background_fetch/background_fetch.dart'; import 'package:florae/screens/error.dart'; import 'package:flutter/material.dart'; -import 'data/box.dart'; +import 'data/care.dart'; import 'data/plant.dart'; +import 'data/garden.dart'; import 'screens/home_page.dart'; import 'package:florae/notifications.dart' as notify; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:shared_preferences/shared_preferences.dart'; -late ObjectBox objectbox; +late Garden garden; Future main() async { WidgetsFlutterBinding.ensureInitialized(); - objectbox = await ObjectBox.create(); + garden = await Garden.load(); // Set default locale for background service final prefs = await SharedPreferences.getInstance(); @@ -41,9 +41,10 @@ void backgroundFetchHeadlessTask(HeadlessTask task) async { print("[BackgroundFetch] Headless event received: $taskId"); - ObjectBox obx = await ObjectBox.create(); + Garden gr = await Garden.load(); + + List allPlants = await gr.getAllPlants(); - List allPlants = obx.plantBox.getAll(); List plants = []; String notificationTitle = "Plants require care"; @@ -60,8 +61,6 @@ void backgroundFetchHeadlessTask(HeadlessTask task) async { } } - obx.store.close(); - try { final prefs = await SharedPreferences.getInstance(); @@ -109,7 +108,7 @@ class FloraeApp extends StatelessWidget { }; return widget!; - }, + }, supportedLocales: const [ Locale('en'), // English Locale('es'), // Spanish diff --git a/lib/notifications.dart b/lib/notifications.dart index 49a89f9..5cf455c 100644 --- a/lib/notifications.dart +++ b/lib/notifications.dart @@ -1,25 +1,10 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'dart:async'; -import 'dart:io'; final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); -Future _startForegroundService() async { - const AndroidNotificationDetails androidPlatformChannelSpecifics = - AndroidNotificationDetails('care_reminder', 'your channel name', - channelDescription: 'your channel description', - importance: Importance.max, - priority: Priority.high, - ticker: 'ticker'); - await flutterLocalNotificationsPlugin - .resolvePlatformSpecificImplementation< - AndroidFlutterLocalNotificationsPlugin>() - ?.startForegroundService(1, 'plain title', 'plain body', - notificationDetails: androidPlatformChannelSpecifics, - payload: 'item x'); -} void _requestPermissions() { flutterLocalNotificationsPlugin @@ -73,15 +58,15 @@ void initNotifications(String channelName, String channelDescription) async { Future singleNotification(String title, String body, int hashCode, {String? payload, String? sound}) async { - const AndroidNotificationDetails androidPlatformChannelSpecifics = + AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails('care_reminder', 'Care reminder', icon: '@drawable/ic_stat_florae', channelDescription: 'Receive plants care notifications', importance: Importance.max, priority: Priority.high, - ticker: 'care_reminder'); + ticker: title); - const NotificationDetails platformChannelSpecifics = + NotificationDetails platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics); await flutterLocalNotificationsPlugin diff --git a/lib/objectbox-model.json b/lib/objectbox-model.json deleted file mode 100644 index 3ddfc2d..0000000 --- a/lib/objectbox-model.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.", - "_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.", - "_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.", - "entities": [ - { - "id": "1:6017369575698615271", - "lastPropertyId": "4:9170897634876619206", - "name": "Care", - "properties": [ - { - "id": "1:8647452937344853257", - "name": "id", - "type": 6, - "flags": 1 - }, - { - "id": "2:9035521047735137659", - "name": "name", - "type": 9 - }, - { - "id": "3:40688042087648428", - "name": "cycles", - "type": 6 - }, - { - "id": "4:9170897634876619206", - "name": "effected", - "type": 10 - } - ], - "relations": [] - }, - { - "id": "2:8248999037139681305", - "lastPropertyId": "6:8156462471304383266", - "name": "Plant", - "properties": [ - { - "id": "1:663235456190999336", - "name": "id", - "type": 6, - "flags": 1 - }, - { - "id": "2:7653806020704880625", - "name": "name", - "type": 9 - }, - { - "id": "3:4563435691994880788", - "name": "location", - "type": 9 - }, - { - "id": "4:370151171891422499", - "name": "description", - "type": 9 - }, - { - "id": "5:8736961919321289742", - "name": "createdAt", - "type": 10 - }, - { - "id": "6:8156462471304383266", - "name": "picture", - "type": 9 - } - ], - "relations": [ - { - "id": "1:4325392459038757092", - "name": "cares", - "targetId": "1:6017369575698615271" - } - ] - } - ], - "lastEntityId": "2:8248999037139681305", - "lastIndexId": "0:0", - "lastRelationId": "1:4325392459038757092", - "lastSequenceId": "0:0", - "modelVersion": 5, - "modelVersionParserMinimum": 5, - "retiredEntityUids": [], - "retiredIndexUids": [], - "retiredPropertyUids": [], - "retiredRelationUids": [], - "version": 1 -} \ No newline at end of file diff --git a/lib/objectbox.g.dart b/lib/objectbox.g.dart deleted file mode 100644 index a4e28e3..0000000 --- a/lib/objectbox.g.dart +++ /dev/null @@ -1,258 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND -// This code was generated by ObjectBox. To update it run the generator again: -// With a Flutter package, run `flutter pub run build_runner build`. -// With a Dart package, run `dart run build_runner build`. -// See also https://docs.objectbox.io/getting-started#generate-objectbox-code - -// ignore_for_file: camel_case_types - -import 'dart:typed_data'; - -import 'package:flat_buffers/flat_buffers.dart' as fb; -import 'package:objectbox/internal.dart'; // generated code can access "internal" functionality -import 'package:objectbox/objectbox.dart'; -import 'package:objectbox_flutter_libs/objectbox_flutter_libs.dart'; - -import 'data/plant.dart'; - -export 'package:objectbox/objectbox.dart'; // so that callers only have to import this file - -final _entities = [ - ModelEntity( - id: const IdUid(1, 6017369575698615271), - name: 'Care', - lastPropertyId: const IdUid(4, 9170897634876619206), - flags: 0, - properties: [ - ModelProperty( - id: const IdUid(1, 8647452937344853257), - name: 'id', - type: 6, - flags: 1), - ModelProperty( - id: const IdUid(2, 9035521047735137659), - name: 'name', - type: 9, - flags: 0), - ModelProperty( - id: const IdUid(3, 40688042087648428), - name: 'cycles', - type: 6, - flags: 0), - ModelProperty( - id: const IdUid(4, 9170897634876619206), - name: 'effected', - type: 10, - flags: 0) - ], - relations: [], - backlinks: []), - ModelEntity( - id: const IdUid(2, 8248999037139681305), - name: 'Plant', - lastPropertyId: const IdUid(6, 8156462471304383266), - flags: 0, - properties: [ - ModelProperty( - id: const IdUid(1, 663235456190999336), - name: 'id', - type: 6, - flags: 1), - ModelProperty( - id: const IdUid(2, 7653806020704880625), - name: 'name', - type: 9, - flags: 0), - ModelProperty( - id: const IdUid(3, 4563435691994880788), - name: 'location', - type: 9, - flags: 0), - ModelProperty( - id: const IdUid(4, 370151171891422499), - name: 'description', - type: 9, - flags: 0), - ModelProperty( - id: const IdUid(5, 8736961919321289742), - name: 'createdAt', - type: 10, - flags: 0), - ModelProperty( - id: const IdUid(6, 8156462471304383266), - name: 'picture', - type: 9, - flags: 0) - ], - relations: [ - ModelRelation( - id: const IdUid(1, 4325392459038757092), - name: 'cares', - targetId: const IdUid(1, 6017369575698615271)) - ], - backlinks: []) -]; - -/// Open an ObjectBox store with the model declared in this file. -Future openStore( - {String? directory, - int? maxDBSizeInKB, - int? fileMode, - int? maxReaders, - bool queriesCaseSensitiveDefault = true, - String? macosApplicationGroup}) async => - Store(getObjectBoxModel(), - directory: directory ?? (await defaultStoreDirectory()).path, - maxDBSizeInKB: maxDBSizeInKB, - fileMode: fileMode, - maxReaders: maxReaders, - queriesCaseSensitiveDefault: queriesCaseSensitiveDefault, - macosApplicationGroup: macosApplicationGroup); - -/// ObjectBox model definition, pass it to [Store] - Store(getObjectBoxModel()) -ModelDefinition getObjectBoxModel() { - final model = ModelInfo( - entities: _entities, - lastEntityId: const IdUid(2, 8248999037139681305), - lastIndexId: const IdUid(0, 0), - lastRelationId: const IdUid(1, 4325392459038757092), - lastSequenceId: const IdUid(0, 0), - retiredEntityUids: const [], - retiredIndexUids: const [], - retiredPropertyUids: const [], - retiredRelationUids: const [], - modelVersion: 5, - modelVersionParserMinimum: 5, - version: 1); - - final bindings = { - Care: EntityDefinition( - model: _entities[0], - toOneRelations: (Care object) => [], - toManyRelations: (Care object) => {}, - getId: (Care object) => object.id, - setId: (Care object, int id) { - object.id = id; - }, - objectToFB: (Care object, fb.Builder fbb) { - final nameOffset = fbb.writeString(object.name); - fbb.startTable(5); - fbb.addInt64(0, object.id); - fbb.addOffset(1, nameOffset); - fbb.addInt64(2, object.cycles); - fbb.addInt64(3, object.effected?.millisecondsSinceEpoch); - fbb.finish(fbb.endTable()); - return object.id; - }, - objectFromFB: (Store store, ByteData fbData) { - final buffer = fb.BufferContext(fbData); - final rootOffset = buffer.derefObject(0); - final effectedValue = - const fb.Int64Reader().vTableGetNullable(buffer, rootOffset, 10); - final object = Care( - name: const fb.StringReader(asciiOptimization: true) - .vTableGet(buffer, rootOffset, 6, ''), - cycles: - const fb.Int64Reader().vTableGet(buffer, rootOffset, 8, 0), - effected: effectedValue == null - ? null - : DateTime.fromMillisecondsSinceEpoch(effectedValue)) - ..id = const fb.Int64Reader().vTableGet(buffer, rootOffset, 4, 0); - - return object; - }), - Plant: EntityDefinition( - model: _entities[1], - toOneRelations: (Plant object) => [], - toManyRelations: (Plant object) => - {RelInfo.toMany(1, object.id): object.cares}, - getId: (Plant object) => object.id, - setId: (Plant object, int id) { - object.id = id; - }, - objectToFB: (Plant object, fb.Builder fbb) { - final nameOffset = fbb.writeString(object.name); - final locationOffset = object.location == null - ? null - : fbb.writeString(object.location!); - final descriptionOffset = fbb.writeString(object.description); - final pictureOffset = - object.picture == null ? null : fbb.writeString(object.picture!); - fbb.startTable(7); - fbb.addInt64(0, object.id); - fbb.addOffset(1, nameOffset); - fbb.addOffset(2, locationOffset); - fbb.addOffset(3, descriptionOffset); - fbb.addInt64(4, object.createdAt.millisecondsSinceEpoch); - fbb.addOffset(5, pictureOffset); - fbb.finish(fbb.endTable()); - return object.id; - }, - objectFromFB: (Store store, ByteData fbData) { - final buffer = fb.BufferContext(fbData); - final rootOffset = buffer.derefObject(0); - - final object = Plant( - name: const fb.StringReader(asciiOptimization: true) - .vTableGet(buffer, rootOffset, 6, ''), - location: const fb.StringReader(asciiOptimization: true) - .vTableGetNullable(buffer, rootOffset, 8), - description: const fb.StringReader(asciiOptimization: true) - .vTableGet(buffer, rootOffset, 10, ''), - createdAt: DateTime.fromMillisecondsSinceEpoch( - const fb.Int64Reader().vTableGet(buffer, rootOffset, 12, 0)), - picture: const fb.StringReader(asciiOptimization: true) - .vTableGetNullable(buffer, rootOffset, 14)) - ..id = const fb.Int64Reader().vTableGet(buffer, rootOffset, 4, 0); - InternalToManyAccess.setRelInfo(object.cares, store, - RelInfo.toMany(1, object.id), store.box()); - return object; - }) - }; - - return ModelDefinition(model, bindings); -} - -/// [Care] entity fields to define ObjectBox queries. -class Care_ { - /// see [Care.id] - static final id = QueryIntegerProperty(_entities[0].properties[0]); - - /// see [Care.name] - static final name = QueryStringProperty(_entities[0].properties[1]); - - /// see [Care.cycles] - static final cycles = QueryIntegerProperty(_entities[0].properties[2]); - - /// see [Care.effected] - static final effected = - QueryIntegerProperty(_entities[0].properties[3]); -} - -/// [Plant] entity fields to define ObjectBox queries. -class Plant_ { - /// see [Plant.id] - static final id = QueryIntegerProperty(_entities[1].properties[0]); - - /// see [Plant.name] - static final name = QueryStringProperty(_entities[1].properties[1]); - - /// see [Plant.location] - static final location = - QueryStringProperty(_entities[1].properties[2]); - - /// see [Plant.description] - static final description = - QueryStringProperty(_entities[1].properties[3]); - - /// see [Plant.createdAt] - static final createdAt = - QueryIntegerProperty(_entities[1].properties[4]); - - /// see [Plant.picture] - static final picture = QueryStringProperty(_entities[1].properties[5]); - - /// see [Plant.cares] - static final cares = - QueryRelationToMany(_entities[1].relations[0]); -} diff --git a/lib/screens/care_plant.dart b/lib/screens/care_plant.dart index 22e5754..ad4fdf0 100644 --- a/lib/screens/care_plant.dart +++ b/lib/screens/care_plant.dart @@ -2,6 +2,7 @@ import 'dart:io'; import 'package:florae/data/plant.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; +import '../data/care.dart'; import '../data/default.dart'; import '../main.dart'; import 'manage_plant.dart'; @@ -17,7 +18,7 @@ class CarePlantScreen extends StatefulWidget { } class _CarePlantScreen extends State { - int periodityCheckInHours = 1; + int periodicityInHours = 1; Map careCheck = {}; @override @@ -31,18 +32,13 @@ class _CarePlantScreen extends State { } String buildCareMessage(int daysToCare) { - - if (daysToCare == 0 ){ + if (daysToCare == 0) { return AppLocalizations.of(context)!.now; - } - else if (daysToCare <0){ + } else if (daysToCare < 0) { return "${AppLocalizations.of(context)!.daysLate} ${daysToCare.abs()} ${AppLocalizations.of(context)!.days}"; + } else { + return "$daysToCare ${AppLocalizations.of(context)!.daysLeft}"; } - else{ - return "$daysToCare ${AppLocalizations.of(context)!.daysLeft}"; - } - - } Future _showDeletePlantDialog(Plant plant) async { @@ -55,8 +51,7 @@ class _CarePlantScreen extends State { content: SingleChildScrollView( child: ListBody( children: [ - Text( - AppLocalizations.of(context)!.deletePlantBody), + Text(AppLocalizations.of(context)!.deletePlantBody), ], ), ), @@ -70,7 +65,8 @@ class _CarePlantScreen extends State { TextButton( child: Text(AppLocalizations.of(context)!.yes), onPressed: () async { - await objectbox.removePlant(plant); + garden.deletePlant(plant); + Navigator.popUntil(context, ModalRoute.withName('/')); }, ), @@ -82,13 +78,14 @@ class _CarePlantScreen extends State { List _buildCares(BuildContext context, Plant plant) { return plant.cares.map((care) { - int daysToCare = care.cycles - DateTime.now().difference(care.effected!).inDays; + int daysToCare = + care.cycles - DateTime.now().difference(care.effected!).inDays; - if (careCheck[care] == null){ + if (careCheck[care] == null) { careCheck[care] = daysToCare <= 0; } return CheckboxListTile( - title: Text(DefaultValues.getCare(context,care.name)!.translatedName), + title: Text(DefaultValues.getCare(context, care.name)!.translatedName), subtitle: Text(buildCareMessage(daysToCare)), value: careCheck[care], onChanged: (bool? value) { @@ -108,7 +105,7 @@ class _CarePlantScreen extends State { return Scaffold( appBar: AppBar( - toolbarHeight : 70, + toolbarHeight: 70, automaticallyImplyLeading: false, title: FittedBox(fit: BoxFit.fitWidth, child: Text(plant.name)), elevation: 0.0, @@ -157,12 +154,10 @@ class _CarePlantScreen extends State { child: plant.picture!.contains("assets/") ? Image.asset( plant.picture!, - // TODO: Adjust the box size (102) fit: BoxFit.fitHeight, ) : Image.file( File(plant.picture!), - // TODO: Adjust the box size (102) fit: BoxFit.fitWidth, ), ), @@ -180,17 +175,21 @@ class _CarePlantScreen extends State { child: Column(children: [ ListTile( leading: const Icon(Icons.topic), - title: Text(AppLocalizations.of(context)!.labelDescription), + title: Text( + AppLocalizations.of(context)!.labelDescription), subtitle: Text(plant.description)), ListTile( leading: const Icon(Icons.location_on), - title: Text(AppLocalizations.of(context)!.labelLocation), + title: + Text(AppLocalizations.of(context)!.labelLocation), subtitle: Text(plant.location ?? "")), ListTile( leading: const Icon(Icons.cake), - title: Text(AppLocalizations.of(context)!.labelDayPlanted), - subtitle: - Text(DateFormat.yMMMMd(Localizations.localeOf(context).languageCode).format(plant.createdAt))), + title: + Text(AppLocalizations.of(context)!.labelDayPlanted), + subtitle: Text(DateFormat.yMMMMd( + Localizations.localeOf(context).languageCode) + .format(plant.createdAt))), ]), ), Card( @@ -223,18 +222,24 @@ class _CarePlantScreen extends State { ), FloatingActionButton.extended( heroTag: "care", - onPressed: () { + onPressed: () async { if (!careCheck.containsValue(true)) { print("NO CARES"); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(AppLocalizations.of(context)!.noCaresError))); + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: + Text(AppLocalizations.of(context)!.noCaresError))); } else { careCheck.forEach((key, value) { - if (value == true){ - key.effected = DateTime.now(); - objectbox.careBox.put(key); - }}); - + if (value == true) { + var careIndex = plant.cares + .indexWhere((element) => element.name == key.name); + if (careIndex != -1) { + plant.cares[careIndex].effected = DateTime.now(); + } + } + }); + + garden.updatePlant(plant); Navigator.of(context).pop(); } }, diff --git a/lib/screens/home_page.dart b/lib/screens/home_page.dart index f4ab493..a9060cb 100644 --- a/lib/screens/home_page.dart +++ b/lib/screens/home_page.dart @@ -13,6 +13,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:intl/intl.dart'; import 'package:responsive_grid_list/responsive_grid_list.dart'; +import '../data/care.dart'; import '../data/default.dart'; import '../main.dart'; import 'manage_plant.dart'; @@ -46,13 +47,11 @@ class _MyHomePageState extends State { @override void dispose() { - objectbox.store.close(); super.dispose(); } @override void initState() { - super.initState(); _loadPlants(); @@ -101,7 +100,8 @@ class _MyHomePageState extends State { print("[BackgroundFetch] Event received: $taskId"); if (taskId == "flutter_background_fetch") { - List allPlants = objectbox.plantBox.getAll(); + List allPlants = await garden.getAllPlants(); + List plants = []; for (Plant p in allPlants) { @@ -363,8 +363,7 @@ class _MyHomePageState extends State { List plants = []; Map> cares = {}; - List allPlants = objectbox.plantBox.getAll(); - + List allPlants = await garden.getAllPlants(); DateTime dateCheck = _dateFilterEnabled ? _dateFilter : DateTime.now(); bool inserted = false; @@ -414,7 +413,8 @@ class _MyHomePageState extends State { } _careAllPlants() async { - List allPlants = objectbox.plantBox.getAll(); + List allPlants = await garden.getAllPlants(); + DateTime dateCheck = _dateFilterEnabled ? _dateFilter : DateTime.now(); for (Plant p in allPlants) { @@ -422,9 +422,9 @@ class _MyHomePageState extends State { var daysSinceLastCare = dateCheck.difference(c.effected!).inDays; if (daysSinceLastCare != 0 && daysSinceLastCare % c.cycles >= 0) { c.effected = DateTime.now(); - objectbox.careBox.put(c); } } + garden.updatePlant(p); } setState(() { @@ -463,8 +463,6 @@ class _MyHomePageState extends State { return list; } -// TODO: Make a collection of cards (102) -// Replace this entire method List _buildPlantCards(BuildContext context) { final ThemeData theme = Theme.of(context); diff --git a/lib/screens/manage_plant.dart b/lib/screens/manage_plant.dart index bc043f9..3867199 100644 --- a/lib/screens/manage_plant.dart +++ b/lib/screens/manage_plant.dart @@ -3,7 +3,6 @@ import 'dart:math'; import 'package:florae/data/default.dart'; import 'package:florae/data/plant.dart'; -import 'package:florae/main.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:image_picker/image_picker.dart'; @@ -13,6 +12,9 @@ import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; import 'package:intl/intl.dart'; +import '../data/care.dart'; +import '../main.dart'; + class ManagePlantScreen extends StatefulWidget { const ManagePlantScreen( {Key? key, required this.title, required this.update, this.plant}) @@ -123,8 +125,11 @@ class _ManagePlantScreen extends State { // If is an update, restore old cares if (widget.update && widget.plant != null) { for (var care in widget.plant!.cares) { - cares[care.name] = - Care(name: care.name, cycles: care.cycles, effected: care.effected); + cares[care.name] = Care( + name: care.name, + cycles: care.cycles, + effected: care.effected, + id: care.name.hashCode); } nameController.text = widget.plant!.name; descriptionController.text = widget.plant!.description; @@ -148,7 +153,10 @@ class _ManagePlantScreen extends State { DefaultValues.getCares(context).forEach((key, value) { if (cares[key] == null) { cares[key] = Care( - cycles: value.defaultCycles, effected: DateTime.now(), name: key); + cycles: value.defaultCycles, + effected: DateTime.now(), + name: key, + id: key.hashCode); } }); } @@ -222,7 +230,6 @@ class _ManagePlantScreen extends State { child: _image == null ? Image.asset( "assets/florae_avatar_$_prefNumber.png", - // TODO: Adjust the box size (102) fit: BoxFit.fitWidth, ) : Image.file(File(_image!.path)), @@ -407,14 +414,17 @@ class _ManagePlantScreen extends State { // Creates new plant object with previous id if we are editing // or generates a Id if we are creating a new plant final newPlant = Plant( - id: widget.plant != null ? widget.plant!.id : 0, + id: widget.plant != null + ? widget.plant!.id + : nameController.text.hashCode, name: nameController.text, createdAt: _planted, description: descriptionController.text, picture: _image != null ? fileName : "assets/florae_avatar_$_prefNumber.png", - location: locationController.text); + location: locationController.text, + cares: []); // Assign cares to plant newPlant.cares.clear(); @@ -422,18 +432,14 @@ class _ManagePlantScreen extends State { cares.forEach((key, value) { if (value.cycles != 0) { newPlant.cares.add(Care( - cycles: value.cycles, effected: value.effected, name: key)); + cycles: value.cycles, + effected: value.effected, + name: key, + id: key.hashCode)); } }); - // ObjectBox does not track ToMany changes - // https://github.com/objectbox/objectbox-dart/issues/326 - if (widget.update && widget.plant != null) { - widget.plant!.cares.clear(); - objectbox.plantBox.put(widget.plant!); - } - - objectbox.plantBox.put(newPlant); + garden.addOrUpdatePlant(newPlant); Navigator.popUntil(context, ModalRoute.withName('/')); } @@ -455,7 +461,8 @@ class _ManagePlantScreen extends State { } _loadPlants() async { - List allPlants = objectbox.plantBox.getAll(); + List allPlants = await garden.getAllPlants(); + setState(() => _plants = allPlants); } diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 782f5f8..68c47bf 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; - import 'package:florae/notifications.dart' as notify; import 'package:flutter/services.dart'; - import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:shared_preferences/shared_preferences.dart'; diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..9f4157e --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,879 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + sha256: "0c80aeab9bc807ab10022cd3b2f4cf2ecdf231949dc1ddd9442406a003f19201" + url: "https://pub.dev" + source: hosted + version: "52.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + sha256: cd8ee83568a77f3ae6b913a36093a1c9b1264e7cb7f834d9ddd2311dade9c1f4 + url: "https://pub.dev" + source: hosted + version: "5.4.0" + args: + dependency: transitive + description: + name: args + sha256: "139d809800a412ebb26a3892da228b2d0ba36f0ef5d9a82166e5e52ec8d61611" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + async: + dependency: transitive + description: + name: async + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" + source: hosted + version: "2.10.0" + background_fetch: + dependency: "direct main" + description: + name: background_fetch + sha256: c49953b72c42e4851cd3837bd2488fab84c0e653260293d9f4730ff00d4b3f99 + url: "https://pub.dev" + source: hosted + version: "1.1.5" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + build: + dependency: transitive + description: + name: build + sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" + url: "https://pub.dev" + source: hosted + version: "2.3.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" + source: hosted + version: "1.1.1" + build_daemon: + dependency: transitive + description: + name: build_daemon + sha256: "6bc5544ea6ce4428266e7ea680e945c68806c4aae2da0eb5e9ccf38df8d6acbf" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + sha256: "7c35a3a7868626257d8aee47b51c26b9dba11eaddf3431117ed2744951416aab" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + build_runner: + dependency: "direct dev" + description: + name: build_runner + sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727 + url: "https://pub.dev" + source: hosted + version: "2.3.3" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292" + url: "https://pub.dev" + source: hosted + version: "7.2.7" + built_collection: + dependency: transitive + description: + name: built_collection + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + sha256: "169565c8ad06adb760c3645bf71f00bff161b00002cace266cad42c5d22a7725" + url: "https://pub.dev" + source: hosted + version: "8.4.3" + characters: + dependency: transitive + description: + name: characters + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" + source: hosted + version: "1.2.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + code_builder: + dependency: transitive + description: + name: code_builder + sha256: "0d43dd1288fd145de1ecc9a3948ad4a6d5a82f0a14c4fdd0892260787d975cbe" + url: "https://pub.dev" + source: hosted + version: "4.4.0" + collection: + dependency: transitive + description: + name: collection + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" + source: hosted + version: "1.17.0" + convert: + dependency: transitive + description: + name: convert + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" + source: hosted + version: "3.1.1" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: f71079978789bc2fe78d79227f1f8cfe195b31bbd8db2399b0d15a4b96fb843b + url: "https://pub.dev" + source: hosted + version: "0.3.3+2" + crypto: + dependency: transitive + description: + name: crypto + sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + url: "https://pub.dev" + source: hosted + version: "3.0.2" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + url: "https://pub.dev" + source: hosted + version: "1.0.5" + dart_style: + dependency: transitive + description: + name: dart_style + sha256: "7a03456c3490394c8e7665890333e91ae8a49be43542b616e414449ac358acd4" + url: "https://pub.dev" + source: hosted + version: "2.2.4" + dbus: + dependency: transitive + description: + name: dbus + sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + url: "https://pub.dev" + source: hosted + version: "0.7.8" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + file: + dependency: transitive + description: + name: file + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.dev" + source: hosted + version: "6.1.4" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: b543301ad291598523947dc534aaddc5aaad597b709d2426d3a0e0d44c5cb493 + url: "https://pub.dev" + source: hosted + version: "1.0.4" + flutter_local_notifications: + dependency: "direct main" + description: + name: flutter_local_notifications + sha256: "57d0012730780fe137260dd180e072c18a73fbeeb924cdc029c18aaa0f338d64" + url: "https://pub.dev" + source: hosted + version: "9.9.1" + flutter_local_notifications_linux: + dependency: transitive + description: + name: flutter_local_notifications_linux + sha256: b472bfc173791b59ede323661eae20f7fff0b6908fea33dd720a6ef5d576bae8 + url: "https://pub.dev" + source: hosted + version: "0.5.1" + flutter_local_notifications_platform_interface: + dependency: transitive + description: + name: flutter_local_notifications_platform_interface + sha256: "21bceee103a66a53b30ea9daf677f990e5b9e89b62f222e60dd241cd08d63d3a" + url: "https://pub.dev" + source: hosted + version: "5.0.0" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b" + url: "https://pub.dev" + source: hosted + version: "2.0.7" + flutter_svg: + dependency: "direct main" + description: + name: flutter_svg + sha256: f991fdb1533c3caeee0cdc14b04f50f0c3916f0dbcbc05237ccbe4e3c6b93f3f + url: "https://pub.dev" + source: hosted + version: "2.0.5" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + url: "https://pub.dev" + source: hosted + version: "3.2.0" + glob: + dependency: transitive + description: + name: glob + sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + graphs: + dependency: transitive + description: + name: graphs + sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2 + url: "https://pub.dev" + source: hosted + version: "2.2.0" + http: + dependency: transitive + description: + name: http + sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + url: "https://pub.dev" + source: hosted + version: "0.13.5" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" + source: hosted + version: "3.2.1" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" + source: hosted + version: "4.0.2" + image_picker: + dependency: "direct main" + description: + name: image_picker + sha256: f98d76672d309c8b7030c323b3394669e122d52b307d2bbd8d06bd70f5b2aabe + url: "https://pub.dev" + source: hosted + version: "0.8.6+1" + image_picker_android: + dependency: transitive + description: + name: image_picker_android + sha256: b1cbfec0f5aef427a18eb573f5445af8c9c568626bf3388553e40c263d3f7368 + url: "https://pub.dev" + source: hosted + version: "0.8.5+5" + image_picker_for_web: + dependency: transitive + description: + name: image_picker_for_web + sha256: "7d319fb74955ca46d9bf7011497860e3923bb67feebcf068f489311065863899" + url: "https://pub.dev" + source: hosted + version: "2.1.10" + image_picker_ios: + dependency: transitive + description: + name: image_picker_ios + sha256: "39c013200046d14c58b71dc4fa3d00e425fc9c699d589136cd3ca018727c0493" + url: "https://pub.dev" + source: hosted + version: "0.8.6+6" + image_picker_platform_interface: + dependency: transitive + description: + name: image_picker_platform_interface + sha256: "7cef2f28f4f2fef99180f636c3d446b4ccbafd6ba0fad2adc9a80c4040f656b8" + url: "https://pub.dev" + source: hosted + version: "2.6.2" + intl: + dependency: transitive + description: + name: intl + sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" + url: "https://pub.dev" + source: hosted + version: "0.17.0" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + js: + dependency: transitive + description: + name: js + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" + source: hosted + version: "0.6.5" + json_annotation: + dependency: "direct main" + description: + name: json_annotation + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 + url: "https://pub.dev" + source: hosted + version: "4.8.1" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + sha256: "43793352f90efa5d8b251893a63d767b2f7c833120e3cc02adad55eefec04dc7" + url: "https://pub.dev" + source: hosted + version: "6.6.2" + lints: + dependency: transitive + description: + name: lints + sha256: a2c3d198cb5ea2e179926622d433331d8b58374ab8f29cdda6e863bd62fd369c + url: "https://pub.dev" + source: hosted + version: "1.0.1" + logging: + dependency: transitive + description: + name: logging + sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + matcher: + dependency: transitive + description: + name: matcher + sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + url: "https://pub.dev" + source: hosted + version: "0.12.13" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + meta: + dependency: transitive + description: + name: meta + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" + source: hosted + version: "1.8.0" + mime: + dependency: transitive + description: + name: mime + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e + url: "https://pub.dev" + source: hosted + version: "1.0.4" + package_config: + dependency: transitive + description: + name: package_config + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + path: + dependency: transitive + description: + name: path + sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + url: "https://pub.dev" + source: hosted + version: "1.8.2" + path_parsing: + dependency: transitive + description: + name: path_parsing + sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf + url: "https://pub.dev" + source: hosted + version: "1.0.1" + path_provider: + dependency: "direct main" + description: + name: path_provider + sha256: dcea5feb97d8abf90cab9e9030b497fb7c3cbf26b7a1fe9e3ef7dcb0a1ddec95 + url: "https://pub.dev" + source: hosted + version: "2.0.12" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e + url: "https://pub.dev" + source: hosted + version: "2.0.22" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "62a68e7e1c6c459f9289859e2fae58290c981ce21d1697faf54910fe1faa4c74" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 + url: "https://pub.dev" + source: hosted + version: "2.1.7" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 + url: "https://pub.dev" + source: hosted + version: "2.0.5" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c + url: "https://pub.dev" + source: hosted + version: "2.1.3" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" + url: "https://pub.dev" + source: hosted + version: "5.1.0" + platform: + dependency: transitive + description: + name: platform + sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + url: "https://pub.dev" + source: hosted + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a + url: "https://pub.dev" + source: hosted + version: "2.1.3" + pool: + dependency: transitive + description: + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" + source: hosted + version: "1.5.1" + process: + dependency: transitive + description: + name: process + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + url: "https://pub.dev" + source: hosted + version: "4.2.4" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" + url: "https://pub.dev" + source: hosted + version: "2.1.3" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a" + url: "https://pub.dev" + source: hosted + version: "1.2.1" + quiver: + dependency: transitive + description: + name: quiver + sha256: b1c1ac5ce6688d77f65f3375a9abb9319b3cb32486bdc7a1e0fdf004d7ba4e47 + url: "https://pub.dev" + source: hosted + version: "3.2.1" + responsive_grid_list: + dependency: "direct main" + description: + name: responsive_grid_list + sha256: "682377659158e46ac7f6b4383b191bfd34ef2c5616046518b58721be370de723" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "5949029e70abe87f75cfe59d17bf5c397619c4b74a099b10116baeb34786fad9" + url: "https://pub.dev" + source: hosted + version: "2.0.17" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "955e9736a12ba776bdd261cf030232b30eadfcd9c79b32a3250dd4a494e8c8f7" + url: "https://pub.dev" + source: hosted + version: "2.0.15" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "1ffa239043ab8baf881ec3094a3c767af9d10399b2839020b9e4d44c0bb23951" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: f8ea038aa6da37090093974ebdcf4397010605fd2ff65c37a66f9d28394cb874 + url: "https://pub.dev" + source: hosted + version: "2.1.3" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: da9431745ede5ece47bc26d5d73a9d3c6936ef6945c101a5aca46f62e52c1cf3 + url: "https://pub.dev" + source: hosted + version: "2.1.0" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: a4b5bc37fe1b368bbc81f953197d55e12f49d0296e7e412dfe2d2d77d6929958 + url: "https://pub.dev" + source: hosted + version: "2.0.4" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "5eaf05ae77658d3521d0e993ede1af962d4b326cd2153d312df716dc250f00c9" + url: "https://pub.dev" + source: hosted + version: "2.1.3" + shelf: + dependency: transitive + description: + name: shelf + sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c + url: "https://pub.dev" + source: hosted + version: "1.4.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 + url: "https://pub.dev" + source: hosted + version: "1.0.3" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + sha256: "373f96cf5a8744bc9816c1ff41cf5391bbdbe3d7a96fe98c622b6738a8a7bd33" + url: "https://pub.dev" + source: hosted + version: "1.3.2" + source_helper: + dependency: transitive + description: + name: source_helper + sha256: "3b67aade1d52416149c633ba1bb36df44d97c6b51830c2198e934e3fca87ca1f" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + source_span: + dependency: transitive + description: + name: source_span + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" + source: hosted + version: "1.9.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" + source: hosted + version: "1.11.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + url: "https://pub.dev" + source: hosted + version: "0.4.16" + timezone: + dependency: transitive + description: + name: timezone + sha256: "57b35f6e8ef731f18529695bffc62f92c6189fac2e52c12d478dec1931afb66e" + url: "https://pub.dev" + source: hosted + version: "0.8.0" + timing: + dependency: transitive + description: + name: timing + sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" + url: "https://pub.dev" + source: hosted + version: "1.0.1" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + vector_graphics: + dependency: transitive + description: + name: vector_graphics + sha256: ea8d3fc7b2e0f35de38a7465063ecfcf03d8217f7962aa2a6717132cb5d43a79 + url: "https://pub.dev" + source: hosted + version: "1.1.5" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: a5eaa5d19e123ad4f61c3718ca1ed921c4e6254238d9145f82aa214955d9aced + url: "https://pub.dev" + source: hosted + version: "1.1.5" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: "15edc42f7eaa478ce854eaf1fbb9062a899c0e4e56e775dd73b7f4709c97c4ca" + url: "https://pub.dev" + source: hosted + version: "1.1.5" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + watcher: + dependency: transitive + description: + name: watcher + sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b + url: "https://pub.dev" + source: hosted + version: "2.3.0" + win32: + dependency: transitive + description: + name: win32 + sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 + url: "https://pub.dev" + source: hosted + version: "3.1.3" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: bd512f03919aac5f1313eb8249f223bacf4927031bf60b02601f81f687689e86 + url: "https://pub.dev" + source: hosted + version: "0.2.0+3" + xml: + dependency: transitive + description: + name: xml + sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5" + url: "https://pub.dev" + source: hosted + version: "6.2.2" + yaml: + dependency: transitive + description: + name: yaml + sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" + url: "https://pub.dev" + source: hosted + version: "3.1.1" +sdks: + dart: ">=2.19.0 <3.0.0" + flutter: ">=3.7.0-0" diff --git a/pubspec.yaml b/pubspec.yaml index d721eec..8263843 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 +version: 2.0.1+4 environment: sdk: ">=2.12.0 <3.0.0" @@ -34,12 +34,11 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 - objectbox: ^1.7.2 - objectbox_flutter_libs: any path_provider: ^2.0.12 image_picker: ^0.8.5+3 flutter_svg: ^2.0.5 - intl: ^0.17.0 + json_annotation: ^4.8.1 + flutter_localizations: sdk: flutter background_fetch: ^1.1.5 @@ -48,8 +47,8 @@ dependencies: responsive_grid_list: ^1.3.0 dev_dependencies: - build_runner: ^2.0.0 - objectbox_generator: any + build_runner: ^2.3.3 + json_serializable: ^6.6.2 flutter_test: sdk: flutter