mirror of
https://gitlab.com/TheOneWithTheBraid/dart_pkpass.git
synced 2025-07-05 12:58:47 +00:00
155 lines
4 KiB
Dart
155 lines
4 KiB
Dart
import 'package:intl/locale.dart';
|
|
|
|
abstract class FileMatcher {
|
|
const FileMatcher._();
|
|
|
|
static String? matchFile({
|
|
required List<String> files,
|
|
required String name,
|
|
String extension = 'png',
|
|
int scale = 1,
|
|
Locale? locale,
|
|
}) {
|
|
final localized = matchLocale(files: files, name: 'logo', extension: 'png');
|
|
if (localized.isEmpty) return null;
|
|
final scaled = matchScale(
|
|
files: localized,
|
|
name: 'logo',
|
|
extension: 'png',
|
|
scale: scale,
|
|
);
|
|
final file = files.singleWhere((element) => element == scaled);
|
|
return file;
|
|
}
|
|
|
|
static List<String> matchLocale({
|
|
required List<String> files,
|
|
Locale? locale,
|
|
required String name,
|
|
required String extension,
|
|
}) {
|
|
files.sort((a, b) {
|
|
final aLocalized = a.startsWith(RegExp('^[a-z]+(-[a-z]+)?\\.lproj\\/'));
|
|
final bLocalized = b.startsWith(RegExp('^[a-z]+(-[a-z]+)?\\.lproj\\/'));
|
|
if (aLocalized && bLocalized) {
|
|
return a.compareTo(b);
|
|
} else if (aLocalized) {
|
|
return -1;
|
|
} else {
|
|
return 1;
|
|
}
|
|
});
|
|
files = files.reversed.toList();
|
|
List<RegExp> expressions = <RegExp>[];
|
|
|
|
// adding the fallbacks
|
|
// - match only unlocalized
|
|
// - match the five mostly spoken languages of the world, copied from Wikipedia
|
|
// - match just *any* language
|
|
expressions.addAll(
|
|
[
|
|
RegExp(
|
|
'^[a-z]+(-[a-z]+)?\\.lproj\\/$name(@\\d+x)?\\.$extension\$',
|
|
unicode: true,
|
|
caseSensitive: false,
|
|
),
|
|
...['en', 'zh', 'hi', 'es', 'fr'].reversed.map(
|
|
(language) => RegExp(
|
|
'^$language(-[a-z]+)?\\.lproj\\/$name(@\\d+x)?\\.$extension\$',
|
|
unicode: true,
|
|
caseSensitive: false,
|
|
),
|
|
),
|
|
RegExp(
|
|
'^$name(@\\d+x)?\\.$extension\$',
|
|
unicode: true,
|
|
caseSensitive: false,
|
|
),
|
|
],
|
|
);
|
|
|
|
if (locale != null) {
|
|
final language = locale.languageCode;
|
|
expressions.add(
|
|
RegExp(
|
|
'^$language(-[a-z]+)?\\.lproj\\/$name(@\\d+x)?\\.$extension\$',
|
|
unicode: true,
|
|
caseSensitive: false,
|
|
),
|
|
);
|
|
|
|
final region = locale.countryCode;
|
|
if (region != null) {
|
|
expressions.add(
|
|
RegExp(
|
|
'^$language-$region\\.lproj\\/$name(@\\d+x)?\\.$extension\$',
|
|
unicode: true,
|
|
caseSensitive: false,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
for (final regex in expressions.reversed) {
|
|
final matches = <String>[];
|
|
for (final file in files) {
|
|
final match = regex.stringMatch(file);
|
|
if (match != null) matches.add(match);
|
|
}
|
|
if (matches.isNotEmpty) return matches;
|
|
}
|
|
return [];
|
|
}
|
|
|
|
static String matchScale({
|
|
required List<String> files,
|
|
int scale = 1,
|
|
required String name,
|
|
required String extension,
|
|
}) {
|
|
files.sort();
|
|
files = files.reversed.toList();
|
|
|
|
final regex = RegExp(
|
|
'$name(@(\\d+)x)?\\.$extension\$',
|
|
unicode: true,
|
|
caseSensitive: false,
|
|
);
|
|
|
|
int closestScale = 0;
|
|
|
|
final matches = <String>[];
|
|
for (final file in files) {
|
|
final match = regex.firstMatch(file);
|
|
if (match != null) {
|
|
String? group = match[2];
|
|
if (group == null) {
|
|
if (scale == 1) return match.input;
|
|
group = '1';
|
|
}
|
|
|
|
final matchedScale = int.parse(group);
|
|
if (matchedScale == scale) return match.input;
|
|
|
|
if (matchedScale < scale) {
|
|
if (closestScale < matchedScale) closestScale = matchedScale;
|
|
} else if (closestScale < matchedScale) {
|
|
closestScale = matchedScale;
|
|
}
|
|
|
|
matches.add(match.input);
|
|
}
|
|
}
|
|
final scaledMatches = matches
|
|
.where(
|
|
(element) => RegExp(
|
|
'$name(@${closestScale}x)?\\.$extension\$',
|
|
unicode: true,
|
|
caseSensitive: false,
|
|
).hasMatch(element),
|
|
)
|
|
.toList();
|
|
scaledMatches.sort();
|
|
return scaledMatches.last;
|
|
}
|
|
}
|