tv layout on non-tv devices
This commit is contained in:
parent
4c6a4e3568
commit
b343e32db0
42 changed files with 379 additions and 237 deletions
|
@ -1,16 +1,21 @@
|
||||||
package deckers.thibault.aves.channel.calls
|
package deckers.thibault.aves.channel.calls
|
||||||
|
|
||||||
|
import android.content.ComponentName
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.media.session.PlaybackState
|
import android.media.session.PlaybackState
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.support.v4.media.MediaMetadataCompat
|
import android.support.v4.media.MediaMetadataCompat
|
||||||
import android.support.v4.media.session.MediaSessionCompat
|
import android.support.v4.media.session.MediaSessionCompat
|
||||||
import android.support.v4.media.session.PlaybackStateCompat
|
import android.support.v4.media.session.PlaybackStateCompat
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.KeyEvent
|
||||||
|
import androidx.media.session.MediaButtonReceiver
|
||||||
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
|
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
|
||||||
import deckers.thibault.aves.channel.calls.Coresult.Companion.safeSuspend
|
import deckers.thibault.aves.channel.calls.Coresult.Companion.safeSuspend
|
||||||
import deckers.thibault.aves.utils.FlutterUtils
|
import deckers.thibault.aves.utils.FlutterUtils
|
||||||
import deckers.thibault.aves.utils.LogUtils
|
import deckers.thibault.aves.utils.LogUtils
|
||||||
|
import deckers.thibault.aves.utils.getParcelableExtraCompat
|
||||||
import io.flutter.plugin.common.MethodCall
|
import io.flutter.plugin.common.MethodCall
|
||||||
import io.flutter.plugin.common.MethodChannel
|
import io.flutter.plugin.common.MethodChannel
|
||||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
||||||
|
@ -74,7 +79,9 @@ class MediaSessionHandler(private val context: Context) : MethodCallHandler {
|
||||||
|
|
||||||
var session = sessions[uri]
|
var session = sessions[uri]
|
||||||
if (session == null) {
|
if (session == null) {
|
||||||
session = MediaSessionCompat(context, "aves-$uri")
|
val mbrIntent = MediaButtonReceiver.buildMediaButtonPendingIntent(context, PlaybackStateCompat.ACTION_PLAY_PAUSE)
|
||||||
|
val mbrName = ComponentName(context, MediaButtonReceiver::class.java)
|
||||||
|
session = MediaSessionCompat(context, "aves-$uri", mbrName, mbrIntent)
|
||||||
sessions[uri] = session
|
sessions[uri] = session
|
||||||
|
|
||||||
val metadata = MediaMetadataCompat.Builder()
|
val metadata = MediaMetadataCompat.Builder()
|
||||||
|
@ -86,6 +93,12 @@ class MediaSessionHandler(private val context: Context) : MethodCallHandler {
|
||||||
session.setMetadata(metadata)
|
session.setMetadata(metadata)
|
||||||
|
|
||||||
val callback: MediaSessionCompat.Callback = object : MediaSessionCompat.Callback() {
|
val callback: MediaSessionCompat.Callback = object : MediaSessionCompat.Callback() {
|
||||||
|
override fun onMediaButtonEvent(mediaButtonEvent: Intent): Boolean {
|
||||||
|
val keyEvent = mediaButtonEvent.getParcelableExtraCompat<KeyEvent?>(Intent.EXTRA_KEY_EVENT) ?: return false
|
||||||
|
Log.d(LOG_TAG, "TLAD onMediaButtonEvent keyEvent=$keyEvent")
|
||||||
|
return super.onMediaButtonEvent(mediaButtonEvent)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onPlay() {
|
override fun onPlay() {
|
||||||
super.onPlay()
|
super.onPlay()
|
||||||
Log.d(LOG_TAG, "TLAD onPlay uri=$uri")
|
Log.d(LOG_TAG, "TLAD onPlay uri=$uri")
|
||||||
|
|
|
@ -656,6 +656,7 @@
|
||||||
"settingsSystemDefault": "System default",
|
"settingsSystemDefault": "System default",
|
||||||
"settingsDefault": "Default",
|
"settingsDefault": "Default",
|
||||||
"settingsDisabled": "Disabled",
|
"settingsDisabled": "Disabled",
|
||||||
|
"settingsModificationWarningDialogMessage": "Other settings will be modified.",
|
||||||
|
|
||||||
"settingsSearchFieldLabel": "Search settings",
|
"settingsSearchFieldLabel": "Search settings",
|
||||||
"settingsSearchEmpty": "No matching setting",
|
"settingsSearchEmpty": "No matching setting",
|
||||||
|
@ -816,6 +817,7 @@
|
||||||
"settingsThemeEnableDynamicColor": "Dynamic color",
|
"settingsThemeEnableDynamicColor": "Dynamic color",
|
||||||
"settingsDisplayRefreshRateModeTile": "Display refresh rate",
|
"settingsDisplayRefreshRateModeTile": "Display refresh rate",
|
||||||
"settingsDisplayRefreshRateModeDialogTitle": "Refresh Rate",
|
"settingsDisplayRefreshRateModeDialogTitle": "Refresh Rate",
|
||||||
|
"settingsDisplayUseTvInterface": "Android TV interface",
|
||||||
|
|
||||||
"settingsLanguageSectionTitle": "Language & Formats",
|
"settingsLanguageSectionTitle": "Language & Formats",
|
||||||
"settingsLanguageTile": "Language",
|
"settingsLanguageTile": "Language",
|
||||||
|
|
|
@ -24,6 +24,7 @@ class SettingsDefaults {
|
||||||
static const themeColorMode = AvesThemeColorMode.polychrome;
|
static const themeColorMode = AvesThemeColorMode.polychrome;
|
||||||
static const enableDynamicColor = false;
|
static const enableDynamicColor = false;
|
||||||
static const enableBlurEffect = true; // `enableBlurEffect` has a contextual default value
|
static const enableBlurEffect = true; // `enableBlurEffect` has a contextual default value
|
||||||
|
static const forceTvLayout = false;
|
||||||
|
|
||||||
// navigation
|
// navigation
|
||||||
static const mustBackTwiceToExit = true;
|
static const mustBackTwiceToExit = true;
|
||||||
|
|
|
@ -70,6 +70,7 @@ class Settings extends ChangeNotifier {
|
||||||
static const themeColorModeKey = 'theme_color_mode';
|
static const themeColorModeKey = 'theme_color_mode';
|
||||||
static const enableDynamicColorKey = 'dynamic_color';
|
static const enableDynamicColorKey = 'dynamic_color';
|
||||||
static const enableBlurEffectKey = 'enable_overlay_blur_effect';
|
static const enableBlurEffectKey = 'enable_overlay_blur_effect';
|
||||||
|
static const forceTvLayoutKey = 'force_tv_layout';
|
||||||
|
|
||||||
// navigation
|
// navigation
|
||||||
static const mustBackTwiceToExitKey = 'must_back_twice_to_exit';
|
static const mustBackTwiceToExitKey = 'must_back_twice_to_exit';
|
||||||
|
@ -240,7 +241,11 @@ class Settings extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device.isTelevision) {
|
applyTvSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyTvSettings() {
|
||||||
|
if (settings.useTvLayout) {
|
||||||
themeBrightness = AvesThemeBrightness.dark;
|
themeBrightness = AvesThemeBrightness.dark;
|
||||||
mustBackTwiceToExit = false;
|
mustBackTwiceToExit = false;
|
||||||
// address `TV-BU` / `TV-BY` requirements from https://developer.android.com/docs/quality-guidelines/tv-app-quality
|
// address `TV-BU` / `TV-BY` requirements from https://developer.android.com/docs/quality-guidelines/tv-app-quality
|
||||||
|
@ -392,6 +397,12 @@ class Settings extends ChangeNotifier {
|
||||||
|
|
||||||
set enableBlurEffect(bool newValue) => setAndNotify(enableBlurEffectKey, newValue);
|
set enableBlurEffect(bool newValue) => setAndNotify(enableBlurEffectKey, newValue);
|
||||||
|
|
||||||
|
bool get forceTvLayout => getBool(forceTvLayoutKey) ?? SettingsDefaults.forceTvLayout;
|
||||||
|
|
||||||
|
set forceTvLayout(bool newValue) => setAndNotify(forceTvLayoutKey, newValue);
|
||||||
|
|
||||||
|
bool get useTvLayout => device.isTelevision || forceTvLayout;
|
||||||
|
|
||||||
// navigation
|
// navigation
|
||||||
|
|
||||||
bool get mustBackTwiceToExit => getBool(mustBackTwiceToExitKey) ?? SettingsDefaults.mustBackTwiceToExit;
|
bool get mustBackTwiceToExit => getBool(mustBackTwiceToExitKey) ?? SettingsDefaults.mustBackTwiceToExit;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:aves/model/device.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/widgets/about/app_ref.dart';
|
import 'package:aves/widgets/about/app_ref.dart';
|
||||||
import 'package:aves/widgets/about/bug_report.dart';
|
import 'package:aves/widgets/about/bug_report.dart';
|
||||||
import 'package:aves/widgets/about/credits.dart';
|
import 'package:aves/widgets/about/credits.dart';
|
||||||
|
@ -28,7 +28,7 @@ class AboutPage extends StatelessWidget {
|
||||||
delegate: SliverChildListDelegate(
|
delegate: SliverChildListDelegate(
|
||||||
[
|
[
|
||||||
const AppReference(),
|
const AppReference(),
|
||||||
if (!device.isTelevision) ...[
|
if (!settings.useTvLayout) ...[
|
||||||
const Divider(),
|
const Divider(),
|
||||||
const BugReport(),
|
const BugReport(),
|
||||||
],
|
],
|
||||||
|
@ -46,7 +46,8 @@ class AboutPage extends StatelessWidget {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
if (device.isTelevision) {
|
if (settings.useTvLayout) {
|
||||||
|
final isRtl = context.isRtl;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: AvesPopScope(
|
body: AvesPopScope(
|
||||||
handlers: const [TvNavigationPopHandler.pop],
|
handlers: const [TvNavigationPopHandler.pop],
|
||||||
|
@ -55,7 +56,13 @@ class AboutPage extends StatelessWidget {
|
||||||
TvRail(
|
TvRail(
|
||||||
controller: context.read<TvRailController>(),
|
controller: context.read<TvRailController>(),
|
||||||
),
|
),
|
||||||
Expanded(child: body),
|
Expanded(
|
||||||
|
child: SafeArea(
|
||||||
|
left: isRtl,
|
||||||
|
right: !isRtl,
|
||||||
|
child: body,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -416,17 +416,20 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
final stopwatch = Stopwatch()..start();
|
final stopwatch = Stopwatch()..start();
|
||||||
|
|
||||||
await device.init();
|
await device.init();
|
||||||
if (device.isTelevision) {
|
await mobileServices.init();
|
||||||
|
await settings.init(monitorPlatformSettings: true);
|
||||||
|
settings.isRotationLocked = await windowService.isRotationLocked();
|
||||||
|
settings.areAnimationsRemoved = await AccessibilityService.areAnimationsRemoved();
|
||||||
|
if (settings.useTvLayout) {
|
||||||
_pageTransitionsBuilderNotifier.value = const TvPageTransitionsBuilder();
|
_pageTransitionsBuilderNotifier.value = const TvPageTransitionsBuilder();
|
||||||
_tvMediaQueryModifierNotifier.value = (mq) => mq.copyWith(
|
_tvMediaQueryModifierNotifier.value = (mq) => mq.copyWith(
|
||||||
textScaleFactor: 1.1,
|
textScaleFactor: 1.1,
|
||||||
navigationMode: NavigationMode.directional,
|
navigationMode: NavigationMode.directional,
|
||||||
);
|
);
|
||||||
|
if (settings.forceTvLayout) {
|
||||||
|
await windowService.requestOrientation(Orientation.landscape);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
await mobileServices.init();
|
|
||||||
await settings.init(monitorPlatformSettings: true);
|
|
||||||
settings.isRotationLocked = await windowService.isRotationLocked();
|
|
||||||
settings.areAnimationsRemoved = await AccessibilityService.areAnimationsRemoved();
|
|
||||||
_monitorSettings();
|
_monitorSettings();
|
||||||
|
|
||||||
FijkLog.setLevel(FijkLogLevel.Warn);
|
FijkLog.setLevel(FijkLogLevel.Warn);
|
||||||
|
@ -448,15 +451,28 @@ class _AvesAppState extends State<AvesApp> with WidgetsBindingObserver {
|
||||||
void applyKeepScreenOn() => settings.keepScreenOn.apply();
|
void applyKeepScreenOn() => settings.keepScreenOn.apply();
|
||||||
|
|
||||||
void applyIsRotationLocked() {
|
void applyIsRotationLocked() {
|
||||||
if (!settings.isRotationLocked) {
|
if (!settings.isRotationLocked && !settings.useTvLayout) {
|
||||||
windowService.requestOrientation();
|
windowService.requestOrientation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void applyForceTvLayout() {
|
||||||
|
settings.applyTvSettings();
|
||||||
|
windowService.requestOrientation(settings.forceTvLayout ? Orientation.landscape : null);
|
||||||
|
AvesApp.navigatorKey.currentState!.pushAndRemoveUntil(
|
||||||
|
MaterialPageRoute(
|
||||||
|
settings: const RouteSettings(name: HomePage.routeName),
|
||||||
|
builder: (_) => _getFirstPage(),
|
||||||
|
),
|
||||||
|
(route) => false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
settings.updateStream.where((event) => event.key == Settings.isInstalledAppAccessAllowedKey).listen((_) => applyIsInstalledAppAccessAllowed());
|
settings.updateStream.where((event) => event.key == Settings.isInstalledAppAccessAllowedKey).listen((_) => applyIsInstalledAppAccessAllowed());
|
||||||
settings.updateStream.where((event) => event.key == Settings.displayRefreshRateModeKey).listen((_) => applyDisplayRefreshRateMode());
|
settings.updateStream.where((event) => event.key == Settings.displayRefreshRateModeKey).listen((_) => applyDisplayRefreshRateMode());
|
||||||
settings.updateStream.where((event) => event.key == Settings.keepScreenOnKey).listen((_) => applyKeepScreenOn());
|
settings.updateStream.where((event) => event.key == Settings.keepScreenOnKey).listen((_) => applyKeepScreenOn());
|
||||||
settings.updateStream.where((event) => event.key == Settings.platformAccelerometerRotationKey).listen((_) => applyIsRotationLocked());
|
settings.updateStream.where((event) => event.key == Settings.platformAccelerometerRotationKey).listen((_) => applyIsRotationLocked());
|
||||||
|
settings.updateStream.where((event) => event.key == Settings.forceTvLayoutKey).listen((_) => applyForceTvLayout());
|
||||||
|
|
||||||
applyDisplayRefreshRateMode();
|
applyDisplayRefreshRateMode();
|
||||||
applyKeepScreenOn();
|
applyKeepScreenOn();
|
||||||
|
|
|
@ -151,70 +151,75 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
final selection = context.watch<Selection<AvesEntry>>();
|
final selection = context.watch<Selection<AvesEntry>>();
|
||||||
final isSelecting = selection.isSelecting;
|
final isSelecting = selection.isSelecting;
|
||||||
_isSelectingNotifier.value = isSelecting;
|
_isSelectingNotifier.value = isSelecting;
|
||||||
return AnimatedBuilder(
|
return NotificationListener<ScrollNotification>(
|
||||||
animation: collection.filterChangeNotifier,
|
// cancel notification bubbling so that the draggable scroll bar
|
||||||
builder: (context, child) {
|
// does not misinterpret filter bar scrolling for collection scrolling
|
||||||
final removableFilters = appMode != AppMode.pickMediaInternal;
|
onNotification: (notification) => true,
|
||||||
return Selector<Query, bool>(
|
child: AnimatedBuilder(
|
||||||
selector: (context, query) => query.enabled,
|
animation: collection.filterChangeNotifier,
|
||||||
builder: (context, queryEnabled, child) {
|
builder: (context, child) {
|
||||||
return Selector<Settings, List<EntrySetAction>>(
|
final removableFilters = appMode != AppMode.pickMediaInternal;
|
||||||
selector: (context, s) => s.collectionBrowsingQuickActions,
|
return Selector<Query, bool>(
|
||||||
builder: (context, _, child) {
|
selector: (context, query) => query.enabled,
|
||||||
final isTelevision = device.isTelevision;
|
builder: (context, queryEnabled, child) {
|
||||||
final actions = _buildActions(context, selection);
|
return Selector<Settings, List<EntrySetAction>>(
|
||||||
final onFilterTap = removableFilters ? collection.removeFilter : null;
|
selector: (context, s) => s.collectionBrowsingQuickActions,
|
||||||
return AvesAppBar(
|
builder: (context, _, child) {
|
||||||
contentHeight: appBarContentHeight,
|
final useTvLayout = settings.useTvLayout;
|
||||||
leading: _buildAppBarLeading(
|
final actions = _buildActions(context, selection);
|
||||||
hasDrawer: appMode.canNavigate,
|
final onFilterTap = removableFilters ? collection.removeFilter : null;
|
||||||
isSelecting: isSelecting,
|
return AvesAppBar(
|
||||||
),
|
contentHeight: appBarContentHeight,
|
||||||
title: _buildAppBarTitle(isSelecting),
|
leading: _buildAppBarLeading(
|
||||||
actions: isTelevision ? [] : actions,
|
hasDrawer: appMode.canNavigate,
|
||||||
bottom: Column(
|
isSelecting: isSelecting,
|
||||||
children: [
|
),
|
||||||
if (isTelevision)
|
title: _buildAppBarTitle(isSelecting),
|
||||||
SizedBox(
|
actions: useTvLayout ? [] : actions,
|
||||||
height: CaptionedButton.getTelevisionButtonHeight(context),
|
bottom: Column(
|
||||||
child: ListView(
|
children: [
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
if (useTvLayout)
|
||||||
scrollDirection: Axis.horizontal,
|
SizedBox(
|
||||||
children: actions,
|
height: CaptionedButton.getTelevisionButtonHeight(context),
|
||||||
|
child: ListView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
children: actions,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
if (showFilterBar)
|
||||||
if (showFilterBar)
|
NotificationListener<ReverseFilterNotification>(
|
||||||
NotificationListener<ReverseFilterNotification>(
|
onNotification: (notification) {
|
||||||
onNotification: (notification) {
|
collection.addFilter(notification.reversedFilter);
|
||||||
collection.addFilter(notification.reversedFilter);
|
return true;
|
||||||
return true;
|
},
|
||||||
},
|
child: FilterBar(
|
||||||
child: FilterBar(
|
filters: visibleFilters,
|
||||||
filters: visibleFilters,
|
onTap: onFilterTap,
|
||||||
onTap: onFilterTap,
|
onRemove: onFilterTap,
|
||||||
onRemove: onFilterTap,
|
),
|
||||||
),
|
),
|
||||||
),
|
if (queryEnabled)
|
||||||
if (queryEnabled)
|
EntryQueryBar(
|
||||||
EntryQueryBar(
|
queryNotifier: context.select<Query, ValueNotifier<String>>((query) => query.queryNotifier),
|
||||||
queryNotifier: context.select<Query, ValueNotifier<String>>((query) => query.queryNotifier),
|
focusNode: _queryBarFocusNode,
|
||||||
focusNode: _queryBarFocusNode,
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
transitionKey: isSelecting,
|
||||||
transitionKey: isSelecting,
|
);
|
||||||
);
|
},
|
||||||
},
|
);
|
||||||
);
|
},
|
||||||
},
|
);
|
||||||
);
|
},
|
||||||
},
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
double get appBarContentHeight {
|
double get appBarContentHeight {
|
||||||
double height = kToolbarHeight;
|
double height = kToolbarHeight;
|
||||||
if (device.isTelevision) {
|
if (settings.useTvLayout) {
|
||||||
height += CaptionedButton.getTelevisionButtonHeight(context);
|
height += CaptionedButton.getTelevisionButtonHeight(context);
|
||||||
}
|
}
|
||||||
if (showFilterBar) {
|
if (showFilterBar) {
|
||||||
|
@ -227,7 +232,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget? _buildAppBarLeading({required bool hasDrawer, required bool isSelecting}) {
|
Widget? _buildAppBarLeading({required bool hasDrawer, required bool isSelecting}) {
|
||||||
if (device.isTelevision) return null;
|
if (settings.useTvLayout) return null;
|
||||||
|
|
||||||
if (!hasDrawer) {
|
if (!hasDrawer) {
|
||||||
return const CloseButton();
|
return const CloseButton();
|
||||||
|
@ -309,7 +314,7 @@ class _CollectionAppBarState extends State<CollectionAppBar> with SingleTickerPr
|
||||||
selectedItemCount: selectedItemCount,
|
selectedItemCount: selectedItemCount,
|
||||||
);
|
);
|
||||||
|
|
||||||
return device.isTelevision
|
return settings.useTvLayout
|
||||||
? _buildTelevisionActions(
|
? _buildTelevisionActions(
|
||||||
context: context,
|
context: context,
|
||||||
appMode: appMode,
|
appMode: appMode,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/app_mode.dart';
|
import 'package:aves/app_mode.dart';
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/favourites.dart';
|
import 'package:aves/model/favourites.dart';
|
||||||
import 'package:aves/model/filters/favourite.dart';
|
import 'package:aves/model/filters/favourite.dart';
|
||||||
|
@ -57,7 +56,7 @@ class CollectionGrid extends StatefulWidget {
|
||||||
static const double fixedExtentLayoutSpacing = 2;
|
static const double fixedExtentLayoutSpacing = 2;
|
||||||
static const double mosaicLayoutSpacing = 4;
|
static const double mosaicLayoutSpacing = 4;
|
||||||
|
|
||||||
static int get columnCountDefault => device.isTelevision ? 6 : 4;
|
static int get columnCountDefault => settings.useTvLayout ? 6 : 4;
|
||||||
|
|
||||||
const CollectionGrid({
|
const CollectionGrid({
|
||||||
super.key,
|
super.key,
|
||||||
|
@ -176,7 +175,7 @@ class _CollectionGridContentState extends State<_CollectionGridContent> {
|
||||||
tileLayout: tileLayout,
|
tileLayout: tileLayout,
|
||||||
isScrollingNotifier: _isScrollingNotifier,
|
isScrollingNotifier: _isScrollingNotifier,
|
||||||
);
|
);
|
||||||
if (!device.isTelevision) return tile;
|
if (!settings.useTvLayout) return tile;
|
||||||
|
|
||||||
return Focus(
|
return Focus(
|
||||||
onFocusChange: (focused) {
|
onFocusChange: (focused) {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/app_mode.dart';
|
import 'package:aves/app_mode.dart';
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
import 'package:aves/model/filters/query.dart';
|
import 'package:aves/model/filters/query.dart';
|
||||||
|
@ -122,7 +121,7 @@ class _CollectionPageState extends State<CollectionPage> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget page;
|
Widget page;
|
||||||
if (device.isTelevision) {
|
if (settings.useTvLayout) {
|
||||||
page = Scaffold(
|
page = Scaffold(
|
||||||
body: Row(
|
body: Row(
|
||||||
children: [
|
children: [
|
||||||
|
|
|
@ -69,7 +69,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
||||||
return isSelecting && selectedItemCount == itemCount;
|
return isSelecting && selectedItemCount == itemCount;
|
||||||
// browsing
|
// browsing
|
||||||
case EntrySetAction.searchCollection:
|
case EntrySetAction.searchCollection:
|
||||||
return !device.isTelevision && appMode.canNavigate && !isSelecting;
|
return !settings.useTvLayout && appMode.canNavigate && !isSelecting;
|
||||||
case EntrySetAction.toggleTitleSearch:
|
case EntrySetAction.toggleTitleSearch:
|
||||||
return !isSelecting;
|
return !isSelecting;
|
||||||
case EntrySetAction.addShortcut:
|
case EntrySetAction.addShortcut:
|
||||||
|
@ -82,7 +82,7 @@ class EntrySetActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAware
|
||||||
case EntrySetAction.stats:
|
case EntrySetAction.stats:
|
||||||
return isMain;
|
return isMain;
|
||||||
case EntrySetAction.rescan:
|
case EntrySetAction.rescan:
|
||||||
return !device.isTelevision && isMain && !isTrash;
|
return !settings.useTvLayout && isMain && !isTrash;
|
||||||
// selecting
|
// selecting
|
||||||
case EntrySetAction.share:
|
case EntrySetAction.share:
|
||||||
case EntrySetAction.toggleFavourite:
|
case EntrySetAction.toggleFavourite:
|
||||||
|
|
|
@ -82,20 +82,15 @@ class _FilterBarState extends State<FilterBar> {
|
||||||
// chip border clipping when the floating app bar is fading
|
// chip border clipping when the floating app bar is fading
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
height: FilterBar.preferredHeight,
|
height: FilterBar.preferredHeight,
|
||||||
child: NotificationListener<ScrollNotification>(
|
child: AnimatedList(
|
||||||
// cancel notification bubbling so that the draggable scroll bar
|
key: _animatedListKey,
|
||||||
// does not misinterpret filter bar scrolling for collection scrolling
|
initialItemCount: filters.length,
|
||||||
onNotification: (notification) => true,
|
scrollDirection: Axis.horizontal,
|
||||||
child: AnimatedList(
|
padding: FilterBar.rowPadding,
|
||||||
key: _animatedListKey,
|
itemBuilder: (context, index, animation) {
|
||||||
initialItemCount: filters.length,
|
if (index >= filters.length) return const SizedBox();
|
||||||
scrollDirection: Axis.horizontal,
|
return _buildChip(filters.toList()[index]);
|
||||||
padding: FilterBar.rowPadding,
|
},
|
||||||
itemBuilder: (context, index, animation) {
|
|
||||||
if (index >= filters.length) return const SizedBox();
|
|
||||||
return _buildChip(filters.toList()[index]);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:aves/model/device.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/utils/constants.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/fx/borders.dart';
|
import 'package:aves/widgets/common/fx/borders.dart';
|
||||||
|
@ -72,13 +72,13 @@ class _ColorPickerDialogState extends State<ColorPickerDialog> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final isTelevision = device.isTelevision;
|
final useTvLayout = settings.useTvLayout;
|
||||||
return AvesDialog(
|
return AvesDialog(
|
||||||
scrollableContent: [
|
scrollableContent: [
|
||||||
ColorPicker(
|
ColorPicker(
|
||||||
color: color,
|
color: color,
|
||||||
onColorChanged: (v) => color = v,
|
onColorChanged: (v) => color = v,
|
||||||
pickersEnabled: isTelevision
|
pickersEnabled: useTvLayout
|
||||||
? const {
|
? const {
|
||||||
ColorPickerType.primary: true,
|
ColorPickerType.primary: true,
|
||||||
ColorPickerType.accent: false,
|
ColorPickerType.accent: false,
|
||||||
|
@ -90,7 +90,7 @@ class _ColorPickerDialogState extends State<ColorPickerDialog> {
|
||||||
},
|
},
|
||||||
hasBorder: true,
|
hasBorder: true,
|
||||||
borderRadius: 20,
|
borderRadius: 20,
|
||||||
subheading: isTelevision ? const SizedBox(height: 16) : null,
|
subheading: useTvLayout ? const SizedBox(height: 16) : null,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:aves/model/device.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/widgets/aves_app.dart';
|
import 'package:aves/widgets/aves_app.dart';
|
||||||
import 'package:aves/widgets/common/extensions/media_query.dart';
|
import 'package:aves/widgets/common/extensions/media_query.dart';
|
||||||
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
import 'package:aves/widgets/common/providers/media_query_data_provider.dart';
|
||||||
|
@ -127,7 +127,7 @@ class TvTileGridBottomPaddingSliver extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SliverToBoxAdapter(
|
return SliverToBoxAdapter(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: device.isTelevision ? context.select<TileExtentController, double>((controller) => controller.spacing) : 0,
|
height: settings.useTvLayout ? context.select<TileExtentController, double>((controller) => controller.spacing) : 0,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/settings/enums/enums.dart';
|
import 'package:aves/model/settings/enums/enums.dart';
|
||||||
import 'package:aves/model/settings/enums/home_page.dart';
|
import 'package:aves/model/settings/enums/home_page.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
|
@ -13,7 +12,7 @@ import 'package:provider/provider.dart';
|
||||||
// address `TV-DB` requirement from https://developer.android.com/docs/quality-guidelines/tv-app-quality
|
// address `TV-DB` requirement from https://developer.android.com/docs/quality-guidelines/tv-app-quality
|
||||||
class TvNavigationPopHandler {
|
class TvNavigationPopHandler {
|
||||||
static bool pop(BuildContext context) {
|
static bool pop(BuildContext context) {
|
||||||
if (!device.isTelevision || _isHome(context)) {
|
if (!settings.useTvLayout || _isHome(context)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/selection.dart';
|
import 'package:aves/model/selection.dart';
|
||||||
|
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';
|
||||||
|
@ -33,7 +33,7 @@ class SectionHeader<T> extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Widget child = _buildContent(context);
|
Widget child = _buildContent(context);
|
||||||
if (device.isTelevision) {
|
if (settings.useTvLayout) {
|
||||||
final colors = Theme.of(context).colorScheme;
|
final colors = Theme.of(context).colorScheme;
|
||||||
child = Material(
|
child = Material(
|
||||||
type: MaterialType.transparency,
|
type: MaterialType.transparency,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
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/colors.dart';
|
||||||
import 'package:aves/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
|
@ -34,7 +33,7 @@ class AvesAppBar extends StatelessWidget {
|
||||||
selector: (context, mq) => mq.padding.top,
|
selector: (context, mq) => mq.padding.top,
|
||||||
builder: (context, mqPaddingTop, child) {
|
builder: (context, mqPaddingTop, child) {
|
||||||
return SliverPersistentHeader(
|
return SliverPersistentHeader(
|
||||||
floating: !device.isTelevision,
|
floating: !settings.useTvLayout,
|
||||||
pinned: false,
|
pinned: false,
|
||||||
delegate: _SliverAppBarDelegate(
|
delegate: _SliverAppBarDelegate(
|
||||||
height: mqPaddingTop + appBarHeightForContentHeight(contentHeight),
|
height: mqPaddingTop + appBarHeightForContentHeight(contentHeight),
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'package:aves/model/device.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/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
|
@ -36,7 +35,7 @@ class MapButtonPanel extends StatelessWidget {
|
||||||
Widget? navigationButton;
|
Widget? navigationButton;
|
||||||
switch (context.select<MapThemeData, MapNavigationButton>((v) => v.navigationButton)) {
|
switch (context.select<MapThemeData, MapNavigationButton>((v) => v.navigationButton)) {
|
||||||
case MapNavigationButton.back:
|
case MapNavigationButton.back:
|
||||||
if (!device.isTelevision) {
|
if (!settings.useTvLayout) {
|
||||||
navigationButton = MapOverlayButton(
|
navigationButton = MapOverlayButton(
|
||||||
icon: const BackButtonIcon(),
|
icon: const BackButtonIcon(),
|
||||||
onPressed: () => Navigator.pop(context),
|
onPressed: () => Navigator.pop(context),
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:aves/model/device.dart';
|
import 'package:aves/model/settings/settings.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:aves/widgets/common/search/route.dart';
|
import 'package:aves/widgets/common/search/route.dart';
|
||||||
|
@ -20,7 +20,7 @@ abstract class AvesSearchDelegate extends SearchDelegate {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? buildLeading(BuildContext context) {
|
Widget? buildLeading(BuildContext context) {
|
||||||
if (device.isTelevision) {
|
if (settings.useTvLayout) {
|
||||||
return const Icon(AIcons.search);
|
return const Icon(AIcons.search);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import 'package:aves/app_mode.dart';
|
import 'package:aves/app_mode.dart';
|
||||||
import 'package:aves/model/actions/chip_set_actions.dart';
|
import 'package:aves/model/actions/chip_set_actions.dart';
|
||||||
import 'package:aves/model/covers.dart';
|
import 'package:aves/model/covers.dart';
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/filters/album.dart';
|
import 'package:aves/model/filters/album.dart';
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
|
@ -83,7 +82,7 @@ abstract class ChipSetActionDelegate<T extends CollectionFilter> with FeedbackMi
|
||||||
return isSelecting && selectedItemCount == itemCount;
|
return isSelecting && selectedItemCount == itemCount;
|
||||||
// browsing
|
// browsing
|
||||||
case ChipSetAction.search:
|
case ChipSetAction.search:
|
||||||
return !device.isTelevision && appMode.canNavigate && !isSelecting;
|
return !settings.useTvLayout && appMode.canNavigate && !isSelecting;
|
||||||
case ChipSetAction.toggleTitleSearch:
|
case ChipSetAction.toggleTitleSearch:
|
||||||
return !isSelecting;
|
return !isSelecting;
|
||||||
case ChipSetAction.createAlbum:
|
case ChipSetAction.createAlbum:
|
||||||
|
|
|
@ -2,10 +2,10 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/app_mode.dart';
|
import 'package:aves/app_mode.dart';
|
||||||
import 'package:aves/model/actions/chip_set_actions.dart';
|
import 'package:aves/model/actions/chip_set_actions.dart';
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
import 'package:aves/model/query.dart';
|
import 'package:aves/model/query.dart';
|
||||||
import 'package:aves/model/selection.dart';
|
import 'package:aves/model/selection.dart';
|
||||||
|
import 'package:aves/model/settings/settings.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/widgets/common/action_controls/togglers/title_search.dart';
|
import 'package:aves/widgets/common/action_controls/togglers/title_search.dart';
|
||||||
|
@ -125,47 +125,52 @@ class _FilterGridAppBarState<T extends CollectionFilter, CSAD extends ChipSetAct
|
||||||
final selection = context.watch<Selection<FilterGridItem<T>>>();
|
final selection = context.watch<Selection<FilterGridItem<T>>>();
|
||||||
final isSelecting = selection.isSelecting;
|
final isSelecting = selection.isSelecting;
|
||||||
_isSelectingNotifier.value = isSelecting;
|
_isSelectingNotifier.value = isSelecting;
|
||||||
return Selector<Query, bool>(
|
return NotificationListener<ScrollNotification>(
|
||||||
selector: (context, query) => query.enabled,
|
// cancel notification bubbling so that the draggable scroll bar
|
||||||
builder: (context, queryEnabled, child) {
|
// does not misinterpret filter bar scrolling for collection scrolling
|
||||||
ActionsBuilder<T, CSAD> actionsBuilder = widget.actionsBuilder ?? _buildActions;
|
onNotification: (notification) => true,
|
||||||
final isTelevision = device.isTelevision;
|
child: Selector<Query, bool>(
|
||||||
final actions = actionsBuilder(context, appMode, selection, widget.actionDelegate);
|
selector: (context, query) => query.enabled,
|
||||||
return AvesAppBar(
|
builder: (context, queryEnabled, child) {
|
||||||
contentHeight: appBarContentHeight,
|
ActionsBuilder<T, CSAD> actionsBuilder = widget.actionsBuilder ?? _buildActions;
|
||||||
leading: _buildAppBarLeading(
|
final useTvLayout = settings.useTvLayout;
|
||||||
hasDrawer: appMode.canNavigate,
|
final actions = actionsBuilder(context, appMode, selection, widget.actionDelegate);
|
||||||
isSelecting: isSelecting,
|
return AvesAppBar(
|
||||||
),
|
contentHeight: appBarContentHeight,
|
||||||
title: _buildAppBarTitle(isSelecting),
|
leading: _buildAppBarLeading(
|
||||||
actions: isTelevision ? [] : actions,
|
hasDrawer: appMode.canNavigate,
|
||||||
bottom: Column(
|
isSelecting: isSelecting,
|
||||||
children: [
|
),
|
||||||
if (isTelevision)
|
title: _buildAppBarTitle(isSelecting),
|
||||||
SizedBox(
|
actions: useTvLayout ? [] : actions,
|
||||||
height: CaptionedButton.getTelevisionButtonHeight(context),
|
bottom: Column(
|
||||||
child: ListView(
|
children: [
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
if (useTvLayout)
|
||||||
scrollDirection: Axis.horizontal,
|
SizedBox(
|
||||||
children: actions,
|
height: CaptionedButton.getTelevisionButtonHeight(context),
|
||||||
|
child: ListView(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
scrollDirection: Axis.horizontal,
|
||||||
|
children: actions,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
if (queryEnabled)
|
||||||
if (queryEnabled)
|
FilterQueryBar<T>(
|
||||||
FilterQueryBar<T>(
|
queryNotifier: context.select<Query, ValueNotifier<String>>((query) => query.queryNotifier),
|
||||||
queryNotifier: context.select<Query, ValueNotifier<String>>((query) => query.queryNotifier),
|
focusNode: _queryBarFocusNode,
|
||||||
focusNode: _queryBarFocusNode,
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
transitionKey: isSelecting,
|
||||||
transitionKey: isSelecting,
|
);
|
||||||
);
|
},
|
||||||
},
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
double get appBarContentHeight {
|
double get appBarContentHeight {
|
||||||
double height = kToolbarHeight;
|
double height = kToolbarHeight;
|
||||||
if (device.isTelevision) {
|
if (settings.useTvLayout) {
|
||||||
height += CaptionedButton.getTelevisionButtonHeight(context);
|
height += CaptionedButton.getTelevisionButtonHeight(context);
|
||||||
}
|
}
|
||||||
if (context.read<Query>().enabled) {
|
if (context.read<Query>().enabled) {
|
||||||
|
@ -175,7 +180,7 @@ class _FilterGridAppBarState<T extends CollectionFilter, CSAD extends ChipSetAct
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget? _buildAppBarLeading({required bool hasDrawer, required bool isSelecting}) {
|
Widget? _buildAppBarLeading({required bool hasDrawer, required bool isSelecting}) {
|
||||||
if (device.isTelevision) return null;
|
if (settings.useTvLayout) return null;
|
||||||
|
|
||||||
if (!hasDrawer) {
|
if (!hasDrawer) {
|
||||||
return const CloseButton();
|
return const CloseButton();
|
||||||
|
@ -251,7 +256,7 @@ class _FilterGridAppBarState<T extends CollectionFilter, CSAD extends ChipSetAct
|
||||||
selectedFilters: selectedFilters,
|
selectedFilters: selectedFilters,
|
||||||
);
|
);
|
||||||
|
|
||||||
return device.isTelevision
|
return settings.useTvLayout
|
||||||
? _buildTelevisionActions(
|
? _buildTelevisionActions(
|
||||||
context: context,
|
context: context,
|
||||||
selection: selection,
|
selection: selection,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/app_mode.dart';
|
import 'package:aves/app_mode.dart';
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
import 'package:aves/model/highlight.dart';
|
import 'package:aves/model/highlight.dart';
|
||||||
import 'package:aves/model/query.dart';
|
import 'package:aves/model/query.dart';
|
||||||
|
@ -113,7 +112,7 @@ class FilterGridPage<T extends CollectionFilter> extends StatelessWidget {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (device.isTelevision) {
|
if (settings.useTvLayout) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Row(
|
body: Row(
|
||||||
children: [
|
children: [
|
||||||
|
@ -202,7 +201,7 @@ class _FilterGridState<T extends CollectionFilter> extends State<_FilterGrid<T>>
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
_tileExtentController ??= TileExtentController(
|
_tileExtentController ??= TileExtentController(
|
||||||
settingsRouteKey: widget.settingsRouteKey ?? context.currentRouteName!,
|
settingsRouteKey: widget.settingsRouteKey ?? context.currentRouteName!,
|
||||||
columnCountDefault: device.isTelevision ? 4 : 3,
|
columnCountDefault: settings.useTvLayout ? 4 : 3,
|
||||||
extentMin: 60,
|
extentMin: 60,
|
||||||
extentMax: 300,
|
extentMax: 300,
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
|
@ -356,7 +355,7 @@ class _FilterGridContentState<T extends CollectionFilter> extends State<_FilterG
|
||||||
banner: _getFilterBanner(context, gridItem.filter),
|
banner: _getFilterBanner(context, gridItem.filter),
|
||||||
heroType: widget.heroType,
|
heroType: widget.heroType,
|
||||||
);
|
);
|
||||||
if (!device.isTelevision) return tile;
|
if (!settings.useTvLayout) return tile;
|
||||||
|
|
||||||
return Focus(
|
return Focus(
|
||||||
onFocusChange: (focused) {
|
onFocusChange: (focused) {
|
||||||
|
|
|
@ -109,25 +109,28 @@ class _TvRailState extends State<TvRail> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return Column(
|
return SafeArea(
|
||||||
children: [
|
child: Column(
|
||||||
const SizedBox(height: 8),
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
header,
|
children: [
|
||||||
const SizedBox(height: 4),
|
const SizedBox(height: 8),
|
||||||
Expanded(
|
header,
|
||||||
child: LayoutBuilder(
|
const SizedBox(height: 4),
|
||||||
builder: (context, constraints) {
|
Expanded(
|
||||||
return SingleChildScrollView(
|
child: LayoutBuilder(
|
||||||
controller: _scrollController,
|
builder: (context, constraints) {
|
||||||
child: ConstrainedBox(
|
return SingleChildScrollView(
|
||||||
constraints: BoxConstraints(minHeight: constraints.maxHeight),
|
controller: _scrollController,
|
||||||
child: IntrinsicHeight(child: rail),
|
child: ConstrainedBox(
|
||||||
),
|
constraints: BoxConstraints(minHeight: constraints.maxHeight),
|
||||||
);
|
child: IntrinsicHeight(child: rail),
|
||||||
},
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/settings/enums/accessibility_animations.dart';
|
import 'package:aves/model/settings/enums/accessibility_animations.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';
|
||||||
|
@ -29,7 +28,7 @@ class AccessibilitySection extends SettingsSection {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<List<SettingsTile>> tiles(BuildContext context) => [
|
FutureOr<List<SettingsTile>> tiles(BuildContext context) => [
|
||||||
if (!device.isTelevision) SettingsTileAccessibilityShowPinchGestureAlternatives(),
|
if (!settings.useTvLayout) SettingsTileAccessibilityShowPinchGestureAlternatives(),
|
||||||
SettingsTileAccessibilityAnimations(),
|
SettingsTileAccessibilityAnimations(),
|
||||||
SettingsTileAccessibilityTimeToTakeAction(),
|
SettingsTileAccessibilityTimeToTakeAction(),
|
||||||
];
|
];
|
||||||
|
|
|
@ -8,6 +8,7 @@ import 'package:aves/model/settings/settings.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/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/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';
|
||||||
import 'package:aves/widgets/settings/settings_definition.dart';
|
import 'package:aves/widgets/settings/settings_definition.dart';
|
||||||
|
@ -29,11 +30,12 @@ class DisplaySection extends SettingsSection {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<List<SettingsTile>> tiles(BuildContext context) => [
|
FutureOr<List<SettingsTile>> tiles(BuildContext context) => [
|
||||||
if (!device.isTelevision) SettingsTileDisplayThemeBrightness(),
|
if (!settings.useTvLayout) SettingsTileDisplayThemeBrightness(),
|
||||||
SettingsTileDisplayThemeColorMode(),
|
SettingsTileDisplayThemeColorMode(),
|
||||||
if (device.isDynamicColorAvailable) SettingsTileDisplayEnableDynamicColor(),
|
if (device.isDynamicColorAvailable) SettingsTileDisplayEnableDynamicColor(),
|
||||||
SettingsTileDisplayEnableBlurEffect(),
|
SettingsTileDisplayEnableBlurEffect(),
|
||||||
if (!device.isTelevision) SettingsTileDisplayDisplayRefreshRateMode(),
|
if (!settings.useTvLayout) SettingsTileDisplayRefreshRateMode(),
|
||||||
|
if (!device.isTelevision) SettingsTileDisplayForceTvLayout(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +90,7 @@ class SettingsTileDisplayEnableBlurEffect extends SettingsTile {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SettingsTileDisplayDisplayRefreshRateMode extends SettingsTile {
|
class SettingsTileDisplayRefreshRateMode extends SettingsTile {
|
||||||
@override
|
@override
|
||||||
String title(BuildContext context) => context.l10n.settingsDisplayRefreshRateModeTile;
|
String title(BuildContext context) => context.l10n.settingsDisplayRefreshRateModeTile;
|
||||||
|
|
||||||
|
@ -102,3 +104,41 @@ class SettingsTileDisplayDisplayRefreshRateMode extends SettingsTile {
|
||||||
dialogTitle: context.l10n.settingsDisplayRefreshRateModeDialogTitle,
|
dialogTitle: context.l10n.settingsDisplayRefreshRateModeDialogTitle,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SettingsTileDisplayForceTvLayout extends SettingsTile {
|
||||||
|
@override
|
||||||
|
String title(BuildContext context) => context.l10n.settingsDisplayUseTvInterface;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) => SettingsSwitchListTile(
|
||||||
|
selector: (context, s) => s.forceTvLayout,
|
||||||
|
onChanged: (v) async {
|
||||||
|
final confirmed = await showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
final l10n = context.l10n;
|
||||||
|
return AvesDialog(
|
||||||
|
content: Text([
|
||||||
|
l10n.settingsModificationWarningDialogMessage,
|
||||||
|
l10n.genericDangerWarningDialogMessage,
|
||||||
|
].join('\n\n')),
|
||||||
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context),
|
||||||
|
child: Text(MaterialLocalizations.of(context).cancelButtonLabel),
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context, true),
|
||||||
|
child: Text(l10n.applyButtonLabel),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (confirmed == null || !confirmed) return;
|
||||||
|
|
||||||
|
settings.forceTvLayout = v;
|
||||||
|
},
|
||||||
|
title: title(context),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/settings/enums/enums.dart';
|
import 'package:aves/model/settings/enums/enums.dart';
|
||||||
import 'package:aves/model/settings/enums/home_page.dart';
|
import 'package:aves/model/settings/enums/home_page.dart';
|
||||||
import 'package:aves/model/settings/enums/screen_on.dart';
|
import 'package:aves/model/settings/enums/screen_on.dart';
|
||||||
|
@ -32,11 +31,11 @@ class NavigationSection extends SettingsSection {
|
||||||
@override
|
@override
|
||||||
FutureOr<List<SettingsTile>> tiles(BuildContext context) => [
|
FutureOr<List<SettingsTile>> tiles(BuildContext context) => [
|
||||||
SettingsTileNavigationHomePage(),
|
SettingsTileNavigationHomePage(),
|
||||||
if (!device.isTelevision) SettingsTileNavigationKeepScreenOn(),
|
if (!settings.useTvLayout) SettingsTileNavigationKeepScreenOn(),
|
||||||
if (!device.isTelevision) SettingsTileShowBottomNavigationBar(),
|
if (!settings.useTvLayout) SettingsTileShowBottomNavigationBar(),
|
||||||
if (!device.isTelevision) SettingsTileNavigationDoubleBackExit(),
|
if (!settings.useTvLayout) SettingsTileNavigationDoubleBackExit(),
|
||||||
SettingsTileNavigationDrawer(),
|
SettingsTileNavigationDrawer(),
|
||||||
if (!device.isTelevision) SettingsTileNavigationConfirmationDialog(),
|
if (!settings.useTvLayout) SettingsTileNavigationConfirmationDialog(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,11 +34,11 @@ class PrivacySection extends SettingsSection {
|
||||||
return [
|
return [
|
||||||
SettingsTilePrivacyAllowInstalledAppAccess(),
|
SettingsTilePrivacyAllowInstalledAppAccess(),
|
||||||
if (canEnableErrorReporting) SettingsTilePrivacyAllowErrorReporting(),
|
if (canEnableErrorReporting) SettingsTilePrivacyAllowErrorReporting(),
|
||||||
if (!device.isTelevision && device.canRequestManageMedia) SettingsTilePrivacyManageMedia(),
|
if (!settings.useTvLayout && device.canRequestManageMedia) SettingsTilePrivacyManageMedia(),
|
||||||
SettingsTilePrivacySaveSearchHistory(),
|
SettingsTilePrivacySaveSearchHistory(),
|
||||||
if (!device.isTelevision) SettingsTilePrivacyEnableBin(),
|
if (!settings.useTvLayout) SettingsTilePrivacyEnableBin(),
|
||||||
SettingsTilePrivacyHiddenItems(),
|
SettingsTilePrivacyHiddenItems(),
|
||||||
if (!device.isTelevision && device.canGrantDirectoryAccess) SettingsTilePrivacyStorageAccess(),
|
if (!settings.useTvLayout && device.canGrantDirectoryAccess) SettingsTilePrivacyStorageAccess(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'dart:math';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:aves/model/actions/settings_actions.dart';
|
import 'package:aves/model/actions/settings_actions.dart';
|
||||||
import 'package:aves/model/device.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
import 'package:aves/ref/mime_types.dart';
|
import 'package:aves/ref/mime_types.dart';
|
||||||
import 'package:aves/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
|
@ -73,7 +73,7 @@ class _SettingsPageState extends State<SettingsPage> with FeedbackMixin {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final appBarTitle = Text(context.l10n.settingsPageTitle);
|
final appBarTitle = Text(context.l10n.settingsPageTitle);
|
||||||
|
|
||||||
if (device.isTelevision) {
|
if (settings.useTvLayout) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: AvesPopScope(
|
body: AvesPopScope(
|
||||||
handlers: const [TvNavigationPopHandler.pop],
|
handlers: const [TvNavigationPopHandler.pop],
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:aves/model/device.dart';
|
import 'package:aves/model/settings/settings.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/widgets/common/extensions/build_context.dart';
|
import 'package:aves/widgets/common/extensions/build_context.dart';
|
||||||
|
@ -25,7 +25,7 @@ class ThumbnailsSection extends SettingsSection {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<SettingsTile> tiles(BuildContext context) => [
|
List<SettingsTile> tiles(BuildContext context) => [
|
||||||
if (!device.isTelevision) SettingsTileCollectionQuickActions(),
|
if (!settings.useTvLayout) SettingsTileCollectionQuickActions(),
|
||||||
SettingsTileThumbnailOverlay(),
|
SettingsTileThumbnailOverlay(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/filters/mime.dart';
|
import 'package:aves/model/filters/mime.dart';
|
||||||
import 'package:aves/model/settings/enums/enums.dart';
|
import 'package:aves/model/settings/enums/enums.dart';
|
||||||
import 'package:aves/model/settings/enums/video_auto_play_mode.dart';
|
import 'package:aves/model/settings/enums/video_auto_play_mode.dart';
|
||||||
|
@ -43,7 +42,7 @@ class VideoSection extends SettingsSection {
|
||||||
SettingsTileVideoEnableHardwareAcceleration(),
|
SettingsTileVideoEnableHardwareAcceleration(),
|
||||||
SettingsTileVideoEnableAutoPlay(),
|
SettingsTileVideoEnableAutoPlay(),
|
||||||
SettingsTileVideoLoopMode(),
|
SettingsTileVideoLoopMode(),
|
||||||
if (!device.isTelevision) SettingsTileVideoControls(),
|
if (!settings.useTvLayout) SettingsTileVideoControls(),
|
||||||
SettingsTileVideoSubtitleTheme(),
|
SettingsTileVideoSubtitleTheme(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.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/tiles.dart';
|
import 'package:aves/widgets/settings/common/tiles.dart';
|
||||||
|
@ -20,7 +19,7 @@ class ViewerOverlayPage extends StatelessWidget {
|
||||||
body: SafeArea(
|
body: SafeArea(
|
||||||
child: ListView(
|
child: ListView(
|
||||||
children: [
|
children: [
|
||||||
if (!device.isTelevision)
|
if (!settings.useTvLayout)
|
||||||
SettingsSwitchListTile(
|
SettingsSwitchListTile(
|
||||||
selector: (context, s) => s.showOverlayOnOpening,
|
selector: (context, s) => s.showOverlayOnOpening,
|
||||||
onChanged: (v) => settings.showOverlayOnOpening = v,
|
onChanged: (v) => settings.showOverlayOnOpening = v,
|
||||||
|
@ -68,13 +67,13 @@ class ViewerOverlayPage extends StatelessWidget {
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (!device.isTelevision)
|
if (!settings.useTvLayout)
|
||||||
SettingsSwitchListTile(
|
SettingsSwitchListTile(
|
||||||
selector: (context, s) => s.showOverlayMinimap,
|
selector: (context, s) => s.showOverlayMinimap,
|
||||||
onChanged: (v) => settings.showOverlayMinimap = v,
|
onChanged: (v) => settings.showOverlayMinimap = v,
|
||||||
title: context.l10n.settingsViewerShowMinimap,
|
title: context.l10n.settingsViewerShowMinimap,
|
||||||
),
|
),
|
||||||
if (!device.isTelevision)
|
if (!settings.useTvLayout)
|
||||||
SettingsSwitchListTile(
|
SettingsSwitchListTile(
|
||||||
selector: (context, s) => s.showOverlayThumbnailPreview,
|
selector: (context, s) => s.showOverlayThumbnailPreview,
|
||||||
onChanged: (v) => settings.showOverlayThumbnailPreview = v,
|
onChanged: (v) => settings.showOverlayThumbnailPreview = v,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/device.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/services/common/services.dart';
|
import 'package:aves/services/common/services.dart';
|
||||||
|
@ -34,12 +33,12 @@ class ViewerSection extends SettingsSection {
|
||||||
FutureOr<List<SettingsTile>> tiles(BuildContext context) async {
|
FutureOr<List<SettingsTile>> tiles(BuildContext context) async {
|
||||||
final isCutoutAware = await windowService.isCutoutAware();
|
final isCutoutAware = await windowService.isCutoutAware();
|
||||||
return [
|
return [
|
||||||
if (!device.isTelevision) SettingsTileViewerQuickActions(),
|
if (!settings.useTvLayout) SettingsTileViewerQuickActions(),
|
||||||
SettingsTileViewerOverlay(),
|
SettingsTileViewerOverlay(),
|
||||||
SettingsTileViewerSlideshow(),
|
SettingsTileViewerSlideshow(),
|
||||||
if (!device.isTelevision) SettingsTileViewerGestureSideTapNext(),
|
if (!settings.useTvLayout) SettingsTileViewerGestureSideTapNext(),
|
||||||
if (!device.isTelevision && isCutoutAware) SettingsTileViewerUseCutout(),
|
if (!settings.useTvLayout && isCutoutAware) SettingsTileViewerUseCutout(),
|
||||||
if (!device.isTelevision) SettingsTileViewerMaxBrightness(),
|
if (!settings.useTvLayout) SettingsTileViewerMaxBrightness(),
|
||||||
SettingsTileViewerMotionPhotoAutoPlay(),
|
SettingsTileViewerMotionPhotoAutoPlay(),
|
||||||
SettingsTileViewerImageBackground(),
|
SettingsTileViewerImageBackground(),
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/filters/album.dart';
|
import 'package:aves/model/filters/album.dart';
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
|
@ -226,7 +225,7 @@ class _StatsPageState extends State<StatsPage> {
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
automaticallyImplyLeading: !device.isTelevision,
|
automaticallyImplyLeading: !settings.useTvLayout,
|
||||||
title: Text(l10n.statsPageTitle),
|
title: Text(l10n.statsPageTitle),
|
||||||
),
|
),
|
||||||
body: GestureAreaProtectorStack(
|
body: GestureAreaProtectorStack(
|
||||||
|
@ -356,7 +355,7 @@ class StatsTopPage extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
automaticallyImplyLeading: !device.isTelevision,
|
automaticallyImplyLeading: !settings.useTvLayout,
|
||||||
title: Text(title),
|
title: Text(title),
|
||||||
),
|
),
|
||||||
body: GestureAreaProtectorStack(
|
body: GestureAreaProtectorStack(
|
||||||
|
|
|
@ -93,7 +93,7 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
case EntryAction.videoCaptureFrame:
|
case EntryAction.videoCaptureFrame:
|
||||||
return canWrite && targetEntry.isVideo;
|
return canWrite && targetEntry.isVideo;
|
||||||
case EntryAction.videoToggleMute:
|
case EntryAction.videoToggleMute:
|
||||||
return !device.isTelevision && targetEntry.isVideo;
|
return !settings.useTvLayout && targetEntry.isVideo;
|
||||||
case EntryAction.videoSelectStreams:
|
case EntryAction.videoSelectStreams:
|
||||||
case EntryAction.videoSetSpeed:
|
case EntryAction.videoSetSpeed:
|
||||||
case EntryAction.videoSettings:
|
case EntryAction.videoSettings:
|
||||||
|
@ -103,13 +103,13 @@ class EntryActionDelegate with FeedbackMixin, PermissionAwareMixin, SizeAwareMix
|
||||||
case EntryAction.openVideo:
|
case EntryAction.openVideo:
|
||||||
return targetEntry.isVideo;
|
return targetEntry.isVideo;
|
||||||
case EntryAction.rotateScreen:
|
case EntryAction.rotateScreen:
|
||||||
return !device.isTelevision && settings.isRotationLocked;
|
return !settings.useTvLayout && settings.isRotationLocked;
|
||||||
case EntryAction.addShortcut:
|
case EntryAction.addShortcut:
|
||||||
return device.canPinShortcut;
|
return device.canPinShortcut;
|
||||||
case EntryAction.edit:
|
case EntryAction.edit:
|
||||||
return canWrite;
|
return canWrite;
|
||||||
case EntryAction.copyToClipboard:
|
case EntryAction.copyToClipboard:
|
||||||
return !device.isTelevision;
|
return !settings.useTvLayout;
|
||||||
case EntryAction.info:
|
case EntryAction.info:
|
||||||
case EntryAction.open:
|
case EntryAction.open:
|
||||||
case EntryAction.setAs:
|
case EntryAction.setAs:
|
||||||
|
|
|
@ -4,7 +4,6 @@ import 'dart:ui';
|
||||||
|
|
||||||
import 'package:aves/app_mode.dart';
|
import 'package:aves/app_mode.dart';
|
||||||
import 'package:aves/model/actions/entry_actions.dart';
|
import 'package:aves/model/actions/entry_actions.dart';
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.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';
|
||||||
|
@ -181,12 +180,12 @@ class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildImagePage() {
|
Widget _buildImagePage() {
|
||||||
final isTelevision = device.isTelevision;
|
final useTvLayout = settings.useTvLayout;
|
||||||
|
|
||||||
Widget? child;
|
Widget? child;
|
||||||
Map<ShortcutActivator, Intent>? shortcuts = {
|
Map<ShortcutActivator, Intent>? shortcuts = {
|
||||||
const SingleActivator(LogicalKeyboardKey.arrowUp): isTelevision ? const TvShowLessInfoIntent() : const _LeaveIntent(),
|
const SingleActivator(LogicalKeyboardKey.arrowUp): useTvLayout ? const TvShowLessInfoIntent() : const _LeaveIntent(),
|
||||||
const SingleActivator(LogicalKeyboardKey.arrowDown): isTelevision ? const _TvShowMoreInfoIntent() : const _ShowInfoIntent(),
|
const SingleActivator(LogicalKeyboardKey.arrowDown): useTvLayout ? const _TvShowMoreInfoIntent() : const _ShowInfoIntent(),
|
||||||
const SingleActivator(LogicalKeyboardKey.mediaPause): const _PlayPauseIntent.pause(),
|
const SingleActivator(LogicalKeyboardKey.mediaPause): const _PlayPauseIntent.pause(),
|
||||||
const SingleActivator(LogicalKeyboardKey.mediaPlay): const _PlayPauseIntent.play(),
|
const SingleActivator(LogicalKeyboardKey.mediaPlay): const _PlayPauseIntent.play(),
|
||||||
const SingleActivator(LogicalKeyboardKey.mediaPlayPause): const _PlayPauseIntent.toggle(),
|
const SingleActivator(LogicalKeyboardKey.mediaPlayPause): const _PlayPauseIntent.toggle(),
|
||||||
|
@ -211,7 +210,7 @@ class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (child != null) {
|
if (child != null) {
|
||||||
if (device.isTelevision) {
|
if (settings.useTvLayout) {
|
||||||
child = ValueListenableBuilder<bool>(
|
child = ValueListenableBuilder<bool>(
|
||||||
valueListenable: _isImageFocusedNotifier,
|
valueListenable: _isImageFocusedNotifier,
|
||||||
builder: (context, isImageFocused, child) {
|
builder: (context, isImageFocused, child) {
|
||||||
|
@ -238,7 +237,7 @@ class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
|
||||||
_TvShowMoreInfoIntent: CallbackAction<Intent>(onInvoke: (intent) => TvShowMoreInfoNotification().dispatch(context)),
|
_TvShowMoreInfoIntent: CallbackAction<Intent>(onInvoke: (intent) => TvShowMoreInfoNotification().dispatch(context)),
|
||||||
_PlayPauseIntent: CallbackAction<_PlayPauseIntent>(onInvoke: (intent) => _onPlayPauseIntent(intent, entry)),
|
_PlayPauseIntent: CallbackAction<_PlayPauseIntent>(onInvoke: (intent) => _onPlayPauseIntent(intent, entry)),
|
||||||
ActivateIntent: CallbackAction<Intent>(onInvoke: (intent) {
|
ActivateIntent: CallbackAction<Intent>(onInvoke: (intent) {
|
||||||
if (isTelevision) {
|
if (useTvLayout) {
|
||||||
final _entry = entry;
|
final _entry = entry;
|
||||||
if (_entry != null && _entry.isVideo) {
|
if (_entry != null && _entry.isVideo) {
|
||||||
// address `TV-PC` requirement from https://developer.android.com/docs/quality-guidelines/tv-app-quality
|
// address `TV-PC` requirement from https://developer.android.com/docs/quality-guidelines/tv-app-quality
|
||||||
|
|
|
@ -689,7 +689,9 @@ class _EntryViewerStackState extends State<EntryViewerStack> with EntryViewContr
|
||||||
|
|
||||||
await AvesApp.showSystemUI();
|
await AvesApp.showSystemUI();
|
||||||
AvesApp.setSystemUIStyle(context);
|
AvesApp.setSystemUIStyle(context);
|
||||||
await windowService.requestOrientation();
|
if (!settings.useTvLayout) {
|
||||||
|
await windowService.requestOrientation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// overlay
|
// overlay
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:aves/model/actions/entry_actions.dart';
|
import 'package:aves/model/actions/entry_actions.dart';
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.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/theme/durations.dart';
|
import 'package:aves/theme/durations.dart';
|
||||||
import 'package:aves/theme/icons.dart';
|
import 'package:aves/theme/icons.dart';
|
||||||
|
@ -37,7 +37,7 @@ class InfoAppBar extends StatelessWidget {
|
||||||
final formatSpecificActions = EntryActions.formatSpecificMetadataActions.where((v) => actionDelegate.isVisible(entry, v));
|
final formatSpecificActions = EntryActions.formatSpecificMetadataActions.where((v) => actionDelegate.isVisible(entry, v));
|
||||||
|
|
||||||
return SliverAppBar(
|
return SliverAppBar(
|
||||||
leading: device.isTelevision
|
leading: settings.useTvLayout
|
||||||
? null
|
? null
|
||||||
: IconButton(
|
: IconButton(
|
||||||
// key is expected by test driver
|
// key is expected by test driver
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:aves/app_mode.dart';
|
import 'package:aves/app_mode.dart';
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.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';
|
||||||
|
@ -186,7 +185,7 @@ class _BottomOverlayContentState extends State<_BottomOverlayContent> {
|
||||||
final viewInsetsPadding = (widget.viewInsets ?? EdgeInsets.zero) + (widget.viewPadding ?? EdgeInsets.zero);
|
final viewInsetsPadding = (widget.viewInsets ?? EdgeInsets.zero) + (widget.viewPadding ?? EdgeInsets.zero);
|
||||||
final viewerButtonRow = FocusableActionDetector(
|
final viewerButtonRow = FocusableActionDetector(
|
||||||
focusNode: _buttonRowFocusScopeNode,
|
focusNode: _buttonRowFocusScopeNode,
|
||||||
shortcuts: device.isTelevision ? const {SingleActivator(LogicalKeyboardKey.arrowUp): TvShowLessInfoIntent()} : null,
|
shortcuts: settings.useTvLayout ? const {SingleActivator(LogicalKeyboardKey.arrowUp): TvShowLessInfoIntent()} : null,
|
||||||
actions: {TvShowLessInfoIntent: CallbackAction<Intent>(onInvoke: (intent) => TvShowLessInfoNotification().dispatch(context))},
|
actions: {TvShowLessInfoIntent: CallbackAction<Intent>(onInvoke: (intent) => TvShowLessInfoNotification().dispatch(context))},
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
top: false,
|
top: false,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:aves/model/actions/slideshow_actions.dart';
|
import 'package:aves/model/actions/slideshow_actions.dart';
|
||||||
import 'package:aves/model/device.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
import 'package:aves/widgets/common/identity/buttons/captioned_button.dart';
|
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/entry_vertical_pager.dart';
|
import 'package:aves/widgets/viewer/entry_vertical_pager.dart';
|
||||||
|
@ -70,9 +70,9 @@ class _SlideshowButtonsState extends State<SlideshowButtons> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FocusableActionDetector(
|
return FocusableActionDetector(
|
||||||
focusNode: _buttonRowFocusScopeNode,
|
focusNode: _buttonRowFocusScopeNode,
|
||||||
shortcuts: device.isTelevision ? const {SingleActivator(LogicalKeyboardKey.arrowUp): TvShowLessInfoIntent()} : null,
|
shortcuts: settings.useTvLayout ? const {SingleActivator(LogicalKeyboardKey.arrowUp): TvShowLessInfoIntent()} : null,
|
||||||
actions: {TvShowLessInfoIntent: CallbackAction<Intent>(onInvoke: (intent) => TvShowLessInfoNotification().dispatch(context))},
|
actions: {TvShowLessInfoIntent: CallbackAction<Intent>(onInvoke: (intent) => TvShowLessInfoNotification().dispatch(context))},
|
||||||
child: device.isTelevision
|
child: settings.useTvLayout
|
||||||
? Row(
|
? Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:aves/model/actions/entry_actions.dart';
|
import 'package:aves/model/actions/entry_actions.dart';
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.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';
|
||||||
|
@ -51,7 +50,7 @@ class ViewerButtons extends StatelessWidget {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final actionDelegate = EntryActionDelegate(mainEntry, pageEntry, collection);
|
final actionDelegate = EntryActionDelegate(mainEntry, pageEntry, collection);
|
||||||
|
|
||||||
if (device.isTelevision) {
|
if (settings.useTvLayout) {
|
||||||
return _TvButtonRowContent(
|
return _TvButtonRowContent(
|
||||||
actionDelegate: actionDelegate,
|
actionDelegate: actionDelegate,
|
||||||
scale: scale,
|
scale: scale,
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/entry_images.dart';
|
import 'package:aves/model/entry_images.dart';
|
||||||
import 'package:aves/model/panorama.dart';
|
import 'package:aves/model/panorama.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/aves_app.dart';
|
||||||
import 'package:aves/widgets/common/basic/insets.dart';
|
import 'package:aves/widgets/common/basic/insets.dart';
|
||||||
|
@ -110,7 +110,7 @@ class _PanoramaPageState extends State<PanoramaPage> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildOverlay(BuildContext context) {
|
Widget _buildOverlay(BuildContext context) {
|
||||||
if (device.isTelevision) return const SizedBox();
|
if (settings.useTvLayout) return const SizedBox();
|
||||||
|
|
||||||
return TooltipTheme(
|
return TooltipTheme(
|
||||||
data: TooltipTheme.of(context).copyWith(
|
data: TooltipTheme.of(context).copyWith(
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:aves/app_flavor.dart';
|
import 'package:aves/app_flavor.dart';
|
||||||
import 'package:aves/model/device.dart';
|
|
||||||
import 'package:aves/model/settings/defaults.dart';
|
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';
|
||||||
|
@ -71,7 +70,7 @@ class _WelcomePageState extends State<WelcomePage> {
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
children: device.isTelevision
|
children: settings.useTvLayout
|
||||||
? [
|
? [
|
||||||
..._buildHeader(context, isPortrait: isPortrait),
|
..._buildHeader(context, isPortrait: isPortrait),
|
||||||
Padding(
|
Padding(
|
||||||
|
|
|
@ -387,6 +387,7 @@
|
||||||
"settingsSystemDefault",
|
"settingsSystemDefault",
|
||||||
"settingsDefault",
|
"settingsDefault",
|
||||||
"settingsDisabled",
|
"settingsDisabled",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsSearchFieldLabel",
|
"settingsSearchFieldLabel",
|
||||||
"settingsSearchEmpty",
|
"settingsSearchEmpty",
|
||||||
"settingsActionExport",
|
"settingsActionExport",
|
||||||
|
@ -526,6 +527,7 @@
|
||||||
"settingsThemeEnableDynamicColor",
|
"settingsThemeEnableDynamicColor",
|
||||||
"settingsDisplayRefreshRateModeTile",
|
"settingsDisplayRefreshRateModeTile",
|
||||||
"settingsDisplayRefreshRateModeDialogTitle",
|
"settingsDisplayRefreshRateModeDialogTitle",
|
||||||
|
"settingsDisplayUseTvInterface",
|
||||||
"settingsLanguageSectionTitle",
|
"settingsLanguageSectionTitle",
|
||||||
"settingsLanguageTile",
|
"settingsLanguageTile",
|
||||||
"settingsLanguagePageTitle",
|
"settingsLanguagePageTitle",
|
||||||
|
@ -592,21 +594,29 @@
|
||||||
],
|
],
|
||||||
|
|
||||||
"cs": [
|
"cs": [
|
||||||
"settingsViewerShowDescription"
|
"settingsModificationWarningDialogMessage",
|
||||||
|
"settingsViewerShowDescription",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
"de": [
|
"de": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives"
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
"el": [
|
"el": [
|
||||||
"settingsViewerShowDescription"
|
"settingsModificationWarningDialogMessage",
|
||||||
|
"settingsViewerShowDescription",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
"es": [
|
"es": [
|
||||||
"settingsViewerShowDescription"
|
"settingsModificationWarningDialogMessage",
|
||||||
|
"settingsViewerShowDescription",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
"fa": [
|
"fa": [
|
||||||
|
@ -867,6 +877,7 @@
|
||||||
"settingsSystemDefault",
|
"settingsSystemDefault",
|
||||||
"settingsDefault",
|
"settingsDefault",
|
||||||
"settingsDisabled",
|
"settingsDisabled",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsSearchFieldLabel",
|
"settingsSearchFieldLabel",
|
||||||
"settingsSearchEmpty",
|
"settingsSearchEmpty",
|
||||||
"settingsActionImport",
|
"settingsActionImport",
|
||||||
|
@ -1002,6 +1013,7 @@
|
||||||
"settingsThemeEnableDynamicColor",
|
"settingsThemeEnableDynamicColor",
|
||||||
"settingsDisplayRefreshRateModeTile",
|
"settingsDisplayRefreshRateModeTile",
|
||||||
"settingsDisplayRefreshRateModeDialogTitle",
|
"settingsDisplayRefreshRateModeDialogTitle",
|
||||||
|
"settingsDisplayUseTvInterface",
|
||||||
"settingsLanguageSectionTitle",
|
"settingsLanguageSectionTitle",
|
||||||
"settingsLanguageTile",
|
"settingsLanguageTile",
|
||||||
"settingsLanguagePageTitle",
|
"settingsLanguagePageTitle",
|
||||||
|
@ -1074,6 +1086,11 @@
|
||||||
"filePickerUseThisFolder"
|
"filePickerUseThisFolder"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"fr": [
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
|
],
|
||||||
|
|
||||||
"gl": [
|
"gl": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
"entryActionShareImageOnly",
|
"entryActionShareImageOnly",
|
||||||
|
@ -1329,6 +1346,7 @@
|
||||||
"settingsSystemDefault",
|
"settingsSystemDefault",
|
||||||
"settingsDefault",
|
"settingsDefault",
|
||||||
"settingsDisabled",
|
"settingsDisabled",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsSearchFieldLabel",
|
"settingsSearchFieldLabel",
|
||||||
"settingsSearchEmpty",
|
"settingsSearchEmpty",
|
||||||
"settingsActionExport",
|
"settingsActionExport",
|
||||||
|
@ -1468,6 +1486,7 @@
|
||||||
"settingsThemeEnableDynamicColor",
|
"settingsThemeEnableDynamicColor",
|
||||||
"settingsDisplayRefreshRateModeTile",
|
"settingsDisplayRefreshRateModeTile",
|
||||||
"settingsDisplayRefreshRateModeDialogTitle",
|
"settingsDisplayRefreshRateModeDialogTitle",
|
||||||
|
"settingsDisplayUseTvInterface",
|
||||||
"settingsLanguageSectionTitle",
|
"settingsLanguageSectionTitle",
|
||||||
"settingsLanguageTile",
|
"settingsLanguageTile",
|
||||||
"settingsLanguagePageTitle",
|
"settingsLanguagePageTitle",
|
||||||
|
@ -1543,11 +1562,15 @@
|
||||||
],
|
],
|
||||||
|
|
||||||
"id": [
|
"id": [
|
||||||
"settingsViewerShowDescription"
|
"settingsModificationWarningDialogMessage",
|
||||||
|
"settingsViewerShowDescription",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
"it": [
|
"it": [
|
||||||
"settingsViewerShowDescription"
|
"settingsModificationWarningDialogMessage",
|
||||||
|
"settingsViewerShowDescription",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ja": [
|
"ja": [
|
||||||
|
@ -1559,16 +1582,25 @@
|
||||||
"keepScreenOnVideoPlayback",
|
"keepScreenOnVideoPlayback",
|
||||||
"subtitlePositionTop",
|
"subtitlePositionTop",
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives",
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
"settingsDisplayUseTvInterface",
|
||||||
"settingsWidgetDisplayedItem"
|
"settingsWidgetDisplayedItem"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"ko": [
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
|
],
|
||||||
|
|
||||||
"lt": [
|
"lt": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
"keepScreenOnVideoPlayback",
|
"keepScreenOnVideoPlayback",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives"
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
"nb": [
|
"nb": [
|
||||||
|
@ -1577,8 +1609,10 @@
|
||||||
"entryActionShareVideoOnly",
|
"entryActionShareVideoOnly",
|
||||||
"entryInfoActionRemoveLocation",
|
"entryInfoActionRemoveLocation",
|
||||||
"keepScreenOnVideoPlayback",
|
"keepScreenOnVideoPlayback",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives"
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
"nl": [
|
"nl": [
|
||||||
|
@ -1595,11 +1629,13 @@
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"widgetDisplayedItemRandom",
|
"widgetDisplayedItemRandom",
|
||||||
"widgetDisplayedItemMostRecent",
|
"widgetDisplayedItemMostRecent",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowRatingTags",
|
"settingsViewerShowRatingTags",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsSubtitleThemeTextPositionTile",
|
"settingsSubtitleThemeTextPositionTile",
|
||||||
"settingsSubtitleThemeTextPositionDialogTitle",
|
"settingsSubtitleThemeTextPositionDialogTitle",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives",
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
"settingsDisplayUseTvInterface",
|
||||||
"settingsWidgetDisplayedItem"
|
"settingsWidgetDisplayedItem"
|
||||||
],
|
],
|
||||||
|
|
||||||
|
@ -1841,6 +1877,7 @@
|
||||||
"settingsSystemDefault",
|
"settingsSystemDefault",
|
||||||
"settingsDefault",
|
"settingsDefault",
|
||||||
"settingsDisabled",
|
"settingsDisabled",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsSearchFieldLabel",
|
"settingsSearchFieldLabel",
|
||||||
"settingsSearchEmpty",
|
"settingsSearchEmpty",
|
||||||
"settingsActionExport",
|
"settingsActionExport",
|
||||||
|
@ -1980,6 +2017,7 @@
|
||||||
"settingsThemeEnableDynamicColor",
|
"settingsThemeEnableDynamicColor",
|
||||||
"settingsDisplayRefreshRateModeTile",
|
"settingsDisplayRefreshRateModeTile",
|
||||||
"settingsDisplayRefreshRateModeDialogTitle",
|
"settingsDisplayRefreshRateModeDialogTitle",
|
||||||
|
"settingsDisplayUseTvInterface",
|
||||||
"settingsLanguageSectionTitle",
|
"settingsLanguageSectionTitle",
|
||||||
"settingsLanguageTile",
|
"settingsLanguageTile",
|
||||||
"settingsLanguagePageTitle",
|
"settingsLanguagePageTitle",
|
||||||
|
@ -2349,6 +2387,7 @@
|
||||||
"settingsSystemDefault",
|
"settingsSystemDefault",
|
||||||
"settingsDefault",
|
"settingsDefault",
|
||||||
"settingsDisabled",
|
"settingsDisabled",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsSearchFieldLabel",
|
"settingsSearchFieldLabel",
|
||||||
"settingsSearchEmpty",
|
"settingsSearchEmpty",
|
||||||
"settingsActionExport",
|
"settingsActionExport",
|
||||||
|
@ -2488,6 +2527,7 @@
|
||||||
"settingsThemeEnableDynamicColor",
|
"settingsThemeEnableDynamicColor",
|
||||||
"settingsDisplayRefreshRateModeTile",
|
"settingsDisplayRefreshRateModeTile",
|
||||||
"settingsDisplayRefreshRateModeDialogTitle",
|
"settingsDisplayRefreshRateModeDialogTitle",
|
||||||
|
"settingsDisplayUseTvInterface",
|
||||||
"settingsLanguageSectionTitle",
|
"settingsLanguageSectionTitle",
|
||||||
"settingsLanguageTile",
|
"settingsLanguageTile",
|
||||||
"settingsLanguagePageTitle",
|
"settingsLanguagePageTitle",
|
||||||
|
@ -2576,16 +2616,25 @@
|
||||||
"subtitlePositionBottom",
|
"subtitlePositionBottom",
|
||||||
"widgetDisplayedItemRandom",
|
"widgetDisplayedItemRandom",
|
||||||
"widgetDisplayedItemMostRecent",
|
"widgetDisplayedItemMostRecent",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowRatingTags",
|
"settingsViewerShowRatingTags",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsSubtitleThemeTextPositionTile",
|
"settingsSubtitleThemeTextPositionTile",
|
||||||
"settingsSubtitleThemeTextPositionDialogTitle",
|
"settingsSubtitleThemeTextPositionDialogTitle",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives",
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
"settingsDisplayUseTvInterface",
|
||||||
"settingsWidgetDisplayedItem"
|
"settingsWidgetDisplayedItem"
|
||||||
],
|
],
|
||||||
|
|
||||||
"ro": [
|
"ro": [
|
||||||
"settingsViewerShowDescription"
|
"settingsModificationWarningDialogMessage",
|
||||||
|
"settingsViewerShowDescription",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
|
],
|
||||||
|
|
||||||
|
"ru": [
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
"th": [
|
"th": [
|
||||||
|
@ -2718,6 +2767,7 @@
|
||||||
"settingsSystemDefault",
|
"settingsSystemDefault",
|
||||||
"settingsDefault",
|
"settingsDefault",
|
||||||
"settingsDisabled",
|
"settingsDisabled",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsSearchFieldLabel",
|
"settingsSearchFieldLabel",
|
||||||
"settingsSearchEmpty",
|
"settingsSearchEmpty",
|
||||||
"settingsActionExport",
|
"settingsActionExport",
|
||||||
|
@ -2857,6 +2907,7 @@
|
||||||
"settingsThemeEnableDynamicColor",
|
"settingsThemeEnableDynamicColor",
|
||||||
"settingsDisplayRefreshRateModeTile",
|
"settingsDisplayRefreshRateModeTile",
|
||||||
"settingsDisplayRefreshRateModeDialogTitle",
|
"settingsDisplayRefreshRateModeDialogTitle",
|
||||||
|
"settingsDisplayUseTvInterface",
|
||||||
"settingsLanguageSectionTitle",
|
"settingsLanguageSectionTitle",
|
||||||
"settingsLanguageTile",
|
"settingsLanguageTile",
|
||||||
"settingsLanguagePageTitle",
|
"settingsLanguagePageTitle",
|
||||||
|
@ -2932,21 +2983,29 @@
|
||||||
],
|
],
|
||||||
|
|
||||||
"tr": [
|
"tr": [
|
||||||
"settingsViewerShowDescription"
|
"settingsModificationWarningDialogMessage",
|
||||||
|
"settingsViewerShowDescription",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
"uk": [
|
"uk": [
|
||||||
"settingsViewerShowDescription"
|
"settingsModificationWarningDialogMessage",
|
||||||
|
"settingsViewerShowDescription",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
"zh": [
|
"zh": [
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives"
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
],
|
],
|
||||||
|
|
||||||
"zh_Hant": [
|
"zh_Hant": [
|
||||||
"columnCount",
|
"columnCount",
|
||||||
|
"settingsModificationWarningDialogMessage",
|
||||||
"settingsViewerShowDescription",
|
"settingsViewerShowDescription",
|
||||||
"settingsAccessibilityShowPinchGestureAlternatives"
|
"settingsAccessibilityShowPinchGestureAlternatives",
|
||||||
|
"settingsDisplayUseTvInterface"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue