Request playback with non-site player types and swap to backup Usher streams on stitched ad breaks; inject vendored vaft into the legacy WebView and expose a Settings toggle. Co-authored-by: Cursor <cursoragent@cursor.com>
99 lines
4 KiB
Dart
99 lines
4 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_mobx/flutter_mobx.dart';
|
|
import 'package:frosty/screens/settings/stores/settings_store.dart';
|
|
import 'package:frosty/screens/settings/widgets/settings_list_switch.dart';
|
|
import 'package:frosty/utils.dart';
|
|
import 'package:frosty/widgets/section_header.dart';
|
|
import 'package:frosty/widgets/settings_page_layout.dart';
|
|
|
|
class VideoSettings extends StatelessWidget {
|
|
final SettingsStore settingsStore;
|
|
|
|
const VideoSettings({super.key, required this.settingsStore});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Observer(
|
|
builder: (context) => SettingsPageLayout(
|
|
children: [
|
|
const SectionHeader('Player', isFirst: true),
|
|
SettingsListSwitch(
|
|
title: 'Show video player',
|
|
value: settingsStore.showVideo,
|
|
onChanged: (newValue) => settingsStore.showVideo = newValue,
|
|
),
|
|
if (settingsStore.showVideo)
|
|
SettingsListSwitch(
|
|
title: 'Native player',
|
|
subtitle: const Text(
|
|
'Picture-in-Picture, quality selection, and lower latency. Turn off to use the legacy WebView player.',
|
|
),
|
|
value: settingsStore.useNativePlayer,
|
|
onChanged: (newValue) =>
|
|
settingsStore.useNativePlayer = newValue,
|
|
),
|
|
if (settingsStore.showVideo)
|
|
SettingsListSwitch(
|
|
title: 'Block Twitch ads',
|
|
subtitle: Text(
|
|
settingsStore.useNativePlayer
|
|
? 'Uses TwitchAdSolutions (vaft): popout/embed/autoplay player types and backup streams during ad breaks.'
|
|
: 'Injects the vaft userscript into the WebView. Native player is more reliable — enable it above if ads still play.',
|
|
),
|
|
value: settingsStore.blockTwitchAds,
|
|
onChanged: (newValue) {
|
|
settingsStore.blockTwitchAds = newValue;
|
|
// Ad blocking is most effective on the native path.
|
|
if (newValue) settingsStore.useNativePlayer = true;
|
|
},
|
|
),
|
|
if (!Platform.isIOS || isIPad())
|
|
SettingsListSwitch(
|
|
title: 'Default to highest quality',
|
|
value: settingsStore.defaultToHighestQuality,
|
|
onChanged: (newValue) =>
|
|
settingsStore.defaultToHighestQuality = newValue,
|
|
),
|
|
if (Platform.isAndroid)
|
|
SettingsListSwitch(
|
|
title: 'Use fast video rendering',
|
|
subtitle: const Text(
|
|
'Uses a faster WebView rendering method. Disable if you experience crashes while watching streams.',
|
|
),
|
|
value: settingsStore.useTextureRendering,
|
|
onChanged: (newValue) =>
|
|
settingsStore.useTextureRendering = newValue,
|
|
),
|
|
const SectionHeader('Overlay'),
|
|
SettingsListSwitch(
|
|
title: 'Use custom video overlay',
|
|
subtitle: const Text(
|
|
'Replaces Twitch\'s default web overlay with a mobile-friendly version.',
|
|
),
|
|
value: settingsStore.showOverlay,
|
|
onChanged: (newValue) => settingsStore.showOverlay = newValue,
|
|
),
|
|
SettingsListSwitch(
|
|
title: 'Toggle overlay on long-press',
|
|
subtitle: const Text(
|
|
'Switch between Twitch\'s overlay and the custom overlay.',
|
|
),
|
|
value: settingsStore.toggleableOverlay,
|
|
onChanged: (newValue) =>
|
|
settingsStore.toggleableOverlay = newValue,
|
|
),
|
|
SettingsListSwitch(
|
|
title: 'Show latency',
|
|
subtitle: const Text(
|
|
'Displays the stream latency in the video overlay.',
|
|
),
|
|
value: settingsStore.showLatency,
|
|
onChanged: (newValue) => settingsStore.showLatency = newValue,
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|