support for external download managers

This commit is contained in:
Fabian Freund
2026-02-04 07:46:50 +01:00
parent c8179c585e
commit 28907a62a7
15 changed files with 584 additions and 2 deletions
@@ -99,6 +99,23 @@ class EngineSettingsReplicationService
},
);
ref.listen(
fireImmediately: true,
generalSettingsWithDefaultsProvider.select(
(settings) => settings.useExternalDownloadManager,
),
(previous, next) async {
await _service.setUseExternalDownloadManager(next);
},
onError: (error, stackTrace) {
logger.e(
'Error listening to useExternalDownloadManager',
error: error,
stackTrace: stackTrace,
);
},
);
ref.listen(
fireImmediately: true,
engineSettingsRepositoryProvider,
@@ -44,7 +44,7 @@ final class EngineSettingsReplicationServiceProvider
}
String _$engineSettingsReplicationServiceHash() =>
r'3e06f0c273090f9f9dfc42f2140d60ef9557f176';
r'7a4db374b521e592847a85cb8d2aa184be788ee4';
abstract class _$EngineSettingsReplicationService extends $Notifier<void> {
void build();
@@ -49,6 +49,7 @@ class TabsBehaviorSettingsScreen extends StatelessWidget {
_TabCreationSection(),
_TabOrganizationSection(),
_TabInteractionSection(),
_DownloadsSection(),
],
);
},
@@ -404,3 +405,45 @@ class _AppLinksModeSection extends HookConsumerWidget {
);
}
}
class _DownloadsSection extends StatelessWidget {
const _DownloadsSection();
@override
Widget build(BuildContext context) {
return const Column(
children: [
SettingSection(name: 'Downloads'),
_ExternalDownloadManagerTile(),
],
);
}
}
class _ExternalDownloadManagerTile extends HookConsumerWidget {
const _ExternalDownloadManagerTile();
@override
Widget build(BuildContext context, WidgetRef ref) {
final useExternalDownloadManager = ref.watch(
generalSettingsWithDefaultsProvider.select(
(s) => s.useExternalDownloadManager,
),
);
return SwitchListTile.adaptive(
title: const Text('Use external download manager'),
subtitle: const Text('Manage downloads with another app'),
secondary: const Icon(MdiIcons.download),
value: useExternalDownloadManager,
onChanged: (value) async {
await ref
.read(saveGeneralSettingsControllerProvider.notifier)
.save(
(currentSettings) =>
currentSettings.copyWith.useExternalDownloadManager(value),
);
},
);
}
}
@@ -81,6 +81,7 @@ class GeneralSettings with FastEquatable {
final TabBarPosition tabBarPosition;
final QuickTabSwitcherMode quickTabSwitcherMode;
final bool pullToRefreshEnabled;
final bool useExternalDownloadManager;
final bool doubleBackCloseTab;
final Duration unassignedTabsAutoCleanInterval;
final int maxSearchHistoryEntries;
@@ -107,6 +108,7 @@ class GeneralSettings with FastEquatable {
required this.tabBarPosition,
required this.quickTabSwitcherMode,
required this.pullToRefreshEnabled,
required this.useExternalDownloadManager,
required this.doubleBackCloseTab,
required this.unassignedTabsAutoCleanInterval,
required this.maxSearchHistoryEntries,
@@ -134,6 +136,7 @@ class GeneralSettings with FastEquatable {
TabBarPosition? tabBarPosition,
QuickTabSwitcherMode? quickTabSwitcherMode,
bool? pullToRefreshEnabled,
bool? useExternalDownloadManager,
bool? doubleBackCloseTab,
Duration? unassignedTabsAutoCleanInterval,
int? maxSearchHistoryEntries,
@@ -161,6 +164,7 @@ class GeneralSettings with FastEquatable {
quickTabSwitcherMode =
quickTabSwitcherMode ?? QuickTabSwitcherMode.lastUsedTabs,
pullToRefreshEnabled = pullToRefreshEnabled ?? true,
useExternalDownloadManager = useExternalDownloadManager ?? false,
doubleBackCloseTab = doubleBackCloseTab ?? true,
unassignedTabsAutoCleanInterval =
unassignedTabsAutoCleanInterval ?? Duration.zero,
@@ -194,6 +198,7 @@ class GeneralSettings with FastEquatable {
tabBarPosition,
quickTabSwitcherMode,
pullToRefreshEnabled,
useExternalDownloadManager,
doubleBackCloseTab,
unassignedTabsAutoCleanInterval,
maxSearchHistoryEntries,
@@ -59,6 +59,8 @@ abstract class _$GeneralSettingsCWProxy {
GeneralSettings pullToRefreshEnabled(bool pullToRefreshEnabled);
GeneralSettings useExternalDownloadManager(bool useExternalDownloadManager);
GeneralSettings doubleBackCloseTab(bool doubleBackCloseTab);
GeneralSettings unassignedTabsAutoCleanInterval(
@@ -96,6 +98,7 @@ abstract class _$GeneralSettingsCWProxy {
TabBarPosition tabBarPosition,
QuickTabSwitcherMode quickTabSwitcherMode,
bool pullToRefreshEnabled,
bool useExternalDownloadManager,
bool doubleBackCloseTab,
Duration unassignedTabsAutoCleanInterval,
int maxSearchHistoryEntries,
@@ -197,6 +200,10 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
GeneralSettings pullToRefreshEnabled(bool pullToRefreshEnabled) =>
call(pullToRefreshEnabled: pullToRefreshEnabled);
@override
GeneralSettings useExternalDownloadManager(bool useExternalDownloadManager) =>
call(useExternalDownloadManager: useExternalDownloadManager);
@override
GeneralSettings doubleBackCloseTab(bool doubleBackCloseTab) =>
call(doubleBackCloseTab: doubleBackCloseTab);
@@ -240,6 +247,7 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
Object? tabBarPosition = const $CopyWithPlaceholder(),
Object? quickTabSwitcherMode = const $CopyWithPlaceholder(),
Object? pullToRefreshEnabled = const $CopyWithPlaceholder(),
Object? useExternalDownloadManager = const $CopyWithPlaceholder(),
Object? doubleBackCloseTab = const $CopyWithPlaceholder(),
Object? unassignedTabsAutoCleanInterval = const $CopyWithPlaceholder(),
Object? maxSearchHistoryEntries = const $CopyWithPlaceholder(),
@@ -367,6 +375,12 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
? _value.pullToRefreshEnabled
// ignore: cast_nullable_to_non_nullable
: pullToRefreshEnabled as bool,
useExternalDownloadManager:
useExternalDownloadManager == const $CopyWithPlaceholder() ||
useExternalDownloadManager == null
? _value.useExternalDownloadManager
// ignore: cast_nullable_to_non_nullable
: useExternalDownloadManager as bool,
doubleBackCloseTab:
doubleBackCloseTab == const $CopyWithPlaceholder() ||
doubleBackCloseTab == null
@@ -450,6 +464,7 @@ GeneralSettings _$GeneralSettingsFromJson(
json['quickTabSwitcherMode'],
),
pullToRefreshEnabled: json['pullToRefreshEnabled'] as bool?,
useExternalDownloadManager: json['useExternalDownloadManager'] as bool?,
doubleBackCloseTab: json['doubleBackCloseTab'] as bool?,
unassignedTabsAutoCleanInterval:
json['unassignedTabsAutoCleanInterval'] == null
@@ -493,6 +508,7 @@ Map<String, dynamic> _$GeneralSettingsToJson(
'quickTabSwitcherMode':
_$QuickTabSwitcherModeEnumMap[instance.quickTabSwitcherMode]!,
'pullToRefreshEnabled': instance.pullToRefreshEnabled,
'useExternalDownloadManager': instance.useExternalDownloadManager,
'doubleBackCloseTab': instance.doubleBackCloseTab,
'unassignedTabsAutoCleanInterval':
instance.unassignedTabsAutoCleanInterval.inMicroseconds,
@@ -126,6 +126,8 @@ class GeneralSettingsRepository extends _$GeneralSettingsRepository {
DriftSqlType.bool,
db.typeMapping,
),
'useExternalDownloadManager': settings['useExternalDownloadManager']
?.readAs(DriftSqlType.bool, db.typeMapping),
'doubleBackCloseTab': settings['doubleBackCloseTab']?.readAs(
DriftSqlType.bool,
db.typeMapping,
@@ -35,7 +35,7 @@ final class GeneralSettingsRepositoryProvider
}
String _$generalSettingsRepositoryHash() =>
r'0d4b01ff15942b513a7cdceee7bf43721ae1c074';
r'7cea68308e2e7847e9bb030e9c9c04860c760edd';
abstract class _$GeneralSettingsRepository
extends $StreamNotifier<GeneralSettings> {