intermediate
This commit is contained in:
@@ -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() {}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:lensai/features/search_browser/domain/entities/sheet.dart';
|
||||
import 'package:lensai/features/search_browser/domain/services/create_tab.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
part 'bottom_sheet.g.dart';
|
||||
|
||||
@Riverpod()
|
||||
class BottomSheetController extends _$BottomSheetController {
|
||||
@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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'bottom_sheet.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$bottomSheetControllerHash() =>
|
||||
r'ae91f911fc35fdc0dfb14149ac2295e58ad13a86';
|
||||
|
||||
/// See also [BottomSheetController].
|
||||
@ProviderFor(BottomSheetController)
|
||||
final bottomSheetControllerProvider =
|
||||
AutoDisposeNotifierProvider<BottomSheetController, Sheet?>.internal(
|
||||
BottomSheetController.new,
|
||||
name: r'bottomSheetControllerProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$bottomSheetControllerHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$BottomSheetController = 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>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
@@ -0,0 +1,20 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'overlay_dialog.g.dart';
|
||||
|
||||
@Riverpod()
|
||||
class OverlayDialogController extends _$OverlayDialogController {
|
||||
@override
|
||||
Widget? build() {
|
||||
return null;
|
||||
}
|
||||
|
||||
void show(Widget dialog) {
|
||||
state = dialog;
|
||||
}
|
||||
|
||||
void dismiss() {
|
||||
state = null;
|
||||
}
|
||||
}
|
||||
+11
-10
@@ -1,26 +1,27 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'session.dart';
|
||||
part of 'overlay_dialog.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$sessionServiceHash() => r'fd2cd03bbf2dd254bb19e541c71a6fb249f5a7bb';
|
||||
String _$overlayDialogControllerHash() =>
|
||||
r'53b44d9567bcb5bd9faecbfb8bb1af5aafb369c9';
|
||||
|
||||
/// See also [SessionService].
|
||||
@ProviderFor(SessionService)
|
||||
final sessionServiceProvider =
|
||||
AutoDisposeNotifierProvider<SessionService, void>.internal(
|
||||
SessionService.new,
|
||||
name: r'sessionServiceProvider',
|
||||
/// See also [OverlayDialogController].
|
||||
@ProviderFor(OverlayDialogController)
|
||||
final overlayDialogControllerProvider =
|
||||
AutoDisposeNotifierProvider<OverlayDialogController, Widget?>.internal(
|
||||
OverlayDialogController.new,
|
||||
name: r'overlayDialogControllerProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$sessionServiceHash,
|
||||
: _$overlayDialogControllerHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$SessionService = AutoDisposeNotifier<void>;
|
||||
typedef _$OverlayDialogController = AutoDisposeNotifier<Widget?>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
@@ -2,25 +2,25 @@ import 'package:collection/collection.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:lensai/features/topics/domain/repositories/topic.dart';
|
||||
import 'package:lensai/features/web_view/domain/entities/web_view_page.dart';
|
||||
import 'package:lensai/features/web_view/domain/repositories/web_view.dart';
|
||||
import 'package:lensai/features/web_view/presentation/widgets/favicon.dart';
|
||||
import 'package:lensai/features/geckoview/domain/entities/tab_state.dart';
|
||||
import 'package:lensai/features/geckoview/domain/providers.dart';
|
||||
import 'package:lensai/features/geckoview/features/topics/domain/repositories/topic.dart';
|
||||
|
||||
class TabActionDialog extends HookConsumerWidget {
|
||||
final WebViewPage initialTab;
|
||||
final String tabId;
|
||||
|
||||
final void Function()? onDismiss;
|
||||
|
||||
const TabActionDialog({
|
||||
required this.initialTab,
|
||||
required this.tabId,
|
||||
this.onDismiss,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final tabState = ref.watch(tabStateProvider(initialTab.id)) ?? initialTab;
|
||||
final tabState =
|
||||
ref.watch(tabStateProvider(tabId)) ?? TabState.$default(tabId);
|
||||
final topics =
|
||||
ref.watch(topicRepositoryProvider.select((value) => value.valueOrNull));
|
||||
final selectedTopic =
|
||||
@@ -42,13 +42,13 @@ class TabActionDialog extends HookConsumerWidget {
|
||||
vertical: 24.0,
|
||||
),
|
||||
title: ListTile(
|
||||
leading: FaviconImage(
|
||||
favicon: tabState.favicon,
|
||||
url: tabState.url,
|
||||
size: 24,
|
||||
leading: RawImage(
|
||||
image: tabState.icon?.value,
|
||||
width: 24,
|
||||
height: 24,
|
||||
),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Text(tabState.title ?? 'Unknown Title'),
|
||||
title: Text(tabState.title),
|
||||
subtitle: Text(tabState.url.authority),
|
||||
),
|
||||
children: [
|
||||
|
||||
@@ -7,11 +7,12 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.dart
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:lensai/core/routing/routes.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/providers.dart';
|
||||
import 'package:lensai/features/search_browser/domain/services/create_tab.dart';
|
||||
import 'package:lensai/features/search_browser/domain/services/session.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/controllers/bottom_sheet.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/controllers/overlay_dialog.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/widgets/app_bar_title.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/widgets/landing/content.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/widgets/sheets/shared_content_sheet.dart';
|
||||
@@ -19,11 +20,6 @@ import 'package:lensai/features/search_browser/presentation/widgets/sheets/view_
|
||||
import 'package:lensai/features/search_browser/presentation/widgets/tabs_action_button.dart';
|
||||
import 'package:lensai/features/settings/data/models/settings.dart';
|
||||
import 'package:lensai/features/settings/data/repositories/settings_repository.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/controllers/readerability.dart';
|
||||
import 'package:lensai/features/web_view/presentation/controllers/switch_new_tab.dart';
|
||||
import 'package:lensai/features/web_view/presentation/widgets/web_page_dialog.dart';
|
||||
import 'package:lensai/presentation/hooks/overlay_portal_controller.dart';
|
||||
import 'package:lensai/presentation/widgets/animate_gradient_shader.dart';
|
||||
import 'package:lensai/presentation/widgets/animated_indexed_stack.dart';
|
||||
@@ -41,8 +37,8 @@ class KagiScreen extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final displayedSheet = ref.watch(bottomSheetProvider);
|
||||
final displayedOverlayDialog = ref.watch(overlayDialogProvider);
|
||||
final displayedSheet = ref.watch(bottomSheetControllerProvider);
|
||||
final displayedOverlayDialog = ref.watch(overlayDialogControllerProvider);
|
||||
|
||||
final showEarlyAccessFeatures = ref.watch(
|
||||
settingsRepositoryProvider.select(
|
||||
@@ -75,7 +71,7 @@ class KagiScreen extends HookConsumerWidget {
|
||||
final activeKagiTool = useValueNotifier<KagiTool?>(null, [displayedSheet]);
|
||||
|
||||
ref.listen(
|
||||
overlayDialogProvider,
|
||||
overlayDialogControllerProvider,
|
||||
(previous, next) {
|
||||
if (next != null) {
|
||||
overlayController.show();
|
||||
@@ -109,7 +105,7 @@ class KagiScreen extends HookConsumerWidget {
|
||||
|
||||
return (page != null)
|
||||
? AppBarTitle(
|
||||
page: page,
|
||||
tab: page,
|
||||
onTap: () {
|
||||
ref.read(overlayDialogProvider.notifier).show(
|
||||
WebPageDialog(
|
||||
@@ -149,7 +145,8 @@ class KagiScreen extends HookConsumerWidget {
|
||||
ref
|
||||
.read(createTabStreamProvider.notifier)
|
||||
.createTab(
|
||||
CreateTab(preferredTool: KagiTool.search),
|
||||
CreateTabSheet(
|
||||
preferredTool: KagiTool.search),
|
||||
);
|
||||
},
|
||||
icon: Icon(KagiTool.search.icon),
|
||||
@@ -162,7 +159,8 @@ class KagiScreen extends HookConsumerWidget {
|
||||
ref
|
||||
.read(createTabStreamProvider.notifier)
|
||||
.createTab(
|
||||
CreateTab(preferredTool: KagiTool.summarizer),
|
||||
CreateTabSheet(
|
||||
preferredTool: KagiTool.summarizer),
|
||||
);
|
||||
},
|
||||
icon: Icon(KagiTool.summarizer.icon),
|
||||
@@ -176,7 +174,7 @@ class KagiScreen extends HookConsumerWidget {
|
||||
ref
|
||||
.read(createTabStreamProvider.notifier)
|
||||
.createTab(
|
||||
CreateTab(
|
||||
CreateTabSheet(
|
||||
preferredTool: KagiTool.assistant,
|
||||
),
|
||||
);
|
||||
@@ -278,7 +276,7 @@ class KagiScreen extends HookConsumerWidget {
|
||||
if (quickAction != null)
|
||||
InkWell(
|
||||
onTap: () async {
|
||||
var tab = CreateTab(
|
||||
var tab = CreateTabSheet(
|
||||
preferredTool: quickAction,
|
||||
);
|
||||
|
||||
@@ -303,7 +301,7 @@ class KagiScreen extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
tab = CreateTab(
|
||||
tab = CreateTabSheet(
|
||||
preferredTool: quickAction,
|
||||
content: await completer.future,
|
||||
);
|
||||
@@ -320,12 +318,12 @@ class KagiScreen extends HookConsumerWidget {
|
||||
),
|
||||
),
|
||||
TabsActionButton(
|
||||
isActive: displayedSheet is ViewTabs,
|
||||
isActive: displayedSheet is ViewTabsSheet,
|
||||
onTap: () {
|
||||
if (displayedSheet case ViewTabs()) {
|
||||
if (displayedSheet case ViewTabsSheet()) {
|
||||
ref.read(bottomSheetProvider.notifier).dismiss();
|
||||
} else {
|
||||
ref.read(bottomSheetProvider.notifier).show(ViewTabs());
|
||||
ref.read(bottomSheetProvider.notifier).show(ViewTabsSheet());
|
||||
}
|
||||
},
|
||||
),
|
||||
@@ -387,7 +385,7 @@ class KagiScreen extends HookConsumerWidget {
|
||||
MenuItemButton(
|
||||
onPressed: () {
|
||||
ref.read(createTabStreamProvider.notifier).createTab(
|
||||
CreateTab(preferredTool: KagiTool.assistant),
|
||||
CreateTabSheet(preferredTool: KagiTool.assistant),
|
||||
);
|
||||
},
|
||||
leadingIcon: Icon(KagiTool.assistant.icon),
|
||||
@@ -396,7 +394,7 @@ class KagiScreen extends HookConsumerWidget {
|
||||
MenuItemButton(
|
||||
onPressed: () {
|
||||
ref.read(createTabStreamProvider.notifier).createTab(
|
||||
CreateTab(preferredTool: KagiTool.summarizer),
|
||||
CreateTabSheet(preferredTool: KagiTool.summarizer),
|
||||
);
|
||||
},
|
||||
leadingIcon: Icon(KagiTool.summarizer.icon),
|
||||
@@ -405,7 +403,7 @@ class KagiScreen extends HookConsumerWidget {
|
||||
MenuItemButton(
|
||||
onPressed: () {
|
||||
ref.read(createTabStreamProvider.notifier).createTab(
|
||||
CreateTab(preferredTool: KagiTool.search),
|
||||
CreateTabSheet(preferredTool: KagiTool.search),
|
||||
);
|
||||
},
|
||||
leadingIcon: Icon(KagiTool.search.icon),
|
||||
@@ -649,7 +647,7 @@ class KagiScreen extends HookConsumerWidget {
|
||||
return false;
|
||||
},
|
||||
child: switch (displayedSheet) {
|
||||
ViewTabs() => DraggableScrollableSheet(
|
||||
ViewTabsSheet() => DraggableScrollableSheet(
|
||||
key: ValueKey(displayedSheet),
|
||||
expand: false,
|
||||
minChildSize: 0.1,
|
||||
@@ -669,7 +667,7 @@ class KagiScreen extends HookConsumerWidget {
|
||||
);
|
||||
},
|
||||
),
|
||||
final CreateTab parameter => DraggableScrollableSheet(
|
||||
final CreateTabSheet parameter => DraggableScrollableSheet(
|
||||
key: ValueKey(displayedSheet),
|
||||
expand: false,
|
||||
initialChildSize: 0.8,
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||
import 'package:lensai/features/web_view/domain/entities/web_view_page.dart';
|
||||
import 'package:lensai/features/web_view/presentation/widgets/favicon.dart';
|
||||
import 'package:lensai/features/geckoview/domain/entities/tab_state.dart';
|
||||
import 'package:text_scroll/text_scroll.dart';
|
||||
|
||||
class AppBarTitle extends StatelessWidget {
|
||||
final WebViewPage page;
|
||||
final TabState tab;
|
||||
|
||||
final void Function()? onTap;
|
||||
|
||||
const AppBarTitle({required this.page, this.onTap, super.key});
|
||||
const AppBarTitle({required this.tab, this.onTap, super.key});
|
||||
|
||||
Icon _securityStatusIcon(BuildContext context, WebViewPage page) {
|
||||
if (page.url.isScheme('http')) {
|
||||
Icon _securityStatusIcon(BuildContext context) {
|
||||
if (tab.url.isScheme('http')) {
|
||||
return Icon(
|
||||
MdiIcons.lockOff,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
size: 14,
|
||||
);
|
||||
} else if (page.sslError != null) {
|
||||
} else if (!tab.securityInfoState.secure) {
|
||||
return Icon(
|
||||
MdiIcons.lockAlert,
|
||||
color: Theme.of(context).colorScheme.errorContainer,
|
||||
@@ -39,9 +38,10 @@ class AppBarTitle extends StatelessWidget {
|
||||
onTap: onTap,
|
||||
child: Row(
|
||||
children: [
|
||||
FaviconImage(
|
||||
favicon: page.favicon,
|
||||
url: page.url,
|
||||
RawImage(
|
||||
image: tab.icon?.value,
|
||||
height: 16,
|
||||
width: 16,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
@@ -52,8 +52,8 @@ class AppBarTitle extends StatelessWidget {
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
TextScroll(
|
||||
key: ValueKey(page.title),
|
||||
page.title ?? 'New Tab',
|
||||
key: ValueKey(tab.title),
|
||||
tab.title,
|
||||
style: theme.textTheme.bodyLarge
|
||||
?.copyWith(color: theme.colorScheme.onSurface),
|
||||
// mode: TextScrollMode.bouncing,
|
||||
@@ -68,13 +68,13 @@ class AppBarTitle extends StatelessWidget {
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
_securityStatusIcon(context, page),
|
||||
_securityStatusIcon(context),
|
||||
const SizedBox(
|
||||
width: 4,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
page.url.authority,
|
||||
tab.url.authority,
|
||||
style: theme.textTheme.bodyMedium
|
||||
?.copyWith(color: theme.colorScheme.onSurface),
|
||||
),
|
||||
|
||||
@@ -6,7 +6,6 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:lensai/domain/services/app_initialization.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/widgets/error_container.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/widgets/landing/action.dart';
|
||||
import 'package:lensai/features/web_view/presentation/controllers/switch_new_tab.dart';
|
||||
import 'package:lensai/presentation/hooks/cached_future.dart';
|
||||
|
||||
class LandingContent extends HookConsumerWidget {
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ import 'package:expandable_page_view/expandable_page_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.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/presentation/widgets/tabs/assistant_tab.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/widgets/tabs/search_tab.dart';
|
||||
@@ -15,7 +15,7 @@ import 'package:lensai/presentation/hooks/sync_page_tab.dart';
|
||||
typedef OnSubmitUri = void Function(Uri url);
|
||||
|
||||
class SharedContentSheet extends HookConsumerWidget {
|
||||
final CreateTab parameter;
|
||||
final CreateTabSheet parameter;
|
||||
final OnSubmitUri onSubmit;
|
||||
final void Function(KagiTool tool)? onActiveToolChanged;
|
||||
|
||||
|
||||
@@ -4,14 +4,10 @@ import 'package:fading_scroll/fading_scroll.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:lensai/features/search_browser/domain/providers.dart';
|
||||
import 'package:lensai/features/geckoview/features/topics/domain/providers.dart';
|
||||
import 'package:lensai/features/geckoview/features/topics/domain/repositories/tab_link.dart';
|
||||
import 'package:lensai/features/geckoview/features/topics/presentation/widgets/topic_chips.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/dialogs/tab_action.dart';
|
||||
import 'package:lensai/features/topics/domain/providers.dart';
|
||||
import 'package:lensai/features/topics/domain/repositories/tab.dart';
|
||||
import 'package:lensai/features/topics/presentation/widgets/topic_chips.dart';
|
||||
import 'package:lensai/features/web_view/domain/repositories/web_view.dart';
|
||||
import 'package:lensai/features/web_view/presentation/controllers/switch_new_tab.dart';
|
||||
import 'package:lensai/features/web_view/presentation/widgets/web_view_tab.dart';
|
||||
|
||||
class _SliverHeaderDelagate extends SliverPersistentHeaderDelegate {
|
||||
static const _headerSize = 104.0;
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.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/providers.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/widgets/sheets/shared_content_sheet.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/widgets/speech_to_text_button.dart';
|
||||
|
||||
@@ -9,6 +9,7 @@ import 'package:lensai/features/bangs/domain/repositories/data.dart';
|
||||
import 'package:lensai/features/bangs/presentation/widgets/bang_icon.dart';
|
||||
import 'package:lensai/features/bangs/presentation/widgets/search_field.dart';
|
||||
import 'package:lensai/features/search_browser/domain/providers.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/controllers/bottom_sheet.dart';
|
||||
import 'package:lensai/features/search_browser/presentation/widgets/sheets/shared_content_sheet.dart';
|
||||
import 'package:lensai/features/share_intent/domain/entities/shared_content.dart';
|
||||
import 'package:lensai/presentation/widgets/selectable_chips.dart';
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||
import 'package:flutter_pdf_text/flutter_pdf_text.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.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/presentation/widgets/sheets/shared_content_sheet.dart';
|
||||
import 'package:lensai/features/search_browser/utils/url_builder.dart'
|
||||
as uri_builder;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:lensai/features/web_view/domain/providers.dart';
|
||||
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
||||
|
||||
class TabsActionButton extends HookConsumerWidget {
|
||||
final bool isActive;
|
||||
@@ -17,7 +17,7 @@ class TabsActionButton extends HookConsumerWidget {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
final tabCount =
|
||||
ref.watch(activeTabsProvider.select((tabs) => tabs.length));
|
||||
ref.watch(tabRepositoryProvider.select((tabs) => tabs.length));
|
||||
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import 'package:lensai/features/search_browser/domain/entities/modes.dart';
|
||||
import 'package:lensai/features/kagi/data/entities/modes.dart';
|
||||
import 'package:lensai/features/share_intent/domain/entities/shared_content.dart';
|
||||
|
||||
final _baseUrl = Uri.https('kagi.com');
|
||||
|
||||
Reference in New Issue
Block a user