minor change
This commit is contained in:
parent
7aee4c6db3
commit
84999053eb
12 changed files with 135 additions and 35 deletions
4
lib/model/actions/entry_info_actions.dart
Normal file
4
lib/model/actions/entry_info_actions.dart
Normal file
|
@ -0,0 +1,4 @@
|
|||
enum SettingsAction {
|
||||
export,
|
||||
import,
|
||||
}
|
|
@ -12,8 +12,8 @@ import 'package:aves/services/geocoding_service.dart';
|
|||
import 'package:aves/services/service_policy.dart';
|
||||
import 'package:aves/services/services.dart';
|
||||
import 'package:aves/services/svg_metadata_service.dart';
|
||||
import 'package:aves/theme/format.dart';
|
||||
import 'package:aves/utils/change_notifier.dart';
|
||||
import 'package:aves/utils/time_utils.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:country_code/country_code.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
|
|
@ -11,10 +11,10 @@ import 'package:aves/model/video/profiles/hevc.dart';
|
|||
import 'package:aves/ref/languages.dart';
|
||||
import 'package:aves/ref/mp4.dart';
|
||||
import 'package:aves/services/services.dart';
|
||||
import 'package:aves/theme/format.dart';
|
||||
import 'package:aves/utils/file_utils.dart';
|
||||
import 'package:aves/utils/math_utils.dart';
|
||||
import 'package:aves/utils/string_utils.dart';
|
||||
import 'package:aves/utils/time_utils.dart';
|
||||
import 'package:aves/widgets/viewer/video/fijkplayer.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:fijkplayer/fijkplayer.dart';
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import 'dart:ui';
|
||||
|
||||
import 'package:aves/services/services.dart';
|
||||
import 'package:aves/theme/format.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class GlobalSearch {
|
||||
static const platform = MethodChannel('deckers.thibault/aves/global_search');
|
||||
|
@ -55,7 +55,7 @@ Future<List<Map<String, String?>>> _getSuggestions(dynamic args) async {
|
|||
'data': entry.uri,
|
||||
'mimeType': entry.mimeType,
|
||||
'title': entry.bestTitle,
|
||||
'subtitle': date != null ? '${DateFormat.yMMMd(locale).format(date)} • ${DateFormat.Hm(locale).format(date)}' : null,
|
||||
'subtitle': date != null ? formatDateTime(date, locale) : null,
|
||||
'iconUri': entry.uri,
|
||||
};
|
||||
}));
|
||||
|
|
23
lib/theme/format.dart
Normal file
23
lib/theme/format.dart
Normal file
|
@ -0,0 +1,23 @@
|
|||
import 'package:intl/intl.dart';
|
||||
|
||||
String formatDay(DateTime date, String locale) => DateFormat.yMMMd(locale).format(date);
|
||||
|
||||
String formatTime(DateTime date, String locale) => DateFormat.Hm(locale).format(date);
|
||||
|
||||
String formatDateTime(DateTime date, String locale) => '${formatDay(date, locale)} • ${formatTime(date, locale)}';
|
||||
|
||||
String formatFriendlyDuration(Duration d) {
|
||||
final seconds = (d.inSeconds.remainder(Duration.secondsPerMinute)).toString().padLeft(2, '0');
|
||||
if (d.inHours == 0) return '${d.inMinutes}:$seconds';
|
||||
|
||||
final minutes = (d.inMinutes.remainder(Duration.minutesPerHour)).toString().padLeft(2, '0');
|
||||
return '${d.inHours}:$minutes:$seconds';
|
||||
}
|
||||
|
||||
String formatPreciseDuration(Duration d) {
|
||||
final millis = ((d.inMicroseconds / 1000.0).round() % 1000).toString().padLeft(3, '0');
|
||||
final seconds = (d.inSeconds.remainder(Duration.secondsPerMinute)).toString().padLeft(2, '0');
|
||||
final minutes = (d.inMinutes.remainder(Duration.minutesPerHour)).toString().padLeft(2, '0');
|
||||
final hours = (d.inHours).toString().padLeft(2, '0');
|
||||
return '$hours:$minutes:$seconds.$millis';
|
||||
}
|
|
@ -1,19 +1,3 @@
|
|||
String formatFriendlyDuration(Duration d) {
|
||||
final seconds = (d.inSeconds.remainder(Duration.secondsPerMinute)).toString().padLeft(2, '0');
|
||||
if (d.inHours == 0) return '${d.inMinutes}:$seconds';
|
||||
|
||||
final minutes = (d.inMinutes.remainder(Duration.minutesPerHour)).toString().padLeft(2, '0');
|
||||
return '${d.inHours}:$minutes:$seconds';
|
||||
}
|
||||
|
||||
String formatPreciseDuration(Duration d) {
|
||||
final millis = ((d.inMicroseconds / 1000.0).round() % 1000).toString().padLeft(3, '0');
|
||||
final seconds = (d.inSeconds.remainder(Duration.secondsPerMinute)).toString().padLeft(2, '0');
|
||||
final minutes = (d.inMinutes.remainder(Duration.minutesPerHour)).toString().padLeft(2, '0');
|
||||
final hours = (d.inHours).toString().padLeft(2, '0');
|
||||
return '$hours:$minutes:$seconds.$millis';
|
||||
}
|
||||
|
||||
extension ExtraDateTime on DateTime {
|
||||
bool isAtSameYearAs(DateTime? other) => year == other?.year;
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:aves/theme/format.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves/widgets/common/grid/section_layout.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -62,6 +63,6 @@ class DraggableThumbLabel<T> extends StatelessWidget {
|
|||
static String formatDayThumbLabel(BuildContext context, DateTime? date) {
|
||||
final l10n = context.l10n;
|
||||
if (date == null) return l10n.sectionUnknown;
|
||||
return DateFormat.yMMMd(l10n.localeName).format(date);
|
||||
return formatDay(date, l10n.localeName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,15 +73,17 @@ class _CoverSelectionDialogState extends State<CoverSelectionDialog> {
|
|||
setState(() {});
|
||||
},
|
||||
title: isCustom
|
||||
? Row(children: [
|
||||
title,
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
icon: const Icon(AIcons.setCover),
|
||||
onPressed: _isCustom ? _pickEntry : null,
|
||||
tooltip: context.l10n.changeTooltip,
|
||||
),
|
||||
])
|
||||
? Row(
|
||||
children: [
|
||||
title,
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
icon: const Icon(AIcons.setCover),
|
||||
onPressed: _isCustom ? _pickEntry : null,
|
||||
tooltip: context.l10n.changeTooltip,
|
||||
),
|
||||
],
|
||||
)
|
||||
: title,
|
||||
);
|
||||
},
|
||||
|
|
86
lib/widgets/dialogs/edit_entry_date_dialog.dart
Normal file
86
lib/widgets/dialogs/edit_entry_date_dialog.dart
Normal file
|
@ -0,0 +1,86 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:aves/model/entry.dart';
|
||||
import 'package:aves/services/services.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'aves_dialog.dart';
|
||||
|
||||
class RenameEntryDialog extends StatefulWidget {
|
||||
final AvesEntry entry;
|
||||
|
||||
const RenameEntryDialog({
|
||||
Key? key,
|
||||
required this.entry,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_RenameEntryDialogState createState() => _RenameEntryDialogState();
|
||||
}
|
||||
|
||||
class _RenameEntryDialogState extends State<RenameEntryDialog> {
|
||||
final TextEditingController _nameController = TextEditingController();
|
||||
final ValueNotifier<bool> _isValidNotifier = ValueNotifier(false);
|
||||
|
||||
AvesEntry get entry => widget.entry;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_nameController.text = entry.filenameWithoutExtension ?? entry.sourceTitle ?? '';
|
||||
_validate();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_nameController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AvesDialog(
|
||||
context: context,
|
||||
content: TextField(
|
||||
controller: _nameController,
|
||||
decoration: InputDecoration(
|
||||
labelText: context.l10n.renameEntryDialogLabel,
|
||||
suffixText: entry.extension,
|
||||
),
|
||||
autofocus: true,
|
||||
onChanged: (_) => _validate(),
|
||||
onSubmitted: (_) => _submit(context),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
||||
),
|
||||
ValueListenableBuilder<bool>(
|
||||
valueListenable: _isValidNotifier,
|
||||
builder: (context, isValid, child) {
|
||||
return TextButton(
|
||||
onPressed: isValid ? () => _submit(context) : null,
|
||||
child: Text(context.l10n.applyButtonLabel),
|
||||
);
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
String _buildEntryPath(String name) {
|
||||
if (name.isEmpty) return '';
|
||||
return pContext.join(entry.directory!, name + entry.extension!);
|
||||
}
|
||||
|
||||
Future<void> _validate() async {
|
||||
final newName = _nameController.text;
|
||||
final path = _buildEntryPath(newName);
|
||||
final exists = newName.isNotEmpty && await FileSystemEntity.type(path) != FileSystemEntityType.notFound;
|
||||
_isValidNotifier.value = newName.isNotEmpty && !exists;
|
||||
}
|
||||
|
||||
void _submit(BuildContext context) => Navigator.pop(context, _nameController.text);
|
||||
}
|
|
@ -8,6 +8,7 @@ import 'package:aves/model/filters/tag.dart';
|
|||
import 'package:aves/model/filters/type.dart';
|
||||
import 'package:aves/model/source/collection_lens.dart';
|
||||
import 'package:aves/services/services.dart';
|
||||
import 'package:aves/theme/format.dart';
|
||||
import 'package:aves/utils/android_file_utils.dart';
|
||||
import 'package:aves/utils/file_utils.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
|
@ -16,7 +17,6 @@ import 'package:aves/widgets/viewer/info/common.dart';
|
|||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class BasicSection extends StatelessWidget {
|
||||
final AvesEntry entry;
|
||||
|
@ -42,7 +42,7 @@ class BasicSection extends StatelessWidget {
|
|||
final infoUnknown = l10n.viewerInfoUnknown;
|
||||
final date = entry.bestDate;
|
||||
final locale = l10n.localeName;
|
||||
final dateText = date != null ? '${DateFormat.yMMMd(locale).format(date)} • ${DateFormat.Hm(locale).format(date)}' : infoUnknown;
|
||||
final dateText = date != null ? formatDateTime(date, locale) : infoUnknown;
|
||||
|
||||
// TODO TLAD line break on all characters for the following fields when this is fixed: https://github.com/flutter/flutter/issues/61081
|
||||
// inserting ZWSP (\u200B) between characters does help, but it messes with width and height computation (another Flutter issue)
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:aves/model/settings/coordinate_format.dart';
|
|||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/services/services.dart';
|
||||
import 'package:aves/theme/durations.dart';
|
||||
import 'package:aves/theme/format.dart';
|
||||
import 'package:aves/theme/icons.dart';
|
||||
import 'package:aves/utils/constants.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
|
@ -18,7 +19,6 @@ import 'package:aves/widgets/viewer/page_entry_builder.dart';
|
|||
import 'package:decorated_icon/decorated_icon.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tuple/tuple.dart';
|
||||
|
||||
|
@ -387,7 +387,7 @@ class _DateRow extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
final locale = context.l10n.localeName;
|
||||
final date = entry.bestDate;
|
||||
final dateText = date != null ? '${DateFormat.yMMMd(locale).format(date)} • ${DateFormat.Hm(locale).format(date)}' : Constants.overlayUnknown;
|
||||
final dateText = date != null ? formatDateTime(date, locale) : Constants.overlayUnknown;
|
||||
final resolutionText = entry.isSvg
|
||||
? entry.aspectRatioText
|
||||
: entry.isSized
|
||||
|
|
|
@ -5,9 +5,9 @@ import 'package:aves/model/entry.dart';
|
|||
import 'package:aves/model/settings/settings.dart';
|
||||
import 'package:aves/services/android_app_service.dart';
|
||||
import 'package:aves/theme/durations.dart';
|
||||
import 'package:aves/theme/format.dart';
|
||||
import 'package:aves/theme/icons.dart';
|
||||
import 'package:aves/utils/constants.dart';
|
||||
import 'package:aves/utils/time_utils.dart';
|
||||
import 'package:aves/widgets/common/basic/menu.dart';
|
||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||
import 'package:aves/widgets/common/fx/blurred.dart';
|
||||
|
|
Loading…
Reference in a new issue