-
Notifications
You must be signed in to change notification settings - Fork 117
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is a first pass to refactor and simplify the appstream code. Some of the main changes: - Removed _late_ class variables by using a factory to compute values - Extracted AppstreamComponent localization logic to extension methods - Removed some dead code and comments - Enable prefer single quotes lint
- Loading branch information
Tim Holmes-Mitra
committed
Sep 8, 2023
1 parent
ca54b38
commit 8da843a
Showing
4 changed files
with
109 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,66 +1,69 @@ | ||
import 'dart:io'; | ||
import 'dart:ui'; | ||
|
||
import 'package:appstream/appstream.dart'; | ||
import 'package:collection/collection.dart'; | ||
|
||
// TODO: uncomment once we re-add packagekit | ||
// import 'package:packagekit/packagekit.dart'; | ||
// import 'package:ubuntu_service/ubuntu_service.dart'; | ||
|
||
String? bestLanguageKey(Iterable<String> keys, {Locale? locale}) { | ||
locale ??= PlatformDispatcher.instance.locale; | ||
if (locale.toLanguageTag() != 'und') { | ||
var key = '${locale.languageCode}_${locale.countryCode}'; | ||
if (keys.contains(key)) return key; | ||
key = locale.languageCode; | ||
if (keys.contains(key)) return key; | ||
|
||
extension _GetOrDefault<K, V> on Map<K, V> { | ||
V getOrDefault(K? key, V fallback) { | ||
if (key == null) { | ||
return fallback; | ||
} | ||
|
||
return this[key] ?? fallback; | ||
} | ||
const fallback = 'C'; | ||
if (keys.contains(fallback)) return fallback; | ||
return null; | ||
} | ||
|
||
extension LocalizedComponent on AppstreamComponent { | ||
String localizedName({Locale? locale}) => | ||
name[bestLanguageKey(name.keys, locale: locale)] ?? ''; | ||
String localizedSummary({Locale? locale}) => | ||
summary[bestLanguageKey(summary.keys, locale: locale)] ?? ''; | ||
String localizedDescription({Locale? locale}) => | ||
description[bestLanguageKey(description.keys, locale: locale)] ?? ''; | ||
} | ||
String getId() => id.toLowerCase(); | ||
String getPackage() => package?.toLowerCase() ?? ''; | ||
|
||
String getLocalizedName() { | ||
final key = bestLanguageKey(name); | ||
return name.getOrDefault(key, ''); | ||
} | ||
|
||
List<String> getLocalizedKeywords() { | ||
final key = bestLanguageKey(keywords); | ||
return keywords.getOrDefault(key, []); | ||
} | ||
|
||
String getLocalizedSummary() { | ||
final key = bestLanguageKey(summary); | ||
return summary.getOrDefault(key, ''); | ||
} | ||
|
||
String getLocalizedDescription() { | ||
final key = bestLanguageKey(description); | ||
return description.getOrDefault(key, ''); | ||
} | ||
|
||
// TODO: uncomment once we re-add packagekit | ||
// extension PackageKitId on AppstreamComponent { | ||
// Future<PackageKitPackageId> get packageKitId => | ||
// getService<PackageService>().resolve(package ?? id); | ||
// } | ||
|
||
int _sizeComparison(int? a, int? b) => a?.compareTo(b ?? 0) ?? 0; | ||
|
||
extension Icons on AppstreamComponent { | ||
String? get icon { | ||
final cached = icons.whereType<AppstreamCachedIcon>().toList(); | ||
cached.sort((a, b) => _sizeComparison(b.width, a.width)); | ||
//for (final icon in cached) { | ||
// XXX: we need the origin to determine if a cached icon exists on disk | ||
// (https://github.com/canonical/appstream.dart/issues/25) | ||
//} | ||
|
||
final local = icons.whereType<AppstreamLocalIcon>().toList(); | ||
local.sort((a, b) => _sizeComparison(b.width, a.width)); | ||
for (final icon in local) { | ||
if (File(icon.filename).existsSync()) { | ||
return icon.filename; | ||
List<String> getLocalizedMediaTypes() { | ||
final List<String> mediaTypes = []; | ||
|
||
for (final provider in provides) { | ||
if (provider is AppstreamProvidesMediatype) { | ||
mediaTypes.add(provider.mediaType.toLowerCase()); | ||
} | ||
} | ||
|
||
final stock = icons.whereType<AppstreamStockIcon>().firstOrNull; | ||
if (stock != null) { | ||
// TODO: check whether the stock icon exists on disk, and return it | ||
return mediaTypes; | ||
} | ||
|
||
String? bestLanguageKey<T>(Map<String, T> keyedByLanguage) { | ||
final locale = PlatformDispatcher.instance.locale; | ||
|
||
if (locale.toLanguageTag() == 'und') return null; | ||
|
||
final countryCode = locale.countryCode; | ||
final languageCode = locale.languageCode; | ||
final fullLocale = '${languageCode}_$countryCode'; | ||
const fallback = 'C'; | ||
final candidates = [fullLocale, languageCode, fallback]; | ||
final keys = keyedByLanguage.keys; | ||
|
||
for (final String candidate in candidates) { | ||
if (keys.contains(candidate)) return candidate; | ||
} | ||
|
||
final remote = icons.whereType<AppstreamRemoteIcon>().firstOrNull; | ||
return remote?.url; | ||
return null; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters