turn empty tab screen into home screen
This commit is contained in:
@@ -286,6 +286,20 @@ class TabRepository extends _$TabRepository {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> resumeLatestTab() async {
|
||||||
|
final latestTab = await ref
|
||||||
|
.read(tabDatabaseProvider)
|
||||||
|
.tabDao
|
||||||
|
.getTabsFifo(limit: 1)
|
||||||
|
.getSingleOrNull();
|
||||||
|
|
||||||
|
if (!ref.mounted || latestTab == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return selectTab(latestTab.id);
|
||||||
|
}
|
||||||
|
|
||||||
Future<bool> selectPreviousTab(
|
Future<bool> selectPreviousTab(
|
||||||
String tabId, {
|
String tabId, {
|
||||||
String? containerId,
|
String? containerId,
|
||||||
|
|||||||
+101
-44
@@ -1,28 +1,40 @@
|
|||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:weblibre/core/routing/routes.dart';
|
import 'package:weblibre/core/routing/routes.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/domain/providers/tab_list.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/providers/browser_viewport_toolbar_insets.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/providers/browser_viewport_toolbar_insets.dart';
|
||||||
import 'package:weblibre/features/quotes/data/database/definitions.drift.dart';
|
import 'package:weblibre/features/quotes/data/database/definitions.drift.dart';
|
||||||
import 'package:weblibre/features/quotes/domain/providers.dart';
|
import 'package:weblibre/features/quotes/domain/providers.dart';
|
||||||
import 'package:weblibre/features/user/domain/repositories/general_settings.dart';
|
import 'package:weblibre/features/user/domain/repositories/general_settings.dart';
|
||||||
|
|
||||||
class TabsEmptyPlaceholder extends ConsumerWidget {
|
class BrowserHome extends ConsumerWidget {
|
||||||
const TabsEmptyPlaceholder();
|
const BrowserHome({super.key});
|
||||||
|
|
||||||
static const _brandPurple = Color(0xFF9C83F8);
|
static const _brandPurple = Color(0xFF9C83F8);
|
||||||
static const _brandYellow = Color(0xFFFBDC6B);
|
static const _brandYellow = Color(0xFFFBDC6B);
|
||||||
static const _brandGrey = Color(0xFFA7A7A7);
|
static const _brandGrey = Color(0xFFA7A7A7);
|
||||||
|
|
||||||
|
static const _auraPurple = Color(0xFF2C2543);
|
||||||
|
static const _auraGold = Color(0xFF3C3827);
|
||||||
|
static const _auraShadow = Color(0xFF222224);
|
||||||
|
static const _auraShadowHighlight = Color(0xFF2D2D31);
|
||||||
|
static const _auraTint = Color(0xFF000000);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
final colorScheme = theme.colorScheme;
|
final colorScheme = theme.colorScheme;
|
||||||
final settings = ref.watch(generalSettingsWithDefaultsProvider);
|
final settings = ref.watch(generalSettingsWithDefaultsProvider);
|
||||||
final quoteAsync = ref.watch(randomQuoteProvider);
|
final quoteAsync = ref.watch(randomQuoteProvider);
|
||||||
|
final hasTabs = ref.watch(
|
||||||
|
tabListProvider.select((tabs) => tabs.value.isNotEmpty),
|
||||||
|
);
|
||||||
final viewportToolbarInsets = ref.watch(
|
final viewportToolbarInsets = ref.watch(
|
||||||
browserViewportToolbarInsetsControllerProvider,
|
browserViewportToolbarInsetsControllerProvider,
|
||||||
);
|
);
|
||||||
@@ -38,6 +50,14 @@ class TabsEmptyPlaceholder extends ConsumerWidget {
|
|||||||
).push(context);
|
).push(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> viewTabs() {
|
||||||
|
return const TabViewRoute().push(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> resumeLatestTab() async {
|
||||||
|
await ref.read(tabRepositoryProvider.notifier).resumeLatestTab();
|
||||||
|
}
|
||||||
|
|
||||||
return DecoratedBox(
|
return DecoratedBox(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
@@ -45,12 +65,15 @@ class TabsEmptyPlaceholder extends ConsumerWidget {
|
|||||||
end: Alignment.bottomRight,
|
end: Alignment.bottomRight,
|
||||||
colors: [
|
colors: [
|
||||||
Color.alphaBlend(
|
Color.alphaBlend(
|
||||||
_brandPurple.withValues(alpha: 0.06),
|
_auraPurple.withValues(alpha: 0.38),
|
||||||
colorScheme.surfaceContainerLowest,
|
colorScheme.surfaceContainerLowest,
|
||||||
),
|
),
|
||||||
colorScheme.surface,
|
|
||||||
Color.alphaBlend(
|
Color.alphaBlend(
|
||||||
_brandYellow.withValues(alpha: 0.05),
|
_auraShadow.withValues(alpha: 0.72),
|
||||||
|
colorScheme.surface,
|
||||||
|
),
|
||||||
|
Color.alphaBlend(
|
||||||
|
_auraGold.withValues(alpha: 0.34),
|
||||||
colorScheme.surfaceContainerHigh,
|
colorScheme.surfaceContainerHigh,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -59,25 +82,33 @@ class TabsEmptyPlaceholder extends ConsumerWidget {
|
|||||||
child: Stack(
|
child: Stack(
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: [
|
children: [
|
||||||
Align(
|
const Positioned(
|
||||||
alignment: const Alignment(-0.9, -0.95),
|
top: -70,
|
||||||
|
left: -120,
|
||||||
|
child: _BackdropOrb(width: 400, height: 400, color: _auraPurple),
|
||||||
|
),
|
||||||
|
const Positioned(
|
||||||
|
top: 220,
|
||||||
|
right: -150,
|
||||||
|
child: _BackdropOrb(width: 340, height: 340, color: _auraGold),
|
||||||
|
),
|
||||||
|
const Positioned(
|
||||||
|
bottom: 18,
|
||||||
|
left: -8,
|
||||||
child: _BackdropOrb(
|
child: _BackdropOrb(
|
||||||
size: 220,
|
width: 320,
|
||||||
color: _brandPurple.withValues(alpha: 0.14),
|
height: 320,
|
||||||
|
color: _auraShadowHighlight,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Align(
|
Positioned.fill(
|
||||||
alignment: const Alignment(1.0, -0.35),
|
child: IgnorePointer(
|
||||||
child: _BackdropOrb(
|
child: ClipRect(
|
||||||
size: 180,
|
child: BackdropFilter(
|
||||||
color: _brandYellow.withValues(alpha: 0.14),
|
filter: ImageFilter.blur(sigmaX: 72, sigmaY: 72),
|
||||||
),
|
child: ColoredBox(color: _auraTint.withValues(alpha: 0.12)),
|
||||||
),
|
),
|
||||||
Align(
|
),
|
||||||
alignment: const Alignment(-0.75, 0.9),
|
|
||||||
child: _BackdropOrb(
|
|
||||||
size: 160,
|
|
||||||
color: _brandGrey.withValues(alpha: 0.12),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
LayoutBuilder(
|
LayoutBuilder(
|
||||||
@@ -148,23 +179,25 @@ class TabsEmptyPlaceholder extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
Text(
|
if (!hasTabs) ...[
|
||||||
'WebLibre is ready',
|
Text(
|
||||||
textAlign: TextAlign.center,
|
'WebLibre is ready',
|
||||||
style: theme.textTheme.headlineSmall?.copyWith(
|
textAlign: TextAlign.center,
|
||||||
fontWeight: FontWeight.w700,
|
style: theme.textTheme.headlineSmall?.copyWith(
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 10),
|
||||||
const SizedBox(height: 10),
|
Text(
|
||||||
Text(
|
'A browser that respects you. Open a tab and experience the web, libre.',
|
||||||
'A browser that respects you. Open a tab and experience the web, libre.',
|
textAlign: TextAlign.center,
|
||||||
textAlign: TextAlign.center,
|
style: theme.textTheme.bodyLarge?.copyWith(
|
||||||
style: theme.textTheme.bodyLarge?.copyWith(
|
color: colorScheme.onSurfaceVariant,
|
||||||
color: colorScheme.onSurfaceVariant,
|
height: 1.45,
|
||||||
height: 1.45,
|
),
|
||||||
),
|
),
|
||||||
),
|
const SizedBox(height: 28),
|
||||||
const SizedBox(height: 28),
|
],
|
||||||
Container(
|
Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
padding: const EdgeInsets.all(20),
|
padding: const EdgeInsets.all(20),
|
||||||
@@ -238,10 +271,29 @@ class TabsEmptyPlaceholder extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 24),
|
const SizedBox(height: 24),
|
||||||
FilledButton.icon(
|
Wrap(
|
||||||
onPressed: openNewTab,
|
alignment: WrapAlignment.center,
|
||||||
icon: const Icon(Icons.add_rounded),
|
spacing: 12,
|
||||||
label: const Text('Open new tab'),
|
runSpacing: 12,
|
||||||
|
children: [
|
||||||
|
if (hasTabs)
|
||||||
|
OutlinedButton.icon(
|
||||||
|
onPressed: viewTabs,
|
||||||
|
icon: const Icon(Icons.tab_rounded),
|
||||||
|
label: const Text('View tabs'),
|
||||||
|
),
|
||||||
|
FilledButton.icon(
|
||||||
|
onPressed: openNewTab,
|
||||||
|
icon: const Icon(Icons.add_rounded),
|
||||||
|
label: const Text('New tab'),
|
||||||
|
),
|
||||||
|
if (hasTabs)
|
||||||
|
FilledButton.tonalIcon(
|
||||||
|
onPressed: resumeLatestTab,
|
||||||
|
icon: const Icon(Icons.history_rounded),
|
||||||
|
label: const Text('Resume last tab'),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -310,17 +362,22 @@ class _QuoteBlock extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _BackdropOrb extends StatelessWidget {
|
class _BackdropOrb extends StatelessWidget {
|
||||||
final double size;
|
final double width;
|
||||||
|
final double height;
|
||||||
final Color color;
|
final Color color;
|
||||||
|
|
||||||
const _BackdropOrb({required this.size, required this.color});
|
const _BackdropOrb({
|
||||||
|
required this.width,
|
||||||
|
required this.height,
|
||||||
|
required this.color,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return IgnorePointer(
|
return IgnorePointer(
|
||||||
child: Container(
|
child: Container(
|
||||||
width: size,
|
width: width,
|
||||||
height: size,
|
height: height,
|
||||||
decoration: BoxDecoration(shape: BoxShape.circle, color: color),
|
decoration: BoxDecoration(shape: BoxShape.circle, color: color),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
+54
-2
@@ -33,6 +33,7 @@ import 'package:weblibre/features/geckoview/features/browser/presentation/provid
|
|||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_icon.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_icon.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/toolbar_button.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/toolbar_button.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode.dart';
|
||||||
|
import 'package:weblibre/features/user/domain/repositories/general_settings.dart';
|
||||||
import 'package:weblibre/presentation/widgets/uri_breadcrumb.dart';
|
import 'package:weblibre/presentation/widgets/uri_breadcrumb.dart';
|
||||||
|
|
||||||
class CompactAppBarTitle extends ConsumerWidget {
|
class CompactAppBarTitle extends ConsumerWidget {
|
||||||
@@ -41,13 +42,21 @@ class CompactAppBarTitle extends ConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final tabState = ref.watch(selectedTabStateProvider);
|
final tabState = ref.watch(selectedTabStateProvider);
|
||||||
|
final selectedTabType = ref.watch(selectedTabTypeProvider);
|
||||||
|
final settings = ref.watch(generalSettingsWithDefaultsProvider);
|
||||||
final isTabTuneledAsync = ref.watch(isTabTunneledProvider(tabState?.id));
|
final isTabTuneledAsync = ref.watch(isTabTunneledProvider(tabState?.id));
|
||||||
final showSiteSettingsBadge = ref.watch(
|
final showSiteSettingsBadge = ref.watch(
|
||||||
showSiteSettingsBadgeProvider.select((value) => value.value == true),
|
showSiteSettingsBadgeProvider.select((value) => value.value == true),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (tabState == null) {
|
if (tabState == null) {
|
||||||
return const SizedBox.shrink();
|
return _EmptyAppBarAddressField(
|
||||||
|
onTap: () async {
|
||||||
|
await SearchRoute(
|
||||||
|
tabType: selectedTabType ?? settings.effectiveDefaultCreateTabType,
|
||||||
|
).push(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CompactAppBarTitleView(
|
return CompactAppBarTitleView(
|
||||||
@@ -178,13 +187,21 @@ class AppBarTitle extends ConsumerWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final tabState = ref.watch(selectedTabStateProvider);
|
final tabState = ref.watch(selectedTabStateProvider);
|
||||||
|
final selectedTabType = ref.watch(selectedTabTypeProvider);
|
||||||
|
final settings = ref.watch(generalSettingsWithDefaultsProvider);
|
||||||
final isTabTuneledAsync = ref.watch(isTabTunneledProvider(tabState?.id));
|
final isTabTuneledAsync = ref.watch(isTabTunneledProvider(tabState?.id));
|
||||||
final showSiteSettingsBadge = ref.watch(
|
final showSiteSettingsBadge = ref.watch(
|
||||||
showSiteSettingsBadgeProvider.select((value) => value.value == true),
|
showSiteSettingsBadgeProvider.select((value) => value.value == true),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (tabState == null) {
|
if (tabState == null) {
|
||||||
return const SizedBox.shrink();
|
return _EmptyAppBarAddressField(
|
||||||
|
onTap: () async {
|
||||||
|
await SearchRoute(
|
||||||
|
tabType: selectedTabType ?? settings.effectiveDefaultCreateTabType,
|
||||||
|
).push(context);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return AppBarTitleView(
|
return AppBarTitleView(
|
||||||
@@ -360,6 +377,41 @@ class _SecurityStatusIcon extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _EmptyAppBarAddressField extends StatelessWidget {
|
||||||
|
const _EmptyAppBarAddressField({required this.onTap});
|
||||||
|
|
||||||
|
final VoidCallback onTap;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 8),
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: onTap,
|
||||||
|
child: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: theme.colorScheme.surfaceContainerHighest,
|
||||||
|
borderRadius: BorderRadius.circular(24),
|
||||||
|
),
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Text(
|
||||||
|
'Search or enter URL',
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: theme.textTheme.bodyMedium?.copyWith(
|
||||||
|
color: theme.colorScheme.onSurface,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String _searchTextForTab(TabState tabState) {
|
String _searchTextForTab(TabState tabState) {
|
||||||
final searchText = tabState.url.scheme == 'about'
|
final searchText = tabState.url.scheme == 'about'
|
||||||
? ''
|
? ''
|
||||||
|
|||||||
+1
-3
@@ -114,7 +114,6 @@ class BrowserBottomAppBar extends StatelessWidget {
|
|||||||
final colorScheme = Theme.of(context).colorScheme;
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
|
||||||
return Material(
|
return Material(
|
||||||
elevation: 0,
|
|
||||||
shadowColor: Colors.transparent,
|
shadowColor: Colors.transparent,
|
||||||
surfaceTintColor: Colors.transparent,
|
surfaceTintColor: Colors.transparent,
|
||||||
color: colorScheme.surfaceContainer,
|
color: colorScheme.surfaceContainer,
|
||||||
@@ -211,8 +210,7 @@ class BrowserTabBar extends HookConsumerWidget {
|
|||||||
|
|
||||||
final dragStartPosition = useRef(Offset.zero);
|
final dragStartPosition = useRef(Offset.zero);
|
||||||
|
|
||||||
final showTabTitle =
|
final showTabTitle = displayedSheet is! ViewTabsSheet;
|
||||||
selectedTabId != null && displayedSheet is! ViewTabsSheet;
|
|
||||||
|
|
||||||
final backgroundColor =
|
final backgroundColor =
|
||||||
(settings.showContainerUi &&
|
(settings.showContainerUi &&
|
||||||
|
|||||||
+2
-2
@@ -45,7 +45,7 @@ import 'package:weblibre/features/geckoview/features/browser/domain/providers/li
|
|||||||
import 'package:weblibre/features/geckoview/features/browser/domain/services/browser_data.dart';
|
import 'package:weblibre/features/geckoview/features/browser/domain/services/browser_data.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/domain/services/engine_settings_replication.dart';
|
import 'package:weblibre/features/geckoview/features/browser/domain/services/engine_settings_replication.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/domain/services/proxy_settings_replication.dart';
|
import 'package:weblibre/features/geckoview/features/browser/domain/services/proxy_settings_replication.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tabs_empty.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_home.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/history/domain/repositories/history.dart';
|
import 'package:weblibre/features/geckoview/features/history/domain/repositories/history.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/preferences/data/repositories/preference_observer.dart';
|
import 'package:weblibre/features/geckoview/features/preferences/data/repositories/preference_observer.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/pwa/domain/providers.dart';
|
import 'package:weblibre/features/geckoview/features/pwa/domain/providers.dart';
|
||||||
@@ -291,7 +291,7 @@ class _BrowserViewState extends ConsumerState<BrowserView>
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (!hasTab) const Positioned.fill(child: TabsEmptyPlaceholder()),
|
if (!hasTab) const Positioned.fill(child: BrowserHome()),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
+32
-3
@@ -30,6 +30,9 @@ import kotlinx.coroutines.GlobalScope
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import mozilla.components.browser.storage.sync.GlobalPlacesDependencyProvider
|
import mozilla.components.browser.storage.sync.GlobalPlacesDependencyProvider
|
||||||
|
import mozilla.components.browser.session.storage.RecoverableBrowserState
|
||||||
|
import mozilla.components.browser.state.action.RestoreCompleteAction
|
||||||
|
import mozilla.components.browser.state.action.TabListAction
|
||||||
import mozilla.components.browser.state.action.CustomTabListAction
|
import mozilla.components.browser.state.action.CustomTabListAction
|
||||||
import mozilla.components.browser.state.selector.findCustomTab
|
import mozilla.components.browser.state.selector.findCustomTab
|
||||||
import mozilla.components.concept.engine.selection.SelectionActionDelegate
|
import mozilla.components.concept.engine.selection.SelectionActionDelegate
|
||||||
@@ -100,9 +103,31 @@ object GlobalComponents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DelicateCoroutinesApi
|
@DelicateCoroutinesApi
|
||||||
private fun restoreBrowserState(newComponents: Components) =
|
private fun restoreBrowserState(
|
||||||
|
newComponents: Components,
|
||||||
|
restoreTabsWithoutResumingSelection: Boolean,
|
||||||
|
) =
|
||||||
GlobalScope.launch(Dispatchers.Main) {
|
GlobalScope.launch(Dispatchers.Main) {
|
||||||
newComponents.useCases.tabsUseCases.restore(newComponents.core.sessionStorage)
|
if (restoreTabsWithoutResumingSelection) {
|
||||||
|
val restoredState = newComponents.core.sessionStorage.restore { true }
|
||||||
|
|
||||||
|
if (restoredState != null) {
|
||||||
|
newComponents.useCases.tabsUseCases.restore(
|
||||||
|
state = RecoverableBrowserState(
|
||||||
|
tabs = restoredState.tabs,
|
||||||
|
// Intentionally do not resume the previously selected tab during the
|
||||||
|
// first full setup. We restore the tab list, but let startup open in
|
||||||
|
// its neutral/default state instead of jumping back into prior content.
|
||||||
|
selectedTabId = null,
|
||||||
|
),
|
||||||
|
restoreLocation = TabListAction.RestoreAction.RestoreLocation.BEGINNING,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
newComponents.core.store.dispatch(RestoreCompleteAction)
|
||||||
|
} else {
|
||||||
|
newComponents.useCases.tabsUseCases.restore(newComponents.core.sessionStorage)
|
||||||
|
}
|
||||||
|
|
||||||
newComponents.core.sessionStorage.autoSave(newComponents.core.store)
|
newComponents.core.sessionStorage.autoSave(newComponents.core.store)
|
||||||
.periodicallyInForeground(interval = 30, unit = TimeUnit.SECONDS)
|
.periodicallyInForeground(interval = 30, unit = TimeUnit.SECONDS)
|
||||||
@@ -198,7 +223,11 @@ object GlobalComponents {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val restoreJob = restoreBrowserState(newComponents)
|
val isFirstFullSetup = previousMode != ComponentsMode.FULL
|
||||||
|
val restoreJob = restoreBrowserState(
|
||||||
|
newComponents,
|
||||||
|
restoreTabsWithoutResumingSelection = isFirstFullSetup,
|
||||||
|
)
|
||||||
if (previousCustomTabs.isNotEmpty()) {
|
if (previousCustomTabs.isNotEmpty()) {
|
||||||
restoreJob.invokeOnCompletion {
|
restoreJob.invokeOnCompletion {
|
||||||
GlobalScope.launch(Dispatchers.Main) {
|
GlobalScope.launch(Dispatchers.Main) {
|
||||||
|
|||||||
Reference in New Issue
Block a user