added context menu support
This commit is contained in:
@@ -198,6 +198,12 @@
|
|||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
</application>
|
</application>
|
||||||
|
<queries>
|
||||||
|
<intent>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
|
<data android:scheme="*" />
|
||||||
|
</intent>
|
||||||
|
</queries>
|
||||||
<!-- Required to query activities that can process text, see:
|
<!-- Required to query activities that can process text, see:
|
||||||
https://developer.android.com/training/package-visibility and
|
https://developer.android.com/training/package-visibility and
|
||||||
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ part of 'routes.dart';
|
|||||||
TypedGoRoute<WebPageRoute>(name: 'WebPageRoute', path: 'page/:url'),
|
TypedGoRoute<WebPageRoute>(name: 'WebPageRoute', path: 'page/:url'),
|
||||||
TypedGoRoute<SearchRoute>(name: 'SearchRoute', path: 'search/:searchText'),
|
TypedGoRoute<SearchRoute>(name: 'SearchRoute', path: 'search/:searchText'),
|
||||||
TypedGoRoute<TorProxyRoute>(name: 'TorProxyRoute', path: 'tor_proxy'),
|
TypedGoRoute<TorProxyRoute>(name: 'TorProxyRoute', path: 'tor_proxy'),
|
||||||
|
TypedGoRoute<ContextMenuRoute>(
|
||||||
|
name: 'ContextMenuRoute',
|
||||||
|
path: 'context_menu',
|
||||||
|
),
|
||||||
TypedGoRoute<ContainerListRoute>(
|
TypedGoRoute<ContainerListRoute>(
|
||||||
name: 'ContainerListRoute',
|
name: 'ContainerListRoute',
|
||||||
path: 'containers',
|
path: 'containers',
|
||||||
@@ -97,3 +101,17 @@ class ContainerCreateRoute extends GoRouteData {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ContextMenuRoute extends GoRouteData {
|
||||||
|
const ContextMenuRoute();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||||
|
return DialogPage(
|
||||||
|
builder:
|
||||||
|
(_) => ContextMenuDialog(
|
||||||
|
hitResult: HitResultJson.fromJson(state.extra! as String),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import 'package:lensai/features/bangs/presentation/screens/list.dart';
|
|||||||
import 'package:lensai/features/bangs/presentation/screens/search.dart';
|
import 'package:lensai/features/bangs/presentation/screens/search.dart';
|
||||||
import 'package:lensai/features/geckoview/features/browser/presentation/dialogs/web_page_dialog.dart';
|
import 'package:lensai/features/geckoview/features/browser/presentation/dialogs/web_page_dialog.dart';
|
||||||
import 'package:lensai/features/geckoview/features/browser/presentation/screens/browser.dart';
|
import 'package:lensai/features/geckoview/features/browser/presentation/screens/browser.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/context_menu_dialog.dart';
|
||||||
import 'package:lensai/features/geckoview/features/search/presentation/screens/search.dart';
|
import 'package:lensai/features/geckoview/features/search/presentation/screens/search.dart';
|
||||||
import 'package:lensai/features/geckoview/features/tabs/data/models/container_data.dart';
|
import 'package:lensai/features/geckoview/features/tabs/data/models/container_data.dart';
|
||||||
import 'package:lensai/features/geckoview/features/tabs/presentation/screens/container_edit.dart';
|
import 'package:lensai/features/geckoview/features/tabs/presentation/screens/container_edit.dart';
|
||||||
|
|||||||
@@ -227,6 +227,11 @@ RouteBase get $browserRoute => GoRouteData.$route(
|
|||||||
name: 'TorProxyRoute',
|
name: 'TorProxyRoute',
|
||||||
factory: $TorProxyRouteExtension._fromState,
|
factory: $TorProxyRouteExtension._fromState,
|
||||||
),
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'context_menu',
|
||||||
|
name: 'ContextMenuRoute',
|
||||||
|
factory: $ContextMenuRouteExtension._fromState,
|
||||||
|
),
|
||||||
GoRouteData.$route(
|
GoRouteData.$route(
|
||||||
path: 'containers',
|
path: 'containers',
|
||||||
name: 'ContainerListRoute',
|
name: 'ContainerListRoute',
|
||||||
@@ -320,6 +325,24 @@ extension $TorProxyRouteExtension on TorProxyRoute {
|
|||||||
void replace(BuildContext context) => context.replace(location);
|
void replace(BuildContext context) => context.replace(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension $ContextMenuRouteExtension on ContextMenuRoute {
|
||||||
|
static ContextMenuRoute _fromState(GoRouterState state) =>
|
||||||
|
const ContextMenuRoute();
|
||||||
|
|
||||||
|
String get location => GoRouteData.$location(
|
||||||
|
'/context_menu',
|
||||||
|
);
|
||||||
|
|
||||||
|
void go(BuildContext context) => context.go(location);
|
||||||
|
|
||||||
|
Future<T?> push<T>(BuildContext context) => context.push<T>(location);
|
||||||
|
|
||||||
|
void pushReplacement(BuildContext context) =>
|
||||||
|
context.pushReplacement(location);
|
||||||
|
|
||||||
|
void replace(BuildContext context) => context.replace(location);
|
||||||
|
}
|
||||||
|
|
||||||
extension $ContainerListRouteExtension on ContainerListRoute {
|
extension $ContainerListRouteExtension on ContainerListRoute {
|
||||||
static ContainerListRoute _fromState(GoRouterState state) =>
|
static ContainerListRoute _fromState(GoRouterState state) =>
|
||||||
ContainerListRoute();
|
ContainerListRoute();
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import 'package:lensai/data/models/drag_data.dart';
|
|||||||
import 'package:lensai/extensions/media_query.dart';
|
import 'package:lensai/extensions/media_query.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/controllers/bottom_sheet.dart';
|
import 'package:lensai/features/geckoview/domain/controllers/bottom_sheet.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/controllers/overlay.dart';
|
import 'package:lensai/features/geckoview/domain/controllers/overlay.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/providers.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/providers/tab_list.dart';
|
import 'package:lensai/features/geckoview/domain/providers/tab_list.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/providers/tab_session.dart';
|
import 'package:lensai/features/geckoview/domain/providers/tab_session.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
||||||
@@ -17,6 +18,7 @@ import 'package:lensai/features/geckoview/features/browser/presentation/widgets/
|
|||||||
import 'package:lensai/features/geckoview/features/browser/presentation/widgets/browser_modules/browser_view.dart';
|
import 'package:lensai/features/geckoview/features/browser/presentation/widgets/browser_modules/browser_view.dart';
|
||||||
import 'package:lensai/features/geckoview/features/browser/presentation/widgets/draggable_scrollable_header.dart';
|
import 'package:lensai/features/geckoview/features/browser/presentation/widgets/draggable_scrollable_header.dart';
|
||||||
import 'package:lensai/features/geckoview/features/browser/presentation/widgets/sheets/view_tabs.dart';
|
import 'package:lensai/features/geckoview/features/browser/presentation/widgets/sheets/view_tabs.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
import 'package:lensai/features/geckoview/features/find_in_page/presentation/widgets/find_in_page.dart';
|
import 'package:lensai/features/geckoview/features/find_in_page/presentation/widgets/find_in_page.dart';
|
||||||
import 'package:lensai/features/geckoview/features/readerview/presentation/widgets/reader_appearance_button.dart';
|
import 'package:lensai/features/geckoview/features/readerview/presentation/widgets/reader_appearance_button.dart';
|
||||||
import 'package:lensai/features/geckoview/features/tabs/features/chat/presentation/widgets/tab_qa_chat.dart';
|
import 'package:lensai/features/geckoview/features/tabs/features/chat/presentation/widgets/tab_qa_chat.dart';
|
||||||
@@ -29,6 +31,8 @@ class BrowserScreen extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final eventService = ref.watch(eventServiceProvider);
|
||||||
|
|
||||||
final displayedSheet = ref.watch(bottomSheetControllerProvider);
|
final displayedSheet = ref.watch(bottomSheetControllerProvider);
|
||||||
final displayedOverlay = ref.watch(overlayControllerProvider);
|
final displayedOverlay = ref.watch(overlayControllerProvider);
|
||||||
|
|
||||||
@@ -48,6 +52,16 @@ class BrowserScreen extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useOnStreamChange(
|
||||||
|
eventService.longPressEvent,
|
||||||
|
onData: (event) async {
|
||||||
|
await context.push(
|
||||||
|
const ContextMenuRoute().location,
|
||||||
|
extra: event.hitResult.toJson(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
return PopScope(
|
return PopScope(
|
||||||
//We need this for BackButtonListener to work downstream
|
//We need this for BackButtonListener to work downstream
|
||||||
//No direct pop result will be handled here
|
//No direct pop result will be handled here
|
||||||
|
|||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
|
||||||
|
class HitResultConverter {
|
||||||
|
const HitResultConverter();
|
||||||
|
|
||||||
|
Map<String, dynamic> encode(HitResult input) {
|
||||||
|
final (type, data) = switch (input) {
|
||||||
|
final UnknownHitResult result => (result.runtimeType, result.encode()),
|
||||||
|
final ImageHitResult result => (result.runtimeType, result.encode()),
|
||||||
|
final VideoHitResult result => (result.runtimeType, result.encode()),
|
||||||
|
final AudioHitResult result => (result.runtimeType, result.encode()),
|
||||||
|
final ImageSrcHitResult result => (result.runtimeType, result.encode()),
|
||||||
|
final PhoneHitResult result => (result.runtimeType, result.encode()),
|
||||||
|
final EmailHitResult result => (result.runtimeType, result.encode()),
|
||||||
|
final GeoHitResult result => (result.runtimeType, result.encode()),
|
||||||
|
};
|
||||||
|
|
||||||
|
return {'type': type.toString(), 'data': data};
|
||||||
|
}
|
||||||
|
|
||||||
|
HitResult decode(Map<String, dynamic> input) {
|
||||||
|
final {'type': String type, 'data': List<Object?> data} = input;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'UnknownHitResult':
|
||||||
|
return UnknownHitResult.decode(data);
|
||||||
|
case 'ImageHitResult':
|
||||||
|
return ImageHitResult.decode(data);
|
||||||
|
case 'VideoHitResult':
|
||||||
|
return VideoHitResult.decode(data);
|
||||||
|
case 'AudioHitResult':
|
||||||
|
return AudioHitResult.decode(data);
|
||||||
|
case 'ImageSrcHitResult':
|
||||||
|
return ImageSrcHitResult.decode(data);
|
||||||
|
case 'PhoneHitResult':
|
||||||
|
return PhoneHitResult.decode(data);
|
||||||
|
case 'EmailHitResult':
|
||||||
|
return EmailHitResult.decode(data);
|
||||||
|
case 'GeoHitResult':
|
||||||
|
return GeoHitResult.decode(data);
|
||||||
|
default:
|
||||||
|
throw FormatException('Unknown HitResult type: $type');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/domain/converters/hit_result_converter.dart';
|
||||||
|
|
||||||
|
extension HitResultJson on HitResult {
|
||||||
|
String toJson() {
|
||||||
|
const codec = HitResultConverter();
|
||||||
|
return jsonEncode(codec.encode(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
static HitResult fromJson(String json) {
|
||||||
|
const codec = HitResultConverter();
|
||||||
|
return codec.decode(jsonDecode(json) as Map<String, dynamic>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension HitResultX on HitResult {
|
||||||
|
Uri? tryGetLink() {
|
||||||
|
final uri = switch (this) {
|
||||||
|
UnknownHitResult(src: final src) => src,
|
||||||
|
ImageHitResult(src: final src) => src,
|
||||||
|
VideoHitResult(src: final src) => src,
|
||||||
|
AudioHitResult(src: final src) => src,
|
||||||
|
ImageSrcHitResult(src: final src) => src,
|
||||||
|
PhoneHitResult(src: final src) => src,
|
||||||
|
EmailHitResult(src: final src) => src,
|
||||||
|
GeoHitResult(src: final src) => src,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Uri.tryParse(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
String getTitle() {
|
||||||
|
const maxTitleLength = 2500;
|
||||||
|
|
||||||
|
return switch (this) {
|
||||||
|
UnknownHitResult(src: final src) => src,
|
||||||
|
ImageSrcHitResult(uri: final uri) => uri,
|
||||||
|
ImageHitResult(src: final src, title: final title) =>
|
||||||
|
title?.isEmpty ?? true
|
||||||
|
? (src.length > maxTitleLength ? 'image' : src)
|
||||||
|
: title!,
|
||||||
|
VideoHitResult(src: final src, title: final title) =>
|
||||||
|
(title?.isEmpty ?? true) ? src : title!,
|
||||||
|
AudioHitResult(src: final src, title: final title) =>
|
||||||
|
(title?.isEmpty ?? true) ? src : title!,
|
||||||
|
_ => 'about:blank',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get hasSrc => tryGetLink() != null;
|
||||||
|
|
||||||
|
bool isImage() {
|
||||||
|
return (this is ImageHitResult || this is ImageSrcHitResult) && hasSrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isVideoAudio() {
|
||||||
|
return (this is VideoHitResult || this is AudioHitResult) && hasSrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFile() {
|
||||||
|
return this is UnknownHitResult && hasSrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isUri() {
|
||||||
|
return (this is UnknownHitResult && hasSrc) || this is ImageSrcHitResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isHttpLink() {
|
||||||
|
return isUri() &&
|
||||||
|
switch (tryGetLink()?.scheme) {
|
||||||
|
'http' => true,
|
||||||
|
'https' => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isIntent() {
|
||||||
|
return this is UnknownHitResult &&
|
||||||
|
hasSrc &&
|
||||||
|
tryGetLink()?.scheme == 'intent';
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isMailto() {
|
||||||
|
return this is UnknownHitResult &&
|
||||||
|
hasSrc &&
|
||||||
|
tryGetLink()?.scheme == 'mailto';
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/extensions/nullable.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
|
||||||
|
class CopyEmail extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const CopyEmail({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
static bool isSupported(HitResult hitResult) {
|
||||||
|
return hitResult.isMailto();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(MdiIcons.emailMultiple),
|
||||||
|
title: const Text('Share email address'),
|
||||||
|
onTap: () async {
|
||||||
|
final email = hitResult.tryGetLink().mapNotNull((url) => url.host);
|
||||||
|
if (email != null) {
|
||||||
|
await Clipboard.setData(ClipboardData(text: email));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
|
||||||
|
class CopyImage extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const CopyImage({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
static bool isSupported(HitResult hitResult) {
|
||||||
|
return hitResult.isImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(MdiIcons.imageMultiple),
|
||||||
|
title: const Text('Copy image'),
|
||||||
|
onTap: () async {
|
||||||
|
final currentTab = ref.read(selectedTabStateProvider);
|
||||||
|
final url = hitResult.tryGetLink();
|
||||||
|
|
||||||
|
if (currentTab != null && url != null) {
|
||||||
|
await GeckoDownloadsService().copyInternetResource(
|
||||||
|
currentTab.id,
|
||||||
|
url: url,
|
||||||
|
isPrivate: currentTab.isPrivate,
|
||||||
|
referrerUrl: currentTab.url,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/extensions/nullable.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
|
||||||
|
class CopyImageLocation extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const CopyImageLocation({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
static bool isSupported(HitResult hitResult) {
|
||||||
|
return hitResult.isImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(MdiIcons.imageMarker),
|
||||||
|
title: const Text('Copy image location'),
|
||||||
|
onTap: () async {
|
||||||
|
await hitResult.tryGetLink().mapNotNull(
|
||||||
|
(link) => Clipboard.setData(ClipboardData(text: link.toString())),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/extensions/nullable.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
|
||||||
|
class CopyLink extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const CopyLink({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
static bool isSupported(HitResult hitResult) {
|
||||||
|
return hitResult.isUri() || hitResult.isImage() || hitResult.isVideoAudio();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(MdiIcons.contentCopy),
|
||||||
|
title: const Text('Copy link'),
|
||||||
|
onTap: () async {
|
||||||
|
await hitResult.tryGetLink().mapNotNull(
|
||||||
|
(link) => Clipboard.setData(ClipboardData(text: link.toString())),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/extensions/nullable.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
import 'package:lensai/utils/ui_helper.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
class LaunchExternal extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const LaunchExternal({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
static Future<bool> isSupported(HitResult hitResult) async {
|
||||||
|
return hitResult.tryGetLink().mapNotNull((url) => canLaunchUrl(url)) ??
|
||||||
|
false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(Icons.open_in_browser),
|
||||||
|
title: const Text('Launch External'),
|
||||||
|
onTap: () async {
|
||||||
|
await hitResult.tryGetLink().mapNotNull(
|
||||||
|
(url) => launchUrlFeedback(context, url),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/providers/selected_tab.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
|
||||||
|
class OpenImageInNewTab extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const OpenImageInNewTab({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
static bool isSupported(HitResult hitResult) {
|
||||||
|
return hitResult.isImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(MdiIcons.tabPlus),
|
||||||
|
title: const Text('Open image in new tab'),
|
||||||
|
onTap: () async {
|
||||||
|
final currentTabId = ref.read(selectedTabProvider);
|
||||||
|
await ref
|
||||||
|
.read(tabRepositoryProvider.notifier)
|
||||||
|
.addTab(url: hitResult.tryGetLink(), parentId: currentTabId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
|
||||||
|
class OpenInNewTab extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const OpenInNewTab({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
static bool isSupported(HitResult hitResult) {
|
||||||
|
return hitResult.isHttpLink();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(MdiIcons.tabPlus),
|
||||||
|
title: const Text('Open in new tab'),
|
||||||
|
onTap: () async {
|
||||||
|
await ref
|
||||||
|
.read(tabRepositoryProvider.notifier)
|
||||||
|
.addTab(url: hitResult.tryGetLink());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
|
||||||
|
class SaveFile extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const SaveFile({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
static bool isSupported(HitResult hitResult) {
|
||||||
|
return hitResult.isVideoAudio() || hitResult.isFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(MdiIcons.fileDownload),
|
||||||
|
title: const Text('Save file'),
|
||||||
|
onTap: () async {
|
||||||
|
final currentTab = ref.read(selectedTabStateProvider);
|
||||||
|
final url = hitResult.tryGetLink();
|
||||||
|
|
||||||
|
if (currentTab != null && url != null) {
|
||||||
|
await GeckoDownloadsService().requestDownload(
|
||||||
|
currentTab.id,
|
||||||
|
url: url,
|
||||||
|
skipConfirmation: true,
|
||||||
|
isPrivate: currentTab.isPrivate,
|
||||||
|
referrerUrl: currentTab.url,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+38
@@ -0,0 +1,38 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
|
||||||
|
class SaveImage extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const SaveImage({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
static bool isSupported(HitResult hitResult) {
|
||||||
|
return hitResult.isImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(MdiIcons.imageMove),
|
||||||
|
title: const Text('Save image'),
|
||||||
|
onTap: () async {
|
||||||
|
final currentTab = ref.read(selectedTabStateProvider);
|
||||||
|
final url = hitResult.tryGetLink();
|
||||||
|
|
||||||
|
if (currentTab != null && url != null) {
|
||||||
|
await GeckoDownloadsService().requestDownload(
|
||||||
|
currentTab.id,
|
||||||
|
url: url,
|
||||||
|
skipConfirmation: true,
|
||||||
|
isPrivate: currentTab.isPrivate,
|
||||||
|
referrerUrl: currentTab.url,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/extensions/nullable.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
|
||||||
|
class ShareEmail extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const ShareEmail({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
static bool isSupported(HitResult hitResult) {
|
||||||
|
return hitResult.isMailto();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(MdiIcons.emailArrowRight),
|
||||||
|
title: const Text('Share email address'),
|
||||||
|
onTap: () async {
|
||||||
|
final email = hitResult.tryGetLink().mapNotNull((url) => url.path);
|
||||||
|
if (email != null) {
|
||||||
|
await Share.share(email);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
|
||||||
|
class ShareImage extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const ShareImage({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
static bool isSupported(HitResult hitResult) {
|
||||||
|
return hitResult.isImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(MdiIcons.imagePlus),
|
||||||
|
title: const Text('Share image'),
|
||||||
|
onTap: () async {
|
||||||
|
final currentTab = ref.read(selectedTabStateProvider);
|
||||||
|
final url = hitResult.tryGetLink();
|
||||||
|
|
||||||
|
if (currentTab != null && url != null) {
|
||||||
|
await GeckoDownloadsService().shareInternetResource(
|
||||||
|
currentTab.id,
|
||||||
|
url: url,
|
||||||
|
isPrivate: currentTab.isPrivate,
|
||||||
|
referrerUrl: currentTab.url,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/extensions/nullable.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
|
||||||
|
class ShareLink extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const ShareLink({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
static bool isSupported(HitResult hitResult) {
|
||||||
|
return hitResult.isUri() || hitResult.isImage() || hitResult.isVideoAudio();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return ListTile(
|
||||||
|
leading: const Icon(Icons.share),
|
||||||
|
title: const Text('Share link'),
|
||||||
|
onTap: () async {
|
||||||
|
await hitResult.tryGetLink().mapNotNull((url) => Share.shareUri(url));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_auto_size_text/flutter_auto_size_text.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/candidates/copy_email.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/candidates/copy_image.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/candidates/copy_image_location.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/candidates/copy_link.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/candidates/launch_external.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/candidates/open_image_new_tab.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/candidates/open_new_tab.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/candidates/save_file.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/candidates/save_image.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/candidates/share_email.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/candidates/share_image.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/contextmenu/presentation/candidates/share_link.dart';
|
||||||
|
import 'package:lensai/presentation/hooks/cached_future.dart';
|
||||||
|
import 'package:skeletonizer/skeletonizer.dart';
|
||||||
|
|
||||||
|
class ContextMenuDialog extends HookConsumerWidget {
|
||||||
|
final HitResult hitResult;
|
||||||
|
|
||||||
|
const ContextMenuDialog({super.key, required this.hitResult});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return SimpleDialog(
|
||||||
|
title: AutoSizeText(
|
||||||
|
hitResult.getTitle(),
|
||||||
|
minFontSize: 18,
|
||||||
|
maxFontSize: DefaultTextStyle.of(context).style.fontSize,
|
||||||
|
maxLines: 10,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
softWrap: true,
|
||||||
|
),
|
||||||
|
children: [
|
||||||
|
if (OpenInNewTab.isSupported(hitResult))
|
||||||
|
OpenInNewTab(hitResult: hitResult),
|
||||||
|
if (CopyLink.isSupported(hitResult)) CopyLink(hitResult: hitResult),
|
||||||
|
if (SaveFile.isSupported(hitResult)) SaveFile(hitResult: hitResult),
|
||||||
|
if (ShareLink.isSupported(hitResult)) ShareLink(hitResult: hitResult),
|
||||||
|
if (ShareImage.isSupported(hitResult)) ShareImage(hitResult: hitResult),
|
||||||
|
if (OpenImageInNewTab.isSupported(hitResult))
|
||||||
|
OpenImageInNewTab(hitResult: hitResult),
|
||||||
|
if (CopyImage.isSupported(hitResult)) CopyImage(hitResult: hitResult),
|
||||||
|
if (SaveImage.isSupported(hitResult)) SaveImage(hitResult: hitResult),
|
||||||
|
if (CopyImageLocation.isSupported(hitResult))
|
||||||
|
CopyImageLocation(hitResult: hitResult),
|
||||||
|
if (ShareEmail.isSupported(hitResult)) ShareEmail(hitResult: hitResult),
|
||||||
|
if (CopyEmail.isSupported(hitResult)) CopyEmail(hitResult: hitResult),
|
||||||
|
HookBuilder(
|
||||||
|
builder: (context) {
|
||||||
|
final isSupported = useCachedFuture(
|
||||||
|
// ignore: discarded_futures useFuture
|
||||||
|
() => LaunchExternal.isSupported(hitResult),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isSupported.data == false) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Skeletonizer(
|
||||||
|
enabled: isSupported.connectionState != ConnectionState.done,
|
||||||
|
child: LaunchExternal(hitResult: hitResult),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@ dependencies:
|
|||||||
fast_equatable: ^1.1.0
|
fast_equatable: ^1.1.0
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
flutter_auto_size_text: ^4.1.0
|
||||||
flutter_background_service: ^5.1.0
|
flutter_background_service: ^5.1.0
|
||||||
flutter_chat_core:
|
flutter_chat_core:
|
||||||
path: ../../flutter_chat_ui/packages/flutter_chat_core
|
path: ../../flutter_chat_ui/packages/flutter_chat_core
|
||||||
|
|||||||
+3
@@ -9,6 +9,7 @@ import eu.lensai.flutter_mozilla_components.api.GeckoBrowserApiImpl
|
|||||||
import eu.lensai.flutter_mozilla_components.api.GeckoContainerProxyApiImpl
|
import eu.lensai.flutter_mozilla_components.api.GeckoContainerProxyApiImpl
|
||||||
import eu.lensai.flutter_mozilla_components.api.GeckoCookieApiImpl
|
import eu.lensai.flutter_mozilla_components.api.GeckoCookieApiImpl
|
||||||
import eu.lensai.flutter_mozilla_components.api.GeckoDeleteBrowsingDataControllerImpl
|
import eu.lensai.flutter_mozilla_components.api.GeckoDeleteBrowsingDataControllerImpl
|
||||||
|
import eu.lensai.flutter_mozilla_components.api.GeckoDownloadsApiImpl
|
||||||
import eu.lensai.flutter_mozilla_components.api.GeckoEngineSettingsApiImpl
|
import eu.lensai.flutter_mozilla_components.api.GeckoEngineSettingsApiImpl
|
||||||
import eu.lensai.flutter_mozilla_components.api.GeckoFindApiImpl
|
import eu.lensai.flutter_mozilla_components.api.GeckoFindApiImpl
|
||||||
import eu.lensai.flutter_mozilla_components.api.GeckoIconsApiImpl
|
import eu.lensai.flutter_mozilla_components.api.GeckoIconsApiImpl
|
||||||
@@ -24,6 +25,7 @@ import eu.lensai.flutter_mozilla_components.pigeons.GeckoBrowserApi
|
|||||||
import eu.lensai.flutter_mozilla_components.pigeons.GeckoContainerProxyApi
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoContainerProxyApi
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.GeckoCookieApi
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoCookieApi
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.GeckoDeleteBrowsingDataController
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoDeleteBrowsingDataController
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoDownloadsApi
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.GeckoEngineSettingsApi
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoEngineSettingsApi
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.GeckoFindApi
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoFindApi
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.GeckoIconsApi
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoIconsApi
|
||||||
@@ -120,6 +122,7 @@ class FlutterMozillaComponentsPlugin: FlutterPlugin, ActivityAware {
|
|||||||
selectionActionDelegate
|
selectionActionDelegate
|
||||||
))
|
))
|
||||||
GeckoDeleteBrowsingDataController.setUp(_flutterPluginBinding.binaryMessenger, GeckoDeleteBrowsingDataControllerImpl())
|
GeckoDeleteBrowsingDataController.setUp(_flutterPluginBinding.binaryMessenger, GeckoDeleteBrowsingDataControllerImpl())
|
||||||
|
GeckoDownloadsApi.setUp(_flutterPluginBinding.binaryMessenger, GeckoDownloadsApiImpl())
|
||||||
|
|
||||||
ReaderViewEvents.setUp(
|
ReaderViewEvents.setUp(
|
||||||
_flutterPluginBinding.binaryMessenger,
|
_flutterPluginBinding.binaryMessenger,
|
||||||
|
|||||||
+91
@@ -0,0 +1,91 @@
|
|||||||
|
package eu.lensai.flutter_mozilla_components.api
|
||||||
|
|
||||||
|
import android.os.Environment
|
||||||
|
import eu.lensai.flutter_mozilla_components.GlobalComponents
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.DownloadState
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoDownloadsApi
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.ShareInternetResourceState
|
||||||
|
import mozilla.components.browser.state.action.ContentAction
|
||||||
|
import mozilla.components.browser.state.action.CopyInternetResourceAction
|
||||||
|
import mozilla.components.browser.state.action.ShareInternetResourceAction
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
class GeckoDownloadsApiImpl : GeckoDownloadsApi {
|
||||||
|
private val components by lazy {
|
||||||
|
requireNotNull(GlobalComponents.components) { "Components not initialized" }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun requestDownload(tabId: String, state: DownloadState) {
|
||||||
|
components.core.store.dispatch(
|
||||||
|
ContentAction.UpdateDownloadAction(
|
||||||
|
tabId,
|
||||||
|
state.toMozillaDownloadState(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun copyInternetResource(tabId: String, state: ShareInternetResourceState) {
|
||||||
|
components.core.store.dispatch(CopyInternetResourceAction.AddCopyAction(tabId, state.toMozillaShareInternetResourceState()))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shareInternetResource(tabId: String, state: ShareInternetResourceState) {
|
||||||
|
components.core.store.dispatch(ShareInternetResourceAction.AddShareAction(tabId, state.toMozillaShareInternetResourceState()))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ShareInternetResourceState.toMozillaShareInternetResourceState(): mozilla.components.browser.state.state.content.ShareInternetResourceState {
|
||||||
|
return mozilla.components.browser.state.state.content.ShareInternetResourceState(
|
||||||
|
url = url,
|
||||||
|
contentType = contentType,
|
||||||
|
private = private,
|
||||||
|
response = null, // Since Pigeon class doesn't have this field
|
||||||
|
referrerUrl = referrerUrl
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun mozilla.components.browser.state.state.content.ShareInternetResourceState.toPigeonShareInternetResourceState(): eu.lensai.flutter_mozilla_components.pigeons.ShareInternetResourceState {
|
||||||
|
return eu.lensai.flutter_mozilla_components.pigeons.ShareInternetResourceState(
|
||||||
|
url = url,
|
||||||
|
contentType = contentType,
|
||||||
|
private = private,
|
||||||
|
referrerUrl = referrerUrl
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun DownloadState.toMozillaDownloadState(): mozilla.components.browser.state.state.content.DownloadState {
|
||||||
|
return mozilla.components.browser.state.state.content.DownloadState(
|
||||||
|
url = url,
|
||||||
|
fileName = fileName,
|
||||||
|
contentType = contentType,
|
||||||
|
contentLength = contentLength,
|
||||||
|
currentBytesCopied = currentBytesCopied ?: 0L,
|
||||||
|
status = status?.toMozillaStatus() ?: mozilla.components.browser.state.state.content.DownloadState.Status.INITIATED,
|
||||||
|
userAgent = userAgent,
|
||||||
|
destinationDirectory = destinationDirectory ?: Environment.DIRECTORY_DOWNLOADS,
|
||||||
|
directoryPath = directoryPath ?: Environment.getExternalStoragePublicDirectory(
|
||||||
|
destinationDirectory ?: Environment.DIRECTORY_DOWNLOADS
|
||||||
|
).path,
|
||||||
|
referrerUrl = referrerUrl,
|
||||||
|
skipConfirmation = skipConfirmation ?: false,
|
||||||
|
openInApp = openInApp ?: false,
|
||||||
|
id = id ?: UUID.randomUUID().toString(),
|
||||||
|
sessionId = sessionId,
|
||||||
|
private = private ?: false,
|
||||||
|
createdTime = createdTime ?: System.currentTimeMillis(),
|
||||||
|
response = null, // Cannot be mapped from Pigeon model
|
||||||
|
notificationId = notificationId?.toInt()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun eu.lensai.flutter_mozilla_components.pigeons.DownloadStatus.toMozillaStatus(): mozilla.components.browser.state.state.content.DownloadState.Status {
|
||||||
|
return when (this) {
|
||||||
|
eu.lensai.flutter_mozilla_components.pigeons.DownloadStatus.INITIATED -> mozilla.components.browser.state.state.content.DownloadState.Status.INITIATED
|
||||||
|
eu.lensai.flutter_mozilla_components.pigeons.DownloadStatus.DOWNLOADING -> mozilla.components.browser.state.state.content.DownloadState.Status.DOWNLOADING
|
||||||
|
eu.lensai.flutter_mozilla_components.pigeons.DownloadStatus.PAUSED -> mozilla.components.browser.state.state.content.DownloadState.Status.PAUSED
|
||||||
|
eu.lensai.flutter_mozilla_components.pigeons.DownloadStatus.CANCELLED -> mozilla.components.browser.state.state.content.DownloadState.Status.CANCELLED
|
||||||
|
eu.lensai.flutter_mozilla_components.pigeons.DownloadStatus.FAILED -> mozilla.components.browser.state.state.content.DownloadState.Status.FAILED
|
||||||
|
eu.lensai.flutter_mozilla_components.pigeons.DownloadStatus.COMPLETED -> mozilla.components.browser.state.state.content.DownloadState.Status.COMPLETED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+27
@@ -8,7 +8,15 @@ import android.util.Log
|
|||||||
import eu.lensai.flutter_mozilla_components.GlobalComponents
|
import eu.lensai.flutter_mozilla_components.GlobalComponents
|
||||||
import eu.lensai.flutter_mozilla_components.ext.resize
|
import eu.lensai.flutter_mozilla_components.ext.resize
|
||||||
import eu.lensai.flutter_mozilla_components.ext.toWebPBytes
|
import eu.lensai.flutter_mozilla_components.ext.toWebPBytes
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.AudioHitResult
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.EmailHitResult
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.GeckoStateEvents
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoStateEvents
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.GeoHitResult
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.ImageHitResult
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.ImageSrcHitResult
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.PhoneHitResult
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.UnknownHitResult
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.VideoHitResult
|
||||||
import mozilla.components.browser.state.action.BrowserAction
|
import mozilla.components.browser.state.action.BrowserAction
|
||||||
import mozilla.components.browser.state.action.ContentAction
|
import mozilla.components.browser.state.action.ContentAction
|
||||||
import mozilla.components.browser.state.action.LastAccessAction
|
import mozilla.components.browser.state.action.LastAccessAction
|
||||||
@@ -16,6 +24,7 @@ import mozilla.components.browser.state.action.ReaderAction
|
|||||||
import mozilla.components.browser.state.action.TabListAction
|
import mozilla.components.browser.state.action.TabListAction
|
||||||
import mozilla.components.browser.state.action.WebExtensionAction
|
import mozilla.components.browser.state.action.WebExtensionAction
|
||||||
import mozilla.components.browser.state.state.BrowserState
|
import mozilla.components.browser.state.state.BrowserState
|
||||||
|
import mozilla.components.concept.engine.HitResult
|
||||||
import mozilla.components.feature.addons.logger
|
import mozilla.components.feature.addons.logger
|
||||||
import mozilla.components.lib.state.Middleware
|
import mozilla.components.lib.state.Middleware
|
||||||
import mozilla.components.lib.state.MiddlewareContext
|
import mozilla.components.lib.state.MiddlewareContext
|
||||||
@@ -81,6 +90,24 @@ class FlutterEventMiddleware(private val flutterEvents: GeckoStateEvents) : Midd
|
|||||||
) { _ -> }
|
) { _ -> }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
is ContentAction.UpdateHitResultAction -> {
|
||||||
|
runOnUiThread {
|
||||||
|
flutterEvents.onLongPress(
|
||||||
|
System.currentTimeMillis(),
|
||||||
|
action.sessionId,
|
||||||
|
when(val result = action.hitResult) {
|
||||||
|
is HitResult.AUDIO -> AudioHitResult(result.src, result.title)
|
||||||
|
is HitResult.EMAIL -> EmailHitResult(result.src)
|
||||||
|
is HitResult.GEO -> GeoHitResult(result.src)
|
||||||
|
is HitResult.IMAGE -> ImageHitResult(result.src, result.title)
|
||||||
|
is HitResult.IMAGE_SRC -> ImageSrcHitResult(result.src, result.uri)
|
||||||
|
is HitResult.PHONE -> PhoneHitResult(result.src)
|
||||||
|
is HitResult.UNKNOWN -> UnknownHitResult(result.src)
|
||||||
|
is HitResult.VIDEO -> VideoHitResult(result.src, result.title)
|
||||||
|
}
|
||||||
|
) { _ -> }
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
//logger.debug("Event fired: " + action.javaClass.name)
|
//logger.debug("Event fired: " + action.javaClass.name)
|
||||||
}
|
}
|
||||||
|
|||||||
+564
-59
@@ -229,6 +229,31 @@ enum class WebContentIsolationStrategy(val raw: Int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Status that represents every state that a download can be in. */
|
||||||
|
enum class DownloadStatus(val raw: Int) {
|
||||||
|
/** Indicates that the download is in the first state after creation but not yet [DOWNLOADING]. */
|
||||||
|
INITIATED(0),
|
||||||
|
/** Indicates that an [INITIATED] download is now actively being downloaded. */
|
||||||
|
DOWNLOADING(1),
|
||||||
|
/** Indicates that the download that has been [DOWNLOADING] has been paused. */
|
||||||
|
PAUSED(2),
|
||||||
|
/** Indicates that the download that has been [DOWNLOADING] has been cancelled. */
|
||||||
|
CANCELLED(3),
|
||||||
|
/**
|
||||||
|
* Indicates that the download that has been [DOWNLOADING] has moved to failed because
|
||||||
|
* something unexpected has happened.
|
||||||
|
*/
|
||||||
|
FAILED(4),
|
||||||
|
/** Indicates that the [DOWNLOADING] download has been completed. */
|
||||||
|
COMPLETED(5);
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun ofRaw(raw: Int): DownloadStatus? {
|
||||||
|
return values().firstOrNull { it.raw == raw }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translation options that map to the Gecko Translations Options.
|
* Translation options that map to the Gecko Translations Options.
|
||||||
*
|
*
|
||||||
@@ -1187,6 +1212,295 @@ data class AutocompleteResult (
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents all the different supported types of data that can be found from long clicking
|
||||||
|
* an element.
|
||||||
|
*
|
||||||
|
* Generated class from Pigeon that represents data sent in messages.
|
||||||
|
* This class should not be extended by any user class outside of the generated file.
|
||||||
|
*/
|
||||||
|
sealed class HitResult
|
||||||
|
/**
|
||||||
|
* Default type if we're unable to match the type to anything. It may or may not have a src.
|
||||||
|
*
|
||||||
|
* Generated class from Pigeon that represents data sent in messages.
|
||||||
|
*/
|
||||||
|
data class UnknownHitResult (
|
||||||
|
val src: String
|
||||||
|
) : HitResult()
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): UnknownHitResult {
|
||||||
|
val src = pigeonVar_list[0] as String
|
||||||
|
return UnknownHitResult(src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
src,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the HTML element was of type 'HTMLImageElement'.
|
||||||
|
*
|
||||||
|
* Generated class from Pigeon that represents data sent in messages.
|
||||||
|
*/
|
||||||
|
data class ImageHitResult (
|
||||||
|
val src: String,
|
||||||
|
val title: String? = null
|
||||||
|
) : HitResult()
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): ImageHitResult {
|
||||||
|
val src = pigeonVar_list[0] as String
|
||||||
|
val title = pigeonVar_list[1] as String?
|
||||||
|
return ImageHitResult(src, title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
src,
|
||||||
|
title,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the HTML element was of type 'HTMLVideoElement'.
|
||||||
|
*
|
||||||
|
* Generated class from Pigeon that represents data sent in messages.
|
||||||
|
*/
|
||||||
|
data class VideoHitResult (
|
||||||
|
val src: String,
|
||||||
|
val title: String? = null
|
||||||
|
) : HitResult()
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): VideoHitResult {
|
||||||
|
val src = pigeonVar_list[0] as String
|
||||||
|
val title = pigeonVar_list[1] as String?
|
||||||
|
return VideoHitResult(src, title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
src,
|
||||||
|
title,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the HTML element was of type 'HTMLAudioElement'.
|
||||||
|
*
|
||||||
|
* Generated class from Pigeon that represents data sent in messages.
|
||||||
|
*/
|
||||||
|
data class AudioHitResult (
|
||||||
|
val src: String,
|
||||||
|
val title: String? = null
|
||||||
|
) : HitResult()
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): AudioHitResult {
|
||||||
|
val src = pigeonVar_list[0] as String
|
||||||
|
val title = pigeonVar_list[1] as String?
|
||||||
|
return AudioHitResult(src, title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
src,
|
||||||
|
title,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the HTML element was of type 'HTMLImageElement' and contained a URI.
|
||||||
|
*
|
||||||
|
* Generated class from Pigeon that represents data sent in messages.
|
||||||
|
*/
|
||||||
|
data class ImageSrcHitResult (
|
||||||
|
val src: String,
|
||||||
|
val uri: String
|
||||||
|
) : HitResult()
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): ImageSrcHitResult {
|
||||||
|
val src = pigeonVar_list[0] as String
|
||||||
|
val uri = pigeonVar_list[1] as String
|
||||||
|
return ImageSrcHitResult(src, uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
src,
|
||||||
|
uri,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type used if the URI is prepended with 'tel:'.
|
||||||
|
*
|
||||||
|
* Generated class from Pigeon that represents data sent in messages.
|
||||||
|
*/
|
||||||
|
data class PhoneHitResult (
|
||||||
|
val src: String
|
||||||
|
) : HitResult()
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): PhoneHitResult {
|
||||||
|
val src = pigeonVar_list[0] as String
|
||||||
|
return PhoneHitResult(src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
src,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type used if the URI is prepended with 'mailto:'.
|
||||||
|
*
|
||||||
|
* Generated class from Pigeon that represents data sent in messages.
|
||||||
|
*/
|
||||||
|
data class EmailHitResult (
|
||||||
|
val src: String
|
||||||
|
) : HitResult()
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): EmailHitResult {
|
||||||
|
val src = pigeonVar_list[0] as String
|
||||||
|
return EmailHitResult(src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
src,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type used if the URI is prepended with 'geo:'.
|
||||||
|
*
|
||||||
|
* Generated class from Pigeon that represents data sent in messages.
|
||||||
|
*/
|
||||||
|
data class GeoHitResult (
|
||||||
|
val src: String
|
||||||
|
) : HitResult()
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): GeoHitResult {
|
||||||
|
val src = pigeonVar_list[0] as String
|
||||||
|
return GeoHitResult(src)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
src,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
|
data class DownloadState (
|
||||||
|
val url: String,
|
||||||
|
val fileName: String? = null,
|
||||||
|
val contentType: String? = null,
|
||||||
|
val contentLength: Long? = null,
|
||||||
|
val currentBytesCopied: Long? = null,
|
||||||
|
val status: DownloadStatus? = null,
|
||||||
|
val userAgent: String? = null,
|
||||||
|
val destinationDirectory: String? = null,
|
||||||
|
val directoryPath: String? = null,
|
||||||
|
val referrerUrl: String? = null,
|
||||||
|
val skipConfirmation: Boolean? = null,
|
||||||
|
val openInApp: Boolean? = null,
|
||||||
|
val id: String? = null,
|
||||||
|
val sessionId: String? = null,
|
||||||
|
val private: Boolean? = null,
|
||||||
|
val createdTime: Long? = null,
|
||||||
|
val notificationId: Long? = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): DownloadState {
|
||||||
|
val url = pigeonVar_list[0] as String
|
||||||
|
val fileName = pigeonVar_list[1] as String?
|
||||||
|
val contentType = pigeonVar_list[2] as String?
|
||||||
|
val contentLength = pigeonVar_list[3] as Long?
|
||||||
|
val currentBytesCopied = pigeonVar_list[4] as Long?
|
||||||
|
val status = pigeonVar_list[5] as DownloadStatus?
|
||||||
|
val userAgent = pigeonVar_list[6] as String?
|
||||||
|
val destinationDirectory = pigeonVar_list[7] as String?
|
||||||
|
val directoryPath = pigeonVar_list[8] as String?
|
||||||
|
val referrerUrl = pigeonVar_list[9] as String?
|
||||||
|
val skipConfirmation = pigeonVar_list[10] as Boolean?
|
||||||
|
val openInApp = pigeonVar_list[11] as Boolean?
|
||||||
|
val id = pigeonVar_list[12] as String?
|
||||||
|
val sessionId = pigeonVar_list[13] as String?
|
||||||
|
val private = pigeonVar_list[14] as Boolean?
|
||||||
|
val createdTime = pigeonVar_list[15] as Long?
|
||||||
|
val notificationId = pigeonVar_list[16] as Long?
|
||||||
|
return DownloadState(url, fileName, contentType, contentLength, currentBytesCopied, status, userAgent, destinationDirectory, directoryPath, referrerUrl, skipConfirmation, openInApp, id, sessionId, private, createdTime, notificationId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
url,
|
||||||
|
fileName,
|
||||||
|
contentType,
|
||||||
|
contentLength,
|
||||||
|
currentBytesCopied,
|
||||||
|
status,
|
||||||
|
userAgent,
|
||||||
|
destinationDirectory,
|
||||||
|
directoryPath,
|
||||||
|
referrerUrl,
|
||||||
|
skipConfirmation,
|
||||||
|
openInApp,
|
||||||
|
id,
|
||||||
|
sessionId,
|
||||||
|
private,
|
||||||
|
createdTime,
|
||||||
|
notificationId,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Generated class from Pigeon that represents data sent in messages. */
|
||||||
|
data class ShareInternetResourceState (
|
||||||
|
val url: String,
|
||||||
|
val contentType: String? = null,
|
||||||
|
val private: Boolean,
|
||||||
|
val referrerUrl: String? = null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
companion object {
|
||||||
|
fun fromList(pigeonVar_list: List<Any?>): ShareInternetResourceState {
|
||||||
|
val url = pigeonVar_list[0] as String
|
||||||
|
val contentType = pigeonVar_list[1] as String?
|
||||||
|
val private = pigeonVar_list[2] as Boolean
|
||||||
|
val referrerUrl = pigeonVar_list[3] as String?
|
||||||
|
return ShareInternetResourceState(url, contentType, private, referrerUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fun toList(): List<Any?> {
|
||||||
|
return listOf(
|
||||||
|
url,
|
||||||
|
contentType,
|
||||||
|
private,
|
||||||
|
referrerUrl,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
private open class GeckoPigeonCodec : StandardMessageCodec() {
|
private open class GeckoPigeonCodec : StandardMessageCodec() {
|
||||||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
@@ -1256,150 +1570,205 @@ private open class GeckoPigeonCodec : StandardMessageCodec() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
142.toByte() -> {
|
142.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as Long?)?.let {
|
||||||
TranslationOptions.fromList(it)
|
DownloadStatus.ofRaw(it.toInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
143.toByte() -> {
|
143.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
ReaderState.fromList(it)
|
TranslationOptions.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
144.toByte() -> {
|
144.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
LastMediaAccessState.fromList(it)
|
ReaderState.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
145.toByte() -> {
|
145.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
HistoryMetadataKey.fromList(it)
|
LastMediaAccessState.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
146.toByte() -> {
|
146.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
PackageCategoryValue.fromList(it)
|
HistoryMetadataKey.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
147.toByte() -> {
|
147.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
ExternalPackage.fromList(it)
|
PackageCategoryValue.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
148.toByte() -> {
|
148.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
LoadUrlFlagsValue.fromList(it)
|
ExternalPackage.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
149.toByte() -> {
|
149.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
SourceValue.fromList(it)
|
LoadUrlFlagsValue.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
150.toByte() -> {
|
150.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
TabState.fromList(it)
|
SourceValue.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
151.toByte() -> {
|
151.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
RecoverableTab.fromList(it)
|
TabState.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
152.toByte() -> {
|
152.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
RecoverableBrowserState.fromList(it)
|
RecoverableTab.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
153.toByte() -> {
|
153.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
IconRequest.fromList(it)
|
RecoverableBrowserState.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
154.toByte() -> {
|
154.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
ResourceSize.fromList(it)
|
IconRequest.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
155.toByte() -> {
|
155.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
Resource.fromList(it)
|
ResourceSize.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
156.toByte() -> {
|
156.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
IconResult.fromList(it)
|
Resource.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
157.toByte() -> {
|
157.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
CookiePartitionKey.fromList(it)
|
IconResult.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
158.toByte() -> {
|
158.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
Cookie.fromList(it)
|
CookiePartitionKey.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
159.toByte() -> {
|
159.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
HistoryItem.fromList(it)
|
Cookie.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
160.toByte() -> {
|
160.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
HistoryState.fromList(it)
|
HistoryItem.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
161.toByte() -> {
|
161.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
ReaderableState.fromList(it)
|
HistoryState.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
162.toByte() -> {
|
162.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
SecurityInfoState.fromList(it)
|
ReaderableState.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
163.toByte() -> {
|
163.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
TabContentState.fromList(it)
|
SecurityInfoState.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
164.toByte() -> {
|
164.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
FindResultState.fromList(it)
|
TabContentState.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
165.toByte() -> {
|
165.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
CustomSelectionAction.fromList(it)
|
FindResultState.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
166.toByte() -> {
|
166.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
WebExtensionData.fromList(it)
|
CustomSelectionAction.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
167.toByte() -> {
|
167.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
GeckoSuggestion.fromList(it)
|
WebExtensionData.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
168.toByte() -> {
|
168.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
TabContent.fromList(it)
|
GeckoSuggestion.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
169.toByte() -> {
|
169.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
GeckoEngineSettings.fromList(it)
|
TabContent.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
170.toByte() -> {
|
170.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
GeckoEngineSettings.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
171.toByte() -> {
|
||||||
return (readValue(buffer) as? List<Any?>)?.let {
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
AutocompleteResult.fromList(it)
|
AutocompleteResult.fromList(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
172.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
UnknownHitResult.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
173.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
ImageHitResult.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
174.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
VideoHitResult.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
175.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
AudioHitResult.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
176.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
ImageSrcHitResult.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
177.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
PhoneHitResult.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
178.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
EmailHitResult.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
179.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
GeoHitResult.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
180.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
DownloadState.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
181.toByte() -> {
|
||||||
|
return (readValue(buffer) as? List<Any?>)?.let {
|
||||||
|
ShareInternetResourceState.fromList(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> super.readValueOfType(type, buffer)
|
else -> super.readValueOfType(type, buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1457,122 +1826,166 @@ private open class GeckoPigeonCodec : StandardMessageCodec() {
|
|||||||
stream.write(141)
|
stream.write(141)
|
||||||
writeValue(stream, value.raw)
|
writeValue(stream, value.raw)
|
||||||
}
|
}
|
||||||
is TranslationOptions -> {
|
is DownloadStatus -> {
|
||||||
stream.write(142)
|
stream.write(142)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.raw)
|
||||||
}
|
}
|
||||||
is ReaderState -> {
|
is TranslationOptions -> {
|
||||||
stream.write(143)
|
stream.write(143)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is LastMediaAccessState -> {
|
is ReaderState -> {
|
||||||
stream.write(144)
|
stream.write(144)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is HistoryMetadataKey -> {
|
is LastMediaAccessState -> {
|
||||||
stream.write(145)
|
stream.write(145)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is PackageCategoryValue -> {
|
is HistoryMetadataKey -> {
|
||||||
stream.write(146)
|
stream.write(146)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is ExternalPackage -> {
|
is PackageCategoryValue -> {
|
||||||
stream.write(147)
|
stream.write(147)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is LoadUrlFlagsValue -> {
|
is ExternalPackage -> {
|
||||||
stream.write(148)
|
stream.write(148)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is SourceValue -> {
|
is LoadUrlFlagsValue -> {
|
||||||
stream.write(149)
|
stream.write(149)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is TabState -> {
|
is SourceValue -> {
|
||||||
stream.write(150)
|
stream.write(150)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is RecoverableTab -> {
|
is TabState -> {
|
||||||
stream.write(151)
|
stream.write(151)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is RecoverableBrowserState -> {
|
is RecoverableTab -> {
|
||||||
stream.write(152)
|
stream.write(152)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is IconRequest -> {
|
is RecoverableBrowserState -> {
|
||||||
stream.write(153)
|
stream.write(153)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is ResourceSize -> {
|
is IconRequest -> {
|
||||||
stream.write(154)
|
stream.write(154)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is Resource -> {
|
is ResourceSize -> {
|
||||||
stream.write(155)
|
stream.write(155)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is IconResult -> {
|
is Resource -> {
|
||||||
stream.write(156)
|
stream.write(156)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is CookiePartitionKey -> {
|
is IconResult -> {
|
||||||
stream.write(157)
|
stream.write(157)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is Cookie -> {
|
is CookiePartitionKey -> {
|
||||||
stream.write(158)
|
stream.write(158)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is HistoryItem -> {
|
is Cookie -> {
|
||||||
stream.write(159)
|
stream.write(159)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is HistoryState -> {
|
is HistoryItem -> {
|
||||||
stream.write(160)
|
stream.write(160)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is ReaderableState -> {
|
is HistoryState -> {
|
||||||
stream.write(161)
|
stream.write(161)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is SecurityInfoState -> {
|
is ReaderableState -> {
|
||||||
stream.write(162)
|
stream.write(162)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is TabContentState -> {
|
is SecurityInfoState -> {
|
||||||
stream.write(163)
|
stream.write(163)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is FindResultState -> {
|
is TabContentState -> {
|
||||||
stream.write(164)
|
stream.write(164)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is CustomSelectionAction -> {
|
is FindResultState -> {
|
||||||
stream.write(165)
|
stream.write(165)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is WebExtensionData -> {
|
is CustomSelectionAction -> {
|
||||||
stream.write(166)
|
stream.write(166)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is GeckoSuggestion -> {
|
is WebExtensionData -> {
|
||||||
stream.write(167)
|
stream.write(167)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is TabContent -> {
|
is GeckoSuggestion -> {
|
||||||
stream.write(168)
|
stream.write(168)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is GeckoEngineSettings -> {
|
is TabContent -> {
|
||||||
stream.write(169)
|
stream.write(169)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
is AutocompleteResult -> {
|
is GeckoEngineSettings -> {
|
||||||
stream.write(170)
|
stream.write(170)
|
||||||
writeValue(stream, value.toList())
|
writeValue(stream, value.toList())
|
||||||
}
|
}
|
||||||
|
is AutocompleteResult -> {
|
||||||
|
stream.write(171)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is UnknownHitResult -> {
|
||||||
|
stream.write(172)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is ImageHitResult -> {
|
||||||
|
stream.write(173)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is VideoHitResult -> {
|
||||||
|
stream.write(174)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is AudioHitResult -> {
|
||||||
|
stream.write(175)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is ImageSrcHitResult -> {
|
||||||
|
stream.write(176)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is PhoneHitResult -> {
|
||||||
|
stream.write(177)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is EmailHitResult -> {
|
||||||
|
stream.write(178)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is GeoHitResult -> {
|
||||||
|
stream.write(179)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is DownloadState -> {
|
||||||
|
stream.write(180)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
|
is ShareInternetResourceState -> {
|
||||||
|
stream.write(181)
|
||||||
|
writeValue(stream, value.toList())
|
||||||
|
}
|
||||||
else -> super.writeValue(stream, value)
|
else -> super.writeValue(stream, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2988,6 +3401,23 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun onLongPress(timestampArg: Long, idArg: String, hitResultArg: HitResult, callback: (Result<Unit>) -> Unit)
|
||||||
|
{
|
||||||
|
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||||
|
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onLongPress$separatedMessageChannelSuffix"
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
||||||
|
channel.send(listOf(timestampArg, idArg, hitResultArg)) {
|
||||||
|
if (it is List<*>) {
|
||||||
|
if (it.size > 1) {
|
||||||
|
callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?)))
|
||||||
|
} else {
|
||||||
|
callback(Result.success(Unit))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(Result.failure(createConnectionError(channelName)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||||
interface ReaderViewEvents {
|
interface ReaderViewEvents {
|
||||||
@@ -3469,3 +3899,78 @@ interface GeckoDeleteBrowsingDataController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||||
|
interface GeckoDownloadsApi {
|
||||||
|
fun requestDownload(tabId: String, state: DownloadState)
|
||||||
|
fun copyInternetResource(tabId: String, state: ShareInternetResourceState)
|
||||||
|
fun shareInternetResource(tabId: String, state: ShareInternetResourceState)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/** The codec used by GeckoDownloadsApi. */
|
||||||
|
val codec: MessageCodec<Any?> by lazy {
|
||||||
|
GeckoPigeonCodec()
|
||||||
|
}
|
||||||
|
/** Sets up an instance of `GeckoDownloadsApi` to handle messages through the `binaryMessenger`. */
|
||||||
|
@JvmOverloads
|
||||||
|
fun setUp(binaryMessenger: BinaryMessenger, api: GeckoDownloadsApi?, messageChannelSuffix: String = "") {
|
||||||
|
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoDownloadsApi.requestDownload$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { message, reply ->
|
||||||
|
val args = message as List<Any?>
|
||||||
|
val tabIdArg = args[0] as String
|
||||||
|
val stateArg = args[1] as DownloadState
|
||||||
|
val wrapped: List<Any?> = try {
|
||||||
|
api.requestDownload(tabIdArg, stateArg)
|
||||||
|
listOf(null)
|
||||||
|
} catch (exception: Throwable) {
|
||||||
|
wrapError(exception)
|
||||||
|
}
|
||||||
|
reply.reply(wrapped)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoDownloadsApi.copyInternetResource$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { message, reply ->
|
||||||
|
val args = message as List<Any?>
|
||||||
|
val tabIdArg = args[0] as String
|
||||||
|
val stateArg = args[1] as ShareInternetResourceState
|
||||||
|
val wrapped: List<Any?> = try {
|
||||||
|
api.copyInternetResource(tabIdArg, stateArg)
|
||||||
|
listOf(null)
|
||||||
|
} catch (exception: Throwable) {
|
||||||
|
wrapError(exception)
|
||||||
|
}
|
||||||
|
reply.reply(wrapped)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoDownloadsApi.shareInternetResource$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { message, reply ->
|
||||||
|
val args = message as List<Any?>
|
||||||
|
val tabIdArg = args[0] as String
|
||||||
|
val stateArg = args[1] as ShareInternetResourceState
|
||||||
|
val wrapped: List<Any?> = try {
|
||||||
|
api.shareInternetResource(tabIdArg, stateArg)
|
||||||
|
listOf(null)
|
||||||
|
} catch (exception: Throwable) {
|
||||||
|
wrapError(exception)
|
||||||
|
}
|
||||||
|
reply.reply(wrapped)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export 'src/domain/services/gecko_addon.dart';
|
|||||||
export 'src/domain/services/gecko_container_proxy.dart';
|
export 'src/domain/services/gecko_container_proxy.dart';
|
||||||
export 'src/domain/services/gecko_cookie.dart';
|
export 'src/domain/services/gecko_cookie.dart';
|
||||||
export 'src/domain/services/gecko_delete_browser_data.dart';
|
export 'src/domain/services/gecko_delete_browser_data.dart';
|
||||||
|
export 'src/domain/services/gecko_downloads.dart';
|
||||||
export 'src/domain/services/gecko_engine_settings.dart';
|
export 'src/domain/services/gecko_engine_settings.dart';
|
||||||
export 'src/domain/services/gecko_event.dart';
|
export 'src/domain/services/gecko_event.dart';
|
||||||
export 'src/domain/services/gecko_find_in_page.dart';
|
export 'src/domain/services/gecko_find_in_page.dart';
|
||||||
@@ -20,22 +21,31 @@ export 'src/domain/services/gecko_tab_content.dart';
|
|||||||
export 'src/geckoview_widget.dart';
|
export 'src/geckoview_widget.dart';
|
||||||
export 'src/pigeons/gecko.g.dart'
|
export 'src/pigeons/gecko.g.dart'
|
||||||
show
|
show
|
||||||
|
AudioHitResult,
|
||||||
ColorScheme,
|
ColorScheme,
|
||||||
CookieBannerHandlingMode,
|
CookieBannerHandlingMode,
|
||||||
CookieSameSiteStatus,
|
CookieSameSiteStatus,
|
||||||
|
EmailHitResult,
|
||||||
GeckoEngineSettings,
|
GeckoEngineSettings,
|
||||||
GeckoSuggestion,
|
GeckoSuggestion,
|
||||||
GeckoSuggestionType,
|
GeckoSuggestionType,
|
||||||
|
GeoHitResult,
|
||||||
HistoryMetadataKey,
|
HistoryMetadataKey,
|
||||||
|
HitResult,
|
||||||
HttpsOnlyMode,
|
HttpsOnlyMode,
|
||||||
IconSource,
|
IconSource,
|
||||||
IconType,
|
IconType,
|
||||||
|
ImageHitResult,
|
||||||
|
ImageSrcHitResult,
|
||||||
|
PhoneHitResult,
|
||||||
Resource,
|
Resource,
|
||||||
ResourceSize,
|
ResourceSize,
|
||||||
SecurityInfoState,
|
SecurityInfoState,
|
||||||
TabContent,
|
TabContent,
|
||||||
TabContentState,
|
TabContentState,
|
||||||
TrackingProtectionPolicy,
|
TrackingProtectionPolicy,
|
||||||
|
UnknownHitResult,
|
||||||
|
VideoHitResult,
|
||||||
WebContentIsolationStrategy,
|
WebContentIsolationStrategy,
|
||||||
WebExtensionActionType,
|
WebExtensionActionType,
|
||||||
WebExtensionData;
|
WebExtensionData;
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
||||||
|
|
||||||
|
final _apiInstance = GeckoDownloadsApi();
|
||||||
|
|
||||||
|
class GeckoDownloadsService {
|
||||||
|
final GeckoDownloadsApi _api;
|
||||||
|
|
||||||
|
GeckoDownloadsService({GeckoDownloadsApi? api}) : _api = api ?? _apiInstance;
|
||||||
|
|
||||||
|
Future<void> copyInternetResource(
|
||||||
|
String tabId, {
|
||||||
|
required Uri url,
|
||||||
|
Uri? referrerUrl,
|
||||||
|
String? contentType,
|
||||||
|
|
||||||
|
bool isPrivate = false,
|
||||||
|
}) {
|
||||||
|
return _api.copyInternetResource(
|
||||||
|
tabId,
|
||||||
|
ShareInternetResourceState(
|
||||||
|
url: url.toString(),
|
||||||
|
referrerUrl: referrerUrl?.toString(),
|
||||||
|
private: isPrivate,
|
||||||
|
contentType: contentType,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> shareInternetResource(
|
||||||
|
String tabId, {
|
||||||
|
required Uri url,
|
||||||
|
Uri? referrerUrl,
|
||||||
|
String? contentType,
|
||||||
|
|
||||||
|
bool isPrivate = false,
|
||||||
|
}) {
|
||||||
|
return _api.shareInternetResource(
|
||||||
|
tabId,
|
||||||
|
ShareInternetResourceState(
|
||||||
|
url: url.toString(),
|
||||||
|
referrerUrl: referrerUrl?.toString(),
|
||||||
|
private: isPrivate,
|
||||||
|
contentType: contentType,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> requestDownload(
|
||||||
|
String tabId, {
|
||||||
|
required Uri url,
|
||||||
|
String? fileName,
|
||||||
|
bool? openInApp,
|
||||||
|
bool? skipConfirmation,
|
||||||
|
Uri? referrerUrl,
|
||||||
|
bool isPrivate = false,
|
||||||
|
}) {
|
||||||
|
return _api.requestDownload(
|
||||||
|
tabId,
|
||||||
|
DownloadState(
|
||||||
|
url: url.toString(),
|
||||||
|
fileName: fileName,
|
||||||
|
openInApp: openInApp,
|
||||||
|
skipConfirmation: skipConfirmation,
|
||||||
|
referrerUrl: referrerUrl?.toString(),
|
||||||
|
private: isPrivate,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ typedef IconChangeEvent = ({String tabId, Uint8List? bytes});
|
|||||||
typedef IconUpdateEvent = ({String url, Uint8List bytes});
|
typedef IconUpdateEvent = ({String url, Uint8List bytes});
|
||||||
typedef ThumbnailEvent = ({String tabId, Uint8List? bytes});
|
typedef ThumbnailEvent = ({String tabId, Uint8List? bytes});
|
||||||
typedef FindResultsEvent = ({String tabId, List<FindResultState> results});
|
typedef FindResultsEvent = ({String tabId, List<FindResultState> results});
|
||||||
|
typedef LongPressEvent = ({String tabId, HitResult hitResult});
|
||||||
|
|
||||||
class GeckoEventService extends GeckoStateEvents {
|
class GeckoEventService extends GeckoStateEvents {
|
||||||
// Stream controllers
|
// Stream controllers
|
||||||
@@ -29,6 +30,7 @@ class GeckoEventService extends GeckoStateEvents {
|
|||||||
final _iconUpdateSubject = PublishSubject<IconUpdateEvent>();
|
final _iconUpdateSubject = PublishSubject<IconUpdateEvent>();
|
||||||
final _thumbnailSubject = PublishSubject<ThumbnailEvent>();
|
final _thumbnailSubject = PublishSubject<ThumbnailEvent>();
|
||||||
final _findResultsSubject = PublishSubject<FindResultsEvent>();
|
final _findResultsSubject = PublishSubject<FindResultsEvent>();
|
||||||
|
final _longPressSubject = PublishSubject<LongPressEvent>();
|
||||||
|
|
||||||
final _tabAddedSubject = PublishSubject<String>();
|
final _tabAddedSubject = PublishSubject<String>();
|
||||||
|
|
||||||
@@ -47,6 +49,7 @@ class GeckoEventService extends GeckoStateEvents {
|
|||||||
Stream<IconUpdateEvent> get iconUpdateEvents => _iconUpdateSubject.stream;
|
Stream<IconUpdateEvent> get iconUpdateEvents => _iconUpdateSubject.stream;
|
||||||
Stream<ThumbnailEvent> get thumbnailEvents => _thumbnailSubject.stream;
|
Stream<ThumbnailEvent> get thumbnailEvents => _thumbnailSubject.stream;
|
||||||
Stream<FindResultsEvent> get findResultsEvent => _findResultsSubject.stream;
|
Stream<FindResultsEvent> get findResultsEvent => _findResultsSubject.stream;
|
||||||
|
Stream<LongPressEvent> get longPressEvent => _longPressSubject.stream;
|
||||||
|
|
||||||
Stream<String> get tabAddedStream => _tabAddedSubject.stream;
|
Stream<String> get tabAddedStream => _tabAddedSubject.stream;
|
||||||
|
|
||||||
@@ -144,6 +147,14 @@ class GeckoEventService extends GeckoStateEvents {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onLongPress(int timestamp, String id, HitResult hitResult) {
|
||||||
|
_longPressSubject.addWhenMoreRecent(timestamp, id, (
|
||||||
|
tabId: id,
|
||||||
|
hitResult: hitResult,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onTabAdded(int timestamp, String tabId) {
|
void onTabAdded(int timestamp, String tabId) {
|
||||||
_tabAddedSubject.addWhenMoreRecent(timestamp, null, tabId);
|
_tabAddedSubject.addWhenMoreRecent(timestamp, null, tabId);
|
||||||
@@ -170,6 +181,7 @@ class GeckoEventService extends GeckoStateEvents {
|
|||||||
unawaited(_iconChangeSubject.close());
|
unawaited(_iconChangeSubject.close());
|
||||||
unawaited(_thumbnailSubject.close());
|
unawaited(_thumbnailSubject.close());
|
||||||
unawaited(_findResultsSubject.close());
|
unawaited(_findResultsSubject.close());
|
||||||
|
unawaited(_longPressSubject.close());
|
||||||
unawaited(_tabAddedSubject.close());
|
unawaited(_tabAddedSubject.close());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,6 +125,23 @@ enum WebContentIsolationStrategy {
|
|||||||
isolateHighValue,
|
isolateHighValue,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Status that represents every state that a download can be in.
|
||||||
|
enum DownloadStatus {
|
||||||
|
/// Indicates that the download is in the first state after creation but not yet [DOWNLOADING].
|
||||||
|
initiated,
|
||||||
|
/// Indicates that an [INITIATED] download is now actively being downloaded.
|
||||||
|
downloading,
|
||||||
|
/// Indicates that the download that has been [DOWNLOADING] has been paused.
|
||||||
|
paused,
|
||||||
|
/// Indicates that the download that has been [DOWNLOADING] has been cancelled.
|
||||||
|
cancelled,
|
||||||
|
/// Indicates that the download that has been [DOWNLOADING] has moved to failed because
|
||||||
|
/// something unexpected has happened.
|
||||||
|
failed,
|
||||||
|
/// Indicates that the [DOWNLOADING] download has been completed.
|
||||||
|
completed,
|
||||||
|
}
|
||||||
|
|
||||||
/// Translation options that map to the Gecko Translations Options.
|
/// Translation options that map to the Gecko Translations Options.
|
||||||
///
|
///
|
||||||
/// @property downloadModel If the necessary models should be downloaded on request. If false, then
|
/// @property downloadModel If the necessary models should be downloaded on request. If false, then
|
||||||
@@ -1314,6 +1331,344 @@ class AutocompleteResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents all the different supported types of data that can be found from long clicking
|
||||||
|
/// an element.
|
||||||
|
sealed class HitResult {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Default type if we're unable to match the type to anything. It may or may not have a src.
|
||||||
|
class UnknownHitResult extends HitResult {
|
||||||
|
UnknownHitResult({
|
||||||
|
required this.src,
|
||||||
|
});
|
||||||
|
|
||||||
|
String src;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
src,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static UnknownHitResult decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return UnknownHitResult(
|
||||||
|
src: result[0]! as String,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the HTML element was of type 'HTMLImageElement'.
|
||||||
|
class ImageHitResult extends HitResult {
|
||||||
|
ImageHitResult({
|
||||||
|
required this.src,
|
||||||
|
this.title,
|
||||||
|
});
|
||||||
|
|
||||||
|
String src;
|
||||||
|
|
||||||
|
String? title;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
src,
|
||||||
|
title,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static ImageHitResult decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return ImageHitResult(
|
||||||
|
src: result[0]! as String,
|
||||||
|
title: result[1] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the HTML element was of type 'HTMLVideoElement'.
|
||||||
|
class VideoHitResult extends HitResult {
|
||||||
|
VideoHitResult({
|
||||||
|
required this.src,
|
||||||
|
this.title,
|
||||||
|
});
|
||||||
|
|
||||||
|
String src;
|
||||||
|
|
||||||
|
String? title;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
src,
|
||||||
|
title,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static VideoHitResult decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return VideoHitResult(
|
||||||
|
src: result[0]! as String,
|
||||||
|
title: result[1] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the HTML element was of type 'HTMLAudioElement'.
|
||||||
|
class AudioHitResult extends HitResult {
|
||||||
|
AudioHitResult({
|
||||||
|
required this.src,
|
||||||
|
this.title,
|
||||||
|
});
|
||||||
|
|
||||||
|
String src;
|
||||||
|
|
||||||
|
String? title;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
src,
|
||||||
|
title,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static AudioHitResult decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return AudioHitResult(
|
||||||
|
src: result[0]! as String,
|
||||||
|
title: result[1] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the HTML element was of type 'HTMLImageElement' and contained a URI.
|
||||||
|
class ImageSrcHitResult extends HitResult {
|
||||||
|
ImageSrcHitResult({
|
||||||
|
required this.src,
|
||||||
|
required this.uri,
|
||||||
|
});
|
||||||
|
|
||||||
|
String src;
|
||||||
|
|
||||||
|
String uri;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
src,
|
||||||
|
uri,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static ImageSrcHitResult decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return ImageSrcHitResult(
|
||||||
|
src: result[0]! as String,
|
||||||
|
uri: result[1]! as String,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The type used if the URI is prepended with 'tel:'.
|
||||||
|
class PhoneHitResult extends HitResult {
|
||||||
|
PhoneHitResult({
|
||||||
|
required this.src,
|
||||||
|
});
|
||||||
|
|
||||||
|
String src;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
src,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static PhoneHitResult decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return PhoneHitResult(
|
||||||
|
src: result[0]! as String,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The type used if the URI is prepended with 'mailto:'.
|
||||||
|
class EmailHitResult extends HitResult {
|
||||||
|
EmailHitResult({
|
||||||
|
required this.src,
|
||||||
|
});
|
||||||
|
|
||||||
|
String src;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
src,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static EmailHitResult decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return EmailHitResult(
|
||||||
|
src: result[0]! as String,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The type used if the URI is prepended with 'geo:'.
|
||||||
|
class GeoHitResult extends HitResult {
|
||||||
|
GeoHitResult({
|
||||||
|
required this.src,
|
||||||
|
});
|
||||||
|
|
||||||
|
String src;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
src,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static GeoHitResult decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return GeoHitResult(
|
||||||
|
src: result[0]! as String,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DownloadState {
|
||||||
|
DownloadState({
|
||||||
|
required this.url,
|
||||||
|
this.fileName,
|
||||||
|
this.contentType,
|
||||||
|
this.contentLength,
|
||||||
|
this.currentBytesCopied,
|
||||||
|
this.status,
|
||||||
|
this.userAgent,
|
||||||
|
this.destinationDirectory,
|
||||||
|
this.directoryPath,
|
||||||
|
this.referrerUrl,
|
||||||
|
this.skipConfirmation,
|
||||||
|
this.openInApp,
|
||||||
|
this.id,
|
||||||
|
this.sessionId,
|
||||||
|
this.private,
|
||||||
|
this.createdTime,
|
||||||
|
this.notificationId,
|
||||||
|
});
|
||||||
|
|
||||||
|
String url;
|
||||||
|
|
||||||
|
String? fileName;
|
||||||
|
|
||||||
|
String? contentType;
|
||||||
|
|
||||||
|
int? contentLength;
|
||||||
|
|
||||||
|
int? currentBytesCopied;
|
||||||
|
|
||||||
|
DownloadStatus? status;
|
||||||
|
|
||||||
|
String? userAgent;
|
||||||
|
|
||||||
|
String? destinationDirectory;
|
||||||
|
|
||||||
|
String? directoryPath;
|
||||||
|
|
||||||
|
String? referrerUrl;
|
||||||
|
|
||||||
|
bool? skipConfirmation;
|
||||||
|
|
||||||
|
bool? openInApp;
|
||||||
|
|
||||||
|
String? id;
|
||||||
|
|
||||||
|
String? sessionId;
|
||||||
|
|
||||||
|
bool? private;
|
||||||
|
|
||||||
|
int? createdTime;
|
||||||
|
|
||||||
|
int? notificationId;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
url,
|
||||||
|
fileName,
|
||||||
|
contentType,
|
||||||
|
contentLength,
|
||||||
|
currentBytesCopied,
|
||||||
|
status,
|
||||||
|
userAgent,
|
||||||
|
destinationDirectory,
|
||||||
|
directoryPath,
|
||||||
|
referrerUrl,
|
||||||
|
skipConfirmation,
|
||||||
|
openInApp,
|
||||||
|
id,
|
||||||
|
sessionId,
|
||||||
|
private,
|
||||||
|
createdTime,
|
||||||
|
notificationId,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static DownloadState decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return DownloadState(
|
||||||
|
url: result[0]! as String,
|
||||||
|
fileName: result[1] as String?,
|
||||||
|
contentType: result[2] as String?,
|
||||||
|
contentLength: result[3] as int?,
|
||||||
|
currentBytesCopied: result[4] as int?,
|
||||||
|
status: result[5] as DownloadStatus?,
|
||||||
|
userAgent: result[6] as String?,
|
||||||
|
destinationDirectory: result[7] as String?,
|
||||||
|
directoryPath: result[8] as String?,
|
||||||
|
referrerUrl: result[9] as String?,
|
||||||
|
skipConfirmation: result[10] as bool?,
|
||||||
|
openInApp: result[11] as bool?,
|
||||||
|
id: result[12] as String?,
|
||||||
|
sessionId: result[13] as String?,
|
||||||
|
private: result[14] as bool?,
|
||||||
|
createdTime: result[15] as int?,
|
||||||
|
notificationId: result[16] as int?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShareInternetResourceState {
|
||||||
|
ShareInternetResourceState({
|
||||||
|
required this.url,
|
||||||
|
this.contentType,
|
||||||
|
required this.private,
|
||||||
|
this.referrerUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
String url;
|
||||||
|
|
||||||
|
String? contentType;
|
||||||
|
|
||||||
|
bool private;
|
||||||
|
|
||||||
|
String? referrerUrl;
|
||||||
|
|
||||||
|
Object encode() {
|
||||||
|
return <Object?>[
|
||||||
|
url,
|
||||||
|
contentType,
|
||||||
|
private,
|
||||||
|
referrerUrl,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
static ShareInternetResourceState decode(Object result) {
|
||||||
|
result as List<Object?>;
|
||||||
|
return ShareInternetResourceState(
|
||||||
|
url: result[0]! as String,
|
||||||
|
contentType: result[1] as String?,
|
||||||
|
private: result[2]! as bool,
|
||||||
|
referrerUrl: result[3] as String?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class _PigeonCodec extends StandardMessageCodec {
|
class _PigeonCodec extends StandardMessageCodec {
|
||||||
const _PigeonCodec();
|
const _PigeonCodec();
|
||||||
@@ -1361,93 +1716,126 @@ class _PigeonCodec extends StandardMessageCodec {
|
|||||||
} else if (value is WebContentIsolationStrategy) {
|
} else if (value is WebContentIsolationStrategy) {
|
||||||
buffer.putUint8(141);
|
buffer.putUint8(141);
|
||||||
writeValue(buffer, value.index);
|
writeValue(buffer, value.index);
|
||||||
} else if (value is TranslationOptions) {
|
} else if (value is DownloadStatus) {
|
||||||
buffer.putUint8(142);
|
buffer.putUint8(142);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.index);
|
||||||
} else if (value is ReaderState) {
|
} else if (value is TranslationOptions) {
|
||||||
buffer.putUint8(143);
|
buffer.putUint8(143);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is LastMediaAccessState) {
|
} else if (value is ReaderState) {
|
||||||
buffer.putUint8(144);
|
buffer.putUint8(144);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is HistoryMetadataKey) {
|
} else if (value is LastMediaAccessState) {
|
||||||
buffer.putUint8(145);
|
buffer.putUint8(145);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is PackageCategoryValue) {
|
} else if (value is HistoryMetadataKey) {
|
||||||
buffer.putUint8(146);
|
buffer.putUint8(146);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is ExternalPackage) {
|
} else if (value is PackageCategoryValue) {
|
||||||
buffer.putUint8(147);
|
buffer.putUint8(147);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is LoadUrlFlagsValue) {
|
} else if (value is ExternalPackage) {
|
||||||
buffer.putUint8(148);
|
buffer.putUint8(148);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is SourceValue) {
|
} else if (value is LoadUrlFlagsValue) {
|
||||||
buffer.putUint8(149);
|
buffer.putUint8(149);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is TabState) {
|
} else if (value is SourceValue) {
|
||||||
buffer.putUint8(150);
|
buffer.putUint8(150);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is RecoverableTab) {
|
} else if (value is TabState) {
|
||||||
buffer.putUint8(151);
|
buffer.putUint8(151);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is RecoverableBrowserState) {
|
} else if (value is RecoverableTab) {
|
||||||
buffer.putUint8(152);
|
buffer.putUint8(152);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is IconRequest) {
|
} else if (value is RecoverableBrowserState) {
|
||||||
buffer.putUint8(153);
|
buffer.putUint8(153);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is ResourceSize) {
|
} else if (value is IconRequest) {
|
||||||
buffer.putUint8(154);
|
buffer.putUint8(154);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is Resource) {
|
} else if (value is ResourceSize) {
|
||||||
buffer.putUint8(155);
|
buffer.putUint8(155);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is IconResult) {
|
} else if (value is Resource) {
|
||||||
buffer.putUint8(156);
|
buffer.putUint8(156);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is CookiePartitionKey) {
|
} else if (value is IconResult) {
|
||||||
buffer.putUint8(157);
|
buffer.putUint8(157);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is Cookie) {
|
} else if (value is CookiePartitionKey) {
|
||||||
buffer.putUint8(158);
|
buffer.putUint8(158);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is HistoryItem) {
|
} else if (value is Cookie) {
|
||||||
buffer.putUint8(159);
|
buffer.putUint8(159);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is HistoryState) {
|
} else if (value is HistoryItem) {
|
||||||
buffer.putUint8(160);
|
buffer.putUint8(160);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is ReaderableState) {
|
} else if (value is HistoryState) {
|
||||||
buffer.putUint8(161);
|
buffer.putUint8(161);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is SecurityInfoState) {
|
} else if (value is ReaderableState) {
|
||||||
buffer.putUint8(162);
|
buffer.putUint8(162);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is TabContentState) {
|
} else if (value is SecurityInfoState) {
|
||||||
buffer.putUint8(163);
|
buffer.putUint8(163);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is FindResultState) {
|
} else if (value is TabContentState) {
|
||||||
buffer.putUint8(164);
|
buffer.putUint8(164);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is CustomSelectionAction) {
|
} else if (value is FindResultState) {
|
||||||
buffer.putUint8(165);
|
buffer.putUint8(165);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is WebExtensionData) {
|
} else if (value is CustomSelectionAction) {
|
||||||
buffer.putUint8(166);
|
buffer.putUint8(166);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is GeckoSuggestion) {
|
} else if (value is WebExtensionData) {
|
||||||
buffer.putUint8(167);
|
buffer.putUint8(167);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is TabContent) {
|
} else if (value is GeckoSuggestion) {
|
||||||
buffer.putUint8(168);
|
buffer.putUint8(168);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is GeckoEngineSettings) {
|
} else if (value is TabContent) {
|
||||||
buffer.putUint8(169);
|
buffer.putUint8(169);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
} else if (value is AutocompleteResult) {
|
} else if (value is GeckoEngineSettings) {
|
||||||
buffer.putUint8(170);
|
buffer.putUint8(170);
|
||||||
writeValue(buffer, value.encode());
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is AutocompleteResult) {
|
||||||
|
buffer.putUint8(171);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is UnknownHitResult) {
|
||||||
|
buffer.putUint8(172);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is ImageHitResult) {
|
||||||
|
buffer.putUint8(173);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is VideoHitResult) {
|
||||||
|
buffer.putUint8(174);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is AudioHitResult) {
|
||||||
|
buffer.putUint8(175);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is ImageSrcHitResult) {
|
||||||
|
buffer.putUint8(176);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is PhoneHitResult) {
|
||||||
|
buffer.putUint8(177);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is EmailHitResult) {
|
||||||
|
buffer.putUint8(178);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is GeoHitResult) {
|
||||||
|
buffer.putUint8(179);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is DownloadState) {
|
||||||
|
buffer.putUint8(180);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
|
} else if (value is ShareInternetResourceState) {
|
||||||
|
buffer.putUint8(181);
|
||||||
|
writeValue(buffer, value.encode());
|
||||||
} else {
|
} else {
|
||||||
super.writeValue(buffer, value);
|
super.writeValue(buffer, value);
|
||||||
}
|
}
|
||||||
@@ -1496,63 +1884,86 @@ class _PigeonCodec extends StandardMessageCodec {
|
|||||||
final int? value = readValue(buffer) as int?;
|
final int? value = readValue(buffer) as int?;
|
||||||
return value == null ? null : WebContentIsolationStrategy.values[value];
|
return value == null ? null : WebContentIsolationStrategy.values[value];
|
||||||
case 142:
|
case 142:
|
||||||
return TranslationOptions.decode(readValue(buffer)!);
|
final int? value = readValue(buffer) as int?;
|
||||||
|
return value == null ? null : DownloadStatus.values[value];
|
||||||
case 143:
|
case 143:
|
||||||
return ReaderState.decode(readValue(buffer)!);
|
return TranslationOptions.decode(readValue(buffer)!);
|
||||||
case 144:
|
case 144:
|
||||||
return LastMediaAccessState.decode(readValue(buffer)!);
|
return ReaderState.decode(readValue(buffer)!);
|
||||||
case 145:
|
case 145:
|
||||||
return HistoryMetadataKey.decode(readValue(buffer)!);
|
return LastMediaAccessState.decode(readValue(buffer)!);
|
||||||
case 146:
|
case 146:
|
||||||
return PackageCategoryValue.decode(readValue(buffer)!);
|
return HistoryMetadataKey.decode(readValue(buffer)!);
|
||||||
case 147:
|
case 147:
|
||||||
return ExternalPackage.decode(readValue(buffer)!);
|
return PackageCategoryValue.decode(readValue(buffer)!);
|
||||||
case 148:
|
case 148:
|
||||||
return LoadUrlFlagsValue.decode(readValue(buffer)!);
|
return ExternalPackage.decode(readValue(buffer)!);
|
||||||
case 149:
|
case 149:
|
||||||
return SourceValue.decode(readValue(buffer)!);
|
return LoadUrlFlagsValue.decode(readValue(buffer)!);
|
||||||
case 150:
|
case 150:
|
||||||
return TabState.decode(readValue(buffer)!);
|
return SourceValue.decode(readValue(buffer)!);
|
||||||
case 151:
|
case 151:
|
||||||
return RecoverableTab.decode(readValue(buffer)!);
|
return TabState.decode(readValue(buffer)!);
|
||||||
case 152:
|
case 152:
|
||||||
return RecoverableBrowserState.decode(readValue(buffer)!);
|
return RecoverableTab.decode(readValue(buffer)!);
|
||||||
case 153:
|
case 153:
|
||||||
return IconRequest.decode(readValue(buffer)!);
|
return RecoverableBrowserState.decode(readValue(buffer)!);
|
||||||
case 154:
|
case 154:
|
||||||
return ResourceSize.decode(readValue(buffer)!);
|
return IconRequest.decode(readValue(buffer)!);
|
||||||
case 155:
|
case 155:
|
||||||
return Resource.decode(readValue(buffer)!);
|
return ResourceSize.decode(readValue(buffer)!);
|
||||||
case 156:
|
case 156:
|
||||||
return IconResult.decode(readValue(buffer)!);
|
return Resource.decode(readValue(buffer)!);
|
||||||
case 157:
|
case 157:
|
||||||
return CookiePartitionKey.decode(readValue(buffer)!);
|
return IconResult.decode(readValue(buffer)!);
|
||||||
case 158:
|
case 158:
|
||||||
return Cookie.decode(readValue(buffer)!);
|
return CookiePartitionKey.decode(readValue(buffer)!);
|
||||||
case 159:
|
case 159:
|
||||||
return HistoryItem.decode(readValue(buffer)!);
|
return Cookie.decode(readValue(buffer)!);
|
||||||
case 160:
|
case 160:
|
||||||
return HistoryState.decode(readValue(buffer)!);
|
return HistoryItem.decode(readValue(buffer)!);
|
||||||
case 161:
|
case 161:
|
||||||
return ReaderableState.decode(readValue(buffer)!);
|
return HistoryState.decode(readValue(buffer)!);
|
||||||
case 162:
|
case 162:
|
||||||
return SecurityInfoState.decode(readValue(buffer)!);
|
return ReaderableState.decode(readValue(buffer)!);
|
||||||
case 163:
|
case 163:
|
||||||
return TabContentState.decode(readValue(buffer)!);
|
return SecurityInfoState.decode(readValue(buffer)!);
|
||||||
case 164:
|
case 164:
|
||||||
return FindResultState.decode(readValue(buffer)!);
|
return TabContentState.decode(readValue(buffer)!);
|
||||||
case 165:
|
case 165:
|
||||||
return CustomSelectionAction.decode(readValue(buffer)!);
|
return FindResultState.decode(readValue(buffer)!);
|
||||||
case 166:
|
case 166:
|
||||||
return WebExtensionData.decode(readValue(buffer)!);
|
return CustomSelectionAction.decode(readValue(buffer)!);
|
||||||
case 167:
|
case 167:
|
||||||
return GeckoSuggestion.decode(readValue(buffer)!);
|
return WebExtensionData.decode(readValue(buffer)!);
|
||||||
case 168:
|
case 168:
|
||||||
return TabContent.decode(readValue(buffer)!);
|
return GeckoSuggestion.decode(readValue(buffer)!);
|
||||||
case 169:
|
case 169:
|
||||||
return GeckoEngineSettings.decode(readValue(buffer)!);
|
return TabContent.decode(readValue(buffer)!);
|
||||||
case 170:
|
case 170:
|
||||||
|
return GeckoEngineSettings.decode(readValue(buffer)!);
|
||||||
|
case 171:
|
||||||
return AutocompleteResult.decode(readValue(buffer)!);
|
return AutocompleteResult.decode(readValue(buffer)!);
|
||||||
|
case 172:
|
||||||
|
return UnknownHitResult.decode(readValue(buffer)!);
|
||||||
|
case 173:
|
||||||
|
return ImageHitResult.decode(readValue(buffer)!);
|
||||||
|
case 174:
|
||||||
|
return VideoHitResult.decode(readValue(buffer)!);
|
||||||
|
case 175:
|
||||||
|
return AudioHitResult.decode(readValue(buffer)!);
|
||||||
|
case 176:
|
||||||
|
return ImageSrcHitResult.decode(readValue(buffer)!);
|
||||||
|
case 177:
|
||||||
|
return PhoneHitResult.decode(readValue(buffer)!);
|
||||||
|
case 178:
|
||||||
|
return EmailHitResult.decode(readValue(buffer)!);
|
||||||
|
case 179:
|
||||||
|
return GeoHitResult.decode(readValue(buffer)!);
|
||||||
|
case 180:
|
||||||
|
return DownloadState.decode(readValue(buffer)!);
|
||||||
|
case 181:
|
||||||
|
return ShareInternetResourceState.decode(readValue(buffer)!);
|
||||||
default:
|
default:
|
||||||
return super.readValueOfType(type, buffer);
|
return super.readValueOfType(type, buffer);
|
||||||
}
|
}
|
||||||
@@ -2940,6 +3351,8 @@ abstract class GeckoStateEvents {
|
|||||||
|
|
||||||
void onFindResults(int timestamp, String id, List<FindResultState> results);
|
void onFindResults(int timestamp, String id, List<FindResultState> results);
|
||||||
|
|
||||||
|
void onLongPress(int timestamp, String id, HitResult hitResult);
|
||||||
|
|
||||||
static void setUp(GeckoStateEvents? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) {
|
static void setUp(GeckoStateEvents? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) {
|
||||||
messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
|
messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
|
||||||
{
|
{
|
||||||
@@ -3321,6 +3734,37 @@ abstract class GeckoStateEvents {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
|
'dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onLongPress$messageChannelSuffix', pigeonChannelCodec,
|
||||||
|
binaryMessenger: binaryMessenger);
|
||||||
|
if (api == null) {
|
||||||
|
pigeonVar_channel.setMessageHandler(null);
|
||||||
|
} else {
|
||||||
|
pigeonVar_channel.setMessageHandler((Object? message) async {
|
||||||
|
assert(message != null,
|
||||||
|
'Argument for dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onLongPress was null.');
|
||||||
|
final List<Object?> args = (message as List<Object?>?)!;
|
||||||
|
final int? arg_timestamp = (args[0] as int?);
|
||||||
|
assert(arg_timestamp != null,
|
||||||
|
'Argument for dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onLongPress was null, expected non-null int.');
|
||||||
|
final String? arg_id = (args[1] as String?);
|
||||||
|
assert(arg_id != null,
|
||||||
|
'Argument for dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onLongPress was null, expected non-null String.');
|
||||||
|
final HitResult? arg_hitResult = (args[2] as HitResult?);
|
||||||
|
assert(arg_hitResult != null,
|
||||||
|
'Argument for dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onLongPress was null, expected non-null HitResult.');
|
||||||
|
try {
|
||||||
|
api.onLongPress(arg_timestamp!, arg_id!, arg_hitResult!);
|
||||||
|
return wrapResponse(empty: true);
|
||||||
|
} on PlatformException catch (e) {
|
||||||
|
return wrapResponse(error: e);
|
||||||
|
} catch (e) {
|
||||||
|
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3960,3 +4404,86 @@ class GeckoDeleteBrowsingDataController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GeckoDownloadsApi {
|
||||||
|
/// Constructor for [GeckoDownloadsApi]. The [binaryMessenger] named argument is
|
||||||
|
/// available for dependency injection. If it is left null, the default
|
||||||
|
/// BinaryMessenger will be used which routes to the host platform.
|
||||||
|
GeckoDownloadsApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''})
|
||||||
|
: pigeonVar_binaryMessenger = binaryMessenger,
|
||||||
|
pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
|
||||||
|
final BinaryMessenger? pigeonVar_binaryMessenger;
|
||||||
|
|
||||||
|
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
|
||||||
|
|
||||||
|
final String pigeonVar_messageChannelSuffix;
|
||||||
|
|
||||||
|
Future<void> requestDownload(String tabId, DownloadState state) async {
|
||||||
|
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoDownloadsApi.requestDownload$pigeonVar_messageChannelSuffix';
|
||||||
|
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
|
pigeonVar_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: pigeonVar_binaryMessenger,
|
||||||
|
);
|
||||||
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[tabId, state]);
|
||||||
|
final List<Object?>? pigeonVar_replyList =
|
||||||
|
await pigeonVar_sendFuture as List<Object?>?;
|
||||||
|
if (pigeonVar_replyList == null) {
|
||||||
|
throw _createConnectionError(pigeonVar_channelName);
|
||||||
|
} else if (pigeonVar_replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: pigeonVar_replyList[0]! as String,
|
||||||
|
message: pigeonVar_replyList[1] as String?,
|
||||||
|
details: pigeonVar_replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> copyInternetResource(String tabId, ShareInternetResourceState state) async {
|
||||||
|
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoDownloadsApi.copyInternetResource$pigeonVar_messageChannelSuffix';
|
||||||
|
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
|
pigeonVar_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: pigeonVar_binaryMessenger,
|
||||||
|
);
|
||||||
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[tabId, state]);
|
||||||
|
final List<Object?>? pigeonVar_replyList =
|
||||||
|
await pigeonVar_sendFuture as List<Object?>?;
|
||||||
|
if (pigeonVar_replyList == null) {
|
||||||
|
throw _createConnectionError(pigeonVar_channelName);
|
||||||
|
} else if (pigeonVar_replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: pigeonVar_replyList[0]! as String,
|
||||||
|
message: pigeonVar_replyList[1] as String?,
|
||||||
|
details: pigeonVar_replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> shareInternetResource(String tabId, ShareInternetResourceState state) async {
|
||||||
|
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoDownloadsApi.shareInternetResource$pigeonVar_messageChannelSuffix';
|
||||||
|
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
|
pigeonVar_channelName,
|
||||||
|
pigeonChannelCodec,
|
||||||
|
binaryMessenger: pigeonVar_binaryMessenger,
|
||||||
|
);
|
||||||
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[tabId, state]);
|
||||||
|
final List<Object?>? pigeonVar_replyList =
|
||||||
|
await pigeonVar_sendFuture as List<Object?>?;
|
||||||
|
if (pigeonVar_replyList == null) {
|
||||||
|
throw _createConnectionError(pigeonVar_channelName);
|
||||||
|
} else if (pigeonVar_replyList.length > 1) {
|
||||||
|
throw PlatformException(
|
||||||
|
code: pigeonVar_replyList[0]! as String,
|
||||||
|
message: pigeonVar_replyList[1] as String?,
|
||||||
|
details: pigeonVar_replyList[2],
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -580,61 +580,147 @@ class AutocompleteResult {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// /// Represents all the different supported types of data that can be found from long clicking
|
/// Represents all the different supported types of data that can be found from long clicking
|
||||||
// /// an element.
|
/// an element.
|
||||||
// sealed class HitResult {
|
sealed class HitResult {}
|
||||||
// final String src;
|
|
||||||
|
|
||||||
// HitResult(this.src);
|
/// Default type if we're unable to match the type to anything. It may or may not have a src.
|
||||||
// }
|
class UnknownHitResult extends HitResult {
|
||||||
|
final String src;
|
||||||
|
|
||||||
// /// Default type if we're unable to match the type to anything. It may or may not have a src.
|
UnknownHitResult(this.src);
|
||||||
// class UnknownHitResult extends HitResult {
|
}
|
||||||
// UnknownHitResult(super.src);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// If the HTML element was of type 'HTMLImageElement'.
|
/// If the HTML element was of type 'HTMLImageElement'.
|
||||||
// class ImageHitResult extends HitResult {
|
class ImageHitResult extends HitResult {
|
||||||
// final String? title;
|
final String src;
|
||||||
|
final String? title;
|
||||||
|
|
||||||
// ImageHitResult(super.src, {this.title});
|
ImageHitResult(this.src, {this.title});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// /// If the HTML element was of type 'HTMLVideoElement'.
|
/// If the HTML element was of type 'HTMLVideoElement'.
|
||||||
// class VideoHitResult extends HitResult {
|
class VideoHitResult extends HitResult {
|
||||||
// final String? title;
|
final String src;
|
||||||
|
final String? title;
|
||||||
|
|
||||||
// VideoHitResult(super.src, {this.title});
|
VideoHitResult(this.src, {this.title});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// /// If the HTML element was of type 'HTMLAudioElement'.
|
/// If the HTML element was of type 'HTMLAudioElement'.
|
||||||
// class AudioHitResult extends HitResult {
|
class AudioHitResult extends HitResult {
|
||||||
// final String? title;
|
final String src;
|
||||||
|
final String? title;
|
||||||
|
|
||||||
// AudioHitResult(super.src, {this.title});
|
AudioHitResult(this.src, {this.title});
|
||||||
// }
|
}
|
||||||
|
|
||||||
// /// If the HTML element was of type 'HTMLImageElement' and contained a URI.
|
/// If the HTML element was of type 'HTMLImageElement' and contained a URI.
|
||||||
// class ImageSrcHitResult extends HitResult {
|
class ImageSrcHitResult extends HitResult {
|
||||||
// final String uri;
|
final String src;
|
||||||
|
final String uri;
|
||||||
|
|
||||||
// ImageSrcHitResult(super.src, this.uri);
|
ImageSrcHitResult(this.src, this.uri);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// /// The type used if the URI is prepended with 'tel:'.
|
/// The type used if the URI is prepended with 'tel:'.
|
||||||
// class PhoneHitResult extends HitResult {
|
class PhoneHitResult extends HitResult {
|
||||||
// PhoneHitResult(super.src);
|
final String src;
|
||||||
// }
|
|
||||||
|
|
||||||
// /// The type used if the URI is prepended with 'mailto:'.
|
PhoneHitResult(this.src);
|
||||||
// class EmailHitResult extends HitResult {
|
}
|
||||||
// EmailHitResult(super.src);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// /// The type used if the URI is prepended with 'geo:'.
|
/// The type used if the URI is prepended with 'mailto:'.
|
||||||
// class GeoHitResult extends HitResult {
|
class EmailHitResult extends HitResult {
|
||||||
// GeoHitResult(super.src);
|
final String src;
|
||||||
// }
|
|
||||||
|
EmailHitResult(this.src);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The type used if the URI is prepended with 'geo:'.
|
||||||
|
class GeoHitResult extends HitResult {
|
||||||
|
final String src;
|
||||||
|
|
||||||
|
GeoHitResult(this.src);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Status that represents every state that a download can be in.
|
||||||
|
enum DownloadStatus {
|
||||||
|
/// Indicates that the download is in the first state after creation but not yet [DOWNLOADING].
|
||||||
|
initiated,
|
||||||
|
|
||||||
|
/// Indicates that an [INITIATED] download is now actively being downloaded.
|
||||||
|
downloading,
|
||||||
|
|
||||||
|
/// Indicates that the download that has been [DOWNLOADING] has been paused.
|
||||||
|
paused,
|
||||||
|
|
||||||
|
/// Indicates that the download that has been [DOWNLOADING] has been cancelled.
|
||||||
|
cancelled,
|
||||||
|
|
||||||
|
/// Indicates that the download that has been [DOWNLOADING] has moved to failed because
|
||||||
|
/// something unexpected has happened.
|
||||||
|
failed,
|
||||||
|
|
||||||
|
/// Indicates that the [DOWNLOADING] download has been completed.
|
||||||
|
completed,
|
||||||
|
}
|
||||||
|
|
||||||
|
class DownloadState {
|
||||||
|
final String url;
|
||||||
|
final String? fileName;
|
||||||
|
final String? contentType;
|
||||||
|
final int? contentLength;
|
||||||
|
final int? currentBytesCopied;
|
||||||
|
final DownloadStatus? status;
|
||||||
|
final String? userAgent;
|
||||||
|
final String? destinationDirectory;
|
||||||
|
final String? directoryPath;
|
||||||
|
final String? referrerUrl;
|
||||||
|
final bool? skipConfirmation;
|
||||||
|
final bool? openInApp;
|
||||||
|
final String? id;
|
||||||
|
final String? sessionId;
|
||||||
|
final bool? private;
|
||||||
|
final int? createdTime;
|
||||||
|
//final Response? response;
|
||||||
|
final int? notificationId;
|
||||||
|
|
||||||
|
DownloadState(
|
||||||
|
this.url,
|
||||||
|
this.fileName,
|
||||||
|
this.contentType,
|
||||||
|
this.contentLength,
|
||||||
|
this.currentBytesCopied,
|
||||||
|
this.status,
|
||||||
|
this.userAgent,
|
||||||
|
this.destinationDirectory,
|
||||||
|
this.directoryPath,
|
||||||
|
this.referrerUrl,
|
||||||
|
this.skipConfirmation,
|
||||||
|
this.openInApp,
|
||||||
|
this.id,
|
||||||
|
this.sessionId,
|
||||||
|
this.private,
|
||||||
|
this.createdTime,
|
||||||
|
this.notificationId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShareInternetResourceState {
|
||||||
|
final String url;
|
||||||
|
final String? contentType;
|
||||||
|
final bool private;
|
||||||
|
// final Response? response ;
|
||||||
|
final String? referrerUrl;
|
||||||
|
|
||||||
|
ShareInternetResourceState(
|
||||||
|
this.url,
|
||||||
|
this.contentType,
|
||||||
|
this.private,
|
||||||
|
this.referrerUrl,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@ConfigurePigeon(
|
@ConfigurePigeon(
|
||||||
PigeonOptions(
|
PigeonOptions(
|
||||||
@@ -933,6 +1019,7 @@ abstract class GeckoStateEvents {
|
|||||||
void onThumbnailChange(int timestamp, String id, Uint8List? bytes);
|
void onThumbnailChange(int timestamp, String id, Uint8List? bytes);
|
||||||
|
|
||||||
void onFindResults(int timestamp, String id, List<FindResultState> results);
|
void onFindResults(int timestamp, String id, List<FindResultState> results);
|
||||||
|
void onLongPress(int timestamp, String id, HitResult hitResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostApi()
|
@HostApi()
|
||||||
@@ -1022,3 +1109,10 @@ abstract class GeckoDeleteBrowsingDataController {
|
|||||||
@async
|
@async
|
||||||
void deleteDownloads();
|
void deleteDownloads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@HostApi()
|
||||||
|
abstract class GeckoDownloadsApi {
|
||||||
|
void requestDownload(String tabId, DownloadState state);
|
||||||
|
void copyInternetResource(String tabId, ShareInternetResourceState state);
|
||||||
|
void shareInternetResource(String tabId, ShareInternetResourceState state);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user