minor fixes
This commit is contained in:
parent
abca3644f5
commit
1ef9d75b0b
10 changed files with 101 additions and 48 deletions
|
@ -22,7 +22,7 @@ import 'package:fijkplayer/fijkplayer.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
class VideoMetadataFormatter {
|
class VideoMetadataFormatter {
|
||||||
static final _dateY4M2D2H2m2s2Pattern = RegExp(r'(\d{4})[-./](\d{1,2})[-./](\d{1,2})([ T](\d{1,2}):(\d{1,2}):(\d{1,2})( ([ap]\.? ?m\.?))?)?');
|
static final _dateY4M2D2H2m2s2Pattern = RegExp(r'(\d{4})[-./:](\d{1,2})[-./:](\d{1,2})([ T](\d{1,2}):(\d{1,2}):(\d{1,2})( ([ap]\.? ?m\.?))?)?');
|
||||||
static final _ambiguousDatePatterns = {
|
static final _ambiguousDatePatterns = {
|
||||||
RegExp(r'^\d{2}[-/]\d{2}[-/]\d{4}$'),
|
RegExp(r'^\d{2}[-/]\d{2}[-/]\d{4}$'),
|
||||||
};
|
};
|
||||||
|
@ -127,6 +127,7 @@ class VideoMetadataFormatter {
|
||||||
// - `2022-01-28T5:07:46 p. m.Z`
|
// - `2022-01-28T5:07:46 p. m.Z`
|
||||||
// - `2012-1-1T12:00:00Z`
|
// - `2012-1-1T12:00:00Z`
|
||||||
// - `2020.10.14`
|
// - `2020.10.14`
|
||||||
|
// - `2016:11:16 18:00:00`
|
||||||
// - `2021` (not enough to build a date)
|
// - `2021` (not enough to build a date)
|
||||||
|
|
||||||
var match = _dateY4M2D2H2m2s2Pattern.firstMatch(dateString);
|
var match = _dateY4M2D2H2m2s2Pattern.firstMatch(dateString);
|
||||||
|
|
|
@ -165,6 +165,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
builder: (context, _, child) {
|
builder: (context, _, child) {
|
||||||
final isTelevision = device.isTelevision;
|
final isTelevision = device.isTelevision;
|
||||||
final actions = _buildActions(context, selection);
|
final actions = _buildActions(context, selection);
|
||||||
|
final onFilterTap = removableFilters ? collection.removeFilter : null;
|
||||||
return AvesAppBar(
|
return AvesAppBar(
|
||||||
contentHeight: appBarContentHeight,
|
contentHeight: appBarContentHeight,
|
||||||
leading: _buildAppBarLeading(
|
leading: _buildAppBarLeading(
|
||||||
|
@ -192,8 +193,8 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
},
|
},
|
||||||
child: FilterBar(
|
child: FilterBar(
|
||||||
filters: visibleFilters,
|
filters: visibleFilters,
|
||||||
removable: removableFilters,
|
onTap: onFilterTap,
|
||||||
onTap: removableFilters ? collection.removeFilter : null,
|
onRemove: onFilterTap,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (queryEnabled)
|
if (queryEnabled)
|
||||||
|
|
|
@ -11,14 +11,13 @@ class FilterBar extends StatefulWidget {
|
||||||
static const double preferredHeight = AvesFilterChip.minChipHeight + verticalPadding;
|
static const double preferredHeight = AvesFilterChip.minChipHeight + verticalPadding;
|
||||||
|
|
||||||
final List<CollectionFilter> filters;
|
final List<CollectionFilter> filters;
|
||||||
final bool removable;
|
final FilterCallback? onTap, onRemove;
|
||||||
final FilterCallback? onTap;
|
|
||||||
|
|
||||||
FilterBar({
|
FilterBar({
|
||||||
super.key,
|
super.key,
|
||||||
required Set<CollectionFilter> filters,
|
required Set<CollectionFilter> filters,
|
||||||
this.removable = false,
|
|
||||||
this.onTap,
|
this.onTap,
|
||||||
|
this.onRemove,
|
||||||
}) : filters = List<CollectionFilter>.from(filters)..sort();
|
}) : filters = List<CollectionFilter>.from(filters)..sort();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -31,8 +30,6 @@ class _FilterBarState extends State<FilterBar> {
|
||||||
|
|
||||||
List<CollectionFilter> get filters => widget.filters;
|
List<CollectionFilter> get filters => widget.filters;
|
||||||
|
|
||||||
FilterCallback? get onTap => widget.onTap;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didUpdateWidget(covariant FilterBar oldWidget) {
|
void didUpdateWidget(covariant FilterBar oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
|
@ -104,30 +101,37 @@ class _FilterBarState extends State<FilterBar> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildChip(CollectionFilter filter) {
|
Widget _buildChip(CollectionFilter filter) {
|
||||||
return _Chip(
|
final onTap = widget.onTap != null
|
||||||
filter: filter,
|
|
||||||
removable: widget.removable,
|
|
||||||
single: filters.length == 1,
|
|
||||||
onTap: onTap != null
|
|
||||||
? (filter) {
|
? (filter) {
|
||||||
_userTappedFilter = filter;
|
_userTappedFilter = filter;
|
||||||
onTap!(filter);
|
widget.onTap?.call(filter);
|
||||||
}
|
}
|
||||||
: null,
|
: null;
|
||||||
|
final onRemove = widget.onRemove != null
|
||||||
|
? (filter) {
|
||||||
|
_userTappedFilter = filter;
|
||||||
|
widget.onRemove?.call(filter);
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
return _Chip(
|
||||||
|
filter: filter,
|
||||||
|
single: filters.length == 1,
|
||||||
|
onTap: onTap,
|
||||||
|
onRemove: onRemove,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _Chip extends StatelessWidget {
|
class _Chip extends StatelessWidget {
|
||||||
final CollectionFilter filter;
|
final CollectionFilter filter;
|
||||||
final bool removable, single;
|
final bool single;
|
||||||
final FilterCallback? onTap;
|
final FilterCallback? onTap, onRemove;
|
||||||
|
|
||||||
const _Chip({
|
const _Chip({
|
||||||
required this.filter,
|
required this.filter,
|
||||||
required this.removable,
|
|
||||||
required this.single,
|
required this.single,
|
||||||
required this.onTap,
|
required this.onTap,
|
||||||
|
required this.onRemove,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -138,7 +142,6 @@ class _Chip extends StatelessWidget {
|
||||||
child: AvesFilterChip(
|
child: AvesFilterChip(
|
||||||
key: ValueKey(filter),
|
key: ValueKey(filter),
|
||||||
filter: filter,
|
filter: filter,
|
||||||
removable: removable,
|
|
||||||
maxWidth: single
|
maxWidth: single
|
||||||
? AvesFilterChip.computeMaxWidth(
|
? AvesFilterChip.computeMaxWidth(
|
||||||
context,
|
context,
|
||||||
|
@ -149,6 +152,7 @@ class _Chip extends StatelessWidget {
|
||||||
: null,
|
: null,
|
||||||
heroType: HeroType.always,
|
heroType: HeroType.always,
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
|
onRemove: onRemove,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -67,10 +67,11 @@ class TitledExpandableFilterRow extends StatelessWidget {
|
||||||
class ExpandableFilterRow extends StatelessWidget {
|
class ExpandableFilterRow extends StatelessWidget {
|
||||||
final List<CollectionFilter> filters;
|
final List<CollectionFilter> filters;
|
||||||
final bool isExpanded;
|
final bool isExpanded;
|
||||||
final bool removable, showGenericIcon;
|
final bool showGenericIcon;
|
||||||
final Widget? Function(CollectionFilter)? leadingBuilder;
|
final Widget? Function(CollectionFilter)? leadingBuilder;
|
||||||
final HeroType Function(CollectionFilter filter)? heroTypeBuilder;
|
final HeroType Function(CollectionFilter filter)? heroTypeBuilder;
|
||||||
final FilterCallback onTap;
|
final FilterCallback onTap;
|
||||||
|
final FilterCallback? onRemove;
|
||||||
final OffsetFilterCallback? onLongPress;
|
final OffsetFilterCallback? onLongPress;
|
||||||
|
|
||||||
static const double horizontalPadding = 8;
|
static const double horizontalPadding = 8;
|
||||||
|
@ -80,11 +81,11 @@ class ExpandableFilterRow extends StatelessWidget {
|
||||||
super.key,
|
super.key,
|
||||||
required this.filters,
|
required this.filters,
|
||||||
required this.isExpanded,
|
required this.isExpanded,
|
||||||
this.removable = false,
|
|
||||||
this.showGenericIcon = true,
|
this.showGenericIcon = true,
|
||||||
this.leadingBuilder,
|
this.leadingBuilder,
|
||||||
this.heroTypeBuilder,
|
this.heroTypeBuilder,
|
||||||
required this.onTap,
|
required this.onTap,
|
||||||
|
this.onRemove,
|
||||||
required this.onLongPress,
|
required this.onLongPress,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -143,11 +144,11 @@ class ExpandableFilterRow extends StatelessWidget {
|
||||||
// key `album-{path}` is expected by test driver
|
// key `album-{path}` is expected by test driver
|
||||||
key: Key(filter.key),
|
key: Key(filter.key),
|
||||||
filter: filter,
|
filter: filter,
|
||||||
removable: removable,
|
|
||||||
showGenericIcon: showGenericIcon,
|
showGenericIcon: showGenericIcon,
|
||||||
leadingOverride: leadingBuilder?.call(filter),
|
leadingOverride: leadingBuilder?.call(filter),
|
||||||
heroType: heroTypeBuilder?.call(filter) ?? HeroType.onTap,
|
heroType: heroTypeBuilder?.call(filter) ?? HeroType.onTap,
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
|
onRemove: onRemove,
|
||||||
onLongPress: onLongPress,
|
onLongPress: onLongPress,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:aves/model/device.dart';
|
import 'package:aves/model/device.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
|
import 'package:aves/theme/colors.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
import 'package:aves/widgets/aves_app.dart';
|
import 'package:aves/widgets/aves_app.dart';
|
||||||
import 'package:aves/widgets/common/fx/blurred.dart';
|
import 'package:aves/widgets/common/fx/blurred.dart';
|
||||||
|
@ -63,7 +64,7 @@ class AvesAppBar extends StatelessWidget {
|
||||||
: const SizedBox(width: 16),
|
: const SizedBox(width: 16),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: DefaultTextStyle(
|
child: DefaultTextStyle(
|
||||||
style: Theme.of(context).appBarTheme.titleTextStyle!,
|
style: context.select<AvesColorsData, TextStyle>((v) => Theme.of(context).appBarTheme.titleTextStyle!),
|
||||||
child: Hero(
|
child: Hero(
|
||||||
tag: titleHeroTag,
|
tag: titleHeroTag,
|
||||||
flightShuttleBuilder: _flightShuttleBuilder,
|
flightShuttleBuilder: _flightShuttleBuilder,
|
||||||
|
|
|
@ -44,14 +44,14 @@ class AvesFilterDecoration {
|
||||||
|
|
||||||
class AvesFilterChip extends StatefulWidget {
|
class AvesFilterChip extends StatefulWidget {
|
||||||
final CollectionFilter filter;
|
final CollectionFilter filter;
|
||||||
final bool removable, showText, showGenericIcon, useFilterColor;
|
final bool showText, showGenericIcon, useFilterColor;
|
||||||
final AvesFilterDecoration? decoration;
|
final AvesFilterDecoration? decoration;
|
||||||
final String? banner;
|
final String? banner;
|
||||||
final Widget? leadingOverride, details;
|
final Widget? leadingOverride, details;
|
||||||
final double padding;
|
final double padding;
|
||||||
final double? maxWidth;
|
final double? maxWidth;
|
||||||
final HeroType heroType;
|
final HeroType heroType;
|
||||||
final FilterCallback? onTap;
|
final FilterCallback? onTap, onRemove;
|
||||||
final OffsetFilterCallback? onLongPress;
|
final OffsetFilterCallback? onLongPress;
|
||||||
|
|
||||||
static const double defaultRadius = 32;
|
static const double defaultRadius = 32;
|
||||||
|
@ -65,7 +65,6 @@ class AvesFilterChip extends StatefulWidget {
|
||||||
const AvesFilterChip({
|
const AvesFilterChip({
|
||||||
super.key,
|
super.key,
|
||||||
required this.filter,
|
required this.filter,
|
||||||
this.removable = false,
|
|
||||||
this.showText = true,
|
this.showText = true,
|
||||||
this.showGenericIcon = true,
|
this.showGenericIcon = true,
|
||||||
this.useFilterColor = true,
|
this.useFilterColor = true,
|
||||||
|
@ -77,6 +76,7 @@ class AvesFilterChip extends StatefulWidget {
|
||||||
this.maxWidth,
|
this.maxWidth,
|
||||||
this.heroType = HeroType.onTap,
|
this.heroType = HeroType.onTap,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
|
this.onRemove,
|
||||||
this.onLongPress = showDefaultLongPressMenu,
|
this.onLongPress = showDefaultLongPressMenu,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -154,10 +154,6 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
|
||||||
|
|
||||||
double get padding => widget.padding;
|
double get padding => widget.padding;
|
||||||
|
|
||||||
FilterCallback? get onTap => widget.onTap;
|
|
||||||
|
|
||||||
OffsetFilterCallback? get onLongPress => widget.onLongPress;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
@ -219,12 +215,40 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
|
||||||
final decoration = widget.decoration;
|
final decoration = widget.decoration;
|
||||||
final chipBackground = Theme.of(context).scaffoldBackgroundColor;
|
final chipBackground = Theme.of(context).scaffoldBackgroundColor;
|
||||||
|
|
||||||
|
final onTap = widget.onTap != null
|
||||||
|
? () {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) => widget.onTap?.call(filter));
|
||||||
|
setState(() => _tapped = true);
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
final onRemove = widget.onRemove != null
|
||||||
|
? () {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) => widget.onRemove?.call(filter));
|
||||||
|
setState(() => _tapped = true);
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
final onLongPress = widget.onLongPress != null
|
||||||
|
? () {
|
||||||
|
if (_tapPosition != null) {
|
||||||
|
widget.onLongPress?.call(context, filter, _tapPosition!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
|
||||||
Widget? content;
|
Widget? content;
|
||||||
if (widget.showText) {
|
if (widget.showText) {
|
||||||
final textScaleFactor = MediaQuery.textScaleFactorOf(context);
|
final textScaleFactor = MediaQuery.textScaleFactorOf(context);
|
||||||
final iconSize = AvesFilterChip.iconSize * textScaleFactor;
|
final iconSize = AvesFilterChip.iconSize * textScaleFactor;
|
||||||
final leading = widget.leadingOverride ?? filter.iconBuilder(context, iconSize, showGenericIcon: widget.showGenericIcon);
|
final leading = widget.leadingOverride ?? filter.iconBuilder(context, iconSize, showGenericIcon: widget.showGenericIcon);
|
||||||
final trailing = widget.removable ? Icon(AIcons.clear, size: iconSize) : null;
|
final trailing = onRemove != null
|
||||||
|
? IconButton(
|
||||||
|
icon: Icon(AIcons.clear, size: iconSize),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
splashRadius: IconTheme.of(context).size,
|
||||||
|
constraints: const BoxConstraints(),
|
||||||
|
onPressed: onRemove,
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
|
||||||
content = Row(
|
content = Row(
|
||||||
mainAxisSize: decoration != null ? MainAxisSize.max : MainAxisSize.min,
|
mainAxisSize: decoration != null ? MainAxisSize.max : MainAxisSize.min,
|
||||||
|
@ -317,13 +341,8 @@ class _AvesFilterChipState extends State<AvesFilterChip> {
|
||||||
// as of Flutter v2.8.0, `InkWell` does not have `onLongPressStart` like `GestureDetector`,
|
// as of Flutter v2.8.0, `InkWell` does not have `onLongPressStart` like `GestureDetector`,
|
||||||
// so we get the long press details from the tap instead
|
// so we get the long press details from the tap instead
|
||||||
onTapDown: onLongPress != null ? (details) => _tapPosition = details.globalPosition : null,
|
onTapDown: onLongPress != null ? (details) => _tapPosition = details.globalPosition : null,
|
||||||
onTap: onTap != null
|
onTap: onTap,
|
||||||
? () {
|
onLongPress: onLongPress,
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) => onTap!(filter));
|
|
||||||
setState(() => _tapped = true);
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
onLongPress: onLongPress != null ? () => onLongPress!(context, filter, _tapPosition!) : null,
|
|
||||||
borderRadius: borderRadius,
|
borderRadius: borderRadius,
|
||||||
child: FutureBuilder<Color>(
|
child: FutureBuilder<Color>(
|
||||||
future: _colorFuture,
|
future: _colorFuture,
|
||||||
|
|
|
@ -150,14 +150,16 @@ class _TagEditorPageState extends State<TagEditorPage> {
|
||||||
secondChild: ExpandableFilterRow(
|
secondChild: ExpandableFilterRow(
|
||||||
filters: sortedTags.map((kv) => kv.key).toList(),
|
filters: sortedTags.map((kv) => kv.key).toList(),
|
||||||
isExpanded: context.select<Settings, bool>((v) => v.tagEditorCurrentFilterSectionExpanded),
|
isExpanded: context.select<Settings, bool>((v) => v.tagEditorCurrentFilterSectionExpanded),
|
||||||
removable: true,
|
|
||||||
showGenericIcon: false,
|
showGenericIcon: false,
|
||||||
leadingBuilder: showCount
|
leadingBuilder: showCount
|
||||||
? (filter) => _TagCount(
|
? (filter) => _TagCount(
|
||||||
count: sortedTags.firstWhere((kv) => kv.key == filter).value,
|
count: sortedTags.firstWhere((kv) => kv.key == filter).value,
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
onTap: _removeTag,
|
onTap: (filter) {
|
||||||
|
// TODO TLAD [#453]
|
||||||
|
},
|
||||||
|
onRemove: _removeTag,
|
||||||
onLongPress: null,
|
onLongPress: null,
|
||||||
),
|
),
|
||||||
crossFadeState: sortedTags.isEmpty ? CrossFadeState.showFirst : CrossFadeState.showSecond,
|
crossFadeState: sortedTags.isEmpty ? CrossFadeState.showFirst : CrossFadeState.showSecond,
|
||||||
|
|
|
@ -88,14 +88,15 @@ class _HiddenFilters extends StatelessWidget {
|
||||||
child: Wrap(
|
child: Wrap(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
runSpacing: 8,
|
runSpacing: 8,
|
||||||
children: filterList
|
children: filterList.map((filter) {
|
||||||
.map((filter) => AvesFilterChip(
|
void onRemove(CollectionFilter filter) => settings.changeFilterVisibility({filter}, true);
|
||||||
|
return AvesFilterChip(
|
||||||
filter: filter,
|
filter: filter,
|
||||||
removable: true,
|
onTap: onRemove,
|
||||||
onTap: (filter) => settings.changeFilterVisibility({filter}, true),
|
onRemove: onRemove,
|
||||||
onLongPress: null,
|
onLongPress: null,
|
||||||
))
|
);
|
||||||
.toList(),
|
}).toList(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
22
scripts/extract_apks.sh
Executable file
22
scripts/extract_apks.sh
Executable file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/bash
|
||||||
|
if [ ! -d "scripts" ]; then
|
||||||
|
cd ..
|
||||||
|
fi
|
||||||
|
|
||||||
|
BUNDLE="/home/tibo/Downloads/app-play-release.aab"
|
||||||
|
|
||||||
|
# shellcheck disable=SC2001
|
||||||
|
OUTPUT=$(sed "s|\.aab|\.apks|" <<<"$BUNDLE")
|
||||||
|
|
||||||
|
KEYS_PATH="android/key.properties"
|
||||||
|
STORE_PATH=$(sed -n 's|.*storeFile=\(.*\)[\r\n]|\1|p' "$KEYS_PATH")
|
||||||
|
# shellcheck disable=SC1003
|
||||||
|
STORE_PW=$(sed -n 's|.*storePassword=\(.*\)[\r\n]|\1|p' "$KEYS_PATH" | sed 's|\\'\''|'\''|g')
|
||||||
|
KEY_ALIAS=$(sed -n 's|.*keyAlias=\(.*\)[\r\n]|\1|p' "$KEYS_PATH")
|
||||||
|
# shellcheck disable=SC1003
|
||||||
|
KEY_PW=$(sed -n 's|.*keyPassword=\(.*\)[\r\n]|\1|p' "$KEYS_PATH" | sed 's|\\'\''|'\''|g')
|
||||||
|
|
||||||
|
echo "$BUNDLE -> $OUTPUT"
|
||||||
|
bundletool build-apks --bundle="$BUNDLE" --output="$OUTPUT" \
|
||||||
|
--ks="$STORE_PATH" --ks-pass="pass:$STORE_PW" \
|
||||||
|
--ks-key-alias="$KEY_ALIAS" --key-pass="pass:$KEY_PW"
|
|
@ -16,6 +16,7 @@ void main() {
|
||||||
expect(VideoMetadataFormatter.parseVideoDate('2022-01-28T5:07:46 p. m.Z'), DateTime(2022, 1, 28, 17, 7, 46).millisecondsSinceEpoch);
|
expect(VideoMetadataFormatter.parseVideoDate('2022-01-28T5:07:46 p. m.Z'), DateTime(2022, 1, 28, 17, 7, 46).millisecondsSinceEpoch);
|
||||||
expect(VideoMetadataFormatter.parseVideoDate('2012-1-1T12:00:00Z'), DateTime(2012, 1, 1, 12, 0, 0).millisecondsSinceEpoch);
|
expect(VideoMetadataFormatter.parseVideoDate('2012-1-1T12:00:00Z'), DateTime(2012, 1, 1, 12, 0, 0).millisecondsSinceEpoch);
|
||||||
expect(VideoMetadataFormatter.parseVideoDate('2020.10.14'), DateTime(2020, 10, 14).millisecondsSinceEpoch);
|
expect(VideoMetadataFormatter.parseVideoDate('2020.10.14'), DateTime(2020, 10, 14).millisecondsSinceEpoch);
|
||||||
|
expect(VideoMetadataFormatter.parseVideoDate('2016:11:16 18:00:00'), DateTime(2016, 11, 16, 18, 0, 0).millisecondsSinceEpoch);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Ambiguous date', () {
|
test('Ambiguous date', () {
|
||||||
|
|
Loading…
Reference in a new issue