Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib/app/home/views/home_screen.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
Expand Down Expand Up @@ -108,7 +109,8 @@ class _HomeScreenState extends ConsumerState<HomeScreen> {
Widget buildPetListTile(PetModel pet) {
return ListTile(
leading: CircleAvatar(
child: Icon(Icons.pets, semanticLabel: 'Pet Icon', color: Colors.white),
backgroundImage: pet.imageUrl != null ? FileImage(File(pet.imageUrl!)) : null,
child: pet.imageUrl == null ? const Icon(Icons.pets, semanticLabel: 'Pet Icon', color: Colors.white) : null,
),
title: Text(pet.name),
subtitle: Text(getPetSubTitle(pet)),
Expand Down
4 changes: 2 additions & 2 deletions lib/app/pet/controller/all_pets_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ class AllPetsController extends _$AllPetsController {
);
}



Future<PetModel?> save(PetModel pet) async {
if (pet.petId == null) {
final newPet = await _databaseService.createPet(
Expand All @@ -41,6 +39,7 @@ class AllPetsController extends _$AllPetsController {
pet.microchipNumber,
pet.microchipCompany,
pet.microchipNotes,
pet.imageUrl,
);

return newPet == null ? null : PetMapper.mapToModel(newPet);
Expand All @@ -66,6 +65,7 @@ class AllPetsController extends _$AllPetsController {
pet.microchipNumber,
pet.microchipCompany,
pet.microchipNotes,
pet.imageUrl,
);
return pet;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/app/pet/controller/all_pets_controller.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions lib/app/pet/models/pet_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ abstract class PetModel with _$PetModel {
String? microchipNotes,
String? microchipNumber,
String? microchipCompany,
String? imageUrl,
}) = _PetModel;

factory PetModel.fromJson(Map<String, Object?> json) =>
Expand Down
31 changes: 17 additions & 14 deletions lib/app/pet/models/pet_model.freezed.dart

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions lib/app/pet/models/pet_model.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

92 changes: 91 additions & 1 deletion lib/app/pet/views/edit_pet_screen.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:io';

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:petjournal/app/pet/controller/all_pets_controller.dart';
import 'package:petjournal/app/pet/views/widgets/pet_sex_dropdown.dart';
Expand All @@ -6,6 +8,7 @@ import 'package:petjournal/app/species/views/widgets/species_dropdown.dart';
import 'package:petjournal/data/lookups/species_lookup.dart';
import 'package:petjournal/extensions/material_colors.dart';
import 'package:flutter/material.dart';
import 'package:petjournal/helpers/image_service.dart';
import 'package:petjournal/widgets/date_field.dart';
import 'package:go_router/go_router.dart';
import 'package:petjournal/route_config.dart';
Expand Down Expand Up @@ -71,6 +74,8 @@ class _EditPetScreenState extends ConsumerState<EditPetScreen> {
SpeciesModel? _selectedSpecies; // Nullable until selected
bool _isMicrochipped = false;
DateTime? _microchipDate;
String? _imageUrl;
bool _imageChanged = false;

@override
void initState() {
Expand All @@ -95,7 +100,6 @@ class _EditPetScreenState extends ConsumerState<EditPetScreen> {
_status = widget.pet?.status ?? PetStatus.active;
_selectedSpecies = SpeciesLookup().getSpecies(widget.pet?.speciesId ?? 0);

//)
_isMicrochipped = widget.pet?.isMicrochipped ?? false;
_microchipDate = widget.pet?.microchipDate;
_microchipNotesController = TextEditingController(
Expand All @@ -107,6 +111,7 @@ class _EditPetScreenState extends ConsumerState<EditPetScreen> {
_microchipCompanyController = TextEditingController(
text: widget.pet?.microchipCompany ?? '',
);
_imageUrl = widget.pet?.imageUrl;
}

@override
Expand Down Expand Up @@ -195,6 +200,45 @@ class _EditPetScreenState extends ConsumerState<EditPetScreen> {
child: SingleChildScrollView(
child: Column(
children: [
CircleAvatar(
radius: 75,
backgroundImage: _imageUrl != null
? FileImage(File(_imageUrl!))
: null,
child: _imageUrl == null
? const Icon(
Icons.pets,
semanticLabel: 'Pet Icon',
color: Colors.white,
size: 75,
)
: null,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_imageUrl == null)
TextButton.icon(
onPressed: _pickImage,
label: Text('Add picture'),
icon: const Icon(Icons.camera_alt),
),
if (_imageUrl != null)
TextButton.icon(
onPressed: _pickImage,
label: Text('Change'),
icon: const Icon(Icons.edit),
),
if (_imageUrl != null)
TextButton.icon(
label: Text('Remove'),
icon: const Icon(Icons.delete),
onPressed: _flagImageForRemoving,
),
],
),
const SizedBox(height: 12),

_buildSectionHeader('Basic Information'),
TextFormField(
key: EditPetScreen.petNameKey,
Expand Down Expand Up @@ -526,6 +570,19 @@ class _EditPetScreenState extends ConsumerState<EditPetScreen> {
}

Future<int?> _saveData() async {
// If the image has been changed, save the image to the app directory
String? fullImageUrl;
if (_imageChanged) {
if (_imageUrl == null) {
await _removeImage();
fullImageUrl = null;
} else {
fullImageUrl = await _saveImage();
}
} else {
fullImageUrl = _imageUrl;
}

// Construct the Pet object
final PetModel petData = PetModel(
petId: widget.pet?.petId,
Expand Down Expand Up @@ -562,6 +619,7 @@ class _EditPetScreenState extends ConsumerState<EditPetScreen> {
_isMicrochipped && _microchipCompanyController.text.isNotEmpty
? _microchipCompanyController.text
: null,
imageUrl: fullImageUrl,
);

final controller = ref.read(allPetsControllerProvider.notifier);
Expand Down Expand Up @@ -666,4 +724,36 @@ class _EditPetScreenState extends ConsumerState<EditPetScreen> {
}
}
}

Future<void> _pickImage() async {
final imageService = ImageService();
final image = await imageService.pickImage();
if (image != null) {
setState(() {
_imageUrl = image.path;
_imageChanged = true;
_unsavedChanges = true;
});
}
}

Future<void> _flagImageForRemoving() async {
setState(() {
_imageUrl = null;
_imageChanged = true;
_unsavedChanges = true;
});
}

Future<void> _removeImage() async {
if (widget.pet == null || widget.pet!.imageUrl == null) return;

final imageService = ImageService();
await imageService.deleteImage(widget.pet!.imageUrl!);
}

Future<String> _saveImage() async {
final imageService = ImageService();
return await imageService.saveImage(_imageUrl!);
}
}
38 changes: 25 additions & 13 deletions lib/app/pet/views/view_pet_screen.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'dart:io';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:petjournal/app/pet/controller/pet_controller.dart';
Expand Down Expand Up @@ -54,21 +55,32 @@ class _ViewPetScreenState extends ConsumerState<ViewPetScreen> {
},
),
],
bottom: const TabBar(
tabs: [
Tab(icon: Icon(Icons.info), text: 'General'),
Tab(icon: Icon(Icons.medical_services), text: 'Health'),
Tab(icon: Icon(Icons.balance), text: 'Weight'),
Tab(icon: Icon(Icons.content_paste), text: 'Journal'),
],
),
),
body: TabBarView(
body: Column(
children: [
_buildGeneralInfoTab(pet),
_buildPetMedsAndVaccinationInfoTab(pet),
_buildPetWeightInfoTab(pet),
_buildPetJournalTab(pet),
if (pet.imageUrl != null)
CircleAvatar(
radius: 75,
backgroundImage: FileImage(File(pet.imageUrl!)),
),
const TabBar(
tabs: [
Tab(icon: Icon(Icons.info), text: 'General'),
Tab(icon: Icon(Icons.medical_services), text: 'Health'),
Tab(icon: Icon(Icons.balance), text: 'Weight'),
Tab(icon: Icon(Icons.content_paste), text: 'Journal'),
],
),
Expanded(
child: TabBarView(
children: [
_buildGeneralInfoTab(pet),
_buildPetMedsAndVaccinationInfoTab(pet),
_buildPetWeightInfoTab(pet),
_buildPetJournalTab(pet),
],
),
),
],
),
floatingActionButton: ExpandableFab(
Expand Down
7 changes: 7 additions & 0 deletions lib/data/database/database_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ class DatabaseService extends _$DatabaseService {
String? microchipNumber,
String? microchipCompany,
String? microchipNotes,
String? imageUrl,
) {
return into(pets).insertReturningOrNull(
PetsCompanion.insert(
Expand All @@ -131,6 +132,7 @@ class DatabaseService extends _$DatabaseService {
microchipNotes: Value(microchipNotes),
microchipNumber: Value(microchipNumber),
microchipCompany: Value(microchipCompany),
imageUrl: Value(imageUrl),
),
);
}
Expand All @@ -157,6 +159,7 @@ class DatabaseService extends _$DatabaseService {
String? microchipNumber,
String? microchipCompany,
String? microchipNotes,
String? imageUrl,
) {
return (update(pets)..where((p) => p.petId.equals(id))).write(
PetsCompanion.insert(
Expand All @@ -183,6 +186,7 @@ class DatabaseService extends _$DatabaseService {
microchipNotes: Value(microchipNotes),
microchipNumber: Value(microchipNumber),
microchipCompany: Value(microchipCompany),
imageUrl: Value(imageUrl),
),
);
}
Expand Down Expand Up @@ -891,6 +895,7 @@ class DatabaseService extends _$DatabaseService {
'microchip number',
'microchip company',
'microchip notes',
null,
);

await createPet(
Expand All @@ -912,6 +917,7 @@ class DatabaseService extends _$DatabaseService {
'microchip number',
'microchip company',
'microchip notes',
null,
);

await createPet(
Expand All @@ -933,6 +939,7 @@ class DatabaseService extends _$DatabaseService {
null,
null,
null,
null,
);
}

Expand Down
Loading