From 570f4cbaeceeaabf1d9efebe8f5ce882d3c1fb78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Uek=C3=B6tter?= Date: Sun, 7 Jul 2024 10:03:48 +0200 Subject: [PATCH] localized images --- passkit/lib/src/pkpass/pk_pass_image.dart | 17 ++++++++- passkit/lib/src/pkpass/pkpass.dart | 46 +++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) diff --git a/passkit/lib/src/pkpass/pk_pass_image.dart b/passkit/lib/src/pkpass/pk_pass_image.dart index f97cc7d..30d081a 100644 --- a/passkit/lib/src/pkpass/pk_pass_image.dart +++ b/passkit/lib/src/pkpass/pk_pass_image.dart @@ -1,16 +1,18 @@ import 'dart:typed_data'; class PkPassImage { - PkPassImage({this.image1, this.image2, this.image3}); + PkPassImage({this.image1, this.image2, this.image3, this.localizedImages}); final Uint8List? image1; final Uint8List? image2; final Uint8List? image3; + final Map>? localizedImages; static PkPassImage? fromImages({ Uint8List? image1, Uint8List? image2, Uint8List? image3, + Map>? localizedImages, }) { if (image1 == null && image2 == null && image3 == null) { return null; @@ -18,8 +20,19 @@ class PkPassImage { return PkPassImage(image1: image1, image2: image2, image3: image3); } - Uint8List fromMultiplier(int multiplier) { + /// [locale] is defined according to https://developer.apple.com/documentation/xcode/choosing-localization-regions-and-scripts + Uint8List fromMultiplier(int multiplier, {String? locale}) { multiplier = multiplier.clamp(1, 3); + if (locale != null) { + final localizedImage = localizedImages?[locale]; + if (localizedImage != null) { + return switch (multiplier) { + 1 => (localizedImage[1] ?? localizedImage[2] ?? localizedImage[3])!, + 2 => (localizedImage[2] ?? localizedImage[3] ?? localizedImage[1])!, + _ => (localizedImage[3] ?? localizedImage[2] ?? localizedImage[1])!, + }; + } + } return switch (multiplier) { 1 => (image1 ?? image2 ?? image3)!, 2 => (image2 ?? image3 ?? image1)!, diff --git a/passkit/lib/src/pkpass/pkpass.dart b/passkit/lib/src/pkpass/pkpass.dart index 2e59eb0..2e36545 100644 --- a/passkit/lib/src/pkpass/pkpass.dart +++ b/passkit/lib/src/pkpass/pkpass.dart @@ -214,6 +214,51 @@ extension on Archive { return data == null ? null : Uint8List.fromList(data); } + /// Returns a map of locale to a map of resolution to image bytes. + /// Returns null, if no image is localized + Map>? loadLocalizedImage(String imageName) { + final map = >{}; + for (final file in files) { + final fileName = file.name; + if (!fileName.endsWith('.png')) { + // file is not an image + continue; + } + if (!fileName.contains(imageName)) { + // file is not the image that's been searched for + continue; + } + if (!fileName.contains('/')) { + // this is a non-localized image, which has been loaded before + continue; + } + // It can be assumed now that the image is localized + + // get the language part of the name, which is something like 'en.lpoj/icon@2x.png' + final language = fileName.split('.').first; + if (!map.containsKey(language)) { + map[language] = {}; + } + + if (fileName.endsWith('@2x.png')) { + map[language]![2] = Uint8List.fromList(file.content as List); + } else if (fileName.endsWith('@3x.png')) { + map[language]![3] = Uint8List.fromList(file.content as List); + } else { + map[language]![1] = Uint8List.fromList(file.content as List); + } + } + + map.removeWhere((lang, images) { + return images.values.isEmpty; + }); + + if (map.isEmpty) { + return null; + } + return map; + } + Map? findFileAndReadAsJson(String fileName) { final bytes = findBytesForFile(fileName); if (bytes == null) { @@ -227,6 +272,7 @@ extension on Archive { image1: findUint8ListForFile('$name.png'), image2: findUint8ListForFile('$name@2.png'), image3: findUint8ListForFile('$name@3.png'), + localizedImages: loadLocalizedImage(name), ); }