Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(passkit): Support for localized images #63

Merged
merged 1 commit into from
Jul 7, 2024
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
17 changes: 15 additions & 2 deletions passkit/lib/src/pkpass/pk_pass_image.dart
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
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<String, Map<int, Uint8List>>? localizedImages;

static PkPassImage? fromImages({
Uint8List? image1,
Uint8List? image2,
Uint8List? image3,
Map<String, Map<int, Uint8List>>? localizedImages,
}) {
if (image1 == null && image2 == null && image3 == null) {
return null;
}
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)!,
Expand Down
46 changes: 46 additions & 0 deletions passkit/lib/src/pkpass/pkpass.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, Map<int, Uint8List>>? loadLocalizedImage(String imageName) {
final map = <String, Map<int, Uint8List>>{};
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<int>);
} else if (fileName.endsWith('@3x.png')) {
map[language]![3] = Uint8List.fromList(file.content as List<int>);
} else {
map[language]![1] = Uint8List.fromList(file.content as List<int>);
}
}

map.removeWhere((lang, images) {
return images.values.isEmpty;
});

if (map.isEmpty) {
return null;
}
return map;
}

Map<String, dynamic>? findFileAndReadAsJson(String fileName) {
final bytes = findBytesForFile(fileName);
if (bytes == null) {
Expand All @@ -227,6 +272,7 @@ extension on Archive {
image1: findUint8ListForFile('$name.png'),
image2: findUint8ListForFile('$name@2.png'),
image3: findUint8ListForFile('$name@3.png'),
localizedImages: loadLocalizedImage(name),
);
}

Expand Down