l10n: fixes for RTL
This commit is contained in:
parent
dd6258d8ac
commit
ff16651ce1
15 changed files with 181 additions and 151 deletions
|
@ -2,6 +2,12 @@ import 'dart:ui';
|
||||||
|
|
||||||
const String asciiLocale = 'en_US';
|
const String asciiLocale = 'en_US';
|
||||||
|
|
||||||
|
// time components hours/minutes/seconds are always displayed in that order
|
||||||
|
const TextDirection timeComponentsDirection = TextDirection.ltr;
|
||||||
|
|
||||||
|
// represents direction of tape being played, not direction of time
|
||||||
|
const TextDirection videoPlaybackDirection = TextDirection.ltr;
|
||||||
|
|
||||||
// cf https://en.wikipedia.org/wiki/Eastern_Arabic_numerals
|
// cf https://en.wikipedia.org/wiki/Eastern_Arabic_numerals
|
||||||
bool shouldUseNativeDigits(Locale? countrifiedLocale) {
|
bool shouldUseNativeDigits(Locale? countrifiedLocale) {
|
||||||
switch (countrifiedLocale?.toString()) {
|
switch (countrifiedLocale?.toString()) {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:aves/ref/locales.dart';
|
||||||
import 'package:aves/utils/time_utils.dart';
|
import 'package:aves/utils/time_utils.dart';
|
||||||
import 'package:aves/widgets/common/basic/wheel.dart';
|
import 'package:aves/widgets/common/basic/wheel.dart';
|
||||||
import 'package:aves/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
|
@ -48,8 +49,7 @@ class _DurationDialogState extends State<DurationDialog> {
|
||||||
padding: const EdgeInsets.only(top: 16),
|
padding: const EdgeInsets.only(top: 16),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Table(
|
child: Table(
|
||||||
// even when ambient direction is RTL, time is displayed in LTR
|
textDirection: timeComponentsDirection,
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
children: [
|
children: [
|
||||||
TableRow(
|
TableRow(
|
||||||
children: [
|
children: [
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'package:aves/model/entry/entry.dart';
|
import 'package:aves/model/entry/entry.dart';
|
||||||
import 'package:aves/model/metadata/date_modifier.dart';
|
import 'package:aves/model/metadata/date_modifier.dart';
|
||||||
import 'package:aves/model/source/collection_lens.dart';
|
import 'package:aves/model/source/collection_lens.dart';
|
||||||
|
import 'package:aves/ref/locales.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.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';
|
||||||
|
@ -204,8 +205,7 @@ class _EditEntryDateDialogState extends State<EditEntryDateDialog> {
|
||||||
const textStyle = TextStyle(fontSize: 34);
|
const textStyle = TextStyle(fontSize: 34);
|
||||||
return Center(
|
return Center(
|
||||||
child: Table(
|
child: Table(
|
||||||
// even when ambient direction is RTL, time is displayed in LTR
|
textDirection: timeComponentsDirection,
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
children: [
|
children: [
|
||||||
TableRow(
|
TableRow(
|
||||||
children: [
|
children: [
|
||||||
|
|
|
@ -19,6 +19,7 @@ import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||||
|
|
||||||
class QuickActionEditorPage<T extends Object> extends StatelessWidget {
|
class QuickActionEditorPage<T extends Object> extends StatelessWidget {
|
||||||
final String title, bannerText;
|
final String title, bannerText;
|
||||||
|
final TextDirection? displayedButtonsDirection;
|
||||||
final List<List<T>> allAvailableActions;
|
final List<List<T>> allAvailableActions;
|
||||||
final Widget Function(T action) actionIcon;
|
final Widget Function(T action) actionIcon;
|
||||||
final String Function(BuildContext context, T action) actionText;
|
final String Function(BuildContext context, T action) actionText;
|
||||||
|
@ -29,6 +30,7 @@ class QuickActionEditorPage<T extends Object> extends StatelessWidget {
|
||||||
super.key,
|
super.key,
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.bannerText,
|
required this.bannerText,
|
||||||
|
this.displayedButtonsDirection,
|
||||||
required this.allAvailableActions,
|
required this.allAvailableActions,
|
||||||
required this.actionIcon,
|
required this.actionIcon,
|
||||||
required this.actionText,
|
required this.actionText,
|
||||||
|
@ -45,6 +47,7 @@ class QuickActionEditorPage<T extends Object> extends StatelessWidget {
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: QuickActionEditorBody(
|
child: QuickActionEditorBody(
|
||||||
bannerText: bannerText,
|
bannerText: bannerText,
|
||||||
|
displayedButtonsDirection: displayedButtonsDirection,
|
||||||
allAvailableActions: allAvailableActions,
|
allAvailableActions: allAvailableActions,
|
||||||
actionIcon: actionIcon,
|
actionIcon: actionIcon,
|
||||||
actionText: actionText,
|
actionText: actionText,
|
||||||
|
@ -58,6 +61,7 @@ class QuickActionEditorPage<T extends Object> extends StatelessWidget {
|
||||||
|
|
||||||
class QuickActionEditorBody<T extends Object> extends StatefulWidget {
|
class QuickActionEditorBody<T extends Object> extends StatefulWidget {
|
||||||
final String bannerText;
|
final String bannerText;
|
||||||
|
final TextDirection? displayedButtonsDirection;
|
||||||
final List<List<T>> allAvailableActions;
|
final List<List<T>> allAvailableActions;
|
||||||
final Widget Function(T action) actionIcon;
|
final Widget Function(T action) actionIcon;
|
||||||
final String Function(BuildContext context, T action) actionText;
|
final String Function(BuildContext context, T action) actionText;
|
||||||
|
@ -67,6 +71,7 @@ class QuickActionEditorBody<T extends Object> extends StatefulWidget {
|
||||||
const QuickActionEditorBody({
|
const QuickActionEditorBody({
|
||||||
super.key,
|
super.key,
|
||||||
required this.bannerText,
|
required this.bannerText,
|
||||||
|
this.displayedButtonsDirection,
|
||||||
required this.allAvailableActions,
|
required this.allAvailableActions,
|
||||||
required this.actionIcon,
|
required this.actionIcon,
|
||||||
required this.actionText,
|
required this.actionText,
|
||||||
|
@ -147,6 +152,7 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
|
||||||
removeAction: _removeQuickAction,
|
removeAction: _removeQuickAction,
|
||||||
onTargetLeave: _onQuickActionTargetLeave,
|
onTargetLeave: _onQuickActionTargetLeave,
|
||||||
);
|
);
|
||||||
|
final originalDirection = Directionality.of(context);
|
||||||
return PopScope(
|
return PopScope(
|
||||||
canPop: true,
|
canPop: true,
|
||||||
onPopInvoked: (didPop) => widget.save(_quickActions),
|
onPopInvoked: (didPop) => widget.save(_quickActions),
|
||||||
|
@ -176,6 +182,8 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
|
||||||
highlight: highlight,
|
highlight: highlight,
|
||||||
child: child!,
|
child: child!,
|
||||||
),
|
),
|
||||||
|
child: Directionality(
|
||||||
|
textDirection: widget.displayedButtonsDirection ?? originalDirection,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: OverlayButton.getSize(context) + quickActionVerticalPadding * 2,
|
height: OverlayButton.getSize(context) + quickActionVerticalPadding * 2,
|
||||||
child: Stack(
|
child: Stack(
|
||||||
|
@ -205,7 +213,9 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
|
||||||
itemBuilder: (context, index, animation) {
|
itemBuilder: (context, index, animation) {
|
||||||
if (index >= _quickActions.length) return const SizedBox();
|
if (index >= _quickActions.length) return const SizedBox();
|
||||||
final action = _quickActions[index];
|
final action = _quickActions[index];
|
||||||
return QuickActionButton<T>(
|
return Directionality(
|
||||||
|
textDirection: originalDirection,
|
||||||
|
child: QuickActionButton<T>(
|
||||||
placement: QuickActionPlacement.action,
|
placement: QuickActionPlacement.action,
|
||||||
action: action,
|
action: action,
|
||||||
panelHighlight: _quickActionHighlight,
|
panelHighlight: _quickActionHighlight,
|
||||||
|
@ -221,6 +231,7 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
|
||||||
onPressed: () {},
|
onPressed: () {},
|
||||||
),
|
),
|
||||||
child: _buildQuickActionButton(action, animation),
|
child: _buildQuickActionButton(action, animation),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
@ -240,6 +251,7 @@ class _QuickActionEditorBodyState<T extends Object> extends State<QuickActionEdi
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|
|
@ -2,6 +2,7 @@ import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/view/view.dart';
|
import 'package:aves/view/view.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/quick_actions/editor_page.dart';
|
import 'package:aves/widgets/settings/common/quick_actions/editor_page.dart';
|
||||||
|
import 'package:aves/widgets/viewer/overlay/bottom.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';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -40,6 +41,7 @@ class ViewerActionEditorPage extends StatelessWidget {
|
||||||
return QuickActionEditorPage<EntryAction>(
|
return QuickActionEditorPage<EntryAction>(
|
||||||
title: context.l10n.settingsViewerQuickActionEditorPageTitle,
|
title: context.l10n.settingsViewerQuickActionEditorPageTitle,
|
||||||
bannerText: context.l10n.settingsViewerQuickActionEditorBanner,
|
bannerText: context.l10n.settingsViewerQuickActionEditorBanner,
|
||||||
|
displayedButtonsDirection: ViewerBottomOverlay.actionsDirection,
|
||||||
allAvailableActions: allAvailableActions,
|
allAvailableActions: allAvailableActions,
|
||||||
actionIcon: (action) => action.getIcon(),
|
actionIcon: (action) => action.getIcon(),
|
||||||
actionText: (context, action) => action.getText(context),
|
actionText: (context, action) => action.getText(context),
|
||||||
|
|
|
@ -30,6 +30,9 @@ class ViewerBottomOverlay extends StatefulWidget {
|
||||||
final EdgeInsets? viewInsets, viewPadding;
|
final EdgeInsets? viewInsets, viewPadding;
|
||||||
final MultiPageController? multiPageController;
|
final MultiPageController? multiPageController;
|
||||||
|
|
||||||
|
// always keep action buttons in the lower right corner, even with RTL locales
|
||||||
|
static const actionsDirection = TextDirection.ltr;
|
||||||
|
|
||||||
const ViewerBottomOverlay({
|
const ViewerBottomOverlay({
|
||||||
super.key,
|
super.key,
|
||||||
required this.entries,
|
required this.entries,
|
||||||
|
@ -185,10 +188,7 @@ class _BottomOverlayContentState extends State<_BottomOverlayContent> {
|
||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
final viewInsetsPadding = (widget.viewInsets ?? EdgeInsets.zero) + (widget.viewPadding ?? EdgeInsets.zero);
|
final viewInsetsPadding = (widget.viewInsets ?? EdgeInsets.zero) + (widget.viewPadding ?? EdgeInsets.zero);
|
||||||
final selection = context.read<Selection<AvesEntry>?>();
|
final selection = context.read<Selection<AvesEntry>?>();
|
||||||
final viewerButtonRow = Directionality(
|
final viewerButtonRow = (selection?.isSelecting ?? false)
|
||||||
// always keep action buttons in the lower right corner, even with RTL locales
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: (selection?.isSelecting ?? false)
|
|
||||||
? SelectionButton(
|
? SelectionButton(
|
||||||
mainEntry: mainEntry,
|
mainEntry: mainEntry,
|
||||||
scale: _buttonScale,
|
scale: _buttonScale,
|
||||||
|
@ -222,7 +222,6 @@ class _BottomOverlayContentState extends State<_BottomOverlayContent> {
|
||||||
scale: _buttonScale,
|
scale: _buttonScale,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final showMultiPageOverlay = mainEntry.isMultiPage && multiPageController != null;
|
final showMultiPageOverlay = mainEntry.isMultiPage && multiPageController != null;
|
||||||
|
@ -250,8 +249,7 @@ class _BottomOverlayContentState extends State<_BottomOverlayContent> {
|
||||||
(showMultiPageOverlay && collapsedPageScroller)
|
(showMultiPageOverlay && collapsedPageScroller)
|
||||||
? Row(
|
? Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
// always keep action buttons in the lower right corner, even with RTL locales
|
textDirection: ViewerBottomOverlay.actionsDirection,
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
children: [
|
children: [
|
||||||
SafeArea(
|
SafeArea(
|
||||||
top: false,
|
top: false,
|
||||||
|
|
|
@ -65,7 +65,7 @@ class _ViewerLockedOverlayState extends State<ViewerLockedOverlay> {
|
||||||
builder: (context, mqPaddingBottom, child) {
|
builder: (context, mqPaddingBottom, child) {
|
||||||
final viewInsetsPadding = (widget.viewInsets ?? EdgeInsets.zero) + (widget.viewPadding ?? EdgeInsets.zero);
|
final viewInsetsPadding = (widget.viewInsets ?? EdgeInsets.zero) + (widget.viewPadding ?? EdgeInsets.zero);
|
||||||
return Container(
|
return Container(
|
||||||
alignment: AlignmentDirectional.bottomEnd,
|
alignment: Alignment.bottomRight,
|
||||||
padding: EdgeInsets.only(bottom: mqPaddingBottom) + const EdgeInsets.all(ViewerButtonRowContent.padding),
|
padding: EdgeInsets.only(bottom: mqPaddingBottom) + const EdgeInsets.all(ViewerButtonRowContent.padding),
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
top: false,
|
top: false,
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'package:aves/model/entry/entry.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.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';
|
||||||
|
import 'package:aves/widgets/viewer/overlay/bottom.dart';
|
||||||
import 'package:aves/widgets/viewer/panorama_page.dart';
|
import 'package:aves/widgets/viewer/panorama_page.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
@ -20,6 +21,7 @@ class PanoramaOverlay extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Row(
|
return Row(
|
||||||
|
textDirection: ViewerBottomOverlay.actionsDirection,
|
||||||
children: [
|
children: [
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
ScalingOverlayTextButton(
|
ScalingOverlayTextButton(
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
import 'package:aves/widgets/viewer/overlay/bottom.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
@ -33,6 +34,7 @@ class SelectionButton extends StatelessWidget {
|
||||||
padding: const EdgeInsets.only(left: padding, right: padding, bottom: padding),
|
padding: const EdgeInsets.only(left: padding, right: padding, bottom: padding),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
textDirection: ViewerBottomOverlay.actionsDirection,
|
||||||
children: [
|
children: [
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
ScalingOverlayTextButton(
|
ScalingOverlayTextButton(
|
||||||
|
@ -43,6 +45,7 @@ class SelectionButton extends StatelessWidget {
|
||||||
builder: (context, count, child) {
|
builder: (context, count, child) {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
textDirection: ViewerBottomOverlay.actionsDirection,
|
||||||
children: [
|
children: [
|
||||||
AnimatedDiffText(
|
AnimatedDiffText(
|
||||||
count == 0 ? l10n.collectionSelectPageTitle : l10n.itemCount(count),
|
count == 0 ? l10n.collectionSelectPageTitle : l10n.itemCount(count),
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
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:aves/widgets/common/identity/buttons/overlay_button.dart';
|
import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
|
||||||
|
import 'package:aves/widgets/viewer/overlay/bottom.dart';
|
||||||
import 'package:aves_video/aves_video.dart';
|
import 'package:aves_video/aves_video.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
@ -55,6 +56,7 @@ class _VideoABRepeatOverlayState extends State<VideoABRepeatOverlay> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Row(
|
return Row(
|
||||||
|
textDirection: ViewerBottomOverlay.actionsDirection,
|
||||||
children: [
|
children: [
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
OverlayButton(
|
OverlayButton(
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/view/view.dart';
|
import 'package:aves/view/view.dart';
|
||||||
import 'package:aves/widgets/common/action_controls/togglers/play.dart';
|
import 'package:aves/widgets/common/action_controls/togglers/play.dart';
|
||||||
import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
|
import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
|
||||||
|
import 'package:aves/widgets/viewer/overlay/bottom.dart';
|
||||||
import 'package:aves_model/aves_model.dart';
|
import 'package:aves_model/aves_model.dart';
|
||||||
import 'package:aves_video/aves_video.dart';
|
import 'package:aves_video/aves_video.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -33,7 +34,7 @@ class VideoControlRow extends StatelessWidget {
|
||||||
switch (videoControls) {
|
switch (videoControls) {
|
||||||
case VideoControls.play:
|
case VideoControls.play:
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsetsDirectional.only(start: padding),
|
padding: const EdgeInsets.only(left: padding),
|
||||||
child: _buildOverlayButton(
|
child: _buildOverlayButton(
|
||||||
child: PlayToggler(
|
child: PlayToggler(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
|
@ -44,6 +45,7 @@ class VideoControlRow extends StatelessWidget {
|
||||||
case VideoControls.playSeek:
|
case VideoControls.playSeek:
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
textDirection: ViewerBottomOverlay.actionsDirection,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(width: padding),
|
const SizedBox(width: padding),
|
||||||
_buildIconButton(
|
_buildIconButton(
|
||||||
|
@ -67,7 +69,7 @@ class VideoControlRow extends StatelessWidget {
|
||||||
);
|
);
|
||||||
case VideoControls.playOutside:
|
case VideoControls.playOutside:
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsetsDirectional.only(start: padding),
|
padding: const EdgeInsets.only(left: padding),
|
||||||
child: _buildIconButton(context, EntryAction.openVideo, enabled: !entry.trashed),
|
child: _buildIconButton(context, EntryAction.openVideo, enabled: !entry.trashed),
|
||||||
);
|
);
|
||||||
case VideoControls.none:
|
case VideoControls.none:
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
|
import 'package:aves/ref/locales.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/styles.dart';
|
||||||
|
@ -122,8 +123,7 @@ class _VideoProgressBarState extends State<VideoProgressBar> {
|
||||||
ClipRRect(
|
ClipRRect(
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
borderRadius: const BorderRadius.all(Radius.circular(4)),
|
||||||
child: Directionality(
|
child: Directionality(
|
||||||
// force directionality for `LinearProgressIndicator`
|
textDirection: videoPlaybackDirection,
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: StreamBuilder<int>(
|
child: StreamBuilder<int>(
|
||||||
stream: positionStream,
|
stream: positionStream,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ import 'dart:async';
|
||||||
import 'package:aves/model/entry/entry.dart';
|
import 'package:aves/model/entry/entry.dart';
|
||||||
import 'package:aves/view/view.dart';
|
import 'package:aves/view/view.dart';
|
||||||
import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
|
import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
|
||||||
|
import 'package:aves/widgets/viewer/overlay/bottom.dart';
|
||||||
import 'package:aves/widgets/viewer/overlay/video/ab_repeat.dart';
|
import 'package:aves/widgets/viewer/overlay/video/ab_repeat.dart';
|
||||||
import 'package:aves/widgets/viewer/overlay/video/controls.dart';
|
import 'package:aves/widgets/viewer/overlay/video/controls.dart';
|
||||||
import 'package:aves/widgets/viewer/overlay/video/progress_bar.dart';
|
import 'package:aves/widgets/viewer/overlay/video/progress_bar.dart';
|
||||||
|
@ -41,10 +42,7 @@ class _VideoControlOverlayState extends State<VideoControlOverlay> with SingleTi
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Directionality(
|
return StreamBuilder<VideoStatus>(
|
||||||
// always keep action buttons in the lower right corner, even with RTL locales
|
|
||||||
textDirection: TextDirection.ltr,
|
|
||||||
child: StreamBuilder<VideoStatus>(
|
|
||||||
stream: statusStream,
|
stream: statusStream,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
// do not use stream snapshot because it is obsolete when switching between videos
|
// do not use stream snapshot because it is obsolete when switching between videos
|
||||||
|
@ -53,7 +51,7 @@ class _VideoControlOverlayState extends State<VideoControlOverlay> with SingleTi
|
||||||
if (status == VideoStatus.error) {
|
if (status == VideoStatus.error) {
|
||||||
const action = EntryAction.openVideo;
|
const action = EntryAction.openVideo;
|
||||||
return Align(
|
return Align(
|
||||||
alignment: AlignmentDirectional.centerEnd,
|
alignment: Alignment.centerRight,
|
||||||
child: OverlayButton(
|
child: OverlayButton(
|
||||||
scale: scale,
|
scale: scale,
|
||||||
child: IconButton(
|
child: IconButton(
|
||||||
|
@ -73,6 +71,7 @@ class _VideoControlOverlayState extends State<VideoControlOverlay> with SingleTi
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Row(
|
Row(
|
||||||
|
textDirection: ViewerBottomOverlay.actionsDirection,
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: VideoProgressBar(
|
child: VideoProgressBar(
|
||||||
|
@ -91,7 +90,6 @@ class _VideoControlOverlayState extends State<VideoControlOverlay> with SingleTi
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import 'package:aves/widgets/common/identity/buttons/captioned_button.dart';
|
||||||
import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
|
import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
|
||||||
import 'package:aves/widgets/viewer/action/entry_action_delegate.dart';
|
import 'package:aves/widgets/viewer/action/entry_action_delegate.dart';
|
||||||
import 'package:aves/widgets/viewer/controls/notifications.dart';
|
import 'package:aves/widgets/viewer/controls/notifications.dart';
|
||||||
|
import 'package:aves/widgets/viewer/overlay/bottom.dart';
|
||||||
import 'package:aves/widgets/viewer/video/conductor.dart';
|
import 'package:aves/widgets/viewer/video/conductor.dart';
|
||||||
import 'package:aves_model/aves_model.dart';
|
import 'package:aves_model/aves_model.dart';
|
||||||
import 'package:aves_utils/aves_utils.dart';
|
import 'package:aves_utils/aves_utils.dart';
|
||||||
|
@ -130,6 +131,7 @@ class _TvButtonRowContent extends StatelessWidget {
|
||||||
return Row(
|
return Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
textDirection: ViewerBottomOverlay.actionsDirection,
|
||||||
children: [
|
children: [
|
||||||
...EntryActions.topLevel,
|
...EntryActions.topLevel,
|
||||||
...EntryActions.export,
|
...EntryActions.export,
|
||||||
|
@ -257,6 +259,7 @@ class _ViewerButtonRowContentState extends State<ViewerButtonRowContent> {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(left: padding / 2, right: padding / 2, bottom: padding),
|
padding: const EdgeInsets.only(left: padding / 2, right: padding / 2, bottom: padding),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
textDirection: ViewerBottomOverlay.actionsDirection,
|
||||||
children: [
|
children: [
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
...widget.quickActions.map((action) => _buildOverlayButton(context, action, videoController)),
|
...widget.quickActions.map((action) => _buildOverlayButton(context, action, videoController)),
|
||||||
|
|
|
@ -10,6 +10,7 @@ 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';
|
||||||
import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
|
import 'package:aves/widgets/common/identity/buttons/overlay_button.dart';
|
||||||
import 'package:aves/widgets/dialogs/wallpaper_settings_dialog.dart';
|
import 'package:aves/widgets/dialogs/wallpaper_settings_dialog.dart';
|
||||||
|
import 'package:aves/widgets/viewer/overlay/bottom.dart';
|
||||||
import 'package:aves/widgets/viewer/overlay/viewer_buttons.dart';
|
import 'package:aves/widgets/viewer/overlay/viewer_buttons.dart';
|
||||||
import 'package:aves/widgets/viewer/video/conductor.dart';
|
import 'package:aves/widgets/viewer/video/conductor.dart';
|
||||||
import 'package:aves/widgets/viewer/view/conductor.dart';
|
import 'package:aves/widgets/viewer/view/conductor.dart';
|
||||||
|
@ -38,6 +39,7 @@ class WallpaperButtons extends StatelessWidget with FeedbackMixin {
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.only(left: padding / 2, right: padding / 2, bottom: padding),
|
padding: const EdgeInsets.only(left: padding / 2, right: padding / 2, bottom: padding),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
textDirection: ViewerBottomOverlay.actionsDirection,
|
||||||
children: [
|
children: [
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
Padding(
|
Padding(
|
||||||
|
|
Loading…
Reference in a new issue