This commit is contained in:
Thibault Deckers 2023-03-24 17:29:50 +01:00
parent 25dc291ba4
commit e8893f7f07
54 changed files with 207 additions and 191 deletions

View file

@ -9,7 +9,7 @@ import 'package:aves/ref/mime_types.dart';
import 'package:aves/services/common/services.dart'; import 'package:aves/services/common/services.dart';
import 'package:aves/services/metadata/svg_metadata_service.dart'; import 'package:aves/services/metadata/svg_metadata_service.dart';
import 'package:aves/theme/colors.dart'; import 'package:aves/theme/colors.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/text.dart';
import 'package:aves/widgets/viewer/info/metadata/metadata_dir.dart'; import 'package:aves/widgets/viewer/info/metadata/metadata_dir.dart';
import 'package:aves_model/aves_model.dart'; import 'package:aves_model/aves_model.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
@ -115,7 +115,7 @@ extension ExtraAvesEntryInfo on AvesEntry {
final dirName = [ final dirName = [
'Stream ${index.toString().padLeft(indexDigits, '0')}', 'Stream ${index.toString().padLeft(indexDigits, '0')}',
typeText, typeText,
].join(Constants.separator); ].join(AText.separator);
final formattedStreamTags = VideoMetadataFormatter.formatInfo(stream); final formattedStreamTags = VideoMetadataFormatter.formatInfo(stream);
if (formattedStreamTags.isNotEmpty) { if (formattedStreamTags.isNotEmpty) {
final color = colors.fromString(typeText); final color = colors.fromString(typeText);

View file

@ -3,6 +3,8 @@ import 'dart:ui';
import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/ref/mime_types.dart'; import 'package:aves/ref/mime_types.dart';
import 'package:aves/ref/unicode.dart';
import 'package:aves/theme/text.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
extension ExtraAvesEntryProps on AvesEntry { extension ExtraAvesEntryProps on AvesEntry {
@ -81,15 +83,12 @@ extension ExtraAvesEntryProps on AvesEntry {
bool get canRemoveMetadata => MimeTypes.canRemoveMetadata(mimeType); bool get canRemoveMetadata => MimeTypes.canRemoveMetadata(mimeType);
static const ratioSeparator = '\u2236';
static const resolutionSeparator = ' \u00D7 ';
bool get isSized => width > 0 && height > 0; bool get isSized => width > 0 && height > 0;
String get resolutionText { String get resolutionText {
final ws = width; final ws = width;
final hs = height; final hs = height;
return isRotated ? '$hs$resolutionSeparator$ws' : '$ws$resolutionSeparator$hs'; return isRotated ? '$hs${AText.resolutionSeparator}$ws' : '$ws${AText.resolutionSeparator}$hs';
} }
String get aspectRatioText { String get aspectRatioText {
@ -97,9 +96,9 @@ extension ExtraAvesEntryProps on AvesEntry {
final gcd = width.gcd(height); final gcd = width.gcd(height);
final w = width ~/ gcd; final w = width ~/ gcd;
final h = height ~/ gcd; final h = height ~/ gcd;
return isRotated ? '$h$ratioSeparator$w' : '$w$ratioSeparator$h'; return isRotated ? '$h${Unicode.ratio}$w' : '$w${Unicode.ratio}$h';
} else { } else {
return '?$ratioSeparator?'; return '?${Unicode.ratio}?';
} }
} }

View file

@ -5,7 +5,6 @@ import 'package:aves/model/settings/enums/coordinate_format.dart';
import 'package:aves/model/settings/enums/enums.dart'; import 'package:aves/model/settings/enums/enums.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/aves_app.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves_map/aves_map.dart'; import 'package:aves_map/aves_map.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -61,7 +60,7 @@ class CoordinateFilter extends CollectionFilter {
bool get exclusiveProp => false; bool get exclusiveProp => false;
@override @override
String get universalLabel => _formatBounds(lookupAppLocalizations(AvesApp.supportedLocales.first), CoordinateFormat.decimal); String get universalLabel => _formatBounds(lookupAppLocalizations(AppLocalizations.supportedLocales.first), CoordinateFormat.decimal);
@override @override
String getLabel(BuildContext context) => _formatBounds(context.l10n, context.read<Settings>().coordinateFormat); String getLabel(BuildContext context) => _formatBounds(context.l10n, context.read<Settings>().coordinateFormat);

View file

@ -1,4 +1,5 @@
import 'package:aves/model/filters/filters.dart'; import 'package:aves/model/filters/filters.dart';
import 'package:aves/ref/unicode.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
@ -67,7 +68,7 @@ class RatingFilter extends CollectionFilter {
case 0: case 0:
return context.l10n.filterNoRatingLabel; return context.l10n.filterNoRatingLabel;
default: default:
return '\u2B50' * rating; return Unicode.whiteMediumStar * rating;
} }
} }
} }

View file

@ -1,11 +1,11 @@
import 'package:flutter/painting.dart'; import 'dart:ui';
class BrandColors { class BrandColors {
static const Color adobeAfterEffects = Color(0xFF9A9AFF); static const adobeAfterEffects = Color(0xFF9A9AFF);
static const Color adobeIllustrator = Color(0xFFFF9B00); static const adobeIllustrator = Color(0xFFFF9B00);
static const Color adobePhotoshop = Color(0xFF2DAAFF); static const adobePhotoshop = Color(0xFF2DAAFF);
static const Color android = Color(0xFF3DDC84); static const android = Color(0xFF3DDC84);
static const Color flutter = Color(0xFF47D1FD); static const flutter = Color(0xFF47D1FD);
static Color? get(String text) { static Color? get(String text) {
switch (text.toLowerCase()) { switch (text.toLowerCase()) {

15
lib/ref/poi.dart Normal file
View file

@ -0,0 +1,15 @@
import 'package:latlong2/latlong.dart';
class PointsOfInterest {
static final pointNemo = LatLng(-48.876667, -123.393333);
static final wonders = [
LatLng(29.979167, 31.134167),
LatLng(36.451000, 28.223615),
LatLng(32.5355, 44.4275),
LatLng(31.213889, 29.885556),
LatLng(37.0379, 27.4241),
LatLng(37.637861, 21.63),
LatLng(37.949722, 27.363889),
];
}

9
lib/ref/unicode.dart Normal file
View file

@ -0,0 +1,9 @@
// cf Flutter's `foundation/unicode.dart` for bidi related characters
class Unicode {
static const noBreakSpace = '\u00A0';
static const multiplicationSign = '\u00D7'; // ×
static const emDash = '\u2014'; //
static const bullet = '\u2022'; //
static const ratio = '\u2236'; //
static const whiteMediumStar = '\u2B50'; //
}

View file

@ -1,6 +1,6 @@
import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/entry.dart';
import 'package:aves/services/common/services.dart'; import 'package:aves/services/common/services.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/text.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
abstract class EmbeddedDataService { abstract class EmbeddedDataService {
@ -42,7 +42,7 @@ class PlatformEmbeddedDataService implements EmbeddedDataService {
'mimeType': entry.mimeType, 'mimeType': entry.mimeType,
'uri': entry.uri, 'uri': entry.uri,
'sizeBytes': entry.sizeBytes, 'sizeBytes': entry.sizeBytes,
'displayName': ['${entry.bestTitle}', dataUri].join(Constants.separator), 'displayName': ['${entry.bestTitle}', dataUri].join(AText.separator),
'dataUri': dataUri, 'dataUri': dataUri,
}); });
if (result != null) return result as Map; if (result != null) return result as Map;
@ -59,7 +59,7 @@ class PlatformEmbeddedDataService implements EmbeddedDataService {
'mimeType': entry.mimeType, 'mimeType': entry.mimeType,
'uri': entry.uri, 'uri': entry.uri,
'sizeBytes': entry.sizeBytes, 'sizeBytes': entry.sizeBytes,
'displayName': ['${entry.bestTitle}', 'Image'].join(Constants.separator), 'displayName': ['${entry.bestTitle}', 'Image'].join(AText.separator),
}); });
if (result != null) return result as Map; if (result != null) return result as Map;
} on PlatformException catch (e, stack) { } on PlatformException catch (e, stack) {
@ -75,7 +75,7 @@ class PlatformEmbeddedDataService implements EmbeddedDataService {
'mimeType': entry.mimeType, 'mimeType': entry.mimeType,
'uri': entry.uri, 'uri': entry.uri,
'sizeBytes': entry.sizeBytes, 'sizeBytes': entry.sizeBytes,
'displayName': ['${entry.bestTitle}', 'Video'].join(Constants.separator), 'displayName': ['${entry.bestTitle}', 'Video'].join(AText.separator),
}); });
if (result != null) return result as Map; if (result != null) return result as Map;
} on PlatformException catch (e, stack) { } on PlatformException catch (e, stack) {
@ -89,7 +89,7 @@ class PlatformEmbeddedDataService implements EmbeddedDataService {
try { try {
final result = await _platform.invokeMethod('extractVideoEmbeddedPicture', <String, dynamic>{ final result = await _platform.invokeMethod('extractVideoEmbeddedPicture', <String, dynamic>{
'uri': entry.uri, 'uri': entry.uri,
'displayName': ['${entry.bestTitle}', 'Cover'].join(Constants.separator), 'displayName': ['${entry.bestTitle}', 'Cover'].join(AText.separator),
}); });
if (result != null) return result as Map; if (result != null) return result as Map;
} on PlatformException catch (e, stack) { } on PlatformException catch (e, stack) {
@ -105,7 +105,7 @@ class PlatformEmbeddedDataService implements EmbeddedDataService {
'mimeType': entry.mimeType, 'mimeType': entry.mimeType,
'uri': entry.uri, 'uri': entry.uri,
'sizeBytes': entry.sizeBytes, 'sizeBytes': entry.sizeBytes,
'displayName': ['${entry.bestTitle}', '$props'].join(Constants.separator), 'displayName': ['${entry.bestTitle}', '$props'].join(AText.separator),
'propPath': props, 'propPath': props,
'propMimeType': propMimeType, 'propMimeType': propMimeType,
}); });

View file

@ -33,6 +33,10 @@ class AvesColorsProvider extends StatelessWidget {
} }
abstract class AvesColorsData { abstract class AvesColorsData {
static const defaultAccent = Colors.indigoAccent;
static const _neutralOnDark = Colors.white;
static const _neutralOnLight = Color(0xAA000000);
Color get neutral; Color get neutral;
Color fromHue(double hue); Color fromHue(double hue);
@ -71,9 +75,6 @@ abstract class AvesColorsData {
void clearAppColor(String album) => _appColors.remove(album); void clearAppColor(String album) => _appColors.remove(album);
static const Color _neutralOnDark = Colors.white;
static const Color _neutralOnLight = Color(0xAA000000);
// mime // mime
Color get image => fromHue(243); Color get image => fromHue(243);

View file

@ -1,4 +1,4 @@
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/text.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
String formatDay(DateTime date, String locale) => DateFormat.yMMMd(locale).format(date); String formatDay(DateTime date, String locale) => DateFormat.yMMMd(locale).format(date);
@ -8,7 +8,7 @@ String formatTime(DateTime date, String locale, bool use24hour) => (use24hour ?
String formatDateTime(DateTime date, String locale, bool use24hour) => [ String formatDateTime(DateTime date, String locale, bool use24hour) => [
formatDay(date, locale), formatDay(date, locale),
formatTime(date, locale, use24hour), formatTime(date, locale, use24hour),
].join(Constants.separator); ].join(AText.separator);
String formatFriendlyDuration(Duration d) { String formatFriendlyDuration(Duration d) {
final seconds = (d.inSeconds.remainder(Duration.secondsPerMinute)).toString().padLeft(2, '0'); final seconds = (d.inSeconds.remainder(Duration.secondsPerMinute)).toString().padLeft(2, '0');

22
lib/theme/styles.dart Normal file
View file

@ -0,0 +1,22 @@
import 'dart:ui';
import 'package:flutter/widgets.dart';
class AStyles {
// as of Flutter v2.8.0, overflowing `Text` miscalculates height and some text (e.g. 'Å') is clipped
// so we give it a `strutStyle` with a slightly larger height
static const overflowStrut = StrutStyle(height: 1.3);
static const knownTitleText = TextStyle(
fontSize: 20,
fontWeight: FontWeight.w300,
fontFeatures: [FontFeature.enable('smcp')],
);
static TextStyle unknownTitleText = knownTitleText;
static void updateStylesForLocale(Locale locale) {
final smcp = locale.languageCode != 'el';
unknownTitleText = smcp ? knownTitleText : knownTitleText.copyWith(fontFeatures: []);
}
}

7
lib/theme/text.dart Normal file
View file

@ -0,0 +1,7 @@
import 'package:aves/ref/unicode.dart';
class AText {
static const separator = ' ${Unicode.bullet} ';
static const resolutionSeparator = ' ${Unicode.multiplicationSign} ';
static const valueNotAvailable = Unicode.emDash;
}

View file

@ -7,8 +7,6 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
class Themes { class Themes {
static const defaultAccent = Colors.indigoAccent;
static const _tooltipTheme = TooltipThemeData( static const _tooltipTheme = TooltipThemeData(
verticalOffset: 32, verticalOffset: 32,
); );

8
lib/utils/colors.dart Normal file
View file

@ -0,0 +1,8 @@
import 'dart:ui';
class ColorUtils {
// `Color(0x00FFFFFF)` is different from `Color(0x00000000)` (or `Colors.transparent`)
// when used in gradients or lerping to it
static const transparentWhite = Color(0x00FFFFFF);
static const transparentBlack = Color(0x00000000);
}

View file

@ -1,7 +1,4 @@
import 'dart:ui';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:latlong2/latlong.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
class Constants { class Constants {
@ -12,32 +9,8 @@ class Constants {
Permission.videos, Permission.videos,
]; ];
static const separator = '';
// `Color(0x00FFFFFF)` is different from `Color(0x00000000)` (or `Colors.transparent`)
// when used in gradients or lerping to it
static const transparentWhite = Color(0x00FFFFFF);
static const transparentBlack = Colors.transparent;
// as of Flutter v2.8.0, overflowing `Text` miscalculates height and some text (e.g. 'Å') is clipped
// so we give it a `strutStyle` with a slightly larger height
static const overflowStrutStyle = StrutStyle(height: 1.3);
static const double colorPickerRadius = 16; static const double colorPickerRadius = 16;
static const knownTitleTextStyle = TextStyle(
fontSize: 20,
fontWeight: FontWeight.w300,
fontFeatures: [FontFeature.enable('smcp')],
);
static TextStyle unknownTitleTextStyle = knownTitleTextStyle;
static void updateStylesForLocale(Locale locale) {
final smcp = locale.languageCode != 'el';
unknownTitleTextStyle = smcp ? knownTitleTextStyle : knownTitleTextStyle.copyWith(fontFeatures: []);
}
static const embossShadows = [ static const embossShadows = [
Shadow( Shadow(
color: Colors.black, color: Colors.black,
@ -50,30 +23,5 @@ class Constants {
Color(0xffeaecc6), Color(0xffeaecc6),
]; ];
// Bidi fun, cf https://www.unicode.org/reports/tr9/
// First Strong Isolate
static const fsi = '\u2068';
// Pop Directional Isolate
static const pdi = '\u2069';
static const zwsp = '\u200B';
static const overlayUnknown = ''; // em dash
static final pointNemo = LatLng(-48.876667, -123.393333);
static final wonders = [
LatLng(29.979167, 31.134167),
LatLng(36.451000, 28.223615),
LatLng(32.5355, 44.4275),
LatLng(31.213889, 29.885556),
LatLng(37.0379, 27.4241),
LatLng(37.637861, 21.63),
LatLng(37.949722, 27.363889),
];
static const int infoGroupMaxValueLength = 140; static const int infoGroupMaxValueLength = 140;
static const String avesGithub = 'https://github.com/deckerst/aves';
} }

View file

@ -1,7 +1,6 @@
import 'dart:ui'; import 'dart:ui';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/about/policy_page.dart'; import 'package:aves/widgets/about/policy_page.dart';
import 'package:aves/widgets/common/basic/link_chip.dart'; import 'package:aves/widgets/common/basic/link_chip.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
@ -10,6 +9,8 @@ import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
class AppReference extends StatefulWidget { class AppReference extends StatefulWidget {
static const avesGithub = 'https://github.com/deckerst/aves';
const AppReference({super.key}); const AppReference({super.key});
@override @override
@ -79,7 +80,7 @@ class _AppReferenceState extends State<AppReference> {
size: 24, size: 24,
), ),
text: 'GitHub', text: 'GitHub',
urlString: Constants.avesGithub, urlString: AppReference.avesGithub,
), ),
LinkChip( LinkChip(
leading: const Icon( leading: const Icon(
@ -87,7 +88,7 @@ class _AppReferenceState extends State<AppReference> {
size: 22, size: 22,
), ),
text: l10n.aboutLinkLicense, text: l10n.aboutLinkLicense,
urlString: '${Constants.avesGithub}/blob/main/LICENSE', urlString: '${AppReference.avesGithub}/blob/main/LICENSE',
), ),
LinkChip( LinkChip(
leading: const Icon( leading: const Icon(

View file

@ -10,7 +10,8 @@ import 'package:aves/ref/mime_types.dart';
import 'package:aves/services/common/services.dart'; import 'package:aves/services/common/services.dart';
import 'package:aves/theme/colors.dart'; import 'package:aves/theme/colors.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/widgets/about/app_ref.dart';
import 'package:aves/widgets/aves_app.dart'; import 'package:aves/widgets/aves_app.dart';
import 'package:aves/widgets/common/action_mixins/feedback.dart'; import 'package:aves/widgets/common/action_mixins/feedback.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
@ -34,7 +35,7 @@ class _BugReportState extends State<BugReport> with FeedbackMixin {
late Future<String> _infoLoader; late Future<String> _infoLoader;
bool _showInstructions = false; bool _showInstructions = false;
static const bugReportUrl = '${Constants.avesGithub}/issues/new?labels=type%3Abug&template=bug_report.md'; static const bugReportUrl = '${AppReference.avesGithub}/issues/new?labels=type%3Abug&template=bug_report.md';
@override @override
void initState() { void initState() {
@ -60,7 +61,7 @@ class _BugReportState extends State<BugReport> with FeedbackMixin {
child: Container( child: Container(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
alignment: AlignmentDirectional.centerStart, alignment: AlignmentDirectional.centerStart,
child: Text(l10n.aboutBugSectionTitle, style: Constants.knownTitleTextStyle), child: Text(l10n.aboutBugSectionTitle, style: AStyles.knownTitleText),
), ),
), ),
body: Padding( body: Padding(

View file

@ -2,7 +2,7 @@ import 'package:aves/app_flavor.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/ref/brand_colors.dart'; import 'package:aves/ref/brand_colors.dart';
import 'package:aves/theme/colors.dart'; import 'package:aves/theme/colors.dart';
import 'package:aves/utils/dependencies.dart'; import 'package:aves/model/dependencies.dart';
import 'package:aves/widgets/about/title.dart'; import 'package:aves/widgets/about/title.dart';
import 'package:aves/widgets/about/tv_license_page.dart'; import 'package:aves/widgets/about/tv_license_page.dart';
import 'package:aves/widgets/common/basic/link_chip.dart'; import 'package:aves/widgets/common/basic/link_chip.dart';

View file

@ -1,5 +1,5 @@
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AboutSectionTitle extends StatelessWidget { class AboutSectionTitle extends StatelessWidget {
@ -15,7 +15,7 @@ class AboutSectionTitle extends StatelessWidget {
Widget child = Container( Widget child = Container(
alignment: AlignmentDirectional.centerStart, alignment: AlignmentDirectional.centerStart,
constraints: const BoxConstraints(minHeight: kMinInteractiveDimension), constraints: const BoxConstraints(minHeight: kMinInteractiveDimension),
child: Text(text, style: Constants.knownTitleTextStyle), child: Text(text, style: AStyles.knownTitleText),
); );
if (settings.useTvLayout) { if (settings.useTvLayout) {

View file

@ -1,6 +1,6 @@
import 'dart:math'; import 'dart:math';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/text.dart';
import 'package:aves/widgets/about/title.dart'; import 'package:aves/widgets/about/title.dart';
import 'package:aves/widgets/common/basic/text/change_highlight.dart'; import 'package:aves/widgets/common/basic/text/change_highlight.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
@ -154,7 +154,7 @@ class _RandomTextSpanHighlighterState extends State<_RandomTextSpanHighlighter>
TextSpan( TextSpan(
children: [ children: [
...widget.spans.expandIndexed((i, v) => [ ...widget.spans.expandIndexed((i, v) => [
if (i != 0) const TextSpan(text: Constants.separator), if (i != 0) const TextSpan(text: AText.separator),
TextSpan(text: v, style: i == _highlightedIndex ? _animatedStyle.value : _baseStyle), TextSpan(text: v, style: i == _highlightedIndex ? _animatedStyle.value : _baseStyle),
]) ])
], ],

View file

@ -22,9 +22,9 @@ import 'package:aves/services/common/services.dart';
import 'package:aves/theme/colors.dart'; import 'package:aves/theme/colors.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/theme/styles.dart';
import 'package:aves/theme/themes.dart'; import 'package:aves/theme/themes.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/utils/debouncer.dart'; import 'package:aves/utils/debouncer.dart';
import 'package:aves/widgets/collection/collection_grid.dart'; import 'package:aves/widgets/collection/collection_grid.dart';
import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/collection/collection_page.dart';
@ -224,12 +224,12 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
final themeBrightness = s.item2; final themeBrightness = s.item2;
final enableDynamicColor = s.item3; final enableDynamicColor = s.item3;
Constants.updateStylesForLocale(settings.appliedLocale); AStyles.updateStylesForLocale(settings.appliedLocale);
return FutureBuilder<CorePalette?>( return FutureBuilder<CorePalette?>(
future: _dynamicColorPaletteLoader, future: _dynamicColorPaletteLoader,
builder: (context, snapshot) { builder: (context, snapshot) {
const defaultAccent = Themes.defaultAccent; const defaultAccent = AvesColorsData.defaultAccent;
Color lightAccent = defaultAccent, darkAccent = defaultAccent; Color lightAccent = defaultAccent, darkAccent = defaultAccent;
if (enableDynamicColor) { if (enableDynamicColor) {
// `DynamicColorBuilder` from package `dynamic_color` provides light/dark // `DynamicColorBuilder` from package `dynamic_color` provides light/dark

View file

@ -4,8 +4,9 @@ import 'package:aves/model/settings/enums/coordinate_format.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/format.dart'; import 'package:aves/theme/format.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/theme/styles.dart';
import 'package:aves/theme/text.dart';
import 'package:aves/utils/collection_utils.dart'; import 'package:aves/utils/collection_utils.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/utils/file_utils.dart'; import 'package:aves/utils/file_utils.dart';
import 'package:aves/widgets/collection/grid/list_details_theme.dart'; import 'package:aves/widgets/collection/grid/list_details_theme.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
@ -59,7 +60,7 @@ class EntryListDetails extends StatelessWidget {
children: spans, children: spans,
), ),
style: style, style: style,
strutStyle: Constants.overflowStrutStyle, strutStyle: AStyles.overflowStrut,
softWrap: false, softWrap: false,
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
); );
@ -79,10 +80,10 @@ class EntryListDetails extends StatelessWidget {
final locale = context.l10n.localeName; final locale = context.l10n.localeName;
final use24hour = context.select<MediaQueryData, bool>((v) => v.alwaysUse24HourFormat); final use24hour = context.select<MediaQueryData, bool>((v) => v.alwaysUse24HourFormat);
final date = entry.bestDate; final date = entry.bestDate;
final dateText = date != null ? formatDateTime(date, locale, use24hour) : Constants.overlayUnknown; final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable;
final size = entry.burstEntries?.map((v) => v.sizeBytes).sum ?? entry.sizeBytes; final size = entry.burstEntries?.map((v) => v.sizeBytes).sum ?? entry.sizeBytes;
final sizeText = size != null ? formatFileSize(locale, size) : Constants.overlayUnknown; final sizeText = size != null ? formatFileSize(locale, size) : AText.valueNotAvailable;
return _buildRow( return _buildRow(
[ [

View file

@ -1,5 +1,5 @@
import 'package:aves/theme/format.dart'; import 'package:aves/theme/format.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
@ -43,7 +43,7 @@ class EntryListDetailsTheme extends StatelessWidget {
TextSpan(text: formatDateTime(DateTime.now(), locale, use24hour), style: captionStyle), TextSpan(text: formatDateTime(DateTime.now(), locale, use24hour), style: captionStyle),
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
textScaleFactor: textScaleFactor, textScaleFactor: textScaleFactor,
strutStyle: Constants.overflowStrutStyle, strutStyle: AStyles.overflowStrut,
)..layout(const BoxConstraints(), parentUsesSize: true)) )..layout(const BoxConstraints(), parentUsesSize: true))
.getMaxIntrinsicHeight(double.infinity); .getMaxIntrinsicHeight(double.infinity);

View file

@ -2,7 +2,7 @@ import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -34,7 +34,7 @@ class TitledExpandableFilterRow extends StatelessWidget {
Widget header = Text( Widget header = Text(
title, title,
style: Constants.knownTitleTextStyle, style: AStyles.knownTitleText,
); );
void toggle() => expandedNotifier.value = isExpanded ? null : title; void toggle() => expandedNotifier.value = isExpanded ? null : title;
if (settings.useTvLayout) { if (settings.useTvLayout) {

View file

@ -3,7 +3,7 @@ import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/section_keys.dart'; import 'package:aves/model/source/section_keys.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/grid/sections/list_layout.dart'; import 'package:aves/widgets/common/grid/sections/list_layout.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -85,7 +85,7 @@ class SectionHeader<T> extends StatelessWidget {
), ),
TextSpan( TextSpan(
text: title, text: title,
style: Constants.unknownTitleTextStyle, style: AStyles.unknownTitleText,
), ),
if (trailing != null) if (trailing != null)
WidgetSpan( WidgetSpan(
@ -141,7 +141,7 @@ class SectionHeader<T> extends StatelessWidget {
if (hasTrailing) TextSpan(text: '\u200A' * 17), if (hasTrailing) TextSpan(text: '\u200A' * 17),
TextSpan( TextSpan(
text: title, text: title,
style: Constants.unknownTitleTextStyle, style: AStyles.unknownTitleText,
), ),
], ],
), ),

View file

@ -1,6 +1,6 @@
import 'package:aves/model/source/enums/enums.dart'; import 'package:aves/model/source/enums/enums.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/colors.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/providers/media_query_data_provider.dart'; import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -123,12 +123,12 @@ class _OverlayBackgroundState extends State<_OverlayBackground> {
gradient: RadialGradient( gradient: RadialGradient(
colors: isDark colors: isDark
? const [ ? const [
Constants.transparentBlack, ColorUtils.transparentBlack,
Constants.transparentBlack, ColorUtils.transparentBlack,
] ]
: const [ : const [
Constants.transparentWhite, ColorUtils.transparentWhite,
Constants.transparentWhite, ColorUtils.transparentWhite,
], ],
), ),
); );

View file

@ -1,5 +1,5 @@
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/utils/colors.dart';
import 'package:aves/widgets/common/grid/sections/mosaic/scale_grid.dart'; import 'package:aves/widgets/common/grid/sections/mosaic/scale_grid.dart';
import 'package:aves/widgets/common/providers/media_query_data_provider.dart'; import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -110,7 +110,7 @@ class _OverlayBackgroundState extends State<_OverlayBackground> {
color: isDark ? Colors.black87 : const Color(0xDDFFFFFF), color: isDark ? Colors.black87 : const Color(0xDDFFFFFF),
) )
: BoxDecoration( : BoxDecoration(
color: isDark ? Constants.transparentBlack : Constants.transparentWhite, color: isDark ? ColorUtils.transparentBlack : ColorUtils.transparentWhite,
); );
} }
} }

View file

@ -9,10 +9,10 @@ import 'package:aves/model/entry/sort.dart';
import 'package:aves/model/settings/enums/l10n.dart'; import 'package:aves/model/settings/enums/l10n.dart';
import 'package:aves/model/settings/enums/map_style.dart'; import 'package:aves/model/settings/enums/map_style.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/ref/poi.dart';
import 'package:aves/services/common/services.dart'; import 'package:aves/services/common/services.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/utils/math_utils.dart'; import 'package:aves/utils/math_utils.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/buttons/overlay_button.dart'; import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
@ -331,7 +331,7 @@ class _GeoMapState extends State<GeoMap> {
// fallback to default center // fallback to default center
var center = settings.mapDefaultCenter; var center = settings.mapDefaultCenter;
if (center == null) { if (center == null) {
center = Constants.wonders[Random().nextInt(Constants.wonders.length)]; center = PointsOfInterest.wonders[Random().nextInt(PointsOfInterest.wonders.length)];
WidgetsBinding.instance.addPostFrameCallback((_) => settings.mapDefaultCenter = center); WidgetsBinding.instance.addPostFrameCallback((_) => settings.mapDefaultCenter = center);
} }
bounds = ZoomedBounds.fromPoints( bounds = ZoomedBounds.fromPoints(

View file

@ -1,11 +1,11 @@
import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/entry/extensions/props.dart';
import 'package:aves/model/metadata/enums/enums.dart'; import 'package:aves/model/metadata/enums/enums.dart';
import 'package:aves/model/metadata/enums/length_unit.dart'; import 'package:aves/model/metadata/enums/length_unit.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/ref/mime_types.dart'; import 'package:aves/ref/mime_types.dart';
import 'package:aves/services/media/media_edit_service.dart'; import 'package:aves/services/media/media_edit_service.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/text.dart';
import 'package:aves/theme/themes.dart'; import 'package:aves/theme/themes.dart';
import 'package:aves/utils/mime_utils.dart'; import 'package:aves/utils/mime_utils.dart';
import 'package:aves/widgets/common/basic/text_dropdown_button.dart'; import 'package:aves/widgets/common/basic/text_dropdown_button.dart';
@ -149,7 +149,7 @@ class _ConvertEntryDialogState extends State<ConvertEntryDialog> {
), ),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
const Text(ExtraAvesEntryProps.resolutionSeparator), const Text(AText.resolutionSeparator),
const SizedBox(width: 8), const SizedBox(width: 8),
Expanded( Expanded(
child: TextField( child: TextField(

View file

@ -6,10 +6,10 @@ import 'package:aves/model/metadata/enums/location_edit_action.dart';
import 'package:aves/model/settings/enums/coordinate_format.dart'; import 'package:aves/model/settings/enums/coordinate_format.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/model/source/collection_lens.dart'; import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/ref/poi.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/theme/themes.dart'; import 'package:aves/theme/themes.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/basic/text_dropdown_button.dart'; import 'package:aves/widgets/common/basic/text_dropdown_button.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/fx/transitions.dart'; import 'package:aves/widgets/common/fx/transitions.dart';
@ -250,7 +250,7 @@ class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
controller: _latitudeController, controller: _latitudeController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: l10n.editEntryLocationDialogLatitude, labelText: l10n.editEntryLocationDialogLatitude,
hintText: coordinateFormatter.format(Constants.pointNemo.latitude), hintText: coordinateFormatter.format(PointsOfInterest.pointNemo.latitude),
), ),
onChanged: (_) => _validate(), onChanged: (_) => _validate(),
), ),
@ -258,7 +258,7 @@ class _EditEntryLocationDialogState extends State<EditEntryLocationDialog> {
controller: _longitudeController, controller: _longitudeController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: l10n.editEntryLocationDialogLongitude, labelText: l10n.editEntryLocationDialogLongitude,
hintText: coordinateFormatter.format(Constants.pointNemo.longitude), hintText: coordinateFormatter.format(PointsOfInterest.pointNemo.longitude),
), ),
onChanged: (_) => _validate(), onChanged: (_) => _validate(),
), ),

View file

@ -2,9 +2,9 @@ import 'dart:io';
import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/entry.dart';
import 'package:aves/services/common/services.dart'; import 'package:aves/services/common/services.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/dialogs/aves_dialog.dart'; import 'package:aves/widgets/dialogs/aves_dialog.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class RenameEntryDialog extends StatefulWidget { class RenameEntryDialog extends StatefulWidget {
@ -43,7 +43,7 @@ class _RenameEntryDialogState extends State<RenameEntryDialog> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final isRtl = context.isRtl; final isRtl = context.isRtl;
final extensionSuffixText = '${Constants.fsi}${entry.extension}${Constants.pdi}'; final extensionSuffixText = '${Unicode.FSI}${entry.extension}${Unicode.PDI}';
return AvesDialog( return AvesDialog(
content: TextField( content: TextField(
controller: _nameController, controller: _nameController,

View file

@ -5,7 +5,7 @@ import 'package:aves/model/naming_pattern.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/widgets/collection/collection_grid.dart'; import 'package:aves/widgets/collection/collection_grid.dart';
import 'package:aves/widgets/common/basic/font_size_icon_theme.dart'; import 'package:aves/widgets/common/basic/font_size_icon_theme.dart';
import 'package:aves/widgets/common/basic/popup/menu_row.dart'; import 'package:aves/widgets/common/basic/popup/menu_row.dart';
@ -117,7 +117,7 @@ class _RenameEntrySetPageState extends State<RenameEntrySetPage> {
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
child: Text( child: Text(
l10n.renameEntrySetPagePreviewSectionTitle, l10n.renameEntrySetPagePreviewSectionTitle,
style: Constants.knownTitleTextStyle, style: AStyles.knownTitleText,
), ),
), ),
Expanded( Expanded(

View file

@ -8,7 +8,8 @@ import 'package:aves/services/common/services.dart';
import 'package:aves/services/geocoding_service.dart'; import 'package:aves/services/geocoding_service.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/theme/text.dart';
import 'package:aves/utils/debouncer.dart'; import 'package:aves/utils/debouncer.dart';
import 'package:aves/widgets/common/basic/scaffold.dart'; import 'package:aves/widgets/common/basic/scaffold.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
@ -267,8 +268,8 @@ class _AddressRowState extends State<_AddressRow> {
valueListenable: _addressLineNotifier, valueListenable: _addressLineNotifier,
builder: (context, addressLine, child) { builder: (context, addressLine, child) {
return Text( return Text(
addressLine ?? Constants.overlayUnknown, addressLine ?? AText.valueNotAvailable,
strutStyle: Constants.overflowStrutStyle, strutStyle: AStyles.overflowStrut,
softWrap: false, softWrap: false,
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
maxLines: 1, maxLines: 1,
@ -317,8 +318,8 @@ class _CoordinateRow extends StatelessWidget {
const SizedBox(width: _LocationInfo.iconPadding), const SizedBox(width: _LocationInfo.iconPadding),
Expanded( Expanded(
child: Text( child: Text(
location != null ? settings.coordinateFormat.format(context.l10n, location!) : Constants.overlayUnknown, location != null ? settings.coordinateFormat.format(context.l10n, location!) : AText.valueNotAvailable,
strutStyle: Constants.overflowStrutStyle, strutStyle: AStyles.overflowStrut,
softWrap: false, softWrap: false,
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
maxLines: 1, maxLines: 1,

View file

@ -1,6 +1,6 @@
import 'package:aves/model/entry/extensions/props.dart';
import 'package:aves/ref/languages.dart'; import 'package:aves/ref/languages.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/theme/text.dart';
import 'package:aves/theme/themes.dart'; import 'package:aves/theme/themes.dart';
import 'package:aves/widgets/common/basic/text_dropdown_button.dart'; import 'package:aves/widgets/common/basic/text_dropdown_button.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
@ -117,7 +117,7 @@ class _VideoStreamSelectionDialogState extends State<VideoStreamSelectionDialog>
final w = stream.width; final w = stream.width;
final h = stream.height; final h = stream.height;
if (w != null && h != null) { if (w != null && h != null) {
return '$common$w${ExtraAvesEntryProps.resolutionSeparator}$h'; return '$common$w${AText.resolutionSeparator}$h';
} }
} }
return common; return common;

View file

@ -12,8 +12,8 @@ import 'package:aves/model/source/tag.dart';
import 'package:aves/model/vaults/vaults.dart'; import 'package:aves/model/vaults/vaults.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/theme/text.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
import 'package:aves/widgets/common/thumbnail/image.dart'; import 'package:aves/widgets/common/thumbnail/image.dart';
@ -214,7 +214,7 @@ class CoveredFilterChip<T extends CollectionFilter> extends StatelessWidget {
), ),
), ),
Text( Text(
locked ? Constants.overlayUnknown : numberFormat.format(source.count(filter)), locked ? AText.valueNotAvailable : numberFormat.format(source.count(filter)),
style: TextStyle( style: TextStyle(
color: _detailColor(context), color: _detailColor(context),
fontSize: fontSize, fontSize: fontSize,

View file

@ -4,8 +4,9 @@ import 'package:aves/model/filters/filters.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:aves/theme/format.dart'; import 'package:aves/theme/format.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/theme/styles.dart';
import 'package:aves/theme/text.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/utils/file_utils.dart'; import 'package:aves/utils/file_utils.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/fx/borders.dart'; import 'package:aves/widgets/common/fx/borders.dart';
@ -87,7 +88,7 @@ class FilterListDetails<T extends CollectionFilter> extends StatelessWidget {
final locale = context.l10n.localeName; final locale = context.l10n.localeName;
final use24hour = context.select<MediaQueryData, bool>((v) => v.alwaysUse24HourFormat); final use24hour = context.select<MediaQueryData, bool>((v) => v.alwaysUse24HourFormat);
final date = entry?.bestDate; final date = entry?.bestDate;
final dateText = date != null ? formatDateTime(date, locale, use24hour) : Constants.overlayUnknown; final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable;
Widget leading = const Icon(AIcons.date); Widget leading = const Icon(AIcons.date);
if (hasTitleLeading) { if (hasTitleLeading) {
@ -106,7 +107,7 @@ class FilterListDetails<T extends CollectionFilter> extends StatelessWidget {
child: Text( child: Text(
dateText, dateText,
style: detailsTheme.captionStyle, style: detailsTheme.captionStyle,
strutStyle: Constants.overflowStrutStyle, strutStyle: AStyles.overflowStrut,
softWrap: false, softWrap: false,
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
), ),
@ -157,7 +158,7 @@ class FilterListDetails<T extends CollectionFilter> extends StatelessWidget {
Text( Text(
'${l10n.itemCount(source.count(filter))}${formatFileSize(locale, source.size(filter))}', '${l10n.itemCount(source.count(filter))}${formatFileSize(locale, source.size(filter))}',
style: detailsTheme.captionStyle, style: detailsTheme.captionStyle,
strutStyle: Constants.overflowStrutStyle, strutStyle: AStyles.overflowStrut,
softWrap: false, softWrap: false,
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
), ),

View file

@ -1,7 +1,7 @@
import 'dart:math'; import 'dart:math';
import 'package:aves/theme/format.dart'; import 'package:aves/theme/format.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -49,7 +49,7 @@ class FilterListDetailsTheme extends StatelessWidget {
TextSpan(text: formatDateTime(DateTime.now(), locale, use24hour), style: captionStyle), TextSpan(text: formatDateTime(DateTime.now(), locale, use24hour), style: captionStyle),
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
textScaleFactor: textScaleFactor, textScaleFactor: textScaleFactor,
strutStyle: Constants.overflowStrutStyle, strutStyle: AStyles.overflowStrut,
)..layout(const BoxConstraints(), parentUsesSize: true)) )..layout(const BoxConstraints(), parentUsesSize: true))
.getMaxIntrinsicHeight(double.infinity); .getMaxIntrinsicHeight(double.infinity);

View file

@ -6,7 +6,8 @@ import 'package:aves/services/common/services.dart';
import 'package:aves/services/geocoding_service.dart'; import 'package:aves/services/geocoding_service.dart';
import 'package:aves/theme/format.dart'; import 'package:aves/theme/format.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/theme/text.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves_map/aves_map.dart'; import 'package:aves_map/aves_map.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -118,13 +119,13 @@ class _AddressRowState extends State<_AddressRow> {
builder: (context, addressLine, child) { builder: (context, addressLine, child) {
final location = addressLine ?? final location = addressLine ??
(entry == null (entry == null
? Constants.overlayUnknown ? AText.valueNotAvailable
: entry.hasAddress : entry.hasAddress
? entry.shortAddress ? entry.shortAddress
: settings.coordinateFormat.format(context.l10n, entry.latLng!)); : settings.coordinateFormat.format(context.l10n, entry.latLng!));
return Text( return Text(
location, location,
strutStyle: Constants.overflowStrutStyle, strutStyle: AStyles.overflowStrut,
softWrap: false, softWrap: false,
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
maxLines: 1, maxLines: 1,
@ -170,7 +171,7 @@ class _DateRow extends StatelessWidget {
final use24hour = context.select<MediaQueryData, bool>((v) => v.alwaysUse24HourFormat); final use24hour = context.select<MediaQueryData, bool>((v) => v.alwaysUse24HourFormat);
final date = entry?.bestDate; final date = entry?.bestDate;
final dateText = date != null ? formatDateTime(date, locale, use24hour) : Constants.overlayUnknown; final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable;
return Row( return Row(
children: [ children: [
const SizedBox(width: MapInfoRow.iconPadding), const SizedBox(width: MapInfoRow.iconPadding),
@ -179,7 +180,7 @@ class _DateRow extends StatelessWidget {
Expanded( Expanded(
child: Text( child: Text(
dateText, dateText,
strutStyle: Constants.overflowStrutStyle, strutStyle: AStyles.overflowStrut,
softWrap: false, softWrap: false,
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
maxLines: 1, maxLines: 1,

View file

@ -2,9 +2,8 @@ import 'dart:async';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/theme/styles.dart';
import 'package:aves/widgets/common/basic/font_size_icon_theme.dart'; import 'package:aves/widgets/common/basic/font_size_icon_theme.dart';
import 'package:aves_utils/aves_utils.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/basic/scaffold.dart'; import 'package:aves/widgets/common/basic/scaffold.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/buttons/captioned_button.dart'; import 'package:aves/widgets/common/identity/buttons/captioned_button.dart';
@ -13,6 +12,7 @@ import 'package:aves/widgets/settings/common/quick_actions/action_panel.dart';
import 'package:aves/widgets/settings/common/quick_actions/available_actions.dart'; import 'package:aves/widgets/settings/common/quick_actions/available_actions.dart';
import 'package:aves/widgets/settings/common/quick_actions/placeholder.dart'; import 'package:aves/widgets/settings/common/quick_actions/placeholder.dart';
import 'package:aves/widgets/settings/common/quick_actions/quick_actions.dart'; import 'package:aves/widgets/settings/common/quick_actions/quick_actions.dart';
import 'package:aves_utils/aves_utils.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -163,7 +163,7 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
padding: const EdgeInsets.only(left: 16, top: 16, right: 16), padding: const EdgeInsets.only(left: 16, top: 16, right: 16),
child: Text( child: Text(
context.l10n.settingsViewerQuickActionEditorDisplayedButtonsSectionTitle, context.l10n.settingsViewerQuickActionEditorDisplayedButtonsSectionTitle,
style: Constants.knownTitleTextStyle, style: AStyles.knownTitleText,
), ),
), ),
ValueListenableBuilder<bool>( ValueListenableBuilder<bool>(
@ -240,7 +240,7 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text( child: Text(
context.l10n.settingsViewerQuickActionEditorAvailableButtonsSectionTitle, context.l10n.settingsViewerQuickActionEditorAvailableButtonsSectionTitle,
style: Constants.knownTitleTextStyle, style: AStyles.knownTitleText,
), ),
), ),
ValueListenableBuilder<bool>( ValueListenableBuilder<bool>(

View file

@ -1,6 +1,6 @@
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/text.dart';
import 'package:aves/utils/time_utils.dart'; import 'package:aves/utils/time_utils.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/aves_caption.dart'; import 'package:aves/widgets/common/identity/aves_caption.dart';
@ -179,7 +179,7 @@ class SettingsMultiSelectionListTile<T> extends StatelessWidget {
} }
return ListTile( return ListTile(
title: titleWidget, title: titleWidget,
subtitle: AvesCaption(current.isEmpty ? noneSubtitle : current.map((v) => getName(context, v)).join(Constants.separator)), subtitle: AvesCaption(current.isEmpty ? noneSubtitle : current.map((v) => getName(context, v)).join(AText.separator)),
onTap: () => showSelectionDialog<List<T>>( onTap: () => showSelectionDialog<List<T>>(
context: context, context: context,
builder: (context) => AvesMultiSelectionDialog<T>( builder: (context) => AvesMultiSelectionDialog<T>(

View file

@ -4,9 +4,9 @@ import 'package:aves/model/settings/enums/coordinate_format.dart';
import 'package:aves/model/settings/enums/enums.dart'; import 'package:aves/model/settings/enums/enums.dart';
import 'package:aves/model/settings/enums/l10n.dart'; import 'package:aves/model/settings/enums/l10n.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/ref/poi.dart';
import 'package:aves/theme/colors.dart'; import 'package:aves/theme/colors.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/settings/common/tile_leading.dart'; import 'package:aves/widgets/settings/common/tile_leading.dart';
import 'package:aves/widgets/settings/common/tiles.dart'; import 'package:aves/widgets/settings/common/tiles.dart';
@ -56,7 +56,7 @@ class SettingsTileLanguageCoordinateFormat extends SettingsTile {
onSelection: (v) => settings.coordinateFormat = v, onSelection: (v) => settings.coordinateFormat = v,
tileTitle: title(context), tileTitle: title(context),
dialogTitle: context.l10n.settingsCoordinateFormatDialogTitle, dialogTitle: context.l10n.settingsCoordinateFormatDialogTitle,
optionSubtitleBuilder: (value) => value.format(context.l10n, Constants.pointNemo), optionSubtitleBuilder: (value) => value.format(context.l10n, PointsOfInterest.pointNemo),
); );
} }

View file

@ -5,7 +5,6 @@ import 'package:aves/services/common/services.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/android_file_utils.dart'; import 'package:aves/utils/android_file_utils.dart';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/basic/font_size_icon_theme.dart'; import 'package:aves/widgets/common/basic/font_size_icon_theme.dart';
import 'package:aves/widgets/common/basic/popup/menu_row.dart'; import 'package:aves/widgets/common/basic/popup/menu_row.dart';
import 'package:aves/widgets/common/basic/scaffold.dart'; import 'package:aves/widgets/common/basic/scaffold.dart';
@ -183,7 +182,7 @@ class _FilePickerPageState extends State<FilePickerPage> {
Widget _buildContentLine(BuildContext context, FileSystemEntity content) { Widget _buildContentLine(BuildContext context, FileSystemEntity content) {
return ListTile( return ListTile(
leading: const Icon(AIcons.folder), leading: const Icon(AIcons.folder),
title: Text('${Constants.fsi}${pContext.split(content.path).last}${Constants.pdi}'), title: Text('${Unicode.FSI}${pContext.split(content.path).last}${Unicode.PDI}'),
onTap: () { onTap: () {
_goTo(content.path); _goTo(content.path);
setState(() {}); setState(() {});

View file

@ -12,7 +12,7 @@ import 'package:aves/model/source/collection_lens.dart';
import 'package:aves/model/source/collection_source.dart'; import 'package:aves/model/source/collection_source.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/widgets/collection/collection_page.dart'; import 'package:aves/widgets/collection/collection_page.dart';
import 'package:aves/widgets/common/action_mixins/feedback.dart'; import 'package:aves/widgets/common/action_mixins/feedback.dart';
import 'package:aves/widgets/common/action_mixins/vault_aware.dart'; import 'package:aves/widgets/common/action_mixins/vault_aware.dart';
@ -285,7 +285,7 @@ class _StatsPageState extends State<StatsPage> with FeedbackMixin, VaultAwareMix
: null; : null;
Widget header = Text( Widget header = Text(
title, title,
style: Constants.knownTitleTextStyle, style: AStyles.knownTitleText,
); );
if (settings.useTvLayout) { if (settings.useTvLayout) {
header = Container( header = Container(

View file

@ -1,7 +1,7 @@
import 'dart:math'; import 'dart:math';
import 'package:aves/utils/constants.dart';
import 'package:aves/widgets/common/identity/aves_filter_chip.dart'; import 'package:aves/widgets/common/identity/aves_filter_chip.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
@ -75,7 +75,7 @@ class InfoRowGroup extends StatefulWidget {
final linkColor = Theme.of(context).colorScheme.primary; final linkColor = Theme.of(context).colorScheme.primary;
final style = InfoRowGroup.valueStyle.copyWith(color: linkColor, decoration: TextDecoration.underline); final style = InfoRowGroup.valueStyle.copyWith(color: linkColor, decoration: TextDecoration.underline);
return [TextSpan(text: '${Constants.fsi}$value${Constants.pdi}', style: style, recognizer: recognizer)]; return [TextSpan(text: '${Unicode.FSI}$value${Unicode.PDI}', style: style, recognizer: recognizer)];
}; };
} }
} }
@ -164,7 +164,7 @@ class _InfoRowGroupState extends State<InfoRowGroup> {
// so that layout of the spans follows the directionality of the locale // so that layout of the spans follows the directionality of the locale
// (e.g. keys on the right for RTL locale, whatever the key intrinsic directionality) // (e.g. keys on the right for RTL locale, whatever the key intrinsic directionality)
// and each span respects the directionality of its inner text only // and each span respects the directionality of its inner text only
String _buildTextValue(String value) => '${Constants.fsi}$value${Constants.pdi}'; String _buildTextValue(String value) => '${Unicode.FSI}$value${Unicode.PDI}';
} }
typedef InfoValueSpanBuilder = List<InlineSpan> Function(BuildContext context, String key, String value); typedef InfoValueSpanBuilder = List<InlineSpan> Function(BuildContext context, String key, String value);

View file

@ -2,7 +2,8 @@ import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/entry/extensions/props.dart'; import 'package:aves/model/entry/extensions/props.dart';
import 'package:aves/theme/format.dart'; import 'package:aves/theme/format.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/theme/text.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/viewer/multipage/controller.dart'; import 'package:aves/widgets/viewer/multipage/controller.dart';
import 'package:aves/widgets/viewer/overlay/details/details.dart'; import 'package:aves/widgets/viewer/overlay/details/details.dart';
@ -26,7 +27,7 @@ class OverlayDateRow extends StatelessWidget {
final use24hour = context.select<MediaQueryData, bool>((v) => v.alwaysUse24HourFormat); final use24hour = context.select<MediaQueryData, bool>((v) => v.alwaysUse24HourFormat);
final date = entry.bestDate; final date = entry.bestDate;
final dateText = date != null ? formatDateTime(date, locale, use24hour) : Constants.overlayUnknown; final dateText = date != null ? formatDateTime(date, locale, use24hour) : AText.valueNotAvailable;
final resolutionText = entry.isSvg final resolutionText = entry.isSvg
? entry.aspectRatioText ? entry.aspectRatioText
: entry.isSized : entry.isSized
@ -37,8 +38,8 @@ class OverlayDateRow extends StatelessWidget {
children: [ children: [
DecoratedIcon(AIcons.date, size: ViewerDetailOverlayContent.iconSize, shadows: ViewerDetailOverlayContent.shadows(context)), DecoratedIcon(AIcons.date, size: ViewerDetailOverlayContent.iconSize, shadows: ViewerDetailOverlayContent.shadows(context)),
const SizedBox(width: ViewerDetailOverlayContent.iconPadding), const SizedBox(width: ViewerDetailOverlayContent.iconPadding),
Expanded(flex: 3, child: Text(dateText, strutStyle: Constants.overflowStrutStyle)), Expanded(flex: 3, child: Text(dateText, strutStyle: AStyles.overflowStrut)),
Expanded(flex: 2, child: Text(resolutionText, strutStyle: Constants.overflowStrutStyle)), Expanded(flex: 2, child: Text(resolutionText, strutStyle: AStyles.overflowStrut)),
], ],
); );
} }

View file

@ -1,5 +1,5 @@
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/widgets/viewer/overlay/details/details.dart'; import 'package:aves/widgets/viewer/overlay/details/details.dart';
import 'package:decorated_icon/decorated_icon.dart'; import 'package:decorated_icon/decorated_icon.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -31,7 +31,7 @@ class OverlayDescriptionRow extends StatelessWidget {
TextSpan(text: description), TextSpan(text: description),
], ],
), ),
strutStyle: Constants.overflowStrutStyle, strutStyle: AStyles.overflowStrut,
); );
} }
} }

View file

@ -3,7 +3,7 @@ import 'package:aves/model/entry/extensions/location.dart';
import 'package:aves/model/settings/enums/coordinate_format.dart'; import 'package:aves/model/settings/enums/coordinate_format.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/viewer/overlay/details/details.dart'; import 'package:aves/widgets/viewer/overlay/details/details.dart';
import 'package:decorated_icon/decorated_icon.dart'; import 'package:decorated_icon/decorated_icon.dart';
@ -34,7 +34,7 @@ class OverlayLocationRow extends AnimatedWidget {
children: [ children: [
DecoratedIcon(AIcons.location, size: ViewerDetailOverlayContent.iconSize, shadows: ViewerDetailOverlayContent.shadows(context)), DecoratedIcon(AIcons.location, size: ViewerDetailOverlayContent.iconSize, shadows: ViewerDetailOverlayContent.shadows(context)),
const SizedBox(width: ViewerDetailOverlayContent.iconPadding), const SizedBox(width: ViewerDetailOverlayContent.iconPadding),
Expanded(child: Text(location, strutStyle: Constants.overflowStrutStyle)), Expanded(child: Text(location, strutStyle: AStyles.overflowStrut)),
], ],
); );
} }

View file

@ -1,7 +1,9 @@
import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/multipage.dart'; import 'package:aves/model/multipage.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/theme/text.dart';
import 'package:aves/widgets/viewer/multipage/controller.dart'; import 'package:aves/widgets/viewer/multipage/controller.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class OverlayPositionTitleRow extends StatelessWidget { class OverlayPositionTitleRow extends StatelessWidget {
@ -26,9 +28,9 @@ class OverlayPositionTitleRow extends StatelessWidget {
[ [
if (collectionPosition != null) collectionPosition, if (collectionPosition != null) collectionPosition,
if (pagePosition != null) pagePosition, if (pagePosition != null) pagePosition,
if (title != null) '${Constants.fsi}$title${Constants.pdi}', if (title != null) '${Unicode.FSI}$title${Unicode.PDI}',
].join(Constants.separator), ].join(AText.separator),
strutStyle: Constants.overflowStrutStyle); strutStyle: AStyles.overflowStrut);
if (multiPageController == null) return toText(); if (multiPageController == null) return toText();

View file

@ -1,6 +1,7 @@
import 'package:aves/model/entry/entry.dart'; import 'package:aves/model/entry/entry.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/theme/text.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/viewer/overlay/details/details.dart'; import 'package:aves/widgets/viewer/overlay/details/details.dart';
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
@ -40,7 +41,7 @@ class OverlayRatingTagsRow extends AnimatedWidget {
children: [ children: [
TextSpan(text: ratingString), TextSpan(text: ratingString),
if (hasTags) ...[ if (hasTags) ...[
if (ratingString.isNotEmpty) const TextSpan(text: Constants.separator), if (ratingString.isNotEmpty) const TextSpan(text: AText.separator),
WidgetSpan( WidgetSpan(
alignment: PlaceholderAlignment.middle, alignment: PlaceholderAlignment.middle,
child: Padding( child: Padding(
@ -52,11 +53,11 @@ class OverlayRatingTagsRow extends AnimatedWidget {
), ),
), ),
), ),
TextSpan(text: tags.join(Constants.separator)), TextSpan(text: tags.join(AText.separator)),
] ]
], ],
), ),
strutStyle: Constants.overflowStrutStyle, strutStyle: AStyles.overflowStrut,
); );
} }
} }

View file

@ -1,6 +1,7 @@
import 'package:aves/model/metadata/overlay.dart'; import 'package:aves/model/metadata/overlay.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/styles.dart';
import 'package:aves/theme/text.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/viewer/overlay/details/details.dart'; import 'package:aves/widgets/viewer/overlay/details/details.dart';
import 'package:decorated_icon/decorated_icon.dart'; import 'package:decorated_icon/decorated_icon.dart';
@ -20,22 +21,22 @@ class OverlayShootingRow extends StatelessWidget {
final locale = context.l10n.localeName; final locale = context.l10n.localeName;
final aperture = details.aperture; final aperture = details.aperture;
final apertureText = aperture != null ? 'ƒ/${NumberFormat('0.0', locale).format(aperture)}' : Constants.overlayUnknown; final apertureText = aperture != null ? 'ƒ/${NumberFormat('0.0', locale).format(aperture)}' : AText.valueNotAvailable;
final focalLength = details.focalLength; final focalLength = details.focalLength;
final focalLengthText = focalLength != null ? context.l10n.focalLength(NumberFormat('0.#', locale).format(focalLength)) : Constants.overlayUnknown; final focalLengthText = focalLength != null ? context.l10n.focalLength(NumberFormat('0.#', locale).format(focalLength)) : AText.valueNotAvailable;
final iso = details.iso; final iso = details.iso;
final isoText = iso != null ? 'ISO$iso' : Constants.overlayUnknown; final isoText = iso != null ? 'ISO$iso' : AText.valueNotAvailable;
return Row( return Row(
children: [ children: [
DecoratedIcon(AIcons.shooting, size: ViewerDetailOverlayContent.iconSize, shadows: ViewerDetailOverlayContent.shadows(context)), DecoratedIcon(AIcons.shooting, size: ViewerDetailOverlayContent.iconSize, shadows: ViewerDetailOverlayContent.shadows(context)),
const SizedBox(width: ViewerDetailOverlayContent.iconPadding), const SizedBox(width: ViewerDetailOverlayContent.iconPadding),
Expanded(child: Text(apertureText, strutStyle: Constants.overflowStrutStyle)), Expanded(child: Text(apertureText, strutStyle: AStyles.overflowStrut)),
Expanded(child: Text(details.exposureTime ?? Constants.overlayUnknown, strutStyle: Constants.overflowStrutStyle)), Expanded(child: Text(details.exposureTime ?? AText.valueNotAvailable, strutStyle: AStyles.overflowStrut)),
Expanded(child: Text(focalLengthText, strutStyle: Constants.overflowStrutStyle)), Expanded(child: Text(focalLengthText, strutStyle: AStyles.overflowStrut)),
Expanded(child: Text(isoText, strutStyle: Constants.overflowStrutStyle)), Expanded(child: Text(isoText, strutStyle: AStyles.overflowStrut)),
], ],
); );
} }

View file

@ -2,7 +2,7 @@ import 'package:aves/model/entry/entry.dart';
import 'package:aves/model/selection.dart'; import 'package:aves/model/selection.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/text.dart';
import 'package:aves/widgets/common/basic/text/animated_diff.dart'; import 'package:aves/widgets/common/basic/text/animated_diff.dart';
import 'package:aves/widgets/common/extensions/build_context.dart'; import 'package:aves/widgets/common/extensions/build_context.dart';
import 'package:aves/widgets/common/identity/buttons/overlay_button.dart'; import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
@ -50,7 +50,7 @@ class SelectionButton extends StatelessWidget {
), ),
const Padding( const Padding(
padding: EdgeInsets.symmetric(horizontal: 8), padding: EdgeInsets.symmetric(horizontal: 8),
child: Text(Constants.separator), child: Text(AText.separator),
), ),
Selector<Selection<AvesEntry>, bool>( Selector<Selection<AvesEntry>, bool>(
selector: (context, selection) => selection.isSelected({mainEntry}), selector: (context, selection) => selection.isSelected({mainEntry}),

View file

@ -1,3 +1,4 @@
import 'package:aves/ref/unicode.dart';
import 'package:aves/widgets/viewer/visual/video/subtitle/line.dart'; import 'package:aves/widgets/viewer/visual/video/subtitle/line.dart';
import 'package:aves/widgets/viewer/visual/video/subtitle/span.dart'; import 'package:aves/widgets/viewer/visual/video/subtitle/span.dart';
import 'package:aves/widgets/viewer/visual/video/subtitle/style.dart'; import 'package:aves/widgets/viewer/visual/video/subtitle/style.dart';
@ -39,8 +40,6 @@ class AssParser {
// e.g. m 937.5 472.67 b 937.5 472.67 937.25 501.25 960 501.5 960 501.5 937.5 500.33 937.5 529.83 // e.g. m 937.5 472.67 b 937.5 472.67 937.25 501.25 960 501.5 960 501.5 937.5 500.33 937.5 529.83
static final pathPattern = RegExp(r'([mnlbspc])([.\s\d]+)'); static final pathPattern = RegExp(r'([mnlbspc])([.\s\d]+)');
static const noBreakSpace = '\u00A0';
// Parse text with ASS style overrides // Parse text with ASS style overrides
// cf https://aegi.vmoe.info/docs/3.0/ASS_Tags/ // cf https://aegi.vmoe.info/docs/3.0/ASS_Tags/
// e.g. `And I'm like, "We can't {\i1}not{\i0} see it."` // e.g. `And I'm like, "We can't {\i1}not{\i0} see it."`
@ -389,7 +388,7 @@ class AssParser {
); );
} }
static String _replaceChars(String text) => text.replaceAll(r'\h', noBreakSpace).replaceAll(r'\N', '\n').trim(); static String _replaceChars(String text) => text.replaceAll(r'\h', Unicode.noBreakSpace).replaceAll(r'\N', '\n').trim();
static int? _parseAlpha(String param) { static int? _parseAlpha(String param) {
final match = alphaPattern.firstMatch(param); final match = alphaPattern.firstMatch(param);

View file

@ -3,7 +3,7 @@ import 'package:aves/model/settings/defaults.dart';
import 'package:aves/model/settings/settings.dart'; import 'package:aves/model/settings/settings.dart';
import 'package:aves/theme/durations.dart'; import 'package:aves/theme/durations.dart';
import 'package:aves/theme/icons.dart'; import 'package:aves/theme/icons.dart';
import 'package:aves/utils/constants.dart'; import 'package:aves/theme/text.dart';
import 'package:aves/widgets/about/policy_page.dart'; import 'package:aves/widgets/about/policy_page.dart';
import 'package:aves/widgets/common/basic/link_chip.dart'; import 'package:aves/widgets/common/basic/link_chip.dart';
import 'package:aves/widgets/common/basic/markdown_container.dart'; import 'package:aves/widgets/common/basic/markdown_container.dart';
@ -174,7 +174,7 @@ class _WelcomePageState extends State<WelcomePage> {
value: settings.isInstalledAppAccessAllowed, value: settings.isInstalledAppAccessAllowed,
onChanged: (v) => setState(() => settings.isInstalledAppAccessAllowed = v), onChanged: (v) => setState(() => settings.isInstalledAppAccessAllowed = v),
title: Text(l10n.settingsAllowInstalledAppAccess), title: Text(l10n.settingsAllowInstalledAppAccess),
subtitle: Text([l10n.welcomeOptional, l10n.settingsAllowInstalledAppAccessSubtitle].join(Constants.separator)), subtitle: Text([l10n.welcomeOptional, l10n.settingsAllowInstalledAppAccessSubtitle].join(AText.separator)),
contentPadding: contentPadding, contentPadding: contentPadding,
), ),
if (canEnableErrorReporting) if (canEnableErrorReporting)