Add Progress Photos feature for plant growth tracking (Phase 8)
Implement progress photo capture with HEIC compression and thumbnail generation, gallery view with grid display and full-size viewing, time-lapse playback with adjustable speed, and photo reminder notifications at weekly/biweekly/monthly intervals. New files: - ProgressPhoto domain entity with imageData and thumbnailData - ProgressPhotoRepositoryProtocol and CoreDataProgressPhotoRepository - CaptureProgressPhotoUseCase with image compression/resizing - SchedulePhotoReminderUseCase with notification scheduling - ProgressPhotosViewModel, ProgressPhotoGalleryView - ProgressPhotoCaptureView, TimeLapsePlayerView Modified: - PlantMO with progressPhotos relationship - Core Data model with ProgressPhotoMO entity - NotificationService with photo reminder support - PlantDetailView with Progress Photos section - DIContainer with photo service registrations Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -72,6 +72,9 @@ struct PlantDetailView: View {
|
||||
|
||||
// Identification info
|
||||
identificationInfoSection
|
||||
|
||||
// Progress photos section
|
||||
progressPhotosSection
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
@@ -359,6 +362,64 @@ struct PlantDetailView: View {
|
||||
.cornerRadius(12)
|
||||
}
|
||||
|
||||
// MARK: - Progress Photos Section
|
||||
|
||||
private var progressPhotosSection: some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
HStack {
|
||||
Text("Progress Photos")
|
||||
.font(.headline)
|
||||
Spacer()
|
||||
Text("\(viewModel.progressPhotoCount) photos")
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
|
||||
NavigationLink {
|
||||
ProgressPhotoGalleryView(
|
||||
plantID: viewModel.plant.id,
|
||||
plantName: viewModel.displayName
|
||||
)
|
||||
} label: {
|
||||
HStack {
|
||||
// Recent thumbnail or placeholder
|
||||
if let recentThumbnail = viewModel.recentProgressPhotoThumbnail {
|
||||
Image(uiImage: UIImage(data: recentThumbnail) ?? UIImage())
|
||||
.resizable()
|
||||
.aspectRatio(contentMode: .fill)
|
||||
.frame(width: 60, height: 60)
|
||||
.clipShape(RoundedRectangle(cornerRadius: 8))
|
||||
} else {
|
||||
RoundedRectangle(cornerRadius: 8)
|
||||
.fill(Color(.systemGray5))
|
||||
.frame(width: 60, height: 60)
|
||||
.overlay {
|
||||
Image(systemName: "camera")
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Text("View Gallery")
|
||||
.font(.subheadline)
|
||||
Text("Track your plant's growth")
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
Image(systemName: "chevron.right")
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
}
|
||||
.padding()
|
||||
.background(Color(.systemGray6))
|
||||
.cornerRadius(12)
|
||||
}
|
||||
|
||||
// MARK: - Private Helpers
|
||||
|
||||
private var identificationSourceDescription: String {
|
||||
|
||||
Reference in New Issue
Block a user