import 'dart:io'; import 'dart:math'; import 'package:firebase_core/firebase_core.dart' as firebase_core; import 'package:http/http.dart' as http; import 'package:image_picker/image_picker.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'dart:typed_data'; class ImageService { // Ladda upp en bild och returnera nedladdnings-URL eller null vid fel Future upload(XFile? image) async { if (image == null) { print('Ingen bild vald att ladda upp'); return null; } File file = File(image.path); final String filename = image.name; /* För framtiden om det blir krockar med filnamn, använd uuid-funktionen Skapa ett unikt filnamn (med mappar) för att undvika krockar var uuid = Uuid(); var uuidV4 = uuid.v4(); */ final String filenameUnique = 'media/$filename'; final storage = FirebaseStorage.instance; final mediaRef = storage.ref().child(filenameUnique); try { // Ladda upp filen till Firebase Storage await mediaRef.putFile(file); // Hämta nedladdnings-URL String downloadUrl = await mediaRef.getDownloadURL(); // Viktigt: Spara `filenameUnique` i din databas så du kan hitta filen senare! print('Bild uppladdad: $filenameUnique'); print('Download URL: $downloadUrl'); return downloadUrl; } on firebase_core.FirebaseException catch (e) { print('Misslyckades med att spara fil i Firebase Storage: ${e.code}'); print(e.message); return null; } } // Future isDefaultGoogleAvatar(String? photoUrl) async { // if (photoUrl == null || photoUrl.isEmpty) return true; // // try { // final response = await http.head(Uri.parse(photoUrl)); // final contentType = response.headers['content-type']; // // print('Content type: ${contentType == 'image/png'}'); // return contentType == 'image/png'; // Defaults are PNG // } catch (e) { // Fail safe: assume default if request fails // return true; // } // } /// SVG till firebase för att inte förstöra dicebear api /// Styles: https://www.dicebear.com/playground/ /// "identicon" - Teams icons /// "rings" - Teams icons /// "avataaars-neutral" - User icons /// Go to url above and grab any style you want to use /// @Method /// Takes a Style and builds a url to a random seed icon for that style then uploads it to firebase and returns the firebase url Future diceStyleToStorageUrl(String style) async { String seedIcon = await randomSeedIcon(); String diceBearUrl = 'https://api.dicebear.com/9.x/$style/svg?Seed=$seedIcon'; final svgData = await fetchSvg(diceBearUrl); final firebaseImageUrl = await uploadSvgDataToFirebase(svgData, 'avatars/$style/$seedIcon.svg'); return firebaseImageUrl; } Future fetchSvg(String url) async { final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { return response.body; } else { throw Exception('Failed to load SVG'); } } Future uploadSvgDataToFirebase(String svgData, String storagePath) async { final storageRef = FirebaseStorage.instance.ref().child(storagePath); final svgBytes = Uint8List.fromList(svgData.codeUnits); final metadata = SettableMetadata(contentType: 'image/svg+xml'); final uploadTask = await storageRef.putData(svgBytes, metadata); return uploadTask.ref.getDownloadURL(); } Future randomSeedIcon() async { final random = Random(); return allSeedNames[random.nextInt(allSeedNames.length)]; } /// Not actually all seed names. /// In playground some names dont exist but if there´s a "miss" you still get a random one. /// Better would be to take a style and use provided parameters to build a random icon based on that style but its more work final List allSeedNames = [ 'Adrian', 'Aiden', 'Alexander', 'Amaya', 'Andrea', 'Avery', 'Brian', 'Chase', 'Christian', 'Christopher', 'Destiny', 'Easton', 'Eden', 'Eliza', 'Emery', 'Jack', 'Jade', 'Jameson', 'Jessica', 'Jude', 'Kingston', 'Leah', 'Leo', 'Liam', 'Liliana', 'Mackenzie', 'Maria', 'Mason', 'Oliver', 'Robert', 'Ryan', 'Ryker', 'Sadie', 'Sara', 'Sarah', 'Sawyer', 'Sophia', 'Valentina', 'Vivian', 'Wyatt' ]; }