// lib/services/note_photo_service.dart // // Fotó kezelő service: // - Kamera / galéria hozzáférés (image_picker) // - Fájl mentés külső tárhelyre // - SQLite CRUD // - Opcionális Supabase Storage szinkron import 'dart:io'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:get/get.dart'; import 'package:image_picker/image_picker.dart'; import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; import '../models/note_item_photo.dart'; import '../services/app_database.dart'; class NotePhotoService extends GetxService { static NotePhotoService get to => Get.find(); final _picker = ImagePicker(); String? _photoDir; @override Future onInit() async { super.onInit(); await _initPhotoDir(); } Future _initPhotoDir() async { final ext = await getExternalStorageDirectory(); final dir = Directory(p.join(ext!.path, 'photos')); if (!await dir.exists()) await dir.create(recursive: true); _photoDir = dir.path; } // ── Fotó készítése kamerával ───────────────────────────────────── Future takePhoto(int noteItemId) async { return _pickAndSave( noteItemId: noteItemId, source: ImageSource.camera, ); } // ── Fotó választása galériából ─────────────────────────────────── Future pickFromGallery(int noteItemId) async { return _pickAndSave( noteItemId: noteItemId, source: ImageSource.gallery, ); } // ── Közös mentési logika ───────────────────────────────────────── Future _pickAndSave({ required int noteItemId, required ImageSource source, }) async { try { final picked = await _picker.pickImage( source: source, imageQuality: 85, // tömörítés a tárhelyért maxWidth: 2048, maxHeight: 2048, ); if (picked == null) return null; // felhasználó visszalépett // GPS pozíció a fotókészítés pillanatában final pos = await _currentPosition(); // Fájl másolása az app saját könyvtárába final fileName = 'photo_${noteItemId}_${DateTime.now().millisecondsSinceEpoch}.jpg'; final destPath = p.join(_photoDir!, fileName); await File(picked.path).copy(destPath); // SQLite mentés final photo = NoteItemPhoto( noteItemId: noteItemId, localPath: destPath, latitude: pos?.latitude, longitude: pos?.longitude, createdAt: DateTime.now(), ); final id = await AppDatabase.instance.insertNotePhoto(photo); return NoteItemPhoto( id: id, noteItemId: photo.noteItemId, localPath: photo.localPath, latitude: photo.latitude, longitude: photo.longitude, createdAt: photo.createdAt, ); } catch (e) { debugPrint('NotePhotoService hiba: $e'); Get.snackbar('Hiba', 'Fotó mentése sikertelen.', snackPosition: SnackPosition.BOTTOM); return null; } } // ── Fotó törlése ───────────────────────────────────────────────── Future deletePhoto(NoteItemPhoto photo) async { // Fájl törlése final file = File(photo.localPath); if (await file.exists()) await file.delete(); // SQLite törlése await AppDatabase.instance.deleteNotePhoto(photo.id!); } // ── Felirat frissítése ──────────────────────────────────────────── Future updateCaption( NoteItemPhoto photo, String caption) async { final updated = photo.copyWith(caption: caption); await AppDatabase.instance.updateNotePhoto(updated); return updated; } // ── GPS pozíció ────────────────────────────────────────────────── Future _currentPosition() async { try { return await Geolocator.getCurrentPosition( locationSettings: const LocationSettings( accuracy: LocationAccuracy.medium, timeLimit: Duration(seconds: 3), ), ).timeout(const Duration(seconds: 3)); } catch (_) { return Geolocator.getLastKnownPosition(); } } // ── Fotók betöltése ────────────────────────────────────────────── Future> loadPhotos(int noteItemId) => AppDatabase.instance.listNotePhotos(noteItemId); }