topics intermediate

This commit is contained in:
Fabian Freund
2024-08-21 13:36:58 +02:00
parent e75052aa99
commit 7fedbe260c
35 changed files with 2511 additions and 198 deletions
@@ -5,6 +5,7 @@ abstract interface class ITab {
String get id;
Uri get url;
String? get title;
String? get topicId;
Favicon? get favicon;
Uint8List? get screenshot;
}
@@ -1,4 +1,3 @@
import 'package:copy_with_extension/copy_with_extension.dart';
import 'package:fast_equatable/fast_equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
@@ -7,17 +6,14 @@ import 'package:lensai/core/uuid.dart';
import 'package:lensai/domain/entities/web_page_info.dart';
import 'package:lensai/features/web_view/domain/entities/abstract/tab.dart';
part 'web_view_page.g.dart';
typedef PageHistory = ({bool canGoBack, bool canGoForward});
@CopyWith(constructor: '_')
class WebViewPage extends WebPageInfo with FastEquatable implements ITab {
@CopyWithField(immutable: true)
//@CopyWithField(immutable: true)
final Key key;
@override
@CopyWithField(immutable: true)
//@CopyWithField(immutable: true)
final String id;
final InAppWebViewController? controller;
@@ -25,35 +21,40 @@ class WebViewPage extends WebPageInfo with FastEquatable implements ITab {
// ignore: missing_field_in_equatable_props
final SslError? sslError;
@override
final String? topicId;
@override
final Uint8List? screenshot;
final PageHistory pageHistory;
WebViewPage({
String? id,
this.controller,
required super.url,
this.sslError,
super.title,
super.favicon,
this.screenshot,
this.pageHistory = (canGoBack: false, canGoForward: false),
}) : key = GlobalKey(),
id = id ?? uuid.v7();
WebViewPage._({
required this.key,
required this.id,
required this.controller,
required super.url,
required this.sslError,
required super.title,
required this.topicId,
required super.favicon,
required this.screenshot,
required this.pageHistory,
});
WebViewPage.create({
String? id,
this.controller,
required super.url,
this.sslError,
super.title,
this.topicId,
super.favicon,
this.screenshot,
this.pageHistory = (canGoBack: false, canGoForward: false),
}) : key = GlobalKey(),
id = id ?? uuid.v7();
@override
bool get cacheHash => true;
@@ -65,6 +66,7 @@ class WebViewPage extends WebPageInfo with FastEquatable implements ITab {
super.url,
sslError?.toString(),
title,
topicId,
favicon?.toString(),
screenshot,
pageHistory,
@@ -1,127 +0,0 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'web_view_page.dart';
// **************************************************************************
// CopyWithGenerator
// **************************************************************************
abstract class _$WebViewPageCWProxy {
WebViewPage controller(InAppWebViewController? controller);
WebViewPage url(Uri url);
WebViewPage sslError(SslError? sslError);
WebViewPage title(String? title);
WebViewPage favicon(Favicon? favicon);
WebViewPage screenshot(Uint8List? screenshot);
WebViewPage pageHistory(({bool canGoBack, bool canGoForward}) pageHistory);
/// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `WebViewPage(...).copyWith.fieldName(...)` to override fields one at a time with nullification support.
///
/// Usage
/// ```dart
/// WebViewPage(...).copyWith(id: 12, name: "My name")
/// ````
WebViewPage call({
InAppWebViewController? controller,
Uri? url,
SslError? sslError,
String? title,
Favicon? favicon,
Uint8List? screenshot,
({bool canGoBack, bool canGoForward})? pageHistory,
});
}
/// Proxy class for `copyWith` functionality. This is a callable class and can be used as follows: `instanceOfWebViewPage.copyWith(...)`. Additionally contains functions for specific fields e.g. `instanceOfWebViewPage.copyWith.fieldName(...)`
class _$WebViewPageCWProxyImpl implements _$WebViewPageCWProxy {
const _$WebViewPageCWProxyImpl(this._value);
final WebViewPage _value;
@override
WebViewPage controller(InAppWebViewController? controller) =>
this(controller: controller);
@override
WebViewPage url(Uri url) => this(url: url);
@override
WebViewPage sslError(SslError? sslError) => this(sslError: sslError);
@override
WebViewPage title(String? title) => this(title: title);
@override
WebViewPage favicon(Favicon? favicon) => this(favicon: favicon);
@override
WebViewPage screenshot(Uint8List? screenshot) => this(screenshot: screenshot);
@override
WebViewPage pageHistory(({bool canGoBack, bool canGoForward}) pageHistory) =>
this(pageHistory: pageHistory);
@override
/// This function **does support** nullification of nullable fields. All `null` values passed to `non-nullable` fields will be ignored. You can also use `WebViewPage(...).copyWith.fieldName(...)` to override fields one at a time with nullification support.
///
/// Usage
/// ```dart
/// WebViewPage(...).copyWith(id: 12, name: "My name")
/// ````
WebViewPage call({
Object? controller = const $CopyWithPlaceholder(),
Object? url = const $CopyWithPlaceholder(),
Object? sslError = const $CopyWithPlaceholder(),
Object? title = const $CopyWithPlaceholder(),
Object? favicon = const $CopyWithPlaceholder(),
Object? screenshot = const $CopyWithPlaceholder(),
Object? pageHistory = const $CopyWithPlaceholder(),
}) {
return WebViewPage._(
key: _value.key,
id: _value.id,
controller: controller == const $CopyWithPlaceholder()
? _value.controller
// ignore: cast_nullable_to_non_nullable
: controller as InAppWebViewController?,
url: url == const $CopyWithPlaceholder() || url == null
? _value.url
// ignore: cast_nullable_to_non_nullable
: url as Uri,
sslError: sslError == const $CopyWithPlaceholder()
? _value.sslError
// ignore: cast_nullable_to_non_nullable
: sslError as SslError?,
title: title == const $CopyWithPlaceholder()
? _value.title
// ignore: cast_nullable_to_non_nullable
: title as String?,
favicon: favicon == const $CopyWithPlaceholder()
? _value.favicon
// ignore: cast_nullable_to_non_nullable
: favicon as Favicon?,
screenshot: screenshot == const $CopyWithPlaceholder()
? _value.screenshot
// ignore: cast_nullable_to_non_nullable
: screenshot as Uint8List?,
pageHistory:
pageHistory == const $CopyWithPlaceholder() || pageHistory == null
? _value.pageHistory
// ignore: cast_nullable_to_non_nullable
: pageHistory as ({bool canGoBack, bool canGoForward}),
);
}
}
extension $WebViewPageCopyWith on WebViewPage {
/// Returns a callable class that can be used as follows: `instanceOfWebViewPage.copyWith(...)` or like so:`instanceOfWebViewPage.copyWith.fieldName(...)`.
// ignore: library_private_types_in_public_api
_$WebViewPageCWProxy get copyWith => _$WebViewPageCWProxyImpl(this);
}
@@ -15,7 +15,7 @@ class SwitchNewTabController extends _$SwitchNewTabController {
state = const AsyncLoading();
state = await AsyncValue.guard(
() async {
final newTab = WebViewPage(
final newTab = WebViewPage.create(
url: WebUri.uri(url),
);
@@ -7,7 +7,7 @@ part of 'switch_new_tab.dart';
// **************************************************************************
String _$switchNewTabControllerHash() =>
r'a5b8f7fd71c8cb6cc2023b41504e5cd467c5b063';
r'fb831015e4b99d3ae86bd2a88a3c6f4c7004783d';
/// See also [SwitchNewTabController].
@ProviderFor(SwitchNewTabController)
@@ -91,7 +91,7 @@ class WebPageDialog extends HookConsumerWidget {
onDismiss: onDismiss,
),
SimpleDialog(
titlePadding: const EdgeInsets.fromLTRB(24.0, 12.0, 24.0, 0.0),
titlePadding: const EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 0.0),
contentPadding: EdgeInsets.zero,
insetPadding: const EdgeInsets.symmetric(
horizontal: 20.0,
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'package:copy_with_extension/copy_with_extension.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
@@ -37,6 +38,109 @@ const _webViewSupportedSchemes = [
"about",
];
abstract class _WebViewPageCWProxy {
WebViewPage controller(InAppWebViewController? controller);
WebViewPage url(Uri url);
WebViewPage sslError(SslError? sslError);
WebViewPage title(String? title);
WebViewPage topicId(String? topicId);
WebViewPage favicon(Favicon? favicon);
WebViewPage screenshot(Uint8List? screenshot);
WebViewPage pageHistory(({bool canGoBack, bool canGoForward}) pageHistory);
WebViewPage call({
InAppWebViewController? controller,
Uri? url,
SslError? sslError,
String? title,
String? topicId,
Favicon? favicon,
Uint8List? screenshot,
({bool canGoBack, bool canGoForward})? pageHistory,
});
}
class _WebViewPageCWProxyImpl implements _WebViewPageCWProxy {
const _WebViewPageCWProxyImpl(this._value);
final WebViewPage _value;
@override
WebViewPage controller(InAppWebViewController? controller) =>
this(controller: controller);
@override
WebViewPage url(Uri url) => this(url: url);
@override
WebViewPage sslError(SslError? sslError) => this(sslError: sslError);
@override
WebViewPage title(String? title) => this(title: title);
@override
WebViewPage topicId(String? topicId) => this(topicId: topicId);
@override
WebViewPage favicon(Favicon? favicon) => this(favicon: favicon);
@override
WebViewPage screenshot(Uint8List? screenshot) => this(screenshot: screenshot);
@override
WebViewPage pageHistory(({bool canGoBack, bool canGoForward}) pageHistory) =>
this(pageHistory: pageHistory);
@override
WebViewPage call({
Object? controller = const $CopyWithPlaceholder(),
Object? url = const $CopyWithPlaceholder(),
Object? sslError = const $CopyWithPlaceholder(),
Object? title = const $CopyWithPlaceholder(),
Object? topicId = const $CopyWithPlaceholder(),
Object? favicon = const $CopyWithPlaceholder(),
Object? screenshot = const $CopyWithPlaceholder(),
Object? pageHistory = const $CopyWithPlaceholder(),
}) {
return WebViewPage(
key: _value.key,
id: _value.id,
controller: controller == const $CopyWithPlaceholder()
? _value.controller
: controller as InAppWebViewController?,
url: url == const $CopyWithPlaceholder() || url == null
? _value.url
: url as Uri,
sslError: sslError == const $CopyWithPlaceholder()
? _value.sslError
: sslError as SslError?,
title: title == const $CopyWithPlaceholder()
? _value.title
: title as String?,
topicId: topicId == const $CopyWithPlaceholder()
? _value.topicId
: topicId as String?,
favicon: favicon == const $CopyWithPlaceholder()
? _value.favicon
: favicon as Favicon?,
screenshot: screenshot == const $CopyWithPlaceholder()
? _value.screenshot
: screenshot as Uint8List?,
pageHistory:
pageHistory == const $CopyWithPlaceholder() || pageHistory == null
? _value.pageHistory
: pageHistory as ({bool canGoBack, bool canGoForward}),
);
}
}
class WebView extends StatefulHookConsumerWidget {
final String tabId;
@@ -48,10 +152,6 @@ class WebView extends StatefulHookConsumerWidget {
InAppWebViewController? get currentController =>
_pageNotifier.value.controller;
void updatePage(WebViewPage Function(WebViewPage page) update) {
_pageNotifier.value = update(_pageNotifier.value);
}
WebView({required WebViewPage tab})
: _pageNotifier = ValueNotifier(tab),
tabId = tab.id,
@@ -65,6 +165,13 @@ class _WebViewState extends ConsumerState<WebView> {
Timer? _onLoadStopDebounce;
Timer? _periodicScreenshotUpdate;
void updatePage(
WebViewPage Function(_WebViewPageCWProxyImpl copyWith) update,
) {
final x = widget._pageNotifier.value =
update(_WebViewPageCWProxyImpl(widget._pageNotifier.value));
}
Future<bool> _downloadChat(
DownloadStartRequest downloadStartRequest,
BuildContext context,
@@ -125,9 +232,7 @@ class _WebViewState extends ConsumerState<WebView> {
},
);
widget.updatePage(
(page) => page.copyWith.screenshot(screenshot),
);
updatePage((copyWith) => copyWith.screenshot(screenshot));
}
@override
@@ -286,7 +391,7 @@ class _WebViewState extends ConsumerState<WebView> {
await controller.startSafeBrowsing();
}
widget.updatePage((page) => page.copyWith.controller(controller));
updatePage((copyWith) => copyWith.controller(controller));
},
onReceivedServerTrustAuthRequest: (controller, challenge) async {
final sslError = challenge.protectionSpace.sslError;
@@ -294,7 +399,7 @@ class _WebViewState extends ConsumerState<WebView> {
if (sslError != null && sslError.code != null) {
if (challenge.protectionSpace.host ==
await controller.getUrl().then((value) => value?.host)) {
widget.updatePage((page) => page.copyWith.sslError(sslError));
updatePage((copyWith) => copyWith.sslError(sslError));
if (context.mounted) {
ui_helper.showErrorMessage(
context,
@@ -309,7 +414,7 @@ class _WebViewState extends ConsumerState<WebView> {
);
}
widget.updatePage((page) => page.copyWith.sslError(null));
updatePage((copyWith) => copyWith.sslError(null));
return ServerTrustAuthResponse(
action: ServerTrustAuthResponseAction.PROCEED,
);
@@ -371,8 +476,8 @@ class _WebViewState extends ConsumerState<WebView> {
);
if (url != null) {
widget.updatePage(
(page) => page.copyWith(
updatePage(
(copyWith) => copyWith(
url: url,
// ignore: avoid_redundant_argument_values
sslError: null,
@@ -384,7 +489,7 @@ class _WebViewState extends ConsumerState<WebView> {
},
onLoadStop: (controller, url) async {
if (url != null) {
widget.updatePage((page) => page.copyWith.url(url));
updatePage((copyWith) => copyWith.url(url));
}
_onLoadStopDebounce?.cancel();
@@ -417,7 +522,7 @@ class _WebViewState extends ConsumerState<WebView> {
canGoForward: await controller.canGoForward()
);
widget.updatePage((page) => page.copyWith.pageHistory(history));
updatePage((copyWith) => copyWith.pageHistory(history));
}
},
shouldOverrideUrlLoading: (controller, navigationAction) async {
@@ -488,7 +593,7 @@ class _WebViewState extends ConsumerState<WebView> {
}
},
onTitleChanged: (controller, title) {
widget.updatePage((page) => page.copyWith.title(title));
updatePage((copyWith) => copyWith.title(title));
},
onDownloadStartRequest: (controller, downloadStartRequest) async {
final handled = switch (downloadStartRequest.mimeType) {