intermediate

This commit is contained in:
Fabian Freund
2024-09-13 09:11:06 +02:00
parent 3b047b5d8a
commit 37d2c84d7f
155 changed files with 5666 additions and 1816 deletions
@@ -1,60 +0,0 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
enum KagiTool {
search(MdiIcons.searchWeb),
summarizer(MdiIcons.text),
//Sort early access features last
assistant(MdiIcons.brain);
final IconData icon;
const KagiTool(this.icon);
}
enum AssistantMode {
research(7),
code(5),
chat(4),
custom(6);
final int value;
const AssistantMode(this.value);
}
enum ResearchVariant {
fast(1),
expert(2);
final int value;
const ResearchVariant(this.value);
}
enum ChatModel {
gpt35Turbo('GPT 3.5 Turbo', 1),
gpt4('GPT 4', 2),
gpt4Turbo('GPT 4 Turbo', 7),
gpt4o('GPT 4o', 15),
claude3Haiku('Claude 3 Haiku', 13),
claude3Sonnet('Claude 3 Sonnet', 14),
claude3Opus('Claude 3 Opus', 12),
gemini15Pro('Gemini 1.5 Pro', 8),
mistralSmall('Mistral Small', 10),
mistralLarge('Mistral Large', 11);
final int value;
final String label;
const ChatModel(this.label, this.value);
}
enum SummarizerMode {
keyMoments('takeaway'),
summary('summary');
final String value;
const SummarizerMode(this.value);
}
@@ -1,16 +1,16 @@
import 'package:fast_equatable/fast_equatable.dart';
import 'package:lensai/features/search_browser/domain/entities/modes.dart';
import 'package:lensai/features/kagi/data/entities/modes.dart';
// ignore: missing_override_of_must_be_overridden
sealed class Sheet with FastEquatable {}
class CreateTab extends Sheet {
class CreateTabSheet extends Sheet {
final String? content;
final KagiTool? preferredTool;
bool get hasParameters => content != null || preferredTool != null;
CreateTab({this.content, this.preferredTool});
CreateTabSheet({this.content, this.preferredTool});
@override
bool get cacheHash => true;
@@ -19,7 +19,7 @@ class CreateTab extends Sheet {
List<Object?> get hashParameters => [content, preferredTool];
}
class ViewTabs extends Sheet {
class ViewTabsSheet extends Sheet {
@override
bool get cacheHash => true;
@@ -2,76 +2,16 @@
import 'dart:async';
import 'package:collection/collection.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:lensai/features/bangs/data/models/bang_data.dart';
import 'package:lensai/features/bangs/domain/repositories/data.dart';
import 'package:lensai/features/search_browser/domain/entities/modes.dart';
import 'package:lensai/features/kagi/data/entities/modes.dart';
import 'package:lensai/features/search_browser/domain/entities/sheet.dart';
import 'package:lensai/features/search_browser/domain/services/create_tab.dart';
import 'package:lensai/features/topics/data/database/database.dart';
import 'package:lensai/features/topics/domain/repositories/tab.dart';
import 'package:lensai/features/web_view/domain/repositories/web_view.dart';
import 'package:lensai/features/web_view/presentation/widgets/web_view.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:rxdart/rxdart.dart';
part 'providers.g.dart';
@Riverpod()
class OverlayDialog extends _$OverlayDialog {
@override
Widget? build() {
return null;
}
void show(Widget dialog) {
state = dialog;
}
void dismiss() {
state = null;
}
}
@Riverpod()
class BottomSheet extends _$BottomSheet {
@override
Sheet? build() {
//Don't use select here because it will only fire on new != previous
return ref.watch(createTabStreamProvider).valueOrNull;
}
void show(Sheet sheet) {
state = sheet;
}
void dismiss() {
state = null;
}
}
@Riverpod(keepAlive: true)
class BottomSheetExtend extends _$BottomSheetExtend {
late StreamController<double> _extentStreamController;
void add(double extent) {
_extentStreamController.add(extent);
}
@override
Stream<double> build() {
_extentStreamController = StreamController();
ref.onDispose(() async {
await _extentStreamController.close();
});
return _extentStreamController.stream
.sampleTime(const Duration(milliseconds: 50));
}
}
@Riverpod(keepAlive: true)
class SelectedBangTrigger extends _$SelectedBangTrigger {
void setTrigger(String trigger) {
@@ -143,65 +83,3 @@ class ShowFindInPage extends _$ShowFindInPage {
return false;
}
}
@Riverpod()
class WebViewWidgetCache extends _$WebViewWidgetCache {
final _requestedWidgets = <String>{};
List<TabData> _availableTabs = [];
@override
List<WebView> build() {
ref.listen(
tabRepositoryProvider,
(previous, next) {
if (next.hasValue && next.valueOrNull != null) {
_availableTabs = next.valueOrNull!;
_removeClosedWidgets();
_requestedWidgets.removeWhere(_ensureWidgetCached);
}
},
);
ref.listen(
webViewTabControllerProvider,
(_, tabId) {
if (tabId != null && !_ensureWidgetCached(tabId)) {
_requestedWidgets.add(tabId);
}
},
);
return stateOrNull ?? [];
}
void _removeClosedWidgets() {
state = [...state]..removeWhere(
(element) => !_availableTabs.any((tab) => tab.id == element.tabId),
);
}
bool _ensureWidgetCached(String tabId) {
final index = state.indexWhere((tab) => tab.tabId == tabId);
if (index < 0) {
final tab = _availableTabs.firstWhereOrNull((tab) => tab.id == tabId);
if (tab != null) {
state = [
...state,
WebView(
key: GlobalKey(),
tabId: tabId,
initialUrlRequest: URLRequest(url: WebUri.uri(tab.url)),
),
];
return true;
}
return false;
}
return true;
}
}
@@ -156,53 +156,6 @@ class _SelectedBangDataProviderElement
String? get domain => (origin as SelectedBangDataProvider).domain;
}
String _$overlayDialogHash() => r'7a0376fff0ba12c70a257a47391e7c049dabd36d';
/// See also [OverlayDialog].
@ProviderFor(OverlayDialog)
final overlayDialogProvider =
AutoDisposeNotifierProvider<OverlayDialog, Widget?>.internal(
OverlayDialog.new,
name: r'overlayDialogProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$overlayDialogHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$OverlayDialog = AutoDisposeNotifier<Widget?>;
String _$bottomSheetHash() => r'4040ec50a488b4b12123bedceab6d8620e6abe3d';
/// See also [BottomSheet].
@ProviderFor(BottomSheet)
final bottomSheetProvider =
AutoDisposeNotifierProvider<BottomSheet, Sheet?>.internal(
BottomSheet.new,
name: r'bottomSheetProvider',
debugGetCreateSourceHash:
const bool.fromEnvironment('dart.vm.product') ? null : _$bottomSheetHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$BottomSheet = AutoDisposeNotifier<Sheet?>;
String _$bottomSheetExtendHash() => r'81ae254499d1d7f57309274b0f18747b94d6dda3';
/// See also [BottomSheetExtend].
@ProviderFor(BottomSheetExtend)
final bottomSheetExtendProvider =
StreamNotifierProvider<BottomSheetExtend, double>.internal(
BottomSheetExtend.new,
name: r'bottomSheetExtendProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$bottomSheetExtendHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$BottomSheetExtend = StreamNotifier<double>;
String _$selectedBangTriggerHash() =>
r'b0e12bc95e93d50d04f1c658230cea9f15ff0385';
@@ -411,22 +364,5 @@ final showFindInPageProvider = NotifierProvider<ShowFindInPage, bool>.internal(
);
typedef _$ShowFindInPage = Notifier<bool>;
String _$webViewWidgetCacheHash() =>
r'7d6f769e8c314d9dc579d700d36d6d4c944e600f';
/// See also [WebViewWidgetCache].
@ProviderFor(WebViewWidgetCache)
final webViewWidgetCacheProvider =
AutoDisposeNotifierProvider<WebViewWidgetCache, List<WebView>>.internal(
WebViewWidgetCache.new,
name: r'webViewWidgetCacheProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$webViewWidgetCacheHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$WebViewWidgetCache = AutoDisposeNotifier<List<WebView>>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
@@ -1,9 +1,9 @@
import 'dart:async';
import 'package:collection/collection.dart';
import 'package:lensai/domain/entities/received_parameter.dart';
import 'package:lensai/data/models/received_parameter.dart';
import 'package:lensai/features/app_widget/domain/services/home_widget.dart';
import 'package:lensai/features/search_browser/domain/entities/modes.dart';
import 'package:lensai/features/kagi/data/entities/modes.dart';
import 'package:lensai/features/search_browser/domain/entities/sheet.dart';
import 'package:lensai/features/share_intent/domain/services/sharing_intent.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -11,10 +11,10 @@ import 'package:rxdart/rxdart.dart';
part 'create_tab.g.dart';
final _parameterToCreateTabTransformer =
StreamTransformer<ReceivedParameter, CreateTab>.fromHandlers(
final _parameterToCreateTabSheetTransformer =
StreamTransformer<ReceivedParameter, CreateTabSheet>.fromHandlers(
handleData: (parameter, sink) {
final createTab = CreateTab(
final createTab = CreateTabSheet(
preferredTool: KagiTool.values
.firstWhereOrNull((tool) => tool.name == parameter.tool),
content: parameter.content,
@@ -28,10 +28,10 @@ final _parameterToCreateTabTransformer =
@Riverpod()
class CreateTabStream extends _$CreateTabStream {
late StreamController<CreateTab> _streamController;
late StreamController<CreateTabSheet> _streamController;
@override
Stream<CreateTab> build() {
Stream<CreateTabSheet> build() {
_streamController = StreamController();
ref.onDispose(() async {
await _streamController.close();
@@ -41,13 +41,13 @@ class CreateTabStream extends _$CreateTabStream {
final appWidgetLaunchStream = ref.watch(appWidgetLaunchStreamProvider);
return MergeStream([
sharingItentStream.transform(_parameterToCreateTabTransformer),
appWidgetLaunchStream.transform(_parameterToCreateTabTransformer),
sharingItentStream.transform(_parameterToCreateTabSheetTransformer),
appWidgetLaunchStream.transform(_parameterToCreateTabSheetTransformer),
_streamController.stream,
]);
}
void createTab(CreateTab parameter) {
void createTab(CreateTabSheet parameter) {
_streamController.add(parameter);
}
}
@@ -6,12 +6,12 @@ part of 'create_tab.dart';
// RiverpodGenerator
// **************************************************************************
String _$createTabStreamHash() => r'3e85020edbebf3ec9927dba6d05af9f06a360a14';
String _$createTabStreamHash() => r'05ad914e41e0d346e082e4638afe5fe5a04052f1';
/// See also [CreateTabStream].
@ProviderFor(CreateTabStream)
final createTabStreamProvider =
AutoDisposeStreamNotifierProvider<CreateTabStream, CreateTab>.internal(
AutoDisposeStreamNotifierProvider<CreateTabStream, CreateTabSheet>.internal(
CreateTabStream.new,
name: r'createTabStreamProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
@@ -21,6 +21,6 @@ final createTabStreamProvider =
allTransitiveDependencies: null,
);
typedef _$CreateTabStream = AutoDisposeStreamNotifier<CreateTab>;
typedef _$CreateTabStream = AutoDisposeStreamNotifier<CreateTabSheet>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
@@ -1,49 +0,0 @@
import 'dart:async';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'session.g.dart';
@Riverpod()
class SessionService extends _$SessionService {
final _cookieManager = CookieManager.instance();
Future<void> setKagiSession(String session) async {
await _cookieManager.setCookie(
url: WebUri.uri(Uri.https('kagi.com')),
name: 'kagi_session',
value: session,
domain: 'kagi.com',
isHttpOnly: true,
isSecure: true,
sameSite: HTTPCookieSameSitePolicy.LAX,
);
}
Future<void> clearAllData() async {
await _cookieManager.deleteAllCookies();
final webViewLoaded = Completer<void>();
final headlessWebView = HeadlessInAppWebView(
initialSettings: InAppWebViewSettings(
//Clears all data on (just) Android
incognito: true,
//Clear other stuff
clearCache: true,
clearSessionCache: true,
),
onWebViewCreated: (controller) {
//wait until settings are applied for sure
webViewLoaded.complete();
},
);
unawaited(headlessWebView.run());
await webViewLoaded.future.whenComplete(() => headlessWebView..dispose());
}
@override
void build() {}
}
@@ -1,26 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'session.dart';
// **************************************************************************
// RiverpodGenerator
// **************************************************************************
String _$sessionServiceHash() => r'fd2cd03bbf2dd254bb19e541c71a6fb249f5a7bb';
/// See also [SessionService].
@ProviderFor(SessionService)
final sessionServiceProvider =
AutoDisposeNotifierProvider<SessionService, void>.internal(
SessionService.new,
name: r'sessionServiceProvider',
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
? null
: _$sessionServiceHash,
dependencies: null,
allTransitiveDependencies: null,
);
typedef _$SessionService = AutoDisposeNotifier<void>;
// ignore_for_file: type=lint
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member