getting there
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
// Typedefs for record types
|
||||
typedef HistoryEvent = ({String tabId, HistoryState history});
|
||||
@@ -12,74 +13,79 @@ typedef FindResultsEvent = ({String tabId, List<FindResultState> results});
|
||||
|
||||
class GeckoEventService extends GeckoStateEvents {
|
||||
// Stream controllers
|
||||
final _tabListController = StreamController<List<String>>.broadcast();
|
||||
final _selectedTabController = StreamController<String?>.broadcast();
|
||||
final _tabContentController = StreamController<TabContentState>.broadcast();
|
||||
final _historyController = StreamController<HistoryEvent>.broadcast();
|
||||
final _readerableController = StreamController<ReaderableEvent>.broadcast();
|
||||
final _securityInfoController =
|
||||
StreamController<SecurityInfoEvent>.broadcast();
|
||||
final _iconController = StreamController<IconEvent>.broadcast();
|
||||
final _thumbnailController = StreamController<ThumbnailEvent>.broadcast();
|
||||
final _findResultsController = StreamController<FindResultsEvent>.broadcast();
|
||||
final _fragmentStateSubject = BehaviorSubject.seeded(false);
|
||||
final _tabListSubject = BehaviorSubject<List<String>>();
|
||||
final _selectedTabSubject = BehaviorSubject<String?>();
|
||||
final _tabContentSubject = BehaviorSubject<TabContentState>();
|
||||
final _historySubject = BehaviorSubject<HistoryEvent>();
|
||||
final _readerableSubject = BehaviorSubject<ReaderableEvent>();
|
||||
final _securityInfoSubject = BehaviorSubject<SecurityInfoEvent>();
|
||||
final _iconSubject = BehaviorSubject<IconEvent>();
|
||||
final _thumbnailSubject = BehaviorSubject<ThumbnailEvent>();
|
||||
final _findResultsSubject = BehaviorSubject<FindResultsEvent>();
|
||||
|
||||
// Event streams
|
||||
Stream<List<String>> get tabListEvents => _tabListController.stream;
|
||||
Stream<String?> get selectedTabEvents => _selectedTabController.stream;
|
||||
Stream<TabContentState> get tabContentEvents => _tabContentController.stream;
|
||||
Stream<HistoryEvent> get historyEvents => _historyController.stream;
|
||||
Stream<ReaderableEvent> get readerableEvents => _readerableController.stream;
|
||||
Stream<bool> get fragmentReadyStateEvents => _fragmentStateSubject.stream;
|
||||
Stream<List<String>> get tabListEvents => _tabListSubject.stream;
|
||||
Stream<String?> get selectedTabEvents => _selectedTabSubject.stream;
|
||||
Stream<TabContentState> get tabContentEvents => _tabContentSubject.stream;
|
||||
Stream<HistoryEvent> get historyEvents => _historySubject.stream;
|
||||
Stream<ReaderableEvent> get readerableEvents => _readerableSubject.stream;
|
||||
Stream<SecurityInfoEvent> get securityInfoEvents =>
|
||||
_securityInfoController.stream;
|
||||
Stream<IconEvent> get iconEvents => _iconController.stream;
|
||||
Stream<ThumbnailEvent> get thumbnailEvents => _thumbnailController.stream;
|
||||
Stream<FindResultsEvent> get findResultsEvent =>
|
||||
_findResultsController.stream;
|
||||
_securityInfoSubject.stream;
|
||||
Stream<IconEvent> get iconEvents => _iconSubject.stream;
|
||||
Stream<ThumbnailEvent> get thumbnailEvents => _thumbnailSubject.stream;
|
||||
Stream<FindResultsEvent> get findResultsEvent => _findResultsSubject.stream;
|
||||
|
||||
@override
|
||||
void onFragmentReadyStateChange(bool state) {
|
||||
_fragmentStateSubject.add(state);
|
||||
}
|
||||
|
||||
// Overridden methods
|
||||
@override
|
||||
void onTabListChange(List<String?> tabIds) {
|
||||
_tabListController.add(tabIds.nonNulls.toList());
|
||||
_tabListSubject.add(tabIds.nonNulls.toList());
|
||||
}
|
||||
|
||||
@override
|
||||
void onSelectedTabChange(String? id) {
|
||||
_selectedTabController.add(id);
|
||||
_selectedTabSubject.add(id);
|
||||
}
|
||||
|
||||
@override
|
||||
void onTabContentStateChange(TabContentState state) {
|
||||
_tabContentController.add(state);
|
||||
_tabContentSubject.add(state);
|
||||
}
|
||||
|
||||
@override
|
||||
void onHistoryStateChange(String id, HistoryState state) {
|
||||
_historyController.add((tabId: id, history: state));
|
||||
_historySubject.add((tabId: id, history: state));
|
||||
}
|
||||
|
||||
@override
|
||||
void onReaderableStateChange(String id, ReaderableState state) {
|
||||
_readerableController.add((tabId: id, readerable: state));
|
||||
_readerableSubject.add((tabId: id, readerable: state));
|
||||
}
|
||||
|
||||
@override
|
||||
void onSecurityInfoStateChange(String id, SecurityInfoState state) {
|
||||
_securityInfoController.add((tabId: id, securityInfo: state));
|
||||
_securityInfoSubject.add((tabId: id, securityInfo: state));
|
||||
}
|
||||
|
||||
@override
|
||||
void onIconChange(String id, Uint8List? bytes) {
|
||||
_iconController.add((tabId: id, bytes: bytes));
|
||||
_iconSubject.add((tabId: id, bytes: bytes));
|
||||
}
|
||||
|
||||
@override
|
||||
void onThumbnailChange(String id, Uint8List? bytes) {
|
||||
_thumbnailController.add((tabId: id, bytes: bytes));
|
||||
_thumbnailSubject.add((tabId: id, bytes: bytes));
|
||||
}
|
||||
|
||||
@override
|
||||
void onFindResults(String id, List<FindResultState?> results) {
|
||||
_findResultsController.add((tabId: id, results: results.nonNulls.toList()));
|
||||
_findResultsSubject.add((tabId: id, results: results.nonNulls.toList()));
|
||||
}
|
||||
|
||||
GeckoEventService.setUp({
|
||||
@@ -94,14 +100,14 @@ class GeckoEventService extends GeckoStateEvents {
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
unawaited(_tabListController.close());
|
||||
unawaited(_selectedTabController.close());
|
||||
unawaited(_tabContentController.close());
|
||||
unawaited(_historyController.close());
|
||||
unawaited(_readerableController.close());
|
||||
unawaited(_securityInfoController.close());
|
||||
unawaited(_iconController.close());
|
||||
unawaited(_thumbnailController.close());
|
||||
unawaited(_findResultsController.close());
|
||||
unawaited(_tabListSubject.close());
|
||||
unawaited(_selectedTabSubject.close());
|
||||
unawaited(_tabContentSubject.close());
|
||||
unawaited(_historySubject.close());
|
||||
unawaited(_readerableSubject.close());
|
||||
unawaited(_securityInfoSubject.close());
|
||||
unawaited(_iconSubject.close());
|
||||
unawaited(_thumbnailSubject.close());
|
||||
unawaited(_findResultsSubject.close());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,15 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
class GeckoReaderableService extends ReaderViewController {
|
||||
final ReaderViewEvents _events;
|
||||
|
||||
final _appearanceVisibility = StreamController<bool>.broadcast();
|
||||
final _readerVisibility = StreamController<bool>.broadcast();
|
||||
final _appearanceVisibility = BehaviorSubject<bool>();
|
||||
final _readerVisibility = BehaviorSubject<bool>();
|
||||
|
||||
Stream<bool> get appearanceVisibility => _appearanceVisibility.stream;
|
||||
Stream<bool> get readerVisibility => _readerVisibility.stream;
|
||||
|
||||
Future<void> toggleReaderView(bool enable) {
|
||||
return _events.onToggleReaderView(enable);
|
||||
@@ -25,11 +25,6 @@ class GeckoReaderableService extends ReaderViewController {
|
||||
_appearanceVisibility.add(visible);
|
||||
}
|
||||
|
||||
@override
|
||||
void readerViewButtonVisibility(bool visible) {
|
||||
_readerVisibility.add(visible);
|
||||
}
|
||||
|
||||
GeckoReaderableService.setUp({
|
||||
ReaderViewEvents? readerEvents,
|
||||
BinaryMessenger? binaryMessenger,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter_mozilla_components/src/data/models/load_url_flags.dart';
|
||||
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
||||
|
||||
@@ -118,6 +120,14 @@ class GeckoSessionService {
|
||||
return _api.purgeHistory();
|
||||
}
|
||||
|
||||
Future<Uint8List?> requestScreenshot() {
|
||||
if (tabId != null) {
|
||||
throw Exception('Screenshot only allowed for selected (visible) tab.');
|
||||
}
|
||||
|
||||
return _api.requestScreenshot();
|
||||
}
|
||||
|
||||
Future<void> updateLastAccess({
|
||||
String? tabId, //If null = current tab
|
||||
DateTime? lastAccess, //If null datetime.now
|
||||
|
||||
@@ -10,6 +10,29 @@ class GeckoTabService {
|
||||
|
||||
GeckoTabService({GeckoTabsApi? api}) : _api = api ?? _apiInstance;
|
||||
|
||||
Future<void> syncEvents({
|
||||
bool onSelectedTabChange = true,
|
||||
bool onTabListChange = true,
|
||||
bool onTabContentStateChange = true,
|
||||
bool onIconChange = true,
|
||||
bool onSecurityInfoStateChange = true,
|
||||
bool onHistoryStateChange = true,
|
||||
bool onFindResults = true,
|
||||
bool onThumbnailChange = true,
|
||||
}) {
|
||||
return _api.syncEvents(
|
||||
onSelectedTabChange: onSelectedTabChange,
|
||||
onTabListChange: onTabListChange,
|
||||
onTabContentStateChange: onTabContentStateChange,
|
||||
onIconChange: onIconChange,
|
||||
onSecurityInfoStateChange: onSecurityInfoStateChange,
|
||||
onHistoryStateChange: onHistoryStateChange,
|
||||
onFindResults: onFindResults,
|
||||
onThumbnailChange: onThumbnailChange,
|
||||
onReaderableStateChange: false,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> selectTab({required String tabId}) {
|
||||
return _api.selectTab(tabId: tabId);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -7,7 +9,9 @@ import 'package:flutter/services.dart';
|
||||
import 'package:flutter_mozilla_components/src/domain/services/gecko_browser.dart';
|
||||
|
||||
class GeckoView extends StatelessWidget {
|
||||
const GeckoView({super.key});
|
||||
final FutureOr<void> Function()? preInitializationStep;
|
||||
|
||||
const GeckoView({super.key, this.preInitializationStep});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -35,6 +39,7 @@ class GeckoView extends StatelessWidget {
|
||||
params.onPlatformViewCreated(value);
|
||||
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
||||
await preInitializationStep?.call();
|
||||
await GeckoBrowserService().showNativeFragment();
|
||||
});
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Autogenerated from Pigeon (v22.4.2), do not edit directly.
|
||||
// Autogenerated from Pigeon (v22.5.0), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
|
||||
|
||||
@@ -1589,6 +1589,28 @@ class GeckoSessionApi {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Uint8List?> requestScreenshot() async {
|
||||
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoSessionApi.requestScreenshot$pigeonVar_messageChannelSuffix';
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
pigeonVar_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: pigeonVar_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? pigeonVar_replyList =
|
||||
await pigeonVar_channel.send(null) 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 (pigeonVar_replyList[0] as Uint8List?);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class GeckoTabsApi {
|
||||
@@ -1604,6 +1626,28 @@ class GeckoTabsApi {
|
||||
|
||||
final String pigeonVar_messageChannelSuffix;
|
||||
|
||||
Future<void> syncEvents({required bool onSelectedTabChange, required bool onTabListChange, required bool onTabContentStateChange, required bool onIconChange, required bool onSecurityInfoStateChange, required bool onReaderableStateChange, required bool onHistoryStateChange, required bool onFindResults, required bool onThumbnailChange,}) async {
|
||||
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoTabsApi.syncEvents$pigeonVar_messageChannelSuffix';
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
pigeonVar_channelName,
|
||||
pigeonChannelCodec,
|
||||
binaryMessenger: pigeonVar_binaryMessenger,
|
||||
);
|
||||
final List<Object?>? pigeonVar_replyList =
|
||||
await pigeonVar_channel.send(<Object?>[onSelectedTabChange, onTabListChange, onTabContentStateChange, onIconChange, onSecurityInfoStateChange, onReaderableStateChange, onHistoryStateChange, onFindResults, onThumbnailChange]) 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> selectTab({required String tabId}) async {
|
||||
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoTabsApi.selectTab$pigeonVar_messageChannelSuffix';
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
@@ -2199,6 +2243,8 @@ class GeckoCookieApi {
|
||||
abstract class GeckoStateEvents {
|
||||
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
|
||||
|
||||
void onFragmentReadyStateChange(bool state);
|
||||
|
||||
void onTabListChange(List<String> tabIds);
|
||||
|
||||
void onSelectedTabChange(String? id);
|
||||
@@ -2219,6 +2265,31 @@ abstract class GeckoStateEvents {
|
||||
|
||||
static void setUp(GeckoStateEvents? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) {
|
||||
messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
|
||||
{
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onFragmentReadyStateChange$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.onFragmentReadyStateChange was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
final bool? arg_state = (args[0] as bool?);
|
||||
assert(arg_state != null,
|
||||
'Argument for dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onFragmentReadyStateChange was null, expected non-null bool.');
|
||||
try {
|
||||
api.onFragmentReadyStateChange(arg_state!);
|
||||
return wrapResponse(empty: true);
|
||||
} on PlatformException catch (e) {
|
||||
return wrapResponse(error: e);
|
||||
} catch (e) {
|
||||
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
{
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onTabListChange$messageChannelSuffix', pigeonChannelCodec,
|
||||
@@ -2522,8 +2593,6 @@ abstract class ReaderViewController {
|
||||
|
||||
void appearanceButtonVisibility(bool visible);
|
||||
|
||||
void readerViewButtonVisibility(bool visible);
|
||||
|
||||
static void setUp(ReaderViewController? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) {
|
||||
messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : '';
|
||||
{
|
||||
@@ -2551,31 +2620,6 @@ abstract class ReaderViewController {
|
||||
});
|
||||
}
|
||||
}
|
||||
{
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.flutter_mozilla_components.ReaderViewController.readerViewButtonVisibility$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.ReaderViewController.readerViewButtonVisibility was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
final bool? arg_visible = (args[0] as bool?);
|
||||
assert(arg_visible != null,
|
||||
'Argument for dev.flutter.pigeon.flutter_mozilla_components.ReaderViewController.readerViewButtonVisibility was null, expected non-null bool.');
|
||||
try {
|
||||
api.readerViewButtonVisibility(arg_visible!);
|
||||
return wrapResponse(empty: true);
|
||||
} on PlatformException catch (e) {
|
||||
return wrapResponse(error: e);
|
||||
} catch (e) {
|
||||
return wrapResponse(error: PlatformException(code: 'error', message: e.toString()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user