intermediate
This commit is contained in:
@@ -2,7 +2,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||
import 'package:lensai/core/logger.dart';
|
||||
import 'package:lensai/features/bangs/domain/providers.dart';
|
||||
import 'package:lensai/features/bangs/domain/providers/bangs.dart';
|
||||
import 'package:lensai/features/geckoview/domain/providers/tab_session.dart';
|
||||
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
||||
import 'package:riverpod/riverpod.dart';
|
||||
@@ -22,7 +22,7 @@ GeckoSelectionActionService selectionActionService(
|
||||
service.setActions([
|
||||
SearchAction((text) async {
|
||||
final defaultSearchBang =
|
||||
await ref.read(kagiSearchBangDataProvider.future);
|
||||
await ref.read(defaultSearchBangDataProvider.future);
|
||||
|
||||
if (defaultSearchBang != null) {
|
||||
await ref
|
||||
@@ -34,7 +34,7 @@ GeckoSelectionActionService selectionActionService(
|
||||
}),
|
||||
PrivateSearchAction((text) async {
|
||||
final defaultSearchBang =
|
||||
await ref.read(kagiSearchBangDataProvider.future);
|
||||
await ref.read(defaultSearchBangDataProvider.future);
|
||||
|
||||
if (defaultSearchBang != null) {
|
||||
await ref.read(tabRepositoryProvider.notifier).addTab(
|
||||
@@ -96,6 +96,17 @@ GeckoAddonService addonService(Ref ref) {
|
||||
return service;
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
GeckoTabContentService tabContentService(Ref ref) {
|
||||
final service = GeckoTabContentService.setUp();
|
||||
|
||||
ref.onDispose(() {
|
||||
service.dispose();
|
||||
});
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class EngineReadyState extends _$EngineReadyState {
|
||||
@override
|
||||
@@ -133,5 +144,5 @@ class EngineReadyState extends _$EngineReadyState {
|
||||
|
||||
@Riverpod()
|
||||
Raw<TabSession> selectedTabSessionNotifier(Ref ref) {
|
||||
return ref.watch(tabSessionProvider(null).notifier);
|
||||
return ref.watch(tabSessionProvider(tabId: null).notifier);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ part of 'providers.dart';
|
||||
// **************************************************************************
|
||||
|
||||
String _$selectionActionServiceHash() =>
|
||||
r'b5bc6b2bc5496ae84d61a74cc6ff052b55d2a3d3';
|
||||
r'd0c04262171976c21441297706273417e3d79b67';
|
||||
|
||||
/// See also [selectionActionService].
|
||||
@ProviderFor(selectionActionService)
|
||||
@@ -57,8 +57,25 @@ final addonServiceProvider = Provider<GeckoAddonService>.internal(
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
typedef AddonServiceRef = ProviderRef<GeckoAddonService>;
|
||||
String _$tabContentServiceHash() => r'd9a991add907ecc138c62790883e59d8e9aa9266';
|
||||
|
||||
/// See also [tabContentService].
|
||||
@ProviderFor(tabContentService)
|
||||
final tabContentServiceProvider = Provider<GeckoTabContentService>.internal(
|
||||
tabContentService,
|
||||
name: r'tabContentServiceProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$tabContentServiceHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||
// ignore: unused_element
|
||||
typedef TabContentServiceRef = ProviderRef<GeckoTabContentService>;
|
||||
String _$selectedTabSessionNotifierHash() =>
|
||||
r'62fcd98a915566d55b5bcb297d87d675fe12786d';
|
||||
r'aef19991d5b05a2bb28e8a6ccb57dc75c2f3148f';
|
||||
|
||||
/// See also [selectedTabSessionNotifier].
|
||||
@ProviderFor(selectedTabSessionNotifier)
|
||||
|
||||
@@ -2,22 +2,16 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||
import 'package:lensai/features/geckoview/domain/providers.dart';
|
||||
import 'package:lensai/features/geckoview/features/tabs/data/database/database.dart';
|
||||
import 'package:lensai/features/geckoview/features/tabs/data/providers.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'selected_tab.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class SelectedTab extends _$SelectedTab {
|
||||
late TabDatabase _db;
|
||||
|
||||
@override
|
||||
String? build() {
|
||||
final eventSerivce = ref.watch(eventServiceProvider);
|
||||
|
||||
_db = ref.watch(tabDatabaseProvider);
|
||||
|
||||
ref.listen(
|
||||
fireImmediately: true,
|
||||
engineReadyStateProvider,
|
||||
@@ -31,10 +25,6 @@ class SelectedTab extends _$SelectedTab {
|
||||
final selectedTabSub = eventSerivce.selectedTabEvents.listen(
|
||||
(tabId) async {
|
||||
state = tabId;
|
||||
|
||||
if (tabId != null) {
|
||||
await _db.tabDao.touchTab(tabId, timestamp: DateTime.now());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ part of 'selected_tab.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$selectedTabHash() => r'e49fb1c3938a97f384673e158742e56479aa8a8f';
|
||||
String _$selectedTabHash() => r'f550ac5b471bab8f8e5d75ef4d7669cde769db9a';
|
||||
|
||||
/// See also [SelectedTab].
|
||||
@ProviderFor(SelectedTab)
|
||||
|
||||
@@ -3,22 +3,16 @@ import 'dart:async';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||
import 'package:lensai/features/geckoview/domain/providers.dart';
|
||||
import 'package:lensai/features/geckoview/features/tabs/data/database/database.dart';
|
||||
import 'package:lensai/features/geckoview/features/tabs/data/providers.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'tab_list.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class TabList extends _$TabList {
|
||||
late TabDatabase _db;
|
||||
|
||||
@override
|
||||
List<String> build() {
|
||||
final eventService = ref.watch(eventServiceProvider);
|
||||
|
||||
_db = ref.watch(tabDatabaseProvider);
|
||||
|
||||
ref.listen(
|
||||
fireImmediately: true,
|
||||
engineReadyStateProvider,
|
||||
@@ -32,15 +26,7 @@ class TabList extends _$TabList {
|
||||
final tabListSub = eventService.tabListEvents.listen(
|
||||
(tabs) async {
|
||||
if (!const DeepCollectionEquality().equals(state, tabs)) {
|
||||
//Make sure we only syncing empty lists when there has been tabs
|
||||
//before as security measurement
|
||||
final syncTabs = tabs.isNotEmpty || state.isNotEmpty;
|
||||
|
||||
state = tabs;
|
||||
|
||||
if (syncTabs) {
|
||||
await _db.tabDao.syncTabs(retainTabIds: tabs);
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -6,7 +6,7 @@ part of 'tab_list.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$tabListHash() => r'3c17372cc467736ce1cfba937999acf4de7345ef';
|
||||
String _$tabListHash() => r'039099bfa102a86fd73c0544ea71f93f91e9d352';
|
||||
|
||||
/// See also [TabList].
|
||||
@ProviderFor(TabList)
|
||||
|
||||
@@ -42,7 +42,7 @@ class TabSession extends _$TabSession {
|
||||
}
|
||||
|
||||
@override
|
||||
void build(String? tabId) {
|
||||
void build({required String? tabId}) {
|
||||
_sessionService = (tabId != null)
|
||||
? GeckoSessionService(tabId: tabId)
|
||||
: GeckoSessionService.forActiveTab();
|
||||
|
||||
@@ -6,7 +6,7 @@ part of 'tab_session.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$tabSessionHash() => r'42b44a4d47b9a551d002fdbc6337c14b2c327dde';
|
||||
String _$tabSessionHash() => r'e4fbbcd430037cc01adb799783fb7974a11a27bf';
|
||||
|
||||
/// Copied from Dart SDK
|
||||
class _SystemHash {
|
||||
@@ -32,9 +32,9 @@ class _SystemHash {
|
||||
abstract class _$TabSession extends BuildlessAutoDisposeNotifier<void> {
|
||||
late final String? tabId;
|
||||
|
||||
void build(
|
||||
String? tabId,
|
||||
);
|
||||
void build({
|
||||
required String? tabId,
|
||||
});
|
||||
}
|
||||
|
||||
/// See also [TabSession].
|
||||
@@ -47,11 +47,11 @@ class TabSessionFamily extends Family<void> {
|
||||
const TabSessionFamily();
|
||||
|
||||
/// See also [TabSession].
|
||||
TabSessionProvider call(
|
||||
String? tabId,
|
||||
) {
|
||||
TabSessionProvider call({
|
||||
required String? tabId,
|
||||
}) {
|
||||
return TabSessionProvider(
|
||||
tabId,
|
||||
tabId: tabId,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class TabSessionFamily extends Family<void> {
|
||||
covariant TabSessionProvider provider,
|
||||
) {
|
||||
return call(
|
||||
provider.tabId,
|
||||
tabId: provider.tabId,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -83,9 +83,9 @@ class TabSessionFamily extends Family<void> {
|
||||
class TabSessionProvider
|
||||
extends AutoDisposeNotifierProviderImpl<TabSession, void> {
|
||||
/// See also [TabSession].
|
||||
TabSessionProvider(
|
||||
String? tabId,
|
||||
) : this._internal(
|
||||
TabSessionProvider({
|
||||
required String? tabId,
|
||||
}) : this._internal(
|
||||
() => TabSession()..tabId = tabId,
|
||||
from: tabSessionProvider,
|
||||
name: r'tabSessionProvider',
|
||||
@@ -116,7 +116,7 @@ class TabSessionProvider
|
||||
covariant TabSession notifier,
|
||||
) {
|
||||
return notifier.build(
|
||||
tabId,
|
||||
tabId: tabId,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,10 +2,15 @@ import 'dart:async';
|
||||
|
||||
import 'package:drift/drift.dart';
|
||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||
import 'package:lensai/features/geckoview/domain/entities/tab_state.dart';
|
||||
import 'package:lensai/features/geckoview/domain/providers.dart';
|
||||
import 'package:lensai/features/geckoview/domain/providers/selected_tab.dart';
|
||||
import 'package:lensai/features/geckoview/domain/providers/tab_list.dart';
|
||||
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
||||
import 'package:lensai/features/geckoview/features/tabs/data/database/database.dart';
|
||||
import 'package:lensai/features/geckoview/features/tabs/data/providers.dart';
|
||||
import 'package:lensai/features/geckoview/features/tabs/domain/providers/selected_container.dart';
|
||||
import 'package:lensai/utils/debouncer.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'tab.g.dart';
|
||||
@@ -57,6 +62,10 @@ class TabRepository extends _$TabRepository {
|
||||
@override
|
||||
void build() {
|
||||
final eventSerivce = ref.watch(eventServiceProvider);
|
||||
final tabContentService = ref.watch(tabContentServiceProvider);
|
||||
|
||||
final tabStateDebouncer = Debouncer(const Duration(seconds: 3));
|
||||
Map<String, TabState>? debounceStartValue;
|
||||
|
||||
_db = ref.watch(tabDatabaseProvider);
|
||||
|
||||
@@ -67,8 +76,58 @@ class TabRepository extends _$TabRepository {
|
||||
},
|
||||
);
|
||||
|
||||
final tabContentSub =
|
||||
tabContentService.tabContentStream.listen((content) async {
|
||||
await _db.tabDao.updateTab(
|
||||
content.tabId,
|
||||
extractedContentMarkdown: Value(content.extractedContentMarkdown),
|
||||
extractedContentPlain: Value(content.extractedContentPlain),
|
||||
fullContentMarkdown: Value(content.fullContentMarkdown),
|
||||
fullContentPlain: Value(content.fullContentPlain),
|
||||
);
|
||||
});
|
||||
|
||||
ref.listen(
|
||||
selectedTabProvider,
|
||||
(previous, tabId) async {
|
||||
if (tabId != null) {
|
||||
await _db.tabDao.touchTab(tabId, timestamp: DateTime.now());
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
ref.listen(
|
||||
tabListProvider,
|
||||
(previous, next) async {
|
||||
//Only sync tabs if there has been a previous value or is not empty
|
||||
final syncTabs = next.isNotEmpty || (previous?.isNotEmpty ?? false);
|
||||
|
||||
if (syncTabs) {
|
||||
await _db.tabDao.syncTabs(retainTabIds: next);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
ref.listen(
|
||||
tabStatesProvider,
|
||||
(previous, next) async {
|
||||
//Since state changes occure pretty often and our map always contains
|
||||
//the latest state, we cache the value before starting debouncing and
|
||||
//later diff to that, to avoid frequent database writes
|
||||
if (!tabStateDebouncer.isDebouncing) {
|
||||
debounceStartValue = previous;
|
||||
}
|
||||
|
||||
tabStateDebouncer.eventOccured(() async {
|
||||
await _db.tabDao.updateTabs(debounceStartValue, next);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
ref.onDispose(() {
|
||||
tabStateDebouncer.dispose();
|
||||
unawaited(tabAddedSub.cancel());
|
||||
unawaited(tabContentSub.cancel());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ part of 'tab.dart';
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$tabRepositoryHash() => r'05040223b83cd5ff80afaf89407043a10e4777cb';
|
||||
String _$tabRepositoryHash() => r'b151be1c18d87eff3a15f4b70f4e82fcc11047ec';
|
||||
|
||||
/// See also [TabRepository].
|
||||
@ProviderFor(TabRepository)
|
||||
|
||||
Reference in New Issue
Block a user