getting there
This commit is contained in:
Vendored
+23
@@ -26,6 +26,29 @@
|
|||||||
"type": "dart",
|
"type": "dart",
|
||||||
"flutterMode": "release",
|
"flutterMode": "release",
|
||||||
"args": ["--device-user", "0"]
|
"args": ["--device-user", "0"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "example",
|
||||||
|
"cwd": "packages/flutter_mozilla_components/example",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"args": ["--device-user", "0"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "example (profile mode)",
|
||||||
|
"cwd": "packages/flutter_mozilla_components/example",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"flutterMode": "profile",
|
||||||
|
"args": ["--device-user", "0"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "example (release mode)",
|
||||||
|
"cwd": "packages/flutter_mozilla_components/example",
|
||||||
|
"request": "launch",
|
||||||
|
"type": "dart",
|
||||||
|
"flutterMode": "release",
|
||||||
|
"args": ["--device-user", "0"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,47 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
|
<!-- This is needed because the android.permission.CAMERA above automatically
|
||||||
|
adds a requirements for camera hardware and we don't want add those restrictions -->
|
||||||
|
<uses-feature
|
||||||
|
android:name="android.hardware.camera"
|
||||||
|
android:required="false" />
|
||||||
|
<uses-feature
|
||||||
|
android:name="android.hardware.camera.autofocus"
|
||||||
|
android:required="false" />
|
||||||
|
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
||||||
|
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.READ_EXTERNAL_STORAGE"
|
||||||
|
android:maxSdkVersion="32" />
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
|
android:maxSdkVersion="28" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
|
||||||
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
|
|
||||||
|
<!-- Needed for uploading media files on devices with Android 13 and later. -->
|
||||||
|
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:label="Lensai"
|
android:label="Lensai"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/launcher_icon"
|
android:icon="@mipmap/launcher_icon"
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true">
|
||||||
|
<activity android:name="eu.lensai.flutter_mozilla_components.NotificationActivity" android:theme="@style/Theme.AppCompat.Translucent" />
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
@@ -46,6 +83,7 @@
|
|||||||
<data android:mimeType="application/pdf" />
|
<data android:mimeType="application/pdf" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<receiver android:name="FullWidgetProvider" android:exported="true">
|
<receiver android:name="FullWidgetProvider" android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
@@ -54,6 +92,7 @@
|
|||||||
<meta-data android:name="android.appwidget.provider"
|
<meta-data android:name="android.appwidget.provider"
|
||||||
android:resource="@xml/full_widget_info"/>
|
android:resource="@xml/full_widget_info"/>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<receiver android:name="CompactWidgetProvider" android:exported="true">
|
<receiver android:name="CompactWidgetProvider" android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
@@ -62,6 +101,7 @@
|
|||||||
<meta-data android:name="android.appwidget.provider"
|
<meta-data android:name="android.appwidget.provider"
|
||||||
android:resource="@xml/compact_widget_info"/>
|
android:resource="@xml/compact_widget_info"/>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<receiver android:name="SearchBarWidgetProvider" android:exported="true">
|
<receiver android:name="SearchBarWidgetProvider" android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
@@ -70,6 +110,15 @@
|
|||||||
<meta-data android:name="android.appwidget.provider"
|
<meta-data android:name="android.appwidget.provider"
|
||||||
android:resource="@xml/search_bar_widget_info"/>
|
android:resource="@xml/search_bar_widget_info"/>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name="eu.lensai.flutter_mozilla_components.DownloadService"
|
||||||
|
android:foregroundServiceType="dataSync" />
|
||||||
|
|
||||||
|
<service android:name="eu.lensai.flutter_mozilla_components.MediaSessionService"
|
||||||
|
android:foregroundServiceType="mediaPlayback"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
<!-- Don't delete the meta-data below.
|
<!-- Don't delete the meta-data below.
|
||||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||||
<meta-data
|
<meta-data
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
package me.movenext.bang_navigator
|
package me.movenext.bang_navigator
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterFragmentActivity
|
||||||
|
|
||||||
class MainActivity: FlutterActivity()
|
class MainActivity: FlutterFragmentActivity()
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import 'package:fast_equatable/fast_equatable.dart';
|
||||||
|
|
||||||
|
class EquatableCollection<T> with FastEquatable {
|
||||||
|
final T collection;
|
||||||
|
final bool immutable;
|
||||||
|
|
||||||
|
EquatableCollection(this.collection, {required this.immutable})
|
||||||
|
: assert(
|
||||||
|
collection is Map || collection is Iterable,
|
||||||
|
'Collection type not supported',
|
||||||
|
);
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get cacheHash => immutable;
|
||||||
|
|
||||||
|
@override
|
||||||
|
List<Object?> get hashParameters => [
|
||||||
|
collection,
|
||||||
|
immutable,
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -4,9 +4,6 @@ import 'package:exceptions/exceptions.dart';
|
|||||||
import 'package:lensai/features/about/data/repositories/package_info_repository.dart';
|
import 'package:lensai/features/about/data/repositories/package_info_repository.dart';
|
||||||
import 'package:lensai/features/bangs/data/models/bang.dart';
|
import 'package:lensai/features/bangs/data/models/bang.dart';
|
||||||
import 'package:lensai/features/bangs/domain/repositories/sync.dart';
|
import 'package:lensai/features/bangs/domain/repositories/sync.dart';
|
||||||
import 'package:lensai/features/kagi/data/services/session.dart';
|
|
||||||
import 'package:lensai/features/settings/data/models/settings.dart';
|
|
||||||
import 'package:lensai/features/settings/data/repositories/settings_repository.dart';
|
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
part 'app_initialization.g.dart';
|
part 'app_initialization.g.dart';
|
||||||
@@ -46,27 +43,8 @@ class AppInitializationService extends _$AppInitializationService {
|
|||||||
.syncBangGroups(syncInterval: const Duration(days: 7));
|
.syncBangGroups(syncInterval: const Duration(days: 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _initIncognito(Settings settings) async {
|
|
||||||
state = Result.success(
|
|
||||||
(
|
|
||||||
initialized: false,
|
|
||||||
stage: 'Enforcing Privacy...',
|
|
||||||
errors: List.empty(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (settings.kagiSession case final String session) {
|
|
||||||
if (session.isNotEmpty) {
|
|
||||||
await ref
|
|
||||||
.read(kagiSessionServiceProvider.notifier)
|
|
||||||
.setKagiSession(session);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
state = await Result.fromAsync(() async {
|
state = await Result.fromAsync(() async {
|
||||||
final settings = await ref.read(settingsRepositoryProvider.future);
|
|
||||||
final errors = <ErrorMessage>[];
|
final errors = <ErrorMessage>[];
|
||||||
|
|
||||||
await _initPackageInfo();
|
await _initPackageInfo();
|
||||||
@@ -76,8 +54,6 @@ class AppInitializationService extends _$AppInitializationService {
|
|||||||
result.onFailure(errors.add);
|
result.onFailure(errors.add);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _initIncognito(settings);
|
|
||||||
|
|
||||||
return (initialized: true, stage: null, errors: errors);
|
return (initialized: true, stage: null, errors: errors);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ part of 'app_initialization.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$appInitializationServiceHash() =>
|
String _$appInitializationServiceHash() =>
|
||||||
r'0d7dc3eb3ed2e17643f4c34e4e172734ed8d09e2';
|
r'fa383398929c8f3c8b430986304775e044b9af7a';
|
||||||
|
|
||||||
/// See also [AppInitializationService].
|
/// See also [AppInitializationService].
|
||||||
@ProviderFor(AppInitializationService)
|
@ProviderFor(AppInitializationService)
|
||||||
|
|||||||
@@ -1246,122 +1246,191 @@ final class $BangTableReferences
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $BangTableFilterComposer
|
class $BangTableFilterComposer extends Composer<_$BangDatabase, BangTable> {
|
||||||
extends FilterComposer<_$BangDatabase, BangTable> {
|
$BangTableFilterComposer({
|
||||||
$BangTableFilterComposer(super.$state);
|
required super.$db,
|
||||||
ColumnFilters<String> get trigger => $state.composableBuilder(
|
required super.$table,
|
||||||
column: $state.table.trigger,
|
super.joinBuilder,
|
||||||
builder: (column, joinBuilders) =>
|
super.$addJoinBuilderToRootComposer,
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnFilters<String> get trigger => $composableBuilder(
|
||||||
|
column: $table.trigger, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnWithTypeConverterFilters<BangGroup, BangGroup, int> get group =>
|
ColumnWithTypeConverterFilters<BangGroup, BangGroup, int> get group =>
|
||||||
$state.composableBuilder(
|
$composableBuilder(
|
||||||
column: $state.table.group,
|
column: $table.group,
|
||||||
builder: (column, joinBuilders) => ColumnWithTypeConverterFilters(
|
builder: (column) => ColumnWithTypeConverterFilters(column));
|
||||||
column,
|
|
||||||
joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnFilters<String> get websiteName => $state.composableBuilder(
|
ColumnFilters<String> get websiteName => $composableBuilder(
|
||||||
column: $state.table.websiteName,
|
column: $table.websiteName, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnFilters<String> get domain => $state.composableBuilder(
|
ColumnFilters<String> get domain => $composableBuilder(
|
||||||
column: $state.table.domain,
|
column: $table.domain, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnFilters<String> get urlTemplate => $state.composableBuilder(
|
ColumnFilters<String> get urlTemplate => $composableBuilder(
|
||||||
column: $state.table.urlTemplate,
|
column: $table.urlTemplate, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnFilters<String> get category => $state.composableBuilder(
|
ColumnFilters<String> get category => $composableBuilder(
|
||||||
column: $state.table.category,
|
column: $table.category, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnFilters<String> get subCategory => $state.composableBuilder(
|
ColumnFilters<String> get subCategory => $composableBuilder(
|
||||||
column: $state.table.subCategory,
|
column: $table.subCategory, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnWithTypeConverterFilters<Set<BangFormat>?, Set<BangFormat>, String>
|
ColumnWithTypeConverterFilters<Set<BangFormat>?, Set<BangFormat>, String>
|
||||||
get format => $state.composableBuilder(
|
get format => $composableBuilder(
|
||||||
column: $state.table.format,
|
column: $table.format,
|
||||||
builder: (column, joinBuilders) => ColumnWithTypeConverterFilters(
|
builder: (column) => ColumnWithTypeConverterFilters(column));
|
||||||
column,
|
|
||||||
joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ComposableFilter bangFrequencyRefs(
|
Expression<bool> bangFrequencyRefs(
|
||||||
ComposableFilter Function($BangFrequencyFilterComposer f) f) {
|
Expression<bool> Function($BangFrequencyFilterComposer f) f) {
|
||||||
final $BangFrequencyFilterComposer composer = $state.composerBuilder(
|
final $BangFrequencyFilterComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
getCurrentColumn: (t) => t.trigger,
|
getCurrentColumn: (t) => t.trigger,
|
||||||
referencedTable: $state.db.bangFrequency,
|
referencedTable: $db.bangFrequency,
|
||||||
getReferencedColumn: (t) => t.trigger,
|
getReferencedColumn: (t) => t.trigger,
|
||||||
builder: (joinBuilder, parentComposers) => $BangFrequencyFilterComposer(
|
builder: (joinBuilder,
|
||||||
ComposerState($state.db, $state.db.bangFrequency, joinBuilder,
|
{$addJoinBuilderToRootComposer,
|
||||||
parentComposers)));
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$BangFrequencyFilterComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.bangFrequency,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
return f(composer);
|
return f(composer);
|
||||||
}
|
}
|
||||||
|
|
||||||
ComposableFilter bangIconRefs(
|
Expression<bool> bangIconRefs(
|
||||||
ComposableFilter Function($BangIconFilterComposer f) f) {
|
Expression<bool> Function($BangIconFilterComposer f) f) {
|
||||||
final $BangIconFilterComposer composer = $state.composerBuilder(
|
final $BangIconFilterComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
getCurrentColumn: (t) => t.trigger,
|
getCurrentColumn: (t) => t.trigger,
|
||||||
referencedTable: $state.db.bangIcon,
|
referencedTable: $db.bangIcon,
|
||||||
getReferencedColumn: (t) => t.trigger,
|
getReferencedColumn: (t) => t.trigger,
|
||||||
builder: (joinBuilder, parentComposers) => $BangIconFilterComposer(
|
builder: (joinBuilder,
|
||||||
ComposerState(
|
{$addJoinBuilderToRootComposer,
|
||||||
$state.db, $state.db.bangIcon, joinBuilder, parentComposers)));
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$BangIconFilterComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.bangIcon,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
return f(composer);
|
return f(composer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $BangTableOrderingComposer
|
class $BangTableOrderingComposer extends Composer<_$BangDatabase, BangTable> {
|
||||||
extends OrderingComposer<_$BangDatabase, BangTable> {
|
$BangTableOrderingComposer({
|
||||||
$BangTableOrderingComposer(super.$state);
|
required super.$db,
|
||||||
ColumnOrderings<String> get trigger => $state.composableBuilder(
|
required super.$table,
|
||||||
column: $state.table.trigger,
|
super.joinBuilder,
|
||||||
builder: (column, joinBuilders) =>
|
super.$addJoinBuilderToRootComposer,
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnOrderings<String> get trigger => $composableBuilder(
|
||||||
|
column: $table.trigger, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<int> get group => $state.composableBuilder(
|
ColumnOrderings<int> get group => $composableBuilder(
|
||||||
column: $state.table.group,
|
column: $table.group, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnOrderings<String> get websiteName => $state.composableBuilder(
|
ColumnOrderings<String> get websiteName => $composableBuilder(
|
||||||
column: $state.table.websiteName,
|
column: $table.websiteName, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnOrderings<String> get domain => $state.composableBuilder(
|
ColumnOrderings<String> get domain => $composableBuilder(
|
||||||
column: $state.table.domain,
|
column: $table.domain, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnOrderings<String> get urlTemplate => $state.composableBuilder(
|
ColumnOrderings<String> get urlTemplate => $composableBuilder(
|
||||||
column: $state.table.urlTemplate,
|
column: $table.urlTemplate, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnOrderings<String> get category => $state.composableBuilder(
|
ColumnOrderings<String> get category => $composableBuilder(
|
||||||
column: $state.table.category,
|
column: $table.category, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnOrderings<String> get subCategory => $state.composableBuilder(
|
ColumnOrderings<String> get subCategory => $composableBuilder(
|
||||||
column: $state.table.subCategory,
|
column: $table.subCategory, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnOrderings<String> get format => $state.composableBuilder(
|
ColumnOrderings<String> get format => $composableBuilder(
|
||||||
column: $state.table.format,
|
column: $table.format, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
}
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
class $BangTableAnnotationComposer extends Composer<_$BangDatabase, BangTable> {
|
||||||
|
$BangTableAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
GeneratedColumn<String> get trigger =>
|
||||||
|
$composableBuilder(column: $table.trigger, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumnWithTypeConverter<BangGroup, int> get group =>
|
||||||
|
$composableBuilder(column: $table.group, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get websiteName => $composableBuilder(
|
||||||
|
column: $table.websiteName, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get domain =>
|
||||||
|
$composableBuilder(column: $table.domain, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get urlTemplate => $composableBuilder(
|
||||||
|
column: $table.urlTemplate, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get category =>
|
||||||
|
$composableBuilder(column: $table.category, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get subCategory => $composableBuilder(
|
||||||
|
column: $table.subCategory, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumnWithTypeConverter<Set<BangFormat>?, String> get format =>
|
||||||
|
$composableBuilder(column: $table.format, builder: (column) => column);
|
||||||
|
|
||||||
|
Expression<T> bangFrequencyRefs<T extends Object>(
|
||||||
|
Expression<T> Function($BangFrequencyAnnotationComposer a) f) {
|
||||||
|
final $BangFrequencyAnnotationComposer composer = $composerBuilder(
|
||||||
|
composer: this,
|
||||||
|
getCurrentColumn: (t) => t.trigger,
|
||||||
|
referencedTable: $db.bangFrequency,
|
||||||
|
getReferencedColumn: (t) => t.trigger,
|
||||||
|
builder: (joinBuilder,
|
||||||
|
{$addJoinBuilderToRootComposer,
|
||||||
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$BangFrequencyAnnotationComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.bangFrequency,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
|
return f(composer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression<T> bangIconRefs<T extends Object>(
|
||||||
|
Expression<T> Function($BangIconAnnotationComposer a) f) {
|
||||||
|
final $BangIconAnnotationComposer composer = $composerBuilder(
|
||||||
|
composer: this,
|
||||||
|
getCurrentColumn: (t) => t.trigger,
|
||||||
|
referencedTable: $db.bangIcon,
|
||||||
|
getReferencedColumn: (t) => t.trigger,
|
||||||
|
builder: (joinBuilder,
|
||||||
|
{$addJoinBuilderToRootComposer,
|
||||||
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$BangIconAnnotationComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.bangIcon,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
|
return f(composer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $BangTableTableManager extends RootTableManager<
|
class $BangTableTableManager extends RootTableManager<
|
||||||
@@ -1370,6 +1439,7 @@ class $BangTableTableManager extends RootTableManager<
|
|||||||
Bang,
|
Bang,
|
||||||
$BangTableFilterComposer,
|
$BangTableFilterComposer,
|
||||||
$BangTableOrderingComposer,
|
$BangTableOrderingComposer,
|
||||||
|
$BangTableAnnotationComposer,
|
||||||
$BangTableCreateCompanionBuilder,
|
$BangTableCreateCompanionBuilder,
|
||||||
$BangTableUpdateCompanionBuilder,
|
$BangTableUpdateCompanionBuilder,
|
||||||
(Bang, $BangTableReferences),
|
(Bang, $BangTableReferences),
|
||||||
@@ -1379,9 +1449,12 @@ class $BangTableTableManager extends RootTableManager<
|
|||||||
: super(TableManagerState(
|
: super(TableManagerState(
|
||||||
db: db,
|
db: db,
|
||||||
table: table,
|
table: table,
|
||||||
filteringComposer: $BangTableFilterComposer(ComposerState(db, table)),
|
createFilteringComposer: () =>
|
||||||
orderingComposer:
|
$BangTableFilterComposer($db: db, $table: table),
|
||||||
$BangTableOrderingComposer(ComposerState(db, table)),
|
createOrderingComposer: () =>
|
||||||
|
$BangTableOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer: () =>
|
||||||
|
$BangTableAnnotationComposer($db: db, $table: table),
|
||||||
updateCompanionCallback: ({
|
updateCompanionCallback: ({
|
||||||
Value<String> trigger = const Value.absent(),
|
Value<String> trigger = const Value.absent(),
|
||||||
Value<BangGroup> group = const Value.absent(),
|
Value<BangGroup> group = const Value.absent(),
|
||||||
@@ -1477,6 +1550,7 @@ typedef $BangTableProcessedTableManager = ProcessedTableManager<
|
|||||||
Bang,
|
Bang,
|
||||||
$BangTableFilterComposer,
|
$BangTableFilterComposer,
|
||||||
$BangTableOrderingComposer,
|
$BangTableOrderingComposer,
|
||||||
|
$BangTableAnnotationComposer,
|
||||||
$BangTableCreateCompanionBuilder,
|
$BangTableCreateCompanionBuilder,
|
||||||
$BangTableUpdateCompanionBuilder,
|
$BangTableUpdateCompanionBuilder,
|
||||||
(Bang, $BangTableReferences),
|
(Bang, $BangTableReferences),
|
||||||
@@ -1491,33 +1565,51 @@ typedef $BangSyncUpdateCompanionBuilder = BangSyncCompanion Function({
|
|||||||
Value<DateTime> lastSync,
|
Value<DateTime> lastSync,
|
||||||
});
|
});
|
||||||
|
|
||||||
class $BangSyncFilterComposer extends FilterComposer<_$BangDatabase, BangSync> {
|
class $BangSyncFilterComposer extends Composer<_$BangDatabase, BangSync> {
|
||||||
$BangSyncFilterComposer(super.$state);
|
$BangSyncFilterComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
ColumnWithTypeConverterFilters<BangGroup, BangGroup, int> get group =>
|
ColumnWithTypeConverterFilters<BangGroup, BangGroup, int> get group =>
|
||||||
$state.composableBuilder(
|
$composableBuilder(
|
||||||
column: $state.table.group,
|
column: $table.group,
|
||||||
builder: (column, joinBuilders) => ColumnWithTypeConverterFilters(
|
builder: (column) => ColumnWithTypeConverterFilters(column));
|
||||||
column,
|
|
||||||
joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnFilters<DateTime> get lastSync => $state.composableBuilder(
|
ColumnFilters<DateTime> get lastSync => $composableBuilder(
|
||||||
column: $state.table.lastSync,
|
column: $table.lastSync, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class $BangSyncOrderingComposer
|
class $BangSyncOrderingComposer extends Composer<_$BangDatabase, BangSync> {
|
||||||
extends OrderingComposer<_$BangDatabase, BangSync> {
|
$BangSyncOrderingComposer({
|
||||||
$BangSyncOrderingComposer(super.$state);
|
required super.$db,
|
||||||
ColumnOrderings<int> get group => $state.composableBuilder(
|
required super.$table,
|
||||||
column: $state.table.group,
|
super.joinBuilder,
|
||||||
builder: (column, joinBuilders) =>
|
super.$addJoinBuilderToRootComposer,
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnOrderings<int> get group => $composableBuilder(
|
||||||
|
column: $table.group, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<DateTime> get lastSync => $state.composableBuilder(
|
ColumnOrderings<DateTime> get lastSync => $composableBuilder(
|
||||||
column: $state.table.lastSync,
|
column: $table.lastSync, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
}
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
class $BangSyncAnnotationComposer extends Composer<_$BangDatabase, BangSync> {
|
||||||
|
$BangSyncAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
GeneratedColumnWithTypeConverter<BangGroup, int> get group =>
|
||||||
|
$composableBuilder(column: $table.group, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<DateTime> get lastSync =>
|
||||||
|
$composableBuilder(column: $table.lastSync, builder: (column) => column);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $BangSyncTableManager extends RootTableManager<
|
class $BangSyncTableManager extends RootTableManager<
|
||||||
@@ -1526,6 +1618,7 @@ class $BangSyncTableManager extends RootTableManager<
|
|||||||
BangSyncData,
|
BangSyncData,
|
||||||
$BangSyncFilterComposer,
|
$BangSyncFilterComposer,
|
||||||
$BangSyncOrderingComposer,
|
$BangSyncOrderingComposer,
|
||||||
|
$BangSyncAnnotationComposer,
|
||||||
$BangSyncCreateCompanionBuilder,
|
$BangSyncCreateCompanionBuilder,
|
||||||
$BangSyncUpdateCompanionBuilder,
|
$BangSyncUpdateCompanionBuilder,
|
||||||
(BangSyncData, BaseReferences<_$BangDatabase, BangSync, BangSyncData>),
|
(BangSyncData, BaseReferences<_$BangDatabase, BangSync, BangSyncData>),
|
||||||
@@ -1535,8 +1628,12 @@ class $BangSyncTableManager extends RootTableManager<
|
|||||||
: super(TableManagerState(
|
: super(TableManagerState(
|
||||||
db: db,
|
db: db,
|
||||||
table: table,
|
table: table,
|
||||||
filteringComposer: $BangSyncFilterComposer(ComposerState(db, table)),
|
createFilteringComposer: () =>
|
||||||
orderingComposer: $BangSyncOrderingComposer(ComposerState(db, table)),
|
$BangSyncFilterComposer($db: db, $table: table),
|
||||||
|
createOrderingComposer: () =>
|
||||||
|
$BangSyncOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer: () =>
|
||||||
|
$BangSyncAnnotationComposer($db: db, $table: table),
|
||||||
updateCompanionCallback: ({
|
updateCompanionCallback: ({
|
||||||
Value<BangGroup> group = const Value.absent(),
|
Value<BangGroup> group = const Value.absent(),
|
||||||
Value<DateTime> lastSync = const Value.absent(),
|
Value<DateTime> lastSync = const Value.absent(),
|
||||||
@@ -1566,6 +1663,7 @@ typedef $BangSyncProcessedTableManager = ProcessedTableManager<
|
|||||||
BangSyncData,
|
BangSyncData,
|
||||||
$BangSyncFilterComposer,
|
$BangSyncFilterComposer,
|
||||||
$BangSyncOrderingComposer,
|
$BangSyncOrderingComposer,
|
||||||
|
$BangSyncAnnotationComposer,
|
||||||
$BangSyncCreateCompanionBuilder,
|
$BangSyncCreateCompanionBuilder,
|
||||||
$BangSyncUpdateCompanionBuilder,
|
$BangSyncUpdateCompanionBuilder,
|
||||||
(BangSyncData, BaseReferences<_$BangDatabase, BangSync, BangSyncData>),
|
(BangSyncData, BaseReferences<_$BangDatabase, BangSync, BangSyncData>),
|
||||||
@@ -1603,53 +1701,109 @@ final class $BangFrequencyReferences
|
|||||||
}
|
}
|
||||||
|
|
||||||
class $BangFrequencyFilterComposer
|
class $BangFrequencyFilterComposer
|
||||||
extends FilterComposer<_$BangDatabase, BangFrequency> {
|
extends Composer<_$BangDatabase, BangFrequency> {
|
||||||
$BangFrequencyFilterComposer(super.$state);
|
$BangFrequencyFilterComposer({
|
||||||
ColumnFilters<int> get frequency => $state.composableBuilder(
|
required super.$db,
|
||||||
column: $state.table.frequency,
|
required super.$table,
|
||||||
builder: (column, joinBuilders) =>
|
super.joinBuilder,
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnFilters<int> get frequency => $composableBuilder(
|
||||||
|
column: $table.frequency, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<DateTime> get lastUsed => $state.composableBuilder(
|
ColumnFilters<DateTime> get lastUsed => $composableBuilder(
|
||||||
column: $state.table.lastUsed,
|
column: $table.lastUsed, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
$BangTableFilterComposer get trigger {
|
$BangTableFilterComposer get trigger {
|
||||||
final $BangTableFilterComposer composer = $state.composerBuilder(
|
final $BangTableFilterComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
getCurrentColumn: (t) => t.trigger,
|
getCurrentColumn: (t) => t.trigger,
|
||||||
referencedTable: $state.db.bang,
|
referencedTable: $db.bang,
|
||||||
getReferencedColumn: (t) => t.trigger,
|
getReferencedColumn: (t) => t.trigger,
|
||||||
builder: (joinBuilder, parentComposers) => $BangTableFilterComposer(
|
builder: (joinBuilder,
|
||||||
ComposerState(
|
{$addJoinBuilderToRootComposer,
|
||||||
$state.db, $state.db.bang, joinBuilder, parentComposers)));
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$BangTableFilterComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.bang,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
return composer;
|
return composer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $BangFrequencyOrderingComposer
|
class $BangFrequencyOrderingComposer
|
||||||
extends OrderingComposer<_$BangDatabase, BangFrequency> {
|
extends Composer<_$BangDatabase, BangFrequency> {
|
||||||
$BangFrequencyOrderingComposer(super.$state);
|
$BangFrequencyOrderingComposer({
|
||||||
ColumnOrderings<int> get frequency => $state.composableBuilder(
|
required super.$db,
|
||||||
column: $state.table.frequency,
|
required super.$table,
|
||||||
builder: (column, joinBuilders) =>
|
super.joinBuilder,
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnOrderings<int> get frequency => $composableBuilder(
|
||||||
|
column: $table.frequency, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<DateTime> get lastUsed => $state.composableBuilder(
|
ColumnOrderings<DateTime> get lastUsed => $composableBuilder(
|
||||||
column: $state.table.lastUsed,
|
column: $table.lastUsed, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
$BangTableOrderingComposer get trigger {
|
$BangTableOrderingComposer get trigger {
|
||||||
final $BangTableOrderingComposer composer = $state.composerBuilder(
|
final $BangTableOrderingComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
getCurrentColumn: (t) => t.trigger,
|
getCurrentColumn: (t) => t.trigger,
|
||||||
referencedTable: $state.db.bang,
|
referencedTable: $db.bang,
|
||||||
getReferencedColumn: (t) => t.trigger,
|
getReferencedColumn: (t) => t.trigger,
|
||||||
builder: (joinBuilder, parentComposers) => $BangTableOrderingComposer(
|
builder: (joinBuilder,
|
||||||
ComposerState(
|
{$addJoinBuilderToRootComposer,
|
||||||
$state.db, $state.db.bang, joinBuilder, parentComposers)));
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$BangTableOrderingComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.bang,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
|
return composer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class $BangFrequencyAnnotationComposer
|
||||||
|
extends Composer<_$BangDatabase, BangFrequency> {
|
||||||
|
$BangFrequencyAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
GeneratedColumn<int> get frequency =>
|
||||||
|
$composableBuilder(column: $table.frequency, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<DateTime> get lastUsed =>
|
||||||
|
$composableBuilder(column: $table.lastUsed, builder: (column) => column);
|
||||||
|
|
||||||
|
$BangTableAnnotationComposer get trigger {
|
||||||
|
final $BangTableAnnotationComposer composer = $composerBuilder(
|
||||||
|
composer: this,
|
||||||
|
getCurrentColumn: (t) => t.trigger,
|
||||||
|
referencedTable: $db.bang,
|
||||||
|
getReferencedColumn: (t) => t.trigger,
|
||||||
|
builder: (joinBuilder,
|
||||||
|
{$addJoinBuilderToRootComposer,
|
||||||
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$BangTableAnnotationComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.bang,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
return composer;
|
return composer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1660,6 +1814,7 @@ class $BangFrequencyTableManager extends RootTableManager<
|
|||||||
BangFrequencyData,
|
BangFrequencyData,
|
||||||
$BangFrequencyFilterComposer,
|
$BangFrequencyFilterComposer,
|
||||||
$BangFrequencyOrderingComposer,
|
$BangFrequencyOrderingComposer,
|
||||||
|
$BangFrequencyAnnotationComposer,
|
||||||
$BangFrequencyCreateCompanionBuilder,
|
$BangFrequencyCreateCompanionBuilder,
|
||||||
$BangFrequencyUpdateCompanionBuilder,
|
$BangFrequencyUpdateCompanionBuilder,
|
||||||
(BangFrequencyData, $BangFrequencyReferences),
|
(BangFrequencyData, $BangFrequencyReferences),
|
||||||
@@ -1669,10 +1824,12 @@ class $BangFrequencyTableManager extends RootTableManager<
|
|||||||
: super(TableManagerState(
|
: super(TableManagerState(
|
||||||
db: db,
|
db: db,
|
||||||
table: table,
|
table: table,
|
||||||
filteringComposer:
|
createFilteringComposer: () =>
|
||||||
$BangFrequencyFilterComposer(ComposerState(db, table)),
|
$BangFrequencyFilterComposer($db: db, $table: table),
|
||||||
orderingComposer:
|
createOrderingComposer: () =>
|
||||||
$BangFrequencyOrderingComposer(ComposerState(db, table)),
|
$BangFrequencyOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer: () =>
|
||||||
|
$BangFrequencyAnnotationComposer($db: db, $table: table),
|
||||||
updateCompanionCallback: ({
|
updateCompanionCallback: ({
|
||||||
Value<String> trigger = const Value.absent(),
|
Value<String> trigger = const Value.absent(),
|
||||||
Value<int> frequency = const Value.absent(),
|
Value<int> frequency = const Value.absent(),
|
||||||
@@ -1716,6 +1873,7 @@ class $BangFrequencyTableManager extends RootTableManager<
|
|||||||
dynamic,
|
dynamic,
|
||||||
dynamic,
|
dynamic,
|
||||||
dynamic,
|
dynamic,
|
||||||
|
dynamic,
|
||||||
dynamic>>(state) {
|
dynamic>>(state) {
|
||||||
if (trigger) {
|
if (trigger) {
|
||||||
state = state.withJoin(
|
state = state.withJoin(
|
||||||
@@ -1743,6 +1901,7 @@ typedef $BangFrequencyProcessedTableManager = ProcessedTableManager<
|
|||||||
BangFrequencyData,
|
BangFrequencyData,
|
||||||
$BangFrequencyFilterComposer,
|
$BangFrequencyFilterComposer,
|
||||||
$BangFrequencyOrderingComposer,
|
$BangFrequencyOrderingComposer,
|
||||||
|
$BangFrequencyAnnotationComposer,
|
||||||
$BangFrequencyCreateCompanionBuilder,
|
$BangFrequencyCreateCompanionBuilder,
|
||||||
$BangFrequencyUpdateCompanionBuilder,
|
$BangFrequencyUpdateCompanionBuilder,
|
||||||
(BangFrequencyData, $BangFrequencyReferences),
|
(BangFrequencyData, $BangFrequencyReferences),
|
||||||
@@ -1779,53 +1938,107 @@ final class $BangIconReferences
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $BangIconFilterComposer extends FilterComposer<_$BangDatabase, BangIcon> {
|
class $BangIconFilterComposer extends Composer<_$BangDatabase, BangIcon> {
|
||||||
$BangIconFilterComposer(super.$state);
|
$BangIconFilterComposer({
|
||||||
ColumnFilters<Uint8List> get iconData => $state.composableBuilder(
|
required super.$db,
|
||||||
column: $state.table.iconData,
|
required super.$table,
|
||||||
builder: (column, joinBuilders) =>
|
super.joinBuilder,
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnFilters<Uint8List> get iconData => $composableBuilder(
|
||||||
|
column: $table.iconData, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<DateTime> get fetchDate => $state.composableBuilder(
|
ColumnFilters<DateTime> get fetchDate => $composableBuilder(
|
||||||
column: $state.table.fetchDate,
|
column: $table.fetchDate, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
$BangTableFilterComposer get trigger {
|
$BangTableFilterComposer get trigger {
|
||||||
final $BangTableFilterComposer composer = $state.composerBuilder(
|
final $BangTableFilterComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
getCurrentColumn: (t) => t.trigger,
|
getCurrentColumn: (t) => t.trigger,
|
||||||
referencedTable: $state.db.bang,
|
referencedTable: $db.bang,
|
||||||
getReferencedColumn: (t) => t.trigger,
|
getReferencedColumn: (t) => t.trigger,
|
||||||
builder: (joinBuilder, parentComposers) => $BangTableFilterComposer(
|
builder: (joinBuilder,
|
||||||
ComposerState(
|
{$addJoinBuilderToRootComposer,
|
||||||
$state.db, $state.db.bang, joinBuilder, parentComposers)));
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$BangTableFilterComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.bang,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
return composer;
|
return composer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $BangIconOrderingComposer
|
class $BangIconOrderingComposer extends Composer<_$BangDatabase, BangIcon> {
|
||||||
extends OrderingComposer<_$BangDatabase, BangIcon> {
|
$BangIconOrderingComposer({
|
||||||
$BangIconOrderingComposer(super.$state);
|
required super.$db,
|
||||||
ColumnOrderings<Uint8List> get iconData => $state.composableBuilder(
|
required super.$table,
|
||||||
column: $state.table.iconData,
|
super.joinBuilder,
|
||||||
builder: (column, joinBuilders) =>
|
super.$addJoinBuilderToRootComposer,
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnOrderings<Uint8List> get iconData => $composableBuilder(
|
||||||
|
column: $table.iconData, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<DateTime> get fetchDate => $state.composableBuilder(
|
ColumnOrderings<DateTime> get fetchDate => $composableBuilder(
|
||||||
column: $state.table.fetchDate,
|
column: $table.fetchDate, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
$BangTableOrderingComposer get trigger {
|
$BangTableOrderingComposer get trigger {
|
||||||
final $BangTableOrderingComposer composer = $state.composerBuilder(
|
final $BangTableOrderingComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
getCurrentColumn: (t) => t.trigger,
|
getCurrentColumn: (t) => t.trigger,
|
||||||
referencedTable: $state.db.bang,
|
referencedTable: $db.bang,
|
||||||
getReferencedColumn: (t) => t.trigger,
|
getReferencedColumn: (t) => t.trigger,
|
||||||
builder: (joinBuilder, parentComposers) => $BangTableOrderingComposer(
|
builder: (joinBuilder,
|
||||||
ComposerState(
|
{$addJoinBuilderToRootComposer,
|
||||||
$state.db, $state.db.bang, joinBuilder, parentComposers)));
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$BangTableOrderingComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.bang,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
|
return composer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class $BangIconAnnotationComposer extends Composer<_$BangDatabase, BangIcon> {
|
||||||
|
$BangIconAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
GeneratedColumn<Uint8List> get iconData =>
|
||||||
|
$composableBuilder(column: $table.iconData, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<DateTime> get fetchDate =>
|
||||||
|
$composableBuilder(column: $table.fetchDate, builder: (column) => column);
|
||||||
|
|
||||||
|
$BangTableAnnotationComposer get trigger {
|
||||||
|
final $BangTableAnnotationComposer composer = $composerBuilder(
|
||||||
|
composer: this,
|
||||||
|
getCurrentColumn: (t) => t.trigger,
|
||||||
|
referencedTable: $db.bang,
|
||||||
|
getReferencedColumn: (t) => t.trigger,
|
||||||
|
builder: (joinBuilder,
|
||||||
|
{$addJoinBuilderToRootComposer,
|
||||||
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$BangTableAnnotationComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.bang,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
return composer;
|
return composer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1836,6 +2049,7 @@ class $BangIconTableManager extends RootTableManager<
|
|||||||
BangIconData,
|
BangIconData,
|
||||||
$BangIconFilterComposer,
|
$BangIconFilterComposer,
|
||||||
$BangIconOrderingComposer,
|
$BangIconOrderingComposer,
|
||||||
|
$BangIconAnnotationComposer,
|
||||||
$BangIconCreateCompanionBuilder,
|
$BangIconCreateCompanionBuilder,
|
||||||
$BangIconUpdateCompanionBuilder,
|
$BangIconUpdateCompanionBuilder,
|
||||||
(BangIconData, $BangIconReferences),
|
(BangIconData, $BangIconReferences),
|
||||||
@@ -1845,8 +2059,12 @@ class $BangIconTableManager extends RootTableManager<
|
|||||||
: super(TableManagerState(
|
: super(TableManagerState(
|
||||||
db: db,
|
db: db,
|
||||||
table: table,
|
table: table,
|
||||||
filteringComposer: $BangIconFilterComposer(ComposerState(db, table)),
|
createFilteringComposer: () =>
|
||||||
orderingComposer: $BangIconOrderingComposer(ComposerState(db, table)),
|
$BangIconFilterComposer($db: db, $table: table),
|
||||||
|
createOrderingComposer: () =>
|
||||||
|
$BangIconOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer: () =>
|
||||||
|
$BangIconAnnotationComposer($db: db, $table: table),
|
||||||
updateCompanionCallback: ({
|
updateCompanionCallback: ({
|
||||||
Value<String> trigger = const Value.absent(),
|
Value<String> trigger = const Value.absent(),
|
||||||
Value<Uint8List> iconData = const Value.absent(),
|
Value<Uint8List> iconData = const Value.absent(),
|
||||||
@@ -1890,6 +2108,7 @@ class $BangIconTableManager extends RootTableManager<
|
|||||||
dynamic,
|
dynamic,
|
||||||
dynamic,
|
dynamic,
|
||||||
dynamic,
|
dynamic,
|
||||||
|
dynamic,
|
||||||
dynamic>>(state) {
|
dynamic>>(state) {
|
||||||
if (trigger) {
|
if (trigger) {
|
||||||
state = state.withJoin(
|
state = state.withJoin(
|
||||||
@@ -1917,6 +2136,7 @@ typedef $BangIconProcessedTableManager = ProcessedTableManager<
|
|||||||
BangIconData,
|
BangIconData,
|
||||||
$BangIconFilterComposer,
|
$BangIconFilterComposer,
|
||||||
$BangIconOrderingComposer,
|
$BangIconOrderingComposer,
|
||||||
|
$BangIconAnnotationComposer,
|
||||||
$BangIconCreateCompanionBuilder,
|
$BangIconCreateCompanionBuilder,
|
||||||
$BangIconUpdateCompanionBuilder,
|
$BangIconUpdateCompanionBuilder,
|
||||||
(BangIconData, $BangIconReferences),
|
(BangIconData, $BangIconReferences),
|
||||||
@@ -1933,31 +2153,49 @@ typedef $BangFtsUpdateCompanionBuilder = BangFtsCompanion Function({
|
|||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
|
|
||||||
class $BangFtsFilterComposer extends FilterComposer<_$BangDatabase, BangFts> {
|
class $BangFtsFilterComposer extends Composer<_$BangDatabase, BangFts> {
|
||||||
$BangFtsFilterComposer(super.$state);
|
$BangFtsFilterComposer({
|
||||||
ColumnFilters<String> get trigger => $state.composableBuilder(
|
required super.$db,
|
||||||
column: $state.table.trigger,
|
required super.$table,
|
||||||
builder: (column, joinBuilders) =>
|
super.joinBuilder,
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnFilters<String> get trigger => $composableBuilder(
|
||||||
|
column: $table.trigger, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<String> get websiteName => $state.composableBuilder(
|
ColumnFilters<String> get websiteName => $composableBuilder(
|
||||||
column: $state.table.websiteName,
|
column: $table.websiteName, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class $BangFtsOrderingComposer
|
class $BangFtsOrderingComposer extends Composer<_$BangDatabase, BangFts> {
|
||||||
extends OrderingComposer<_$BangDatabase, BangFts> {
|
$BangFtsOrderingComposer({
|
||||||
$BangFtsOrderingComposer(super.$state);
|
required super.$db,
|
||||||
ColumnOrderings<String> get trigger => $state.composableBuilder(
|
required super.$table,
|
||||||
column: $state.table.trigger,
|
super.joinBuilder,
|
||||||
builder: (column, joinBuilders) =>
|
super.$addJoinBuilderToRootComposer,
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnOrderings<String> get trigger => $composableBuilder(
|
||||||
|
column: $table.trigger, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<String> get websiteName => $state.composableBuilder(
|
ColumnOrderings<String> get websiteName => $composableBuilder(
|
||||||
column: $state.table.websiteName,
|
column: $table.websiteName, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
}
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
class $BangFtsAnnotationComposer extends Composer<_$BangDatabase, BangFts> {
|
||||||
|
$BangFtsAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
GeneratedColumn<String> get trigger =>
|
||||||
|
$composableBuilder(column: $table.trigger, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get websiteName => $composableBuilder(
|
||||||
|
column: $table.websiteName, builder: (column) => column);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $BangFtsTableManager extends RootTableManager<
|
class $BangFtsTableManager extends RootTableManager<
|
||||||
@@ -1966,6 +2204,7 @@ class $BangFtsTableManager extends RootTableManager<
|
|||||||
BangFt,
|
BangFt,
|
||||||
$BangFtsFilterComposer,
|
$BangFtsFilterComposer,
|
||||||
$BangFtsOrderingComposer,
|
$BangFtsOrderingComposer,
|
||||||
|
$BangFtsAnnotationComposer,
|
||||||
$BangFtsCreateCompanionBuilder,
|
$BangFtsCreateCompanionBuilder,
|
||||||
$BangFtsUpdateCompanionBuilder,
|
$BangFtsUpdateCompanionBuilder,
|
||||||
(BangFt, BaseReferences<_$BangDatabase, BangFts, BangFt>),
|
(BangFt, BaseReferences<_$BangDatabase, BangFts, BangFt>),
|
||||||
@@ -1975,8 +2214,12 @@ class $BangFtsTableManager extends RootTableManager<
|
|||||||
: super(TableManagerState(
|
: super(TableManagerState(
|
||||||
db: db,
|
db: db,
|
||||||
table: table,
|
table: table,
|
||||||
filteringComposer: $BangFtsFilterComposer(ComposerState(db, table)),
|
createFilteringComposer: () =>
|
||||||
orderingComposer: $BangFtsOrderingComposer(ComposerState(db, table)),
|
$BangFtsFilterComposer($db: db, $table: table),
|
||||||
|
createOrderingComposer: () =>
|
||||||
|
$BangFtsOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer: () =>
|
||||||
|
$BangFtsAnnotationComposer($db: db, $table: table),
|
||||||
updateCompanionCallback: ({
|
updateCompanionCallback: ({
|
||||||
Value<String> trigger = const Value.absent(),
|
Value<String> trigger = const Value.absent(),
|
||||||
Value<String> websiteName = const Value.absent(),
|
Value<String> websiteName = const Value.absent(),
|
||||||
@@ -2010,6 +2253,7 @@ typedef $BangFtsProcessedTableManager = ProcessedTableManager<
|
|||||||
BangFt,
|
BangFt,
|
||||||
$BangFtsFilterComposer,
|
$BangFtsFilterComposer,
|
||||||
$BangFtsOrderingComposer,
|
$BangFtsOrderingComposer,
|
||||||
|
$BangFtsAnnotationComposer,
|
||||||
$BangFtsCreateCompanionBuilder,
|
$BangFtsCreateCompanionBuilder,
|
||||||
$BangFtsUpdateCompanionBuilder,
|
$BangFtsUpdateCompanionBuilder,
|
||||||
(BangFt, BaseReferences<_$BangDatabase, BangFts, BangFt>),
|
(BangFt, BaseReferences<_$BangDatabase, BangFts, BangFt>),
|
||||||
|
|||||||
@@ -455,41 +455,58 @@ typedef $ChatUpdateCompanionBuilder = ChatCompanion Function({
|
|||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
|
|
||||||
class $ChatFilterComposer extends FilterComposer<_$ChatSearchDatabase, Chat> {
|
class $ChatFilterComposer extends Composer<_$ChatSearchDatabase, Chat> {
|
||||||
$ChatFilterComposer(super.$state);
|
$ChatFilterComposer({
|
||||||
ColumnFilters<String> get fileName => $state.composableBuilder(
|
required super.$db,
|
||||||
column: $state.table.fileName,
|
required super.$table,
|
||||||
builder: (column, joinBuilders) =>
|
super.joinBuilder,
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnFilters<String> get fileName => $composableBuilder(
|
||||||
|
column: $table.fileName, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<String> get title => $state.composableBuilder(
|
ColumnFilters<String> get title => $composableBuilder(
|
||||||
column: $state.table.title,
|
column: $table.title, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnFilters<String> get content => $state.composableBuilder(
|
ColumnFilters<String> get content => $composableBuilder(
|
||||||
column: $state.table.content,
|
column: $table.content, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class $ChatOrderingComposer
|
class $ChatOrderingComposer extends Composer<_$ChatSearchDatabase, Chat> {
|
||||||
extends OrderingComposer<_$ChatSearchDatabase, Chat> {
|
$ChatOrderingComposer({
|
||||||
$ChatOrderingComposer(super.$state);
|
required super.$db,
|
||||||
ColumnOrderings<String> get fileName => $state.composableBuilder(
|
required super.$table,
|
||||||
column: $state.table.fileName,
|
super.joinBuilder,
|
||||||
builder: (column, joinBuilders) =>
|
super.$addJoinBuilderToRootComposer,
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnOrderings<String> get fileName => $composableBuilder(
|
||||||
|
column: $table.fileName, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<String> get title => $state.composableBuilder(
|
ColumnOrderings<String> get title => $composableBuilder(
|
||||||
column: $state.table.title,
|
column: $table.title, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnOrderings<String> get content => $state.composableBuilder(
|
ColumnOrderings<String> get content => $composableBuilder(
|
||||||
column: $state.table.content,
|
column: $table.content, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
}
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
class $ChatAnnotationComposer extends Composer<_$ChatSearchDatabase, Chat> {
|
||||||
|
$ChatAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
GeneratedColumn<String> get fileName =>
|
||||||
|
$composableBuilder(column: $table.fileName, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get title =>
|
||||||
|
$composableBuilder(column: $table.title, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get content =>
|
||||||
|
$composableBuilder(column: $table.content, builder: (column) => column);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $ChatTableManager extends RootTableManager<
|
class $ChatTableManager extends RootTableManager<
|
||||||
@@ -498,6 +515,7 @@ class $ChatTableManager extends RootTableManager<
|
|||||||
ChatData,
|
ChatData,
|
||||||
$ChatFilterComposer,
|
$ChatFilterComposer,
|
||||||
$ChatOrderingComposer,
|
$ChatOrderingComposer,
|
||||||
|
$ChatAnnotationComposer,
|
||||||
$ChatCreateCompanionBuilder,
|
$ChatCreateCompanionBuilder,
|
||||||
$ChatUpdateCompanionBuilder,
|
$ChatUpdateCompanionBuilder,
|
||||||
(ChatData, BaseReferences<_$ChatSearchDatabase, Chat, ChatData>),
|
(ChatData, BaseReferences<_$ChatSearchDatabase, Chat, ChatData>),
|
||||||
@@ -507,8 +525,12 @@ class $ChatTableManager extends RootTableManager<
|
|||||||
: super(TableManagerState(
|
: super(TableManagerState(
|
||||||
db: db,
|
db: db,
|
||||||
table: table,
|
table: table,
|
||||||
filteringComposer: $ChatFilterComposer(ComposerState(db, table)),
|
createFilteringComposer: () =>
|
||||||
orderingComposer: $ChatOrderingComposer(ComposerState(db, table)),
|
$ChatFilterComposer($db: db, $table: table),
|
||||||
|
createOrderingComposer: () =>
|
||||||
|
$ChatOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer: () =>
|
||||||
|
$ChatAnnotationComposer($db: db, $table: table),
|
||||||
updateCompanionCallback: ({
|
updateCompanionCallback: ({
|
||||||
Value<String> fileName = const Value.absent(),
|
Value<String> fileName = const Value.absent(),
|
||||||
Value<String> title = const Value.absent(),
|
Value<String> title = const Value.absent(),
|
||||||
@@ -546,6 +568,7 @@ typedef $ChatProcessedTableManager = ProcessedTableManager<
|
|||||||
ChatData,
|
ChatData,
|
||||||
$ChatFilterComposer,
|
$ChatFilterComposer,
|
||||||
$ChatOrderingComposer,
|
$ChatOrderingComposer,
|
||||||
|
$ChatAnnotationComposer,
|
||||||
$ChatCreateCompanionBuilder,
|
$ChatCreateCompanionBuilder,
|
||||||
$ChatUpdateCompanionBuilder,
|
$ChatUpdateCompanionBuilder,
|
||||||
(ChatData, BaseReferences<_$ChatSearchDatabase, Chat, ChatData>),
|
(ChatData, BaseReferences<_$ChatSearchDatabase, Chat, ChatData>),
|
||||||
@@ -562,32 +585,50 @@ typedef $ChatFtsUpdateCompanionBuilder = ChatFtsCompanion Function({
|
|||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
|
|
||||||
class $ChatFtsFilterComposer
|
class $ChatFtsFilterComposer extends Composer<_$ChatSearchDatabase, ChatFts> {
|
||||||
extends FilterComposer<_$ChatSearchDatabase, ChatFts> {
|
$ChatFtsFilterComposer({
|
||||||
$ChatFtsFilterComposer(super.$state);
|
required super.$db,
|
||||||
ColumnFilters<String> get title => $state.composableBuilder(
|
required super.$table,
|
||||||
column: $state.table.title,
|
super.joinBuilder,
|
||||||
builder: (column, joinBuilders) =>
|
super.$addJoinBuilderToRootComposer,
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnFilters<String> get title => $composableBuilder(
|
||||||
|
column: $table.title, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<String> get content => $state.composableBuilder(
|
ColumnFilters<String> get content => $composableBuilder(
|
||||||
column: $state.table.content,
|
column: $table.content, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class $ChatFtsOrderingComposer
|
class $ChatFtsOrderingComposer extends Composer<_$ChatSearchDatabase, ChatFts> {
|
||||||
extends OrderingComposer<_$ChatSearchDatabase, ChatFts> {
|
$ChatFtsOrderingComposer({
|
||||||
$ChatFtsOrderingComposer(super.$state);
|
required super.$db,
|
||||||
ColumnOrderings<String> get title => $state.composableBuilder(
|
required super.$table,
|
||||||
column: $state.table.title,
|
super.joinBuilder,
|
||||||
builder: (column, joinBuilders) =>
|
super.$addJoinBuilderToRootComposer,
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnOrderings<String> get title => $composableBuilder(
|
||||||
|
column: $table.title, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<String> get content => $state.composableBuilder(
|
ColumnOrderings<String> get content => $composableBuilder(
|
||||||
column: $state.table.content,
|
column: $table.content, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
}
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
class $ChatFtsAnnotationComposer
|
||||||
|
extends Composer<_$ChatSearchDatabase, ChatFts> {
|
||||||
|
$ChatFtsAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
GeneratedColumn<String> get title =>
|
||||||
|
$composableBuilder(column: $table.title, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get content =>
|
||||||
|
$composableBuilder(column: $table.content, builder: (column) => column);
|
||||||
}
|
}
|
||||||
|
|
||||||
class $ChatFtsTableManager extends RootTableManager<
|
class $ChatFtsTableManager extends RootTableManager<
|
||||||
@@ -596,6 +637,7 @@ class $ChatFtsTableManager extends RootTableManager<
|
|||||||
ChatFt,
|
ChatFt,
|
||||||
$ChatFtsFilterComposer,
|
$ChatFtsFilterComposer,
|
||||||
$ChatFtsOrderingComposer,
|
$ChatFtsOrderingComposer,
|
||||||
|
$ChatFtsAnnotationComposer,
|
||||||
$ChatFtsCreateCompanionBuilder,
|
$ChatFtsCreateCompanionBuilder,
|
||||||
$ChatFtsUpdateCompanionBuilder,
|
$ChatFtsUpdateCompanionBuilder,
|
||||||
(ChatFt, BaseReferences<_$ChatSearchDatabase, ChatFts, ChatFt>),
|
(ChatFt, BaseReferences<_$ChatSearchDatabase, ChatFts, ChatFt>),
|
||||||
@@ -605,8 +647,12 @@ class $ChatFtsTableManager extends RootTableManager<
|
|||||||
: super(TableManagerState(
|
: super(TableManagerState(
|
||||||
db: db,
|
db: db,
|
||||||
table: table,
|
table: table,
|
||||||
filteringComposer: $ChatFtsFilterComposer(ComposerState(db, table)),
|
createFilteringComposer: () =>
|
||||||
orderingComposer: $ChatFtsOrderingComposer(ComposerState(db, table)),
|
$ChatFtsFilterComposer($db: db, $table: table),
|
||||||
|
createOrderingComposer: () =>
|
||||||
|
$ChatFtsOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer: () =>
|
||||||
|
$ChatFtsAnnotationComposer($db: db, $table: table),
|
||||||
updateCompanionCallback: ({
|
updateCompanionCallback: ({
|
||||||
Value<String> title = const Value.absent(),
|
Value<String> title = const Value.absent(),
|
||||||
Value<String> content = const Value.absent(),
|
Value<String> content = const Value.absent(),
|
||||||
@@ -640,6 +686,7 @@ typedef $ChatFtsProcessedTableManager = ProcessedTableManager<
|
|||||||
ChatFt,
|
ChatFt,
|
||||||
$ChatFtsFilterComposer,
|
$ChatFtsFilterComposer,
|
||||||
$ChatFtsOrderingComposer,
|
$ChatFtsOrderingComposer,
|
||||||
|
$ChatFtsAnnotationComposer,
|
||||||
$ChatFtsCreateCompanionBuilder,
|
$ChatFtsCreateCompanionBuilder,
|
||||||
$ChatFtsUpdateCompanionBuilder,
|
$ChatFtsUpdateCompanionBuilder,
|
||||||
(ChatFt, BaseReferences<_$ChatSearchDatabase, ChatFts, ChatFt>),
|
(ChatFt, BaseReferences<_$ChatSearchDatabase, ChatFts, ChatFt>),
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/providers/tab_session.dart';
|
import 'package:lensai/features/geckoview/domain/providers/tab_session.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
@@ -8,6 +10,8 @@ part 'providers.g.dart';
|
|||||||
GeckoEventService eventService(EventServiceRef ref) {
|
GeckoEventService eventService(EventServiceRef ref) {
|
||||||
final service = GeckoEventService.setUp();
|
final service = GeckoEventService.setUp();
|
||||||
|
|
||||||
|
unawaited(GeckoTabService().syncEvents());
|
||||||
|
|
||||||
ref.onDispose(() {
|
ref.onDispose(() {
|
||||||
service.dispose();
|
service.dispose();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ part of 'providers.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$eventServiceHash() => r'5aa357fdf0d217677a9a66ecb50417ac18929cad';
|
String _$eventServiceHash() => r'c36c6d895629002945c7b4eafba8389771e2eb2d';
|
||||||
|
|
||||||
/// See also [eventService].
|
/// See also [eventService].
|
||||||
@ProviderFor(eventService)
|
@ProviderFor(eventService)
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:lensai/features/geckoview/domain/providers.dart';
|
import 'package:lensai/features/geckoview/domain/providers.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/topics/data/database/database.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/topics/data/providers.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
part 'selected_tab.g.dart';
|
part 'selected_tab.g.dart';
|
||||||
|
|
||||||
@Riverpod(keepAlive: true)
|
@Riverpod(keepAlive: true)
|
||||||
class SelectedTab extends _$SelectedTab {
|
class SelectedTab extends _$SelectedTab {
|
||||||
|
late TabDatabase _db;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String? build() {
|
String? build() {
|
||||||
|
_db = ref.watch(tabDatabaseProvider);
|
||||||
|
|
||||||
final eventSerivce = ref.watch(eventServiceProvider);
|
final eventSerivce = ref.watch(eventServiceProvider);
|
||||||
|
|
||||||
final selectedTabSub = eventSerivce.selectedTabEvents.listen(
|
final selectedTabSub = eventSerivce.selectedTabEvents.listen(
|
||||||
@@ -17,6 +23,12 @@ class SelectedTab extends _$SelectedTab {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
ref.listenSelf((previous, next) async {
|
||||||
|
if (next != null) {
|
||||||
|
await _db.tabLinkDao.touchTabLink(next, timestamp: DateTime.now());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
ref.onDispose(() {
|
ref.onDispose(() {
|
||||||
unawaited(selectedTabSub.cancel());
|
unawaited(selectedTabSub.cancel());
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ part of 'selected_tab.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$selectedTabHash() => r'd30f0490c7924b7de30e23f3d4d132311bf336d0';
|
String _$selectedTabHash() => r'd57003aa20d8a6f711918821ae355e5537a55685';
|
||||||
|
|
||||||
/// See also [SelectedTab].
|
/// See also [SelectedTab].
|
||||||
@ProviderFor(SelectedTab)
|
@ProviderFor(SelectedTab)
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
@@ -31,6 +33,10 @@ class TabSession extends _$TabSession {
|
|||||||
return _sessionService.goForward();
|
return _sessionService.goForward();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Uint8List?> requestScreenshot() {
|
||||||
|
return _sessionService.requestScreenshot();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void build(String? tabId) {
|
void build(String? tabId) {
|
||||||
_sessionService = (tabId != null)
|
_sessionService = (tabId != null)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ part of 'tab_session.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$tabSessionHash() => r'cdde9c7426178f50dc430284939e215f158e8535';
|
String _$tabSessionHash() => r'25afbead5c1110ca865e48a5009da70eb20d3a28';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
import 'package:lensai/extensions/image.dart';
|
import 'package:lensai/extensions/image.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/entities/find_result_state.dart';
|
import 'package:lensai/features/geckoview/domain/entities/find_result_state.dart';
|
||||||
@@ -9,6 +10,8 @@ import 'package:lensai/features/geckoview/domain/entities/security_state.dart';
|
|||||||
import 'package:lensai/features/geckoview/domain/entities/tab_state.dart';
|
import 'package:lensai/features/geckoview/domain/entities/tab_state.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/providers.dart';
|
import 'package:lensai/features/geckoview/domain/providers.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/providers/selected_tab.dart';
|
import 'package:lensai/features/geckoview/domain/providers/selected_tab.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/topics/data/database/database.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/topics/data/providers.dart';
|
||||||
import 'package:lensai/features/geckoview/utils/image_helper.dart';
|
import 'package:lensai/features/geckoview/utils/image_helper.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
@@ -18,6 +21,8 @@ part 'tab_state.g.dart';
|
|||||||
class TabStates extends _$TabStates {
|
class TabStates extends _$TabStates {
|
||||||
final _tabsService = GeckoTabService();
|
final _tabsService = GeckoTabService();
|
||||||
|
|
||||||
|
late TabDatabase _db;
|
||||||
|
|
||||||
void _onTabListChange(List<String> tabs) {
|
void _onTabListChange(List<String> tabs) {
|
||||||
state = {
|
state = {
|
||||||
for (final tabId in tabs) tabId: state[tabId] ?? TabState.$default(tabId),
|
for (final tabId in tabs) tabId: state[tabId] ?? TabState.$default(tabId),
|
||||||
@@ -166,6 +171,7 @@ class TabStates extends _$TabStates {
|
|||||||
@override
|
@override
|
||||||
Map<String, TabState> build() {
|
Map<String, TabState> build() {
|
||||||
final eventService = ref.watch(eventServiceProvider);
|
final eventService = ref.watch(eventServiceProvider);
|
||||||
|
_db = ref.watch(tabDatabaseProvider);
|
||||||
|
|
||||||
final subscriptions = [
|
final subscriptions = [
|
||||||
eventService.tabListEvents.listen(_onTabListChange),
|
eventService.tabListEvents.listen(_onTabListChange),
|
||||||
@@ -178,6 +184,18 @@ class TabStates extends _$TabStates {
|
|||||||
eventService.findResultsEvent.listen(_onFindResults),
|
eventService.findResultsEvent.listen(_onFindResults),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
ref.listenSelf(
|
||||||
|
(previous, next) async {
|
||||||
|
if (!const DeepCollectionEquality()
|
||||||
|
.equals(previous?.keys.toSet(), next.keys.toSet())) {
|
||||||
|
final ids = next.keys.toList();
|
||||||
|
if (ids.isNotEmpty) {
|
||||||
|
await _db.tabLinkDao.syncTabLinks(retainTabIds: ids);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
ref.onDispose(() {
|
ref.onDispose(() {
|
||||||
for (final sub in subscriptions) {
|
for (final sub in subscriptions) {
|
||||||
unawaited(sub.cancel());
|
unawaited(sub.cancel());
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ final selectedTabStateProvider = AutoDisposeProvider<TabState?>.internal(
|
|||||||
);
|
);
|
||||||
|
|
||||||
typedef SelectedTabStateRef = AutoDisposeProviderRef<TabState?>;
|
typedef SelectedTabStateRef = AutoDisposeProviderRef<TabState?>;
|
||||||
String _$tabStatesHash() => r'22fd36fe2e443fd2dfb703dc3be72716fbccef6d';
|
String _$tabStatesHash() => r'f3ae09e49150955dcb29ec89f0f3fe63155a1d6e';
|
||||||
|
|
||||||
/// See also [TabStates].
|
/// See also [TabStates].
|
||||||
@ProviderFor(TabStates)
|
@ProviderFor(TabStates)
|
||||||
|
|||||||
@@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:lensai/data/models/equatable_iterable.dart';
|
||||||
import 'package:lensai/features/bangs/data/models/bang_data.dart';
|
import 'package:lensai/features/bangs/data/models/bang_data.dart';
|
||||||
import 'package:lensai/features/bangs/domain/repositories/data.dart';
|
import 'package:lensai/features/bangs/domain/repositories/data.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/topics/data/providers.dart';
|
||||||
import 'package:lensai/features/kagi/data/entities/modes.dart';
|
import 'package:lensai/features/kagi/data/entities/modes.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
|
|
||||||
@@ -80,3 +83,29 @@ class ShowFindInPage extends _$ShowFindInPage {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Riverpod()
|
||||||
|
Stream<List<String>> availableTabIds(AvailableTabIdsRef ref, String? topicId) {
|
||||||
|
final db = ref.watch(tabDatabaseProvider);
|
||||||
|
final openTabs = ref
|
||||||
|
.watch(
|
||||||
|
tabStatesProvider.select(
|
||||||
|
(states) =>
|
||||||
|
EquatableCollection(states.keys.toSet(), immutable: false),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.collection;
|
||||||
|
|
||||||
|
if (topicId != null) {
|
||||||
|
return db.tabLinkDao.topicTabIds(topicId).watch().map(
|
||||||
|
(tabIds) =>
|
||||||
|
tabIds.where((tabId) => openTabs.contains(tabId)).toList(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return db.tabLinkDao.allTabIds().watch().map(
|
||||||
|
(assignedTabIds) => openTabs
|
||||||
|
.where((tabId) => !assignedTabIds.contains(tabId))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -156,6 +156,135 @@ class _SelectedBangDataProviderElement
|
|||||||
String? get domain => (origin as SelectedBangDataProvider).domain;
|
String? get domain => (origin as SelectedBangDataProvider).domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _$availableTabIdsHash() => r'bea231cdf6211fc876b8031b5d72999eae5d7b15';
|
||||||
|
|
||||||
|
/// See also [availableTabIds].
|
||||||
|
@ProviderFor(availableTabIds)
|
||||||
|
const availableTabIdsProvider = AvailableTabIdsFamily();
|
||||||
|
|
||||||
|
/// See also [availableTabIds].
|
||||||
|
class AvailableTabIdsFamily extends Family<AsyncValue<List<String>>> {
|
||||||
|
/// See also [availableTabIds].
|
||||||
|
const AvailableTabIdsFamily();
|
||||||
|
|
||||||
|
/// See also [availableTabIds].
|
||||||
|
AvailableTabIdsProvider call(
|
||||||
|
String? topicId,
|
||||||
|
) {
|
||||||
|
return AvailableTabIdsProvider(
|
||||||
|
topicId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
AvailableTabIdsProvider getProviderOverride(
|
||||||
|
covariant AvailableTabIdsProvider provider,
|
||||||
|
) {
|
||||||
|
return call(
|
||||||
|
provider.topicId,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const Iterable<ProviderOrFamily>? _dependencies = null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<ProviderOrFamily>? get dependencies => _dependencies;
|
||||||
|
|
||||||
|
static const Iterable<ProviderOrFamily>? _allTransitiveDependencies = null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Iterable<ProviderOrFamily>? get allTransitiveDependencies =>
|
||||||
|
_allTransitiveDependencies;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get name => r'availableTabIdsProvider';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// See also [availableTabIds].
|
||||||
|
class AvailableTabIdsProvider extends AutoDisposeStreamProvider<List<String>> {
|
||||||
|
/// See also [availableTabIds].
|
||||||
|
AvailableTabIdsProvider(
|
||||||
|
String? topicId,
|
||||||
|
) : this._internal(
|
||||||
|
(ref) => availableTabIds(
|
||||||
|
ref as AvailableTabIdsRef,
|
||||||
|
topicId,
|
||||||
|
),
|
||||||
|
from: availableTabIdsProvider,
|
||||||
|
name: r'availableTabIdsProvider',
|
||||||
|
debugGetCreateSourceHash:
|
||||||
|
const bool.fromEnvironment('dart.vm.product')
|
||||||
|
? null
|
||||||
|
: _$availableTabIdsHash,
|
||||||
|
dependencies: AvailableTabIdsFamily._dependencies,
|
||||||
|
allTransitiveDependencies:
|
||||||
|
AvailableTabIdsFamily._allTransitiveDependencies,
|
||||||
|
topicId: topicId,
|
||||||
|
);
|
||||||
|
|
||||||
|
AvailableTabIdsProvider._internal(
|
||||||
|
super._createNotifier, {
|
||||||
|
required super.name,
|
||||||
|
required super.dependencies,
|
||||||
|
required super.allTransitiveDependencies,
|
||||||
|
required super.debugGetCreateSourceHash,
|
||||||
|
required super.from,
|
||||||
|
required this.topicId,
|
||||||
|
}) : super.internal();
|
||||||
|
|
||||||
|
final String? topicId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Override overrideWith(
|
||||||
|
Stream<List<String>> Function(AvailableTabIdsRef provider) create,
|
||||||
|
) {
|
||||||
|
return ProviderOverride(
|
||||||
|
origin: this,
|
||||||
|
override: AvailableTabIdsProvider._internal(
|
||||||
|
(ref) => create(ref as AvailableTabIdsRef),
|
||||||
|
from: from,
|
||||||
|
name: null,
|
||||||
|
dependencies: null,
|
||||||
|
allTransitiveDependencies: null,
|
||||||
|
debugGetCreateSourceHash: null,
|
||||||
|
topicId: topicId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
AutoDisposeStreamProviderElement<List<String>> createElement() {
|
||||||
|
return _AvailableTabIdsProviderElement(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return other is AvailableTabIdsProvider && other.topicId == topicId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
var hash = _SystemHash.combine(0, runtimeType.hashCode);
|
||||||
|
hash = _SystemHash.combine(hash, topicId.hashCode);
|
||||||
|
|
||||||
|
return _SystemHash.finish(hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixin AvailableTabIdsRef on AutoDisposeStreamProviderRef<List<String>> {
|
||||||
|
/// The parameter `topicId` of this provider.
|
||||||
|
String? get topicId;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AvailableTabIdsProviderElement
|
||||||
|
extends AutoDisposeStreamProviderElement<List<String>>
|
||||||
|
with AvailableTabIdsRef {
|
||||||
|
_AvailableTabIdsProviderElement(super.provider);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String? get topicId => (origin as AvailableTabIdsProvider).topicId;
|
||||||
|
}
|
||||||
|
|
||||||
String _$selectedBangTriggerHash() =>
|
String _$selectedBangTriggerHash() =>
|
||||||
r'b0e12bc95e93d50d04f1c658230cea9f15ff0385';
|
r'b0e12bc95e93d50d04f1c658230cea9f15ff0385';
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/data/models/equatable_iterable.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/entities/tab_state.dart';
|
import 'package:lensai/features/geckoview/domain/entities/tab_state.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
||||||
import 'package:lensai/features/geckoview/features/topics/domain/providers.dart';
|
import 'package:lensai/features/geckoview/features/topics/domain/providers.dart';
|
||||||
@@ -25,8 +26,14 @@ class TabActionDialog extends HookConsumerWidget {
|
|||||||
tabTopicIdProvider(initialTab.id).select((value) => value.valueOrNull),
|
tabTopicIdProvider(initialTab.id).select((value) => value.valueOrNull),
|
||||||
);
|
);
|
||||||
|
|
||||||
final topics =
|
final topics = ref
|
||||||
ref.watch(topicsWithCountProvider.select((value) => value.valueOrNull));
|
.watch(
|
||||||
|
topicsWithCountProvider.select(
|
||||||
|
(value) => EquatableCollection(value.valueOrNull, immutable: true),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.collection;
|
||||||
|
|
||||||
final selectedTopic =
|
final selectedTopic =
|
||||||
topics?.firstWhereOrNull((topic) => topic.id == tabTopicId);
|
topics?.firstWhereOrNull((topic) => topic.id == tabTopicId);
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
@@ -7,6 +9,7 @@ import 'package:lensai/data/models/web_page_info.dart';
|
|||||||
import 'package:lensai/features/bangs/data/models/bang_data.dart';
|
import 'package:lensai/features/bangs/data/models/bang_data.dart';
|
||||||
import 'package:lensai/features/bangs/domain/providers.dart';
|
import 'package:lensai/features/bangs/domain/providers.dart';
|
||||||
import 'package:lensai/features/bangs/presentation/widgets/site_search.dart';
|
import 'package:lensai/features/bangs/presentation/widgets/site_search.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/providers.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/repositories/tab.dart';
|
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
||||||
import 'package:lensai/features/kagi/data/entities/modes.dart';
|
import 'package:lensai/features/kagi/data/entities/modes.dart';
|
||||||
@@ -55,6 +58,7 @@ class WebPageDialog extends HookConsumerWidget {
|
|||||||
|
|
||||||
final formKey = useMemoized(() => GlobalKey<FormState>());
|
final formKey = useMemoized(() => GlobalKey<FormState>());
|
||||||
final urlTextController = useTextEditingController(text: url.toString());
|
final urlTextController = useTextEditingController(text: url.toString());
|
||||||
|
final urlTextFocusNode = useFocusNode();
|
||||||
|
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
@@ -80,6 +84,7 @@ class WebPageDialog extends HookConsumerWidget {
|
|||||||
key: formKey,
|
key: formKey,
|
||||||
child: TextFormField(
|
child: TextFormField(
|
||||||
controller: urlTextController,
|
controller: urlTextController,
|
||||||
|
focusNode: urlTextFocusNode,
|
||||||
enableIMEPersonalizedLearning: !incognitoEnabled,
|
enableIMEPersonalizedLearning: !incognitoEnabled,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'URL',
|
labelText: 'URL',
|
||||||
@@ -109,6 +114,15 @@ class WebPageDialog extends HookConsumerWidget {
|
|||||||
|
|
||||||
return 'Invalid URL';
|
return 'Invalid URL';
|
||||||
},
|
},
|
||||||
|
onTap: () {
|
||||||
|
if (!urlTextFocusNode.hasFocus) {
|
||||||
|
// Select all text when the field is tapped
|
||||||
|
urlTextController.selection = TextSelection(
|
||||||
|
baseOffset: 0,
|
||||||
|
extentOffset: urlTextController.text.length,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -183,6 +197,40 @@ class WebPageDialog extends HookConsumerWidget {
|
|||||||
onDismiss?.call();
|
onDismiss?.call();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(Icons.mobile_screen_share),
|
||||||
|
title: const Text('Share screenshot'),
|
||||||
|
onTap: () async {
|
||||||
|
final screenshot = await ref
|
||||||
|
.read(selectedTabSessionNotifierProvider)
|
||||||
|
.requestScreenshot();
|
||||||
|
|
||||||
|
if (screenshot != null) {
|
||||||
|
ui.decodeImageFromList(
|
||||||
|
screenshot,
|
||||||
|
(result) async {
|
||||||
|
final png = await result.toByteData(
|
||||||
|
format: ui.ImageByteFormat.png,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (png != null) {
|
||||||
|
final file = XFile.fromData(
|
||||||
|
png.buffer.asUint8List(),
|
||||||
|
mimeType: 'image/png',
|
||||||
|
);
|
||||||
|
|
||||||
|
await Share.shareXFiles(
|
||||||
|
[file],
|
||||||
|
subject: precachedInfo?.title,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onDismiss?.call();
|
||||||
|
},
|
||||||
|
),
|
||||||
const Divider(),
|
const Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(KagiTool.summarizer.icon),
|
leading: Icon(KagiTool.summarizer.icon),
|
||||||
|
|||||||
+11
-4
@@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart' show rootBundle;
|
import 'package:flutter/services.dart' show rootBundle;
|
||||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/data/models/equatable_iterable.dart';
|
||||||
import 'package:lensai/domain/services/app_initialization.dart';
|
import 'package:lensai/domain/services/app_initialization.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
||||||
import 'package:lensai/features/geckoview/features/browser/presentation/widgets/error_container.dart';
|
import 'package:lensai/features/geckoview/features/browser/presentation/widgets/error_container.dart';
|
||||||
@@ -51,10 +52,16 @@ class LandingContent extends HookConsumerWidget {
|
|||||||
const LandingAction(),
|
const LandingAction(),
|
||||||
Consumer(
|
Consumer(
|
||||||
builder: (context, ref, child) {
|
builder: (context, ref, child) {
|
||||||
final errors = ref.watch(
|
final errors = ref
|
||||||
appInitializationServiceProvider
|
.watch(
|
||||||
.select((result) => result.valueOrNull?.errors),
|
appInitializationServiceProvider.select(
|
||||||
);
|
(result) => EquatableCollection(
|
||||||
|
result.valueOrNull?.errors,
|
||||||
|
immutable: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.collection;
|
||||||
|
|
||||||
if (errors == null || errors.isEmpty) {
|
if (errors == null || errors.isEmpty) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
|
|||||||
+18
-20
@@ -1,16 +1,16 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:fading_scroll/fading_scroll.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/data/models/equatable_iterable.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/providers/selected_tab.dart';
|
import 'package:lensai/features/geckoview/domain/providers/selected_tab.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
||||||
|
import 'package:lensai/features/geckoview/features/browser/domain/providers.dart';
|
||||||
import 'package:lensai/features/geckoview/features/browser/presentation/dialogs/tab_action.dart';
|
import 'package:lensai/features/geckoview/features/browser/presentation/dialogs/tab_action.dart';
|
||||||
import 'package:lensai/features/geckoview/features/browser/presentation/widgets/tab_preview.dart';
|
import 'package:lensai/features/geckoview/features/browser/presentation/widgets/tab_preview.dart';
|
||||||
import 'package:lensai/features/geckoview/features/controllers/overlay_dialog.dart';
|
import 'package:lensai/features/geckoview/features/controllers/overlay_dialog.dart';
|
||||||
import 'package:lensai/features/geckoview/features/topics/domain/providers.dart';
|
|
||||||
import 'package:lensai/features/geckoview/features/topics/domain/providers/selected_topic.dart';
|
import 'package:lensai/features/geckoview/features/topics/domain/providers/selected_topic.dart';
|
||||||
import 'package:lensai/features/geckoview/features/topics/domain/repositories/tab_link.dart';
|
import 'package:lensai/features/geckoview/features/topics/domain/repositories/tab_link.dart';
|
||||||
import 'package:lensai/features/geckoview/features/topics/presentation/widgets/topic_chips.dart';
|
import 'package:lensai/features/geckoview/features/topics/presentation/widgets/topic_chips.dart';
|
||||||
@@ -116,14 +116,8 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
return FadingScroll(
|
|
||||||
fadingSize: 25,
|
|
||||||
shaderPadding:
|
|
||||||
const EdgeInsets.only(top: _SliverHeaderDelagate._headerSize),
|
|
||||||
controller: sheetScrollController,
|
|
||||||
builder: (context, controller) {
|
|
||||||
return CustomScrollView(
|
return CustomScrollView(
|
||||||
controller: controller,
|
controller: sheetScrollController,
|
||||||
slivers: [
|
slivers: [
|
||||||
SliverPersistentHeader(
|
SliverPersistentHeader(
|
||||||
pinned: true,
|
pinned: true,
|
||||||
@@ -132,10 +126,16 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
HookConsumer(
|
HookConsumer(
|
||||||
builder: (context, ref, child) {
|
builder: (context, ref, child) {
|
||||||
final topic = ref.watch(selectedTopicProvider);
|
final topic = ref.watch(selectedTopicProvider);
|
||||||
final availableTabs = ref.watch(
|
final availableTabs = ref
|
||||||
topicTabIdsProvider(topic)
|
.watch(
|
||||||
.select((value) => value.valueOrNull ?? []),
|
availableTabIdsProvider(topic).select(
|
||||||
);
|
(value) => EquatableCollection(
|
||||||
|
value.valueOrNull ?? [],
|
||||||
|
immutable: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.collection;
|
||||||
final activeTab = ref.watch(selectedTabProvider);
|
final activeTab = ref.watch(selectedTabProvider);
|
||||||
|
|
||||||
final itemHeight = useMemoized(
|
final itemHeight = useMemoized(
|
||||||
@@ -152,16 +152,16 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() {
|
() {
|
||||||
final index = availableTabs
|
final index =
|
||||||
.indexWhere((webView) => webView == activeTab);
|
availableTabs.indexWhere((webView) => webView == activeTab);
|
||||||
|
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
final reversedIndex = availableTabs.length - 1 - index;
|
final reversedIndex = availableTabs.length - 1 - index;
|
||||||
final offset = (reversedIndex ~/ 2) * itemHeight;
|
final offset = (reversedIndex ~/ 2) * itemHeight;
|
||||||
|
|
||||||
if (offset != controller.offset) {
|
if (offset != sheetScrollController.offset) {
|
||||||
unawaited(
|
unawaited(
|
||||||
controller.animateTo(
|
sheetScrollController.animateTo(
|
||||||
offset,
|
offset,
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(milliseconds: 200),
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
@@ -172,7 +172,7 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
[],
|
[availableTabs, activeTab],
|
||||||
);
|
);
|
||||||
|
|
||||||
return SliverPadding(
|
return SliverPadding(
|
||||||
@@ -244,7 +244,5 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.dart
|
|||||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/core/logger.dart';
|
||||||
import 'package:lensai/core/routing/routes.dart';
|
import 'package:lensai/core/routing/routes.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/providers.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';
|
||||||
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
||||||
@@ -22,6 +24,7 @@ import 'package:lensai/features/geckoview/features/controllers/bottom_sheet.dart
|
|||||||
import 'package:lensai/features/geckoview/features/controllers/overlay_dialog.dart';
|
import 'package:lensai/features/geckoview/features/controllers/overlay_dialog.dart';
|
||||||
import 'package:lensai/features/geckoview/features/find_in_page/presentation/controllers/find_in_page_visibility.dart';
|
import 'package:lensai/features/geckoview/features/find_in_page/presentation/controllers/find_in_page_visibility.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_button.dart';
|
import 'package:lensai/features/geckoview/features/readerview/presentation/widgets/reader_button.dart';
|
||||||
import 'package:lensai/features/kagi/data/entities/modes.dart';
|
import 'package:lensai/features/kagi/data/entities/modes.dart';
|
||||||
import 'package:lensai/features/kagi/data/services/session.dart';
|
import 'package:lensai/features/kagi/data/services/session.dart';
|
||||||
@@ -546,7 +549,23 @@ class BrowserScreen extends HookConsumerWidget {
|
|||||||
SafeArea(
|
SafeArea(
|
||||||
child: Stack(
|
child: Stack(
|
||||||
children: [
|
children: [
|
||||||
const GeckoView(),
|
GeckoView(
|
||||||
|
preInitializationStep: () async {
|
||||||
|
await ref
|
||||||
|
.read(eventServiceProvider)
|
||||||
|
.fragmentReadyStateEvents
|
||||||
|
.firstWhere((state) => state == true)
|
||||||
|
.timeout(
|
||||||
|
const Duration(seconds: 3),
|
||||||
|
onTimeout: () {
|
||||||
|
logger.e(
|
||||||
|
'Browser fragement not reported ready, trying to intitialize anyways',
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
@@ -604,6 +623,7 @@ class BrowserScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
floatingActionButton: ReaderAppearanceButton(),
|
||||||
bottomSheet: (displayedSheet != null)
|
bottomSheet: (displayedSheet != null)
|
||||||
? NotificationListener<DraggableScrollableNotification>(
|
? NotificationListener<DraggableScrollableNotification>(
|
||||||
onNotification: (notification) {
|
onNotification: (notification) {
|
||||||
|
|||||||
@@ -19,9 +19,3 @@ Stream<bool> appearanceButtonVisibility(AppearanceButtonVisibilityRef ref) {
|
|||||||
final service = ref.watch(readerableServiceProvider);
|
final service = ref.watch(readerableServiceProvider);
|
||||||
return service.appearanceVisibility;
|
return service.appearanceVisibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Riverpod()
|
|
||||||
Stream<bool> readerButtonVisibility(ReaderButtonVisibilityRef ref) {
|
|
||||||
final service = ref.watch(readerableServiceProvider);
|
|
||||||
return service.readerVisibility;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -38,21 +38,5 @@ final appearanceButtonVisibilityProvider =
|
|||||||
);
|
);
|
||||||
|
|
||||||
typedef AppearanceButtonVisibilityRef = AutoDisposeStreamProviderRef<bool>;
|
typedef AppearanceButtonVisibilityRef = AutoDisposeStreamProviderRef<bool>;
|
||||||
String _$readerButtonVisibilityHash() =>
|
|
||||||
r'd58132aa4e9a5ba311a0b5d99b9f8416e952b1ab';
|
|
||||||
|
|
||||||
/// See also [readerButtonVisibility].
|
|
||||||
@ProviderFor(readerButtonVisibility)
|
|
||||||
final readerButtonVisibilityProvider = AutoDisposeStreamProvider<bool>.internal(
|
|
||||||
readerButtonVisibility,
|
|
||||||
name: r'readerButtonVisibilityProvider',
|
|
||||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
|
||||||
? null
|
|
||||||
: _$readerButtonVisibilityHash,
|
|
||||||
dependencies: null,
|
|
||||||
allTransitiveDependencies: null,
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef ReaderButtonVisibilityRef = AutoDisposeStreamProviderRef<bool>;
|
|
||||||
// ignore_for_file: type=lint
|
// ignore_for_file: type=lint
|
||||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||||
|
|||||||
+14
-5
@@ -1,6 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/entities/readerable_state.dart';
|
||||||
|
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
||||||
import 'package:lensai/features/geckoview/features/readerview/domain/providers/readerable.dart';
|
import 'package:lensai/features/geckoview/features/readerview/domain/providers/readerable.dart';
|
||||||
|
|
||||||
class ReaderAppearanceButton extends HookConsumerWidget {
|
class ReaderAppearanceButton extends HookConsumerWidget {
|
||||||
@@ -11,13 +13,20 @@ class ReaderAppearanceButton extends HookConsumerWidget {
|
|||||||
.select((value) => value.valueOrNull ?? false),
|
.select((value) => value.valueOrNull ?? false),
|
||||||
);
|
);
|
||||||
|
|
||||||
return FloatingActionButton(
|
final readerabilityState = ref.watch(
|
||||||
onPressed: buttonVisible
|
selectedTabStateProvider.select(
|
||||||
? () async {
|
(state) => state?.readerableState ?? ReaderableState.$default(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return Visibility(
|
||||||
|
visible: readerabilityState.active && buttonVisible,
|
||||||
|
child: FloatingActionButton(
|
||||||
|
onPressed: () async {
|
||||||
await ref.read(readerableServiceProvider).onAppearanceButtonTap();
|
await ref.read(readerableServiceProvider).onAppearanceButtonTap();
|
||||||
}
|
},
|
||||||
: null,
|
|
||||||
child: const Icon(MdiIcons.formatFont),
|
child: const Icon(MdiIcons.formatFont),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-8
@@ -4,7 +4,6 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.dart
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/entities/readerable_state.dart';
|
import 'package:lensai/features/geckoview/domain/entities/readerable_state.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
||||||
import 'package:lensai/features/geckoview/features/readerview/domain/providers/readerable.dart';
|
|
||||||
import 'package:lensai/features/geckoview/features/readerview/presentation/controllers/readerable.dart';
|
import 'package:lensai/features/geckoview/features/readerview/presentation/controllers/readerable.dart';
|
||||||
import 'package:lensai/presentation/widgets/animate_gradient_shader.dart';
|
import 'package:lensai/presentation/widgets/animate_gradient_shader.dart';
|
||||||
|
|
||||||
@@ -21,11 +20,6 @@ class ReaderButton extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
final readerButtonVisible = ref.watch(
|
|
||||||
readerButtonVisibilityProvider
|
|
||||||
.select((value) => value.valueOrNull ?? false),
|
|
||||||
);
|
|
||||||
|
|
||||||
final icon = useMemoized(
|
final icon = useMemoized(
|
||||||
() => readerabilityState.active
|
() => readerabilityState.active
|
||||||
? Icon(
|
? Icon(
|
||||||
@@ -40,7 +34,7 @@ class ReaderButton extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return Visibility(
|
return Visibility(
|
||||||
visible: readerButtonVisible,
|
visible: readerabilityState.readerable,
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
vertical: 15.0,
|
vertical: 15.0,
|
||||||
@@ -48,7 +42,7 @@ class ReaderButton extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
child: readerChanging.when(
|
child: readerChanging.when(
|
||||||
data: (_) => Visibility(
|
data: (_) => Visibility(
|
||||||
visible: readerButtonVisible,
|
visible: readerabilityState.readerable,
|
||||||
child: InkWell(
|
child: InkWell(
|
||||||
onTap: readerChanging.isLoading
|
onTap: readerChanging.isLoading
|
||||||
? null
|
? null
|
||||||
|
|||||||
@@ -7,14 +7,18 @@ part 'tab.g.dart';
|
|||||||
class TabLinkDao extends DatabaseAccessor<TabDatabase> with _$TabLinkDaoMixin {
|
class TabLinkDao extends DatabaseAccessor<TabDatabase> with _$TabLinkDaoMixin {
|
||||||
TabLinkDao(super.db);
|
TabLinkDao(super.db);
|
||||||
|
|
||||||
Selectable<String> topicTabIds(String? topicId) {
|
Selectable<String> topicTabIds(String topicId) {
|
||||||
|
final query = selectOnly(db.tabLink)
|
||||||
|
..addColumns([db.tabLink.id])
|
||||||
|
..where(db.tabLink.topicId.equals(topicId))
|
||||||
|
..orderBy([OrderingTerm.asc(db.tabLink.id)]);
|
||||||
|
|
||||||
|
return query.map((row) => row.read(db.tabLink.id)!);
|
||||||
|
}
|
||||||
|
|
||||||
|
Selectable<String> allTabIds() {
|
||||||
final query = selectOnly(db.tabLink)
|
final query = selectOnly(db.tabLink)
|
||||||
..addColumns([db.tabLink.id])
|
..addColumns([db.tabLink.id])
|
||||||
..where(
|
|
||||||
(topicId == null)
|
|
||||||
? db.tabLink.topicId.isNull()
|
|
||||||
: db.tabLink.topicId.equals(topicId),
|
|
||||||
)
|
|
||||||
..orderBy([OrderingTerm.asc(db.tabLink.id)]);
|
..orderBy([OrderingTerm.asc(db.tabLink.id)]);
|
||||||
|
|
||||||
return query.map((row) => row.read(db.tabLink.id)!);
|
return query.map((row) => row.read(db.tabLink.id)!);
|
||||||
@@ -25,13 +29,13 @@ class TabLinkDao extends DatabaseAccessor<TabDatabase> with _$TabLinkDaoMixin {
|
|||||||
..addColumns([db.tabLink.topicId])
|
..addColumns([db.tabLink.topicId])
|
||||||
..where(db.tabLink.id.equals(tabId));
|
..where(db.tabLink.id.equals(tabId));
|
||||||
|
|
||||||
return query.map((row) => row.read(db.tabLink.id)!);
|
return query.map((row) => row.read(db.tabLink.topicId)!);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> upsertTabLink(
|
Future<void> upsertTabLink(
|
||||||
String tabId, {
|
String tabId, {
|
||||||
required DateTime timestamp,
|
required DateTime timestamp,
|
||||||
Value<String?> topicId = const Value.absent(),
|
required String topicId,
|
||||||
}) {
|
}) {
|
||||||
return db.tabLink.insertOne(
|
return db.tabLink.insertOne(
|
||||||
TabLinkCompanion.insert(
|
TabLinkCompanion.insert(
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ class TabDatabase extends _$TabDatabase {
|
|||||||
await m.dropColumn(tabLink, 'url');
|
await m.dropColumn(tabLink, 'url');
|
||||||
await m.dropColumn(tabLink, 'title');
|
await m.dropColumn(tabLink, 'title');
|
||||||
await m.dropColumn(tabLink, 'screenshot');
|
await m.dropColumn(tabLink, 'screenshot');
|
||||||
|
|
||||||
|
await m.alterTable(TableMigration(tabLink));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ CREATE TABLE topic (
|
|||||||
|
|
||||||
CREATE TABLE tab_link (
|
CREATE TABLE tab_link (
|
||||||
id TEXT PRIMARY KEY NOT NULL,
|
id TEXT PRIMARY KEY NOT NULL,
|
||||||
topic_id TEXT REFERENCES topic (id) ON DELETE CASCADE,
|
topic_id TEXT NOT NULL REFERENCES topic (id) ON DELETE CASCADE,
|
||||||
timestamp DATETIME NOT NULL
|
timestamp DATETIME NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -142,10 +142,10 @@ class TabLink extends Table with TableInfo<TabLink, TabLinkData> {
|
|||||||
requiredDuringInsert: true,
|
requiredDuringInsert: true,
|
||||||
$customConstraints: 'PRIMARY KEY NOT NULL');
|
$customConstraints: 'PRIMARY KEY NOT NULL');
|
||||||
late final GeneratedColumn<String> topicId = GeneratedColumn<String>(
|
late final GeneratedColumn<String> topicId = GeneratedColumn<String>(
|
||||||
'topic_id', aliasedName, true,
|
'topic_id', aliasedName, false,
|
||||||
type: DriftSqlType.string,
|
type: DriftSqlType.string,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: true,
|
||||||
$customConstraints: 'REFERENCES topic(id)ON DELETE CASCADE');
|
$customConstraints: 'NOT NULL REFERENCES topic(id)ON DELETE CASCADE');
|
||||||
late final GeneratedColumn<DateTime> timestamp = GeneratedColumn<DateTime>(
|
late final GeneratedColumn<DateTime> timestamp = GeneratedColumn<DateTime>(
|
||||||
'timestamp', aliasedName, false,
|
'timestamp', aliasedName, false,
|
||||||
type: DriftSqlType.dateTime,
|
type: DriftSqlType.dateTime,
|
||||||
@@ -167,7 +167,7 @@ class TabLink extends Table with TableInfo<TabLink, TabLinkData> {
|
|||||||
id: attachedDatabase.typeMapping
|
id: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}id'])!,
|
.read(DriftSqlType.string, data['${effectivePrefix}id'])!,
|
||||||
topicId: attachedDatabase.typeMapping
|
topicId: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}topic_id']),
|
.read(DriftSqlType.string, data['${effectivePrefix}topic_id'])!,
|
||||||
timestamp: attachedDatabase.typeMapping
|
timestamp: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.dateTime, data['${effectivePrefix}timestamp'])!,
|
.read(DriftSqlType.dateTime, data['${effectivePrefix}timestamp'])!,
|
||||||
);
|
);
|
||||||
@@ -184,16 +184,15 @@ class TabLink extends Table with TableInfo<TabLink, TabLinkData> {
|
|||||||
|
|
||||||
class TabLinkData extends DataClass implements Insertable<TabLinkData> {
|
class TabLinkData extends DataClass implements Insertable<TabLinkData> {
|
||||||
final String id;
|
final String id;
|
||||||
final String? topicId;
|
final String topicId;
|
||||||
final DateTime timestamp;
|
final DateTime timestamp;
|
||||||
const TabLinkData({required this.id, this.topicId, required this.timestamp});
|
const TabLinkData(
|
||||||
|
{required this.id, required this.topicId, required this.timestamp});
|
||||||
@override
|
@override
|
||||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
final map = <String, Expression>{};
|
final map = <String, Expression>{};
|
||||||
map['id'] = Variable<String>(id);
|
map['id'] = Variable<String>(id);
|
||||||
if (!nullToAbsent || topicId != null) {
|
|
||||||
map['topic_id'] = Variable<String>(topicId);
|
map['topic_id'] = Variable<String>(topicId);
|
||||||
}
|
|
||||||
map['timestamp'] = Variable<DateTime>(timestamp);
|
map['timestamp'] = Variable<DateTime>(timestamp);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
@@ -203,7 +202,7 @@ class TabLinkData extends DataClass implements Insertable<TabLinkData> {
|
|||||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||||
return TabLinkData(
|
return TabLinkData(
|
||||||
id: serializer.fromJson<String>(json['id']),
|
id: serializer.fromJson<String>(json['id']),
|
||||||
topicId: serializer.fromJson<String?>(json['topic_id']),
|
topicId: serializer.fromJson<String>(json['topic_id']),
|
||||||
timestamp: serializer.fromJson<DateTime>(json['timestamp']),
|
timestamp: serializer.fromJson<DateTime>(json['timestamp']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -212,18 +211,15 @@ class TabLinkData extends DataClass implements Insertable<TabLinkData> {
|
|||||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||||
return <String, dynamic>{
|
return <String, dynamic>{
|
||||||
'id': serializer.toJson<String>(id),
|
'id': serializer.toJson<String>(id),
|
||||||
'topic_id': serializer.toJson<String?>(topicId),
|
'topic_id': serializer.toJson<String>(topicId),
|
||||||
'timestamp': serializer.toJson<DateTime>(timestamp),
|
'timestamp': serializer.toJson<DateTime>(timestamp),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
TabLinkData copyWith(
|
TabLinkData copyWith({String? id, String? topicId, DateTime? timestamp}) =>
|
||||||
{String? id,
|
|
||||||
Value<String?> topicId = const Value.absent(),
|
|
||||||
DateTime? timestamp}) =>
|
|
||||||
TabLinkData(
|
TabLinkData(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
topicId: topicId.present ? topicId.value : this.topicId,
|
topicId: topicId ?? this.topicId,
|
||||||
timestamp: timestamp ?? this.timestamp,
|
timestamp: timestamp ?? this.timestamp,
|
||||||
);
|
);
|
||||||
TabLinkData copyWithCompanion(TabLinkCompanion data) {
|
TabLinkData copyWithCompanion(TabLinkCompanion data) {
|
||||||
@@ -257,7 +253,7 @@ class TabLinkData extends DataClass implements Insertable<TabLinkData> {
|
|||||||
|
|
||||||
class TabLinkCompanion extends UpdateCompanion<TabLinkData> {
|
class TabLinkCompanion extends UpdateCompanion<TabLinkData> {
|
||||||
final Value<String> id;
|
final Value<String> id;
|
||||||
final Value<String?> topicId;
|
final Value<String> topicId;
|
||||||
final Value<DateTime> timestamp;
|
final Value<DateTime> timestamp;
|
||||||
final Value<int> rowid;
|
final Value<int> rowid;
|
||||||
const TabLinkCompanion({
|
const TabLinkCompanion({
|
||||||
@@ -268,10 +264,11 @@ class TabLinkCompanion extends UpdateCompanion<TabLinkData> {
|
|||||||
});
|
});
|
||||||
TabLinkCompanion.insert({
|
TabLinkCompanion.insert({
|
||||||
required String id,
|
required String id,
|
||||||
this.topicId = const Value.absent(),
|
required String topicId,
|
||||||
required DateTime timestamp,
|
required DateTime timestamp,
|
||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
}) : id = Value(id),
|
}) : id = Value(id),
|
||||||
|
topicId = Value(topicId),
|
||||||
timestamp = Value(timestamp);
|
timestamp = Value(timestamp);
|
||||||
static Insertable<TabLinkData> custom({
|
static Insertable<TabLinkData> custom({
|
||||||
Expression<String>? id,
|
Expression<String>? id,
|
||||||
@@ -289,7 +286,7 @@ class TabLinkCompanion extends UpdateCompanion<TabLinkData> {
|
|||||||
|
|
||||||
TabLinkCompanion copyWith(
|
TabLinkCompanion copyWith(
|
||||||
{Value<String>? id,
|
{Value<String>? id,
|
||||||
Value<String?>? topicId,
|
Value<String>? topicId,
|
||||||
Value<DateTime>? timestamp,
|
Value<DateTime>? timestamp,
|
||||||
Value<int>? rowid}) {
|
Value<int>? rowid}) {
|
||||||
return TabLinkCompanion(
|
return TabLinkCompanion(
|
||||||
@@ -403,55 +400,102 @@ final class $TopicReferences
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $TopicFilterComposer extends FilterComposer<_$TabDatabase, Topic> {
|
class $TopicFilterComposer extends Composer<_$TabDatabase, Topic> {
|
||||||
$TopicFilterComposer(super.$state);
|
$TopicFilterComposer({
|
||||||
ColumnFilters<String> get id => $state.composableBuilder(
|
required super.$db,
|
||||||
column: $state.table.id,
|
required super.$table,
|
||||||
builder: (column, joinBuilders) =>
|
super.joinBuilder,
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnFilters<String> get id => $composableBuilder(
|
||||||
|
column: $table.id, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<String> get name => $state.composableBuilder(
|
ColumnFilters<String> get name => $composableBuilder(
|
||||||
column: $state.table.name,
|
column: $table.name, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnWithTypeConverterFilters<Color, Color, int> get color =>
|
ColumnWithTypeConverterFilters<Color, Color, int> get color =>
|
||||||
$state.composableBuilder(
|
$composableBuilder(
|
||||||
column: $state.table.color,
|
column: $table.color,
|
||||||
builder: (column, joinBuilders) => ColumnWithTypeConverterFilters(
|
builder: (column) => ColumnWithTypeConverterFilters(column));
|
||||||
column,
|
|
||||||
joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ComposableFilter tabLinkRefs(
|
Expression<bool> tabLinkRefs(
|
||||||
ComposableFilter Function($TabLinkFilterComposer f) f) {
|
Expression<bool> Function($TabLinkFilterComposer f) f) {
|
||||||
final $TabLinkFilterComposer composer = $state.composerBuilder(
|
final $TabLinkFilterComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
getCurrentColumn: (t) => t.id,
|
getCurrentColumn: (t) => t.id,
|
||||||
referencedTable: $state.db.tabLink,
|
referencedTable: $db.tabLink,
|
||||||
getReferencedColumn: (t) => t.topicId,
|
getReferencedColumn: (t) => t.topicId,
|
||||||
builder: (joinBuilder, parentComposers) => $TabLinkFilterComposer(
|
builder: (joinBuilder,
|
||||||
ComposerState(
|
{$addJoinBuilderToRootComposer,
|
||||||
$state.db, $state.db.tabLink, joinBuilder, parentComposers)));
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$TabLinkFilterComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.tabLink,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
return f(composer);
|
return f(composer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $TopicOrderingComposer extends OrderingComposer<_$TabDatabase, Topic> {
|
class $TopicOrderingComposer extends Composer<_$TabDatabase, Topic> {
|
||||||
$TopicOrderingComposer(super.$state);
|
$TopicOrderingComposer({
|
||||||
ColumnOrderings<String> get id => $state.composableBuilder(
|
required super.$db,
|
||||||
column: $state.table.id,
|
required super.$table,
|
||||||
builder: (column, joinBuilders) =>
|
super.joinBuilder,
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnOrderings<String> get id => $composableBuilder(
|
||||||
|
column: $table.id, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<String> get name => $state.composableBuilder(
|
ColumnOrderings<String> get name => $composableBuilder(
|
||||||
column: $state.table.name,
|
column: $table.name, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
ColumnOrderings<int> get color => $state.composableBuilder(
|
ColumnOrderings<int> get color => $composableBuilder(
|
||||||
column: $state.table.color,
|
column: $table.color, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
}
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
class $TopicAnnotationComposer extends Composer<_$TabDatabase, Topic> {
|
||||||
|
$TopicAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
GeneratedColumn<String> get id =>
|
||||||
|
$composableBuilder(column: $table.id, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<String> get name =>
|
||||||
|
$composableBuilder(column: $table.name, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumnWithTypeConverter<Color, int> get color =>
|
||||||
|
$composableBuilder(column: $table.color, builder: (column) => column);
|
||||||
|
|
||||||
|
Expression<T> tabLinkRefs<T extends Object>(
|
||||||
|
Expression<T> Function($TabLinkAnnotationComposer a) f) {
|
||||||
|
final $TabLinkAnnotationComposer composer = $composerBuilder(
|
||||||
|
composer: this,
|
||||||
|
getCurrentColumn: (t) => t.id,
|
||||||
|
referencedTable: $db.tabLink,
|
||||||
|
getReferencedColumn: (t) => t.topicId,
|
||||||
|
builder: (joinBuilder,
|
||||||
|
{$addJoinBuilderToRootComposer,
|
||||||
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$TabLinkAnnotationComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.tabLink,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
|
return f(composer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $TopicTableManager extends RootTableManager<
|
class $TopicTableManager extends RootTableManager<
|
||||||
@@ -460,6 +504,7 @@ class $TopicTableManager extends RootTableManager<
|
|||||||
TopicData,
|
TopicData,
|
||||||
$TopicFilterComposer,
|
$TopicFilterComposer,
|
||||||
$TopicOrderingComposer,
|
$TopicOrderingComposer,
|
||||||
|
$TopicAnnotationComposer,
|
||||||
$TopicCreateCompanionBuilder,
|
$TopicCreateCompanionBuilder,
|
||||||
$TopicUpdateCompanionBuilder,
|
$TopicUpdateCompanionBuilder,
|
||||||
(TopicData, $TopicReferences),
|
(TopicData, $TopicReferences),
|
||||||
@@ -469,8 +514,12 @@ class $TopicTableManager extends RootTableManager<
|
|||||||
: super(TableManagerState(
|
: super(TableManagerState(
|
||||||
db: db,
|
db: db,
|
||||||
table: table,
|
table: table,
|
||||||
filteringComposer: $TopicFilterComposer(ComposerState(db, table)),
|
createFilteringComposer: () =>
|
||||||
orderingComposer: $TopicOrderingComposer(ComposerState(db, table)),
|
$TopicFilterComposer($db: db, $table: table),
|
||||||
|
createOrderingComposer: () =>
|
||||||
|
$TopicOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer: () =>
|
||||||
|
$TopicAnnotationComposer($db: db, $table: table),
|
||||||
updateCompanionCallback: ({
|
updateCompanionCallback: ({
|
||||||
Value<String> id = const Value.absent(),
|
Value<String> id = const Value.absent(),
|
||||||
Value<String?> name = const Value.absent(),
|
Value<String?> name = const Value.absent(),
|
||||||
@@ -528,6 +577,7 @@ typedef $TopicProcessedTableManager = ProcessedTableManager<
|
|||||||
TopicData,
|
TopicData,
|
||||||
$TopicFilterComposer,
|
$TopicFilterComposer,
|
||||||
$TopicOrderingComposer,
|
$TopicOrderingComposer,
|
||||||
|
$TopicAnnotationComposer,
|
||||||
$TopicCreateCompanionBuilder,
|
$TopicCreateCompanionBuilder,
|
||||||
$TopicUpdateCompanionBuilder,
|
$TopicUpdateCompanionBuilder,
|
||||||
(TopicData, $TopicReferences),
|
(TopicData, $TopicReferences),
|
||||||
@@ -535,13 +585,13 @@ typedef $TopicProcessedTableManager = ProcessedTableManager<
|
|||||||
PrefetchHooks Function({bool tabLinkRefs})>;
|
PrefetchHooks Function({bool tabLinkRefs})>;
|
||||||
typedef $TabLinkCreateCompanionBuilder = TabLinkCompanion Function({
|
typedef $TabLinkCreateCompanionBuilder = TabLinkCompanion Function({
|
||||||
required String id,
|
required String id,
|
||||||
Value<String?> topicId,
|
required String topicId,
|
||||||
required DateTime timestamp,
|
required DateTime timestamp,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
typedef $TabLinkUpdateCompanionBuilder = TabLinkCompanion Function({
|
typedef $TabLinkUpdateCompanionBuilder = TabLinkCompanion Function({
|
||||||
Value<String> id,
|
Value<String> id,
|
||||||
Value<String?> topicId,
|
Value<String> topicId,
|
||||||
Value<DateTime> timestamp,
|
Value<DateTime> timestamp,
|
||||||
Value<int> rowid,
|
Value<int> rowid,
|
||||||
});
|
});
|
||||||
@@ -564,53 +614,107 @@ final class $TabLinkReferences
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $TabLinkFilterComposer extends FilterComposer<_$TabDatabase, TabLink> {
|
class $TabLinkFilterComposer extends Composer<_$TabDatabase, TabLink> {
|
||||||
$TabLinkFilterComposer(super.$state);
|
$TabLinkFilterComposer({
|
||||||
ColumnFilters<String> get id => $state.composableBuilder(
|
required super.$db,
|
||||||
column: $state.table.id,
|
required super.$table,
|
||||||
builder: (column, joinBuilders) =>
|
super.joinBuilder,
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnFilters<String> get id => $composableBuilder(
|
||||||
|
column: $table.id, builder: (column) => ColumnFilters(column));
|
||||||
|
|
||||||
ColumnFilters<DateTime> get timestamp => $state.composableBuilder(
|
ColumnFilters<DateTime> get timestamp => $composableBuilder(
|
||||||
column: $state.table.timestamp,
|
column: $table.timestamp, builder: (column) => ColumnFilters(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnFilters(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
$TopicFilterComposer get topicId {
|
$TopicFilterComposer get topicId {
|
||||||
final $TopicFilterComposer composer = $state.composerBuilder(
|
final $TopicFilterComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
getCurrentColumn: (t) => t.topicId,
|
getCurrentColumn: (t) => t.topicId,
|
||||||
referencedTable: $state.db.topic,
|
referencedTable: $db.topic,
|
||||||
getReferencedColumn: (t) => t.id,
|
getReferencedColumn: (t) => t.id,
|
||||||
builder: (joinBuilder, parentComposers) => $TopicFilterComposer(
|
builder: (joinBuilder,
|
||||||
ComposerState(
|
{$addJoinBuilderToRootComposer,
|
||||||
$state.db, $state.db.topic, joinBuilder, parentComposers)));
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$TopicFilterComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.topic,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
return composer;
|
return composer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class $TabLinkOrderingComposer
|
class $TabLinkOrderingComposer extends Composer<_$TabDatabase, TabLink> {
|
||||||
extends OrderingComposer<_$TabDatabase, TabLink> {
|
$TabLinkOrderingComposer({
|
||||||
$TabLinkOrderingComposer(super.$state);
|
required super.$db,
|
||||||
ColumnOrderings<String> get id => $state.composableBuilder(
|
required super.$table,
|
||||||
column: $state.table.id,
|
super.joinBuilder,
|
||||||
builder: (column, joinBuilders) =>
|
super.$addJoinBuilderToRootComposer,
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
ColumnOrderings<String> get id => $composableBuilder(
|
||||||
|
column: $table.id, builder: (column) => ColumnOrderings(column));
|
||||||
|
|
||||||
ColumnOrderings<DateTime> get timestamp => $state.composableBuilder(
|
ColumnOrderings<DateTime> get timestamp => $composableBuilder(
|
||||||
column: $state.table.timestamp,
|
column: $table.timestamp, builder: (column) => ColumnOrderings(column));
|
||||||
builder: (column, joinBuilders) =>
|
|
||||||
ColumnOrderings(column, joinBuilders: joinBuilders));
|
|
||||||
|
|
||||||
$TopicOrderingComposer get topicId {
|
$TopicOrderingComposer get topicId {
|
||||||
final $TopicOrderingComposer composer = $state.composerBuilder(
|
final $TopicOrderingComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
getCurrentColumn: (t) => t.topicId,
|
getCurrentColumn: (t) => t.topicId,
|
||||||
referencedTable: $state.db.topic,
|
referencedTable: $db.topic,
|
||||||
getReferencedColumn: (t) => t.id,
|
getReferencedColumn: (t) => t.id,
|
||||||
builder: (joinBuilder, parentComposers) => $TopicOrderingComposer(
|
builder: (joinBuilder,
|
||||||
ComposerState(
|
{$addJoinBuilderToRootComposer,
|
||||||
$state.db, $state.db.topic, joinBuilder, parentComposers)));
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$TopicOrderingComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.topic,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
|
return composer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class $TabLinkAnnotationComposer extends Composer<_$TabDatabase, TabLink> {
|
||||||
|
$TabLinkAnnotationComposer({
|
||||||
|
required super.$db,
|
||||||
|
required super.$table,
|
||||||
|
super.joinBuilder,
|
||||||
|
super.$addJoinBuilderToRootComposer,
|
||||||
|
super.$removeJoinBuilderFromRootComposer,
|
||||||
|
});
|
||||||
|
GeneratedColumn<String> get id =>
|
||||||
|
$composableBuilder(column: $table.id, builder: (column) => column);
|
||||||
|
|
||||||
|
GeneratedColumn<DateTime> get timestamp =>
|
||||||
|
$composableBuilder(column: $table.timestamp, builder: (column) => column);
|
||||||
|
|
||||||
|
$TopicAnnotationComposer get topicId {
|
||||||
|
final $TopicAnnotationComposer composer = $composerBuilder(
|
||||||
|
composer: this,
|
||||||
|
getCurrentColumn: (t) => t.topicId,
|
||||||
|
referencedTable: $db.topic,
|
||||||
|
getReferencedColumn: (t) => t.id,
|
||||||
|
builder: (joinBuilder,
|
||||||
|
{$addJoinBuilderToRootComposer,
|
||||||
|
$removeJoinBuilderFromRootComposer}) =>
|
||||||
|
$TopicAnnotationComposer(
|
||||||
|
$db: $db,
|
||||||
|
$table: $db.topic,
|
||||||
|
$addJoinBuilderToRootComposer: $addJoinBuilderToRootComposer,
|
||||||
|
joinBuilder: joinBuilder,
|
||||||
|
$removeJoinBuilderFromRootComposer:
|
||||||
|
$removeJoinBuilderFromRootComposer,
|
||||||
|
));
|
||||||
return composer;
|
return composer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -621,6 +725,7 @@ class $TabLinkTableManager extends RootTableManager<
|
|||||||
TabLinkData,
|
TabLinkData,
|
||||||
$TabLinkFilterComposer,
|
$TabLinkFilterComposer,
|
||||||
$TabLinkOrderingComposer,
|
$TabLinkOrderingComposer,
|
||||||
|
$TabLinkAnnotationComposer,
|
||||||
$TabLinkCreateCompanionBuilder,
|
$TabLinkCreateCompanionBuilder,
|
||||||
$TabLinkUpdateCompanionBuilder,
|
$TabLinkUpdateCompanionBuilder,
|
||||||
(TabLinkData, $TabLinkReferences),
|
(TabLinkData, $TabLinkReferences),
|
||||||
@@ -630,11 +735,15 @@ class $TabLinkTableManager extends RootTableManager<
|
|||||||
: super(TableManagerState(
|
: super(TableManagerState(
|
||||||
db: db,
|
db: db,
|
||||||
table: table,
|
table: table,
|
||||||
filteringComposer: $TabLinkFilterComposer(ComposerState(db, table)),
|
createFilteringComposer: () =>
|
||||||
orderingComposer: $TabLinkOrderingComposer(ComposerState(db, table)),
|
$TabLinkFilterComposer($db: db, $table: table),
|
||||||
|
createOrderingComposer: () =>
|
||||||
|
$TabLinkOrderingComposer($db: db, $table: table),
|
||||||
|
createComputedFieldComposer: () =>
|
||||||
|
$TabLinkAnnotationComposer($db: db, $table: table),
|
||||||
updateCompanionCallback: ({
|
updateCompanionCallback: ({
|
||||||
Value<String> id = const Value.absent(),
|
Value<String> id = const Value.absent(),
|
||||||
Value<String?> topicId = const Value.absent(),
|
Value<String> topicId = const Value.absent(),
|
||||||
Value<DateTime> timestamp = const Value.absent(),
|
Value<DateTime> timestamp = const Value.absent(),
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) =>
|
}) =>
|
||||||
@@ -646,7 +755,7 @@ class $TabLinkTableManager extends RootTableManager<
|
|||||||
),
|
),
|
||||||
createCompanionCallback: ({
|
createCompanionCallback: ({
|
||||||
required String id,
|
required String id,
|
||||||
Value<String?> topicId = const Value.absent(),
|
required String topicId,
|
||||||
required DateTime timestamp,
|
required DateTime timestamp,
|
||||||
Value<int> rowid = const Value.absent(),
|
Value<int> rowid = const Value.absent(),
|
||||||
}) =>
|
}) =>
|
||||||
@@ -675,6 +784,7 @@ class $TabLinkTableManager extends RootTableManager<
|
|||||||
dynamic,
|
dynamic,
|
||||||
dynamic,
|
dynamic,
|
||||||
dynamic,
|
dynamic,
|
||||||
|
dynamic,
|
||||||
dynamic>>(state) {
|
dynamic>>(state) {
|
||||||
if (topicId) {
|
if (topicId) {
|
||||||
state = state.withJoin(
|
state = state.withJoin(
|
||||||
@@ -701,6 +811,7 @@ typedef $TabLinkProcessedTableManager = ProcessedTableManager<
|
|||||||
TabLinkData,
|
TabLinkData,
|
||||||
$TabLinkFilterComposer,
|
$TabLinkFilterComposer,
|
||||||
$TabLinkOrderingComposer,
|
$TabLinkOrderingComposer,
|
||||||
|
$TabLinkAnnotationComposer,
|
||||||
$TabLinkCreateCompanionBuilder,
|
$TabLinkCreateCompanionBuilder,
|
||||||
$TabLinkUpdateCompanionBuilder,
|
$TabLinkUpdateCompanionBuilder,
|
||||||
(TabLinkData, $TabLinkReferences),
|
(TabLinkData, $TabLinkReferences),
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ Stream<List<TopicDataWithCount>> topicsWithCount(TopicsWithCountRef ref) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Riverpod()
|
@Riverpod()
|
||||||
Stream<List<String>> topicTabIds(TopicTabIdsRef ref, String? topicId) {
|
Stream<List<String>> topicTabIds(TopicTabIdsRef ref, String topicId) {
|
||||||
final db = ref.watch(tabDatabaseProvider);
|
final db = ref.watch(tabDatabaseProvider);
|
||||||
return db.tabLinkDao.topicTabIds(topicId).watch();
|
return db.tabLinkDao.topicTabIds(topicId).watch();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ final topicsWithCountProvider =
|
|||||||
|
|
||||||
typedef TopicsWithCountRef
|
typedef TopicsWithCountRef
|
||||||
= AutoDisposeStreamProviderRef<List<TopicDataWithCount>>;
|
= AutoDisposeStreamProviderRef<List<TopicDataWithCount>>;
|
||||||
String _$topicTabIdsHash() => r'f7ce2633804421a22df1efc42eb4d19d440d9fd3';
|
String _$topicTabIdsHash() => r'43719c70e01cf9e030d75171405ab9650936ddf8';
|
||||||
|
|
||||||
/// Copied from Dart SDK
|
/// Copied from Dart SDK
|
||||||
class _SystemHash {
|
class _SystemHash {
|
||||||
@@ -74,7 +74,7 @@ class TopicTabIdsFamily extends Family<AsyncValue<List<String>>> {
|
|||||||
|
|
||||||
/// See also [topicTabIds].
|
/// See also [topicTabIds].
|
||||||
TopicTabIdsProvider call(
|
TopicTabIdsProvider call(
|
||||||
String? topicId,
|
String topicId,
|
||||||
) {
|
) {
|
||||||
return TopicTabIdsProvider(
|
return TopicTabIdsProvider(
|
||||||
topicId,
|
topicId,
|
||||||
@@ -109,7 +109,7 @@ class TopicTabIdsFamily extends Family<AsyncValue<List<String>>> {
|
|||||||
class TopicTabIdsProvider extends AutoDisposeStreamProvider<List<String>> {
|
class TopicTabIdsProvider extends AutoDisposeStreamProvider<List<String>> {
|
||||||
/// See also [topicTabIds].
|
/// See also [topicTabIds].
|
||||||
TopicTabIdsProvider(
|
TopicTabIdsProvider(
|
||||||
String? topicId,
|
String topicId,
|
||||||
) : this._internal(
|
) : this._internal(
|
||||||
(ref) => topicTabIds(
|
(ref) => topicTabIds(
|
||||||
ref as TopicTabIdsRef,
|
ref as TopicTabIdsRef,
|
||||||
@@ -137,7 +137,7 @@ class TopicTabIdsProvider extends AutoDisposeStreamProvider<List<String>> {
|
|||||||
required this.topicId,
|
required this.topicId,
|
||||||
}) : super.internal();
|
}) : super.internal();
|
||||||
|
|
||||||
final String? topicId;
|
final String topicId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Override overrideWith(
|
Override overrideWith(
|
||||||
@@ -178,7 +178,7 @@ class TopicTabIdsProvider extends AutoDisposeStreamProvider<List<String>> {
|
|||||||
|
|
||||||
mixin TopicTabIdsRef on AutoDisposeStreamProviderRef<List<String>> {
|
mixin TopicTabIdsRef on AutoDisposeStreamProviderRef<List<String>> {
|
||||||
/// The parameter `topicId` of this provider.
|
/// The parameter `topicId` of this provider.
|
||||||
String? get topicId;
|
String get topicId;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TopicTabIdsProviderElement
|
class _TopicTabIdsProviderElement
|
||||||
@@ -186,7 +186,7 @@ class _TopicTabIdsProviderElement
|
|||||||
_TopicTabIdsProviderElement(super.provider);
|
_TopicTabIdsProviderElement(super.provider);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String? get topicId => (origin as TopicTabIdsProvider).topicId;
|
String get topicId => (origin as TopicTabIdsProvider).topicId;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$tabTopicIdHash() => r'284164ac3acd9be3ba4e15eba99fc8d97602ee84';
|
String _$tabTopicIdHash() => r'284164ac3acd9be3ba4e15eba99fc8d97602ee84';
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import 'package:drift/drift.dart';
|
|
||||||
import 'package:lensai/features/geckoview/domain/providers/selected_tab.dart';
|
|
||||||
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
import 'package:lensai/features/geckoview/domain/providers/tab_state.dart';
|
||||||
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
import 'package:lensai/features/geckoview/domain/repositories/tab.dart';
|
||||||
import 'package:lensai/features/geckoview/features/topics/data/database/database.dart';
|
import 'package:lensai/features/geckoview/features/topics/data/database/database.dart';
|
||||||
@@ -15,38 +13,28 @@ class TabLinkRepository extends _$TabLinkRepository {
|
|||||||
@override
|
@override
|
||||||
void build() {
|
void build() {
|
||||||
_db = ref.watch(tabDatabaseProvider);
|
_db = ref.watch(tabDatabaseProvider);
|
||||||
|
|
||||||
//Sync existing tabs
|
|
||||||
ref.listen(
|
|
||||||
tabStatesProvider.select((tabs) => tabs.keys.toList()),
|
|
||||||
(previous, next) async {
|
|
||||||
//No empty list to avoid data loss
|
|
||||||
if (next.isNotEmpty) {
|
|
||||||
await _db.tabLinkDao.syncTabLinks(retainTabIds: next);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
ref.listen(
|
|
||||||
selectedTabProvider,
|
|
||||||
(previous, next) async {
|
|
||||||
if (next != null) {
|
|
||||||
await _db.tabLinkDao.touchTabLink(next, timestamp: DateTime.now());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> assignTab(String tabId, String? topicId) {
|
Future<void> assignTab(String tabId, String topicId) {
|
||||||
return _db.tabLinkDao.upsertTabLink(
|
return _db.tabLinkDao.upsertTabLink(
|
||||||
tabId,
|
tabId,
|
||||||
timestamp: DateTime.now(),
|
timestamp: DateTime.now(),
|
||||||
topicId: Value(topicId),
|
topicId: topicId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> closeAllTabs(String? topicId) async {
|
Future<void> closeAllTabs(String? topicId) async {
|
||||||
final tabIds = await _db.tabLinkDao.topicTabIds(topicId).get();
|
final List<String> tabIds;
|
||||||
|
if (topicId != null) {
|
||||||
|
tabIds = await _db.tabLinkDao.topicTabIds(topicId).get();
|
||||||
|
} else {
|
||||||
|
final openTabs = ref.read(tabStatesProvider).keys.toSet();
|
||||||
|
final assignedTabIds = await _db.tabLinkDao.allTabIds().get();
|
||||||
|
|
||||||
|
tabIds =
|
||||||
|
openTabs.where((tabId) => !assignedTabIds.contains(tabId)).toList();
|
||||||
|
}
|
||||||
|
|
||||||
if (tabIds.isNotEmpty) {
|
if (tabIds.isNotEmpty) {
|
||||||
await ref.read(tabRepositoryProvider.notifier).closeTabs(tabIds);
|
await ref.read(tabRepositoryProvider.notifier).closeTabs(tabIds);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ part of 'tab_link.dart';
|
|||||||
// RiverpodGenerator
|
// RiverpodGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$tabLinkRepositoryHash() => r'c4944c1f6792bd725f889b1d6e12946b1439be11';
|
String _$tabLinkRepositoryHash() => r'cdc23ca6ea215925f39842b16f9abcc289b0efbb';
|
||||||
|
|
||||||
/// See also [TabLinkRepository].
|
/// See also [TabLinkRepository].
|
||||||
@ProviderFor(TabLinkRepository)
|
@ProviderFor(TabLinkRepository)
|
||||||
|
|||||||
@@ -17,12 +17,8 @@ abstract class _$SettingsCWProxy {
|
|||||||
|
|
||||||
Settings launchUrlExternal(bool launchUrlExternal);
|
Settings launchUrlExternal(bool launchUrlExternal);
|
||||||
|
|
||||||
Settings enableContentBlocking(bool enableContentBlocking);
|
|
||||||
|
|
||||||
Settings blockHttpProtocol(bool blockHttpProtocol);
|
Settings blockHttpProtocol(bool blockHttpProtocol);
|
||||||
|
|
||||||
Settings enableHostList(Set<HostSource> enableHostList);
|
|
||||||
|
|
||||||
Settings themeMode(ThemeMode themeMode);
|
Settings themeMode(ThemeMode themeMode);
|
||||||
|
|
||||||
Settings quickAction(KagiTool? quickAction);
|
Settings quickAction(KagiTool? quickAction);
|
||||||
@@ -43,9 +39,7 @@ abstract class _$SettingsCWProxy {
|
|||||||
bool? incognitoMode,
|
bool? incognitoMode,
|
||||||
bool? enableJavascript,
|
bool? enableJavascript,
|
||||||
bool? launchUrlExternal,
|
bool? launchUrlExternal,
|
||||||
bool? enableContentBlocking,
|
|
||||||
bool? blockHttpProtocol,
|
bool? blockHttpProtocol,
|
||||||
Set<HostSource>? enableHostList,
|
|
||||||
ThemeMode? themeMode,
|
ThemeMode? themeMode,
|
||||||
KagiTool? quickAction,
|
KagiTool? quickAction,
|
||||||
bool? quickActionVoiceInput,
|
bool? quickActionVoiceInput,
|
||||||
@@ -78,18 +72,10 @@ class _$SettingsCWProxyImpl implements _$SettingsCWProxy {
|
|||||||
Settings launchUrlExternal(bool launchUrlExternal) =>
|
Settings launchUrlExternal(bool launchUrlExternal) =>
|
||||||
this(launchUrlExternal: launchUrlExternal);
|
this(launchUrlExternal: launchUrlExternal);
|
||||||
|
|
||||||
@override
|
|
||||||
Settings enableContentBlocking(bool enableContentBlocking) =>
|
|
||||||
this(enableContentBlocking: enableContentBlocking);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Settings blockHttpProtocol(bool blockHttpProtocol) =>
|
Settings blockHttpProtocol(bool blockHttpProtocol) =>
|
||||||
this(blockHttpProtocol: blockHttpProtocol);
|
this(blockHttpProtocol: blockHttpProtocol);
|
||||||
|
|
||||||
@override
|
|
||||||
Settings enableHostList(Set<HostSource> enableHostList) =>
|
|
||||||
this(enableHostList: enableHostList);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Settings themeMode(ThemeMode themeMode) => this(themeMode: themeMode);
|
Settings themeMode(ThemeMode themeMode) => this(themeMode: themeMode);
|
||||||
|
|
||||||
@@ -118,9 +104,7 @@ class _$SettingsCWProxyImpl implements _$SettingsCWProxy {
|
|||||||
Object? incognitoMode = const $CopyWithPlaceholder(),
|
Object? incognitoMode = const $CopyWithPlaceholder(),
|
||||||
Object? enableJavascript = const $CopyWithPlaceholder(),
|
Object? enableJavascript = const $CopyWithPlaceholder(),
|
||||||
Object? launchUrlExternal = const $CopyWithPlaceholder(),
|
Object? launchUrlExternal = const $CopyWithPlaceholder(),
|
||||||
Object? enableContentBlocking = const $CopyWithPlaceholder(),
|
|
||||||
Object? blockHttpProtocol = const $CopyWithPlaceholder(),
|
Object? blockHttpProtocol = const $CopyWithPlaceholder(),
|
||||||
Object? enableHostList = const $CopyWithPlaceholder(),
|
|
||||||
Object? themeMode = const $CopyWithPlaceholder(),
|
Object? themeMode = const $CopyWithPlaceholder(),
|
||||||
Object? quickAction = const $CopyWithPlaceholder(),
|
Object? quickAction = const $CopyWithPlaceholder(),
|
||||||
Object? quickActionVoiceInput = const $CopyWithPlaceholder(),
|
Object? quickActionVoiceInput = const $CopyWithPlaceholder(),
|
||||||
@@ -152,22 +136,11 @@ class _$SettingsCWProxyImpl implements _$SettingsCWProxy {
|
|||||||
? _value.launchUrlExternal
|
? _value.launchUrlExternal
|
||||||
// ignore: cast_nullable_to_non_nullable
|
// ignore: cast_nullable_to_non_nullable
|
||||||
: launchUrlExternal as bool,
|
: launchUrlExternal as bool,
|
||||||
enableContentBlocking:
|
|
||||||
enableContentBlocking == const $CopyWithPlaceholder() ||
|
|
||||||
enableContentBlocking == null
|
|
||||||
? _value.enableContentBlocking
|
|
||||||
// ignore: cast_nullable_to_non_nullable
|
|
||||||
: enableContentBlocking as bool,
|
|
||||||
blockHttpProtocol: blockHttpProtocol == const $CopyWithPlaceholder() ||
|
blockHttpProtocol: blockHttpProtocol == const $CopyWithPlaceholder() ||
|
||||||
blockHttpProtocol == null
|
blockHttpProtocol == null
|
||||||
? _value.blockHttpProtocol
|
? _value.blockHttpProtocol
|
||||||
// ignore: cast_nullable_to_non_nullable
|
// ignore: cast_nullable_to_non_nullable
|
||||||
: blockHttpProtocol as bool,
|
: blockHttpProtocol as bool,
|
||||||
enableHostList: enableHostList == const $CopyWithPlaceholder() ||
|
|
||||||
enableHostList == null
|
|
||||||
? _value.enableHostList
|
|
||||||
// ignore: cast_nullable_to_non_nullable
|
|
||||||
: enableHostList as Set<HostSource>,
|
|
||||||
themeMode: themeMode == const $CopyWithPlaceholder() || themeMode == null
|
themeMode: themeMode == const $CopyWithPlaceholder() || themeMode == null
|
||||||
? _value.themeMode
|
? _value.themeMode
|
||||||
// ignore: cast_nullable_to_non_nullable
|
// ignore: cast_nullable_to_non_nullable
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ part of 'settings_repository.dart';
|
|||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
String _$settingsRepositoryHash() =>
|
String _$settingsRepositoryHash() =>
|
||||||
r'f7c42efda64f0fb647e5daf0a92c2d118596cc52';
|
r'b0a498899546b6a0c8566458ed8848fef410c537';
|
||||||
|
|
||||||
/// See also [SettingsRepository].
|
/// See also [SettingsRepository].
|
||||||
@ProviderFor(SettingsRepository)
|
@ProviderFor(SettingsRepository)
|
||||||
|
|||||||
+25
-24
@@ -50,10 +50,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
|
sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0"
|
version: "2.6.0"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -290,18 +290,18 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: drift
|
name: drift
|
||||||
sha256: d6ff1ec6a0f3fa097dda6b776cf601f1f3d88b53b287288e09c1306f394fb1b3
|
sha256: df027d168a2985a2e9da900adeba2ab0136f0d84436592cf3cd5135f82c8579c
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.20.3"
|
version: "2.21.0"
|
||||||
drift_dev:
|
drift_dev:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: drift_dev
|
name: drift_dev
|
||||||
sha256: "3ee987578ca2281b5ff91eadd757cd6dd36001458d6e33784f990d67ff38f756"
|
sha256: "27bab15e7869b69259663590381180117873b9b273a1ea9ebb21bb73133d1233"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.20.3"
|
version: "2.21.0"
|
||||||
dynamic_color:
|
dynamic_color:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -479,10 +479,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: flutter_markdown
|
name: flutter_markdown
|
||||||
sha256: e17575ca576a34b46c58c91f9948891117a1bd97815d2e661813c7f90c647a78
|
sha256: bd9c475d9aae256369edacafc29d1e74c81f78a10cdcdacbbbc9e3c43d009e4a
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.3+2"
|
version: "0.7.4"
|
||||||
flutter_material_design_icons:
|
flutter_material_design_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -501,10 +501,11 @@ packages:
|
|||||||
flutter_pdf_text:
|
flutter_pdf_text:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "/home/fafre/Repos/flutter-pdf-text"
|
name: flutter_pdf_text
|
||||||
relative: false
|
sha256: "456fcc92ee6297f87e2e5bd46c35f1951a9cd716b8a00ab557d9d087c37a3b9c"
|
||||||
source: path
|
url: "https://pub.dev"
|
||||||
version: "0.6.0"
|
source: hosted
|
||||||
|
version: "0.7.0"
|
||||||
flutter_plugin_android_lifecycle:
|
flutter_plugin_android_lifecycle:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -517,10 +518,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_riverpod
|
name: flutter_riverpod
|
||||||
sha256: "0f1974eff5bbe774bf1d870e406fc6f29e3d6f1c46bd9c58e7172ff68a785d7d"
|
sha256: "711d916456563f715bde1e139d7cfdca009f8264befab3ac9f8ded8b6ec26405"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.1"
|
version: "2.5.3"
|
||||||
flutter_secure_storage:
|
flutter_secure_storage:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -655,10 +656,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: hooks_riverpod
|
name: hooks_riverpod
|
||||||
sha256: "97266a91c994951a06ef0ff3a1c7fb261e52ec7f74e87f0614ea0b7411b859b2"
|
sha256: "534ca8af331235f700f3916a74e4579cdfdd708e2fbed342fc8aa969d41a7af0"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.2"
|
version: "2.5.4"
|
||||||
hotreloader:
|
hotreloader:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -983,10 +984,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: riverpod
|
name: riverpod
|
||||||
sha256: f21b32ffd26a36555e501b04f4a5dca43ed59e16343f1a30c13632b2351dfa4d
|
sha256: c86fedfb45dd1da98ee6493dd9374325cdf494e7d523ebfb0c387eecc5f7b5c9
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.1"
|
version: "2.5.3"
|
||||||
riverpod_analyzer_utils:
|
riverpod_analyzer_utils:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -999,10 +1000,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: riverpod_annotation
|
name: riverpod_annotation
|
||||||
sha256: e5e796c0eba4030c704e9dae1b834a6541814963292839dcf9638d53eba84f5c
|
sha256: "77fdedb87d09344809e8b514ab864d0537b1cb580a93d09bf579b0403aa6203a"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.3.5"
|
version: "2.5.3"
|
||||||
riverpod_generator:
|
riverpod_generator:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
@@ -1187,10 +1188,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: sqlparser
|
name: sqlparser
|
||||||
sha256: "852cf80f9e974ac8e1b613758a8aa640215f7701352b66a7f468e95711eb570b"
|
sha256: c5f63dff8677407ddcddfa4744c176ea6dc44286c47ba9e69e76d8071398034d
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.38.1"
|
version: "0.39.1"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1418,10 +1419,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
sha256: "4d45dc9069dba4619dc0ebd93c7cec5e66d8482cb625a370ac806dcc8165f2ec"
|
sha256: e5c39a90447e7c81cfec14b041cdbd0d0916bd9ebbc7fe02ab69568be703b9bd
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.5.5"
|
version: "5.6.0"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
+7
-8
@@ -11,7 +11,7 @@ dependencies:
|
|||||||
collection: ^1.19.0
|
collection: ^1.19.0
|
||||||
copy_with_extension: ^5.0.4
|
copy_with_extension: ^5.0.4
|
||||||
crypto: ^3.0.5
|
crypto: ^3.0.5
|
||||||
drift: ^2.20.3
|
drift: ^2.21.0
|
||||||
dynamic_color: ^1.7.0
|
dynamic_color: ^1.7.0
|
||||||
exceptions: ^0.6.1
|
exceptions: ^0.6.1
|
||||||
expandable_page_view: ^1.0.17
|
expandable_page_view: ^1.0.17
|
||||||
@@ -22,18 +22,17 @@ dependencies:
|
|||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_hooks: ^0.20.5
|
flutter_hooks: ^0.20.5
|
||||||
flutter_inappwebview: ^6.1.5
|
flutter_inappwebview: ^6.1.5
|
||||||
flutter_markdown: ^0.7.3+2
|
flutter_markdown: ^0.7.4
|
||||||
flutter_material_design_icons: ^1.1.7447
|
flutter_material_design_icons: ^1.1.7447
|
||||||
flutter_mozilla_components:
|
flutter_mozilla_components:
|
||||||
path: ../packages/flutter_mozilla_components
|
path: ../packages/flutter_mozilla_components
|
||||||
flutter_pdf_text:
|
flutter_pdf_text: ^0.7.0
|
||||||
path: ../../flutter-pdf-text
|
|
||||||
flutter_secure_storage: ^9.2.2
|
flutter_secure_storage: ^9.2.2
|
||||||
flutter_sharing_intent: ^1.1.1
|
flutter_sharing_intent: ^1.1.1
|
||||||
go_router: ^14.3.0
|
go_router: ^14.3.0
|
||||||
google_fonts: ^6.2.1
|
google_fonts: ^6.2.1
|
||||||
home_widget: ^0.7.0
|
home_widget: ^0.7.0
|
||||||
hooks_riverpod: ^2.5.2
|
hooks_riverpod: ^2.5.4
|
||||||
html: ^0.15.4
|
html: ^0.15.4
|
||||||
http: ^1.2.2
|
http: ^1.2.2
|
||||||
json_annotation: ^4.9.0
|
json_annotation: ^4.9.0
|
||||||
@@ -43,8 +42,8 @@ dependencies:
|
|||||||
package_info_plus: ^8.0.3
|
package_info_plus: ^8.0.3
|
||||||
path: ^1.9.0
|
path: ^1.9.0
|
||||||
path_provider: ^2.1.4
|
path_provider: ^2.1.4
|
||||||
riverpod: ^2.5.1
|
riverpod: ^2.5.3
|
||||||
riverpod_annotation: ^2.3.5
|
riverpod_annotation: ^2.5.3
|
||||||
rxdart: ^0.28.0
|
rxdart: ^0.28.0
|
||||||
share_plus: ^10.0.3
|
share_plus: ^10.0.3
|
||||||
shared_preferences: ^2.3.2
|
shared_preferences: ^2.3.2
|
||||||
@@ -67,7 +66,7 @@ dev_dependencies:
|
|||||||
copy_with_extension_gen: ^5.0.4
|
copy_with_extension_gen: ^5.0.4
|
||||||
custom_lint: ^0.6.8
|
custom_lint: ^0.6.8
|
||||||
dependency_validator: ^4.1.1
|
dependency_validator: ^4.1.1
|
||||||
drift_dev: ^2.20.3
|
drift_dev: ^2.21.0
|
||||||
fast_equatable_lint: ^0.3.0
|
fast_equatable_lint: ^0.3.0
|
||||||
flutter_launcher_icons: ^0.14.1
|
flutter_launcher_icons: ^0.14.1
|
||||||
go_router_builder: ^2.7.1
|
go_router_builder: ^2.7.1
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
name: lensai_project
|
name: lensai_project
|
||||||
|
|
||||||
|
command:
|
||||||
|
clean:
|
||||||
|
hooks:
|
||||||
|
pre: melos exec -c 6 -- "flutter clean"
|
||||||
|
|
||||||
scripts:
|
scripts:
|
||||||
upgrade-major-tighten:
|
upgrade-major-tighten:
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
+1
@@ -68,6 +68,7 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Activit
|
|||||||
_components = GlobalComponents.components
|
_components = GlobalComponents.components
|
||||||
|
|
||||||
_engineView = createEngine(components)
|
_engineView = createEngine(components)
|
||||||
|
_components?.engineView = _engineView
|
||||||
|
|
||||||
val engineNativeView = engineView.asView()
|
val engineNativeView = engineView.asView()
|
||||||
// Set layout parameters
|
// Set layout parameters
|
||||||
|
|||||||
+22
-3
@@ -17,6 +17,8 @@ import eu.lensai.flutter_mozilla_components.pigeons.ReaderableState
|
|||||||
import eu.lensai.flutter_mozilla_components.pigeons.SecurityInfoState
|
import eu.lensai.flutter_mozilla_components.pigeons.SecurityInfoState
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.SelectionAction
|
import eu.lensai.flutter_mozilla_components.pigeons.SelectionAction
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.TabContentState
|
import eu.lensai.flutter_mozilla_components.pigeons.TabContentState
|
||||||
|
import kotlinx.coroutines.FlowPreview
|
||||||
|
import kotlinx.coroutines.flow.debounce
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.mapNotNull
|
import kotlinx.coroutines.flow.mapNotNull
|
||||||
@@ -31,10 +33,12 @@ import mozilla.components.browser.thumbnails.storage.ThumbnailStorage
|
|||||||
import mozilla.components.concept.base.crash.Breadcrumb
|
import mozilla.components.concept.base.crash.Breadcrumb
|
||||||
import mozilla.components.concept.engine.DefaultSettings
|
import mozilla.components.concept.engine.DefaultSettings
|
||||||
import mozilla.components.concept.engine.Engine
|
import mozilla.components.concept.engine.Engine
|
||||||
|
import mozilla.components.concept.engine.EngineView
|
||||||
import mozilla.components.concept.engine.mediaquery.PreferredColorScheme
|
import mozilla.components.concept.engine.mediaquery.PreferredColorScheme
|
||||||
import mozilla.components.concept.fetch.Client
|
import mozilla.components.concept.fetch.Client
|
||||||
import mozilla.components.feature.addons.AddonManager
|
import mozilla.components.feature.addons.AddonManager
|
||||||
import mozilla.components.feature.addons.amo.AMOAddonsProvider
|
import mozilla.components.feature.addons.amo.AMOAddonsProvider
|
||||||
|
import mozilla.components.feature.addons.logger
|
||||||
import mozilla.components.feature.addons.migration.DefaultSupportedAddonsChecker
|
import mozilla.components.feature.addons.migration.DefaultSupportedAddonsChecker
|
||||||
import mozilla.components.feature.addons.update.DefaultAddonUpdater
|
import mozilla.components.feature.addons.update.DefaultAddonUpdater
|
||||||
import mozilla.components.feature.app.links.AppLinksInterceptor
|
import mozilla.components.feature.app.links.AppLinksInterceptor
|
||||||
@@ -73,7 +77,7 @@ private const val DAY_IN_MINUTES = 24 * 60L
|
|||||||
@Suppress("LargeClass")
|
@Suppress("LargeClass")
|
||||||
open class DefaultComponents(
|
open class DefaultComponents(
|
||||||
private val applicationContext: Context,
|
private val applicationContext: Context,
|
||||||
private val flutterEvents: GeckoStateEvents,
|
val flutterEvents: GeckoStateEvents,
|
||||||
val readerViewController: ReaderViewController,
|
val readerViewController: ReaderViewController,
|
||||||
val selectionAction: SelectionAction,
|
val selectionAction: SelectionAction,
|
||||||
) {
|
) {
|
||||||
@@ -83,6 +87,8 @@ open class DefaultComponents(
|
|||||||
const val PREF_GLOBAL_PRIVACY_CONTROL = "sample_browser_global_privacy_control"
|
const val PREF_GLOBAL_PRIVACY_CONTROL = "sample_browser_global_privacy_control"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var engineView: EngineView? = null
|
||||||
|
|
||||||
val preferences: SharedPreferences =
|
val preferences: SharedPreferences =
|
||||||
applicationContext.getSharedPreferences(SAMPLE_BROWSER_PREFERENCES, Context.MODE_PRIVATE)
|
applicationContext.getSharedPreferences(SAMPLE_BROWSER_PREFERENCES, Context.MODE_PRIVATE)
|
||||||
|
|
||||||
@@ -140,6 +146,7 @@ open class DefaultComponents(
|
|||||||
FileUploadsDirCleaner { applicationContext.cacheDir }
|
FileUploadsDirCleaner { applicationContext.cacheDir }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(FlowPreview::class)
|
||||||
val store by lazy {
|
val store by lazy {
|
||||||
BrowserStore(
|
BrowserStore(
|
||||||
middleware = listOf(
|
middleware = listOf(
|
||||||
@@ -156,6 +163,7 @@ open class DefaultComponents(
|
|||||||
).apply {
|
).apply {
|
||||||
this.flowScoped { flow ->
|
this.flowScoped { flow ->
|
||||||
flow.map { state -> state.selectedTabId }
|
flow.map { state -> state.selectedTabId }
|
||||||
|
.distinctUntilChanged()
|
||||||
.collect { tabId ->
|
.collect { tabId ->
|
||||||
flutterEvents.onSelectedTabChange(
|
flutterEvents.onSelectedTabChange(
|
||||||
tabId
|
tabId
|
||||||
@@ -166,8 +174,10 @@ open class DefaultComponents(
|
|||||||
this.flowScoped { flow ->
|
this.flowScoped { flow ->
|
||||||
flow.mapNotNull { state -> state.tabs }
|
flow.mapNotNull { state -> state.tabs }
|
||||||
.filterChanged {
|
.filterChanged {
|
||||||
it.content.icon
|
it.content
|
||||||
}
|
}
|
||||||
|
.ifAnyChanged { arrayOf (it.content.icon) }
|
||||||
|
.debounce { 50 }
|
||||||
.collect { tab ->
|
.collect { tab ->
|
||||||
val iconBytes = tab.content.icon?.toWebPBytes()
|
val iconBytes = tab.content.icon?.toWebPBytes()
|
||||||
flutterEvents.onIconChange(
|
flutterEvents.onIconChange(
|
||||||
@@ -182,6 +192,7 @@ open class DefaultComponents(
|
|||||||
.filterChanged {
|
.filterChanged {
|
||||||
it.content.securityInfo
|
it.content.securityInfo
|
||||||
}
|
}
|
||||||
|
.debounce { 50 }
|
||||||
.collect { tab ->
|
.collect { tab ->
|
||||||
flutterEvents.onSecurityInfoStateChange(
|
flutterEvents.onSecurityInfoStateChange(
|
||||||
tab.id,
|
tab.id,
|
||||||
@@ -204,6 +215,7 @@ open class DefaultComponents(
|
|||||||
it.readerState.active,
|
it.readerState.active,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
.debounce { 50 }
|
||||||
.collect { tab ->
|
.collect { tab ->
|
||||||
flutterEvents.onReaderableStateChange(
|
flutterEvents.onReaderableStateChange(
|
||||||
tab.id,
|
tab.id,
|
||||||
@@ -226,6 +238,7 @@ open class DefaultComponents(
|
|||||||
it.content.canGoForward,
|
it.content.canGoForward,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
.debounce { 50 }
|
||||||
.collect { tab ->
|
.collect { tab ->
|
||||||
flutterEvents.onHistoryStateChange(
|
flutterEvents.onHistoryStateChange(
|
||||||
tab.id,
|
tab.id,
|
||||||
@@ -261,8 +274,11 @@ open class DefaultComponents(
|
|||||||
it.content.private,
|
it.content.private,
|
||||||
it.content.fullScreen,
|
it.content.fullScreen,
|
||||||
it.content.progress,
|
it.content.progress,
|
||||||
it.content.loading) }
|
it.content.loading)
|
||||||
|
}
|
||||||
|
.debounce { 50 }
|
||||||
.collect { tab ->
|
.collect { tab ->
|
||||||
|
logger.info("title: ${tab.content.title} ${tab.content.url}")
|
||||||
flutterEvents.onTabContentStateChange(
|
flutterEvents.onTabContentStateChange(
|
||||||
TabContentState(
|
TabContentState(
|
||||||
id = tab.id,
|
id = tab.id,
|
||||||
@@ -283,6 +299,7 @@ open class DefaultComponents(
|
|||||||
.filterChanged {
|
.filterChanged {
|
||||||
it.content.findResults
|
it.content.findResults
|
||||||
}
|
}
|
||||||
|
.distinctUntilChanged()
|
||||||
.collect { tab ->
|
.collect { tab ->
|
||||||
tab.content.findResults
|
tab.content.findResults
|
||||||
flutterEvents.onFindResults(
|
flutterEvents.onFindResults(
|
||||||
@@ -296,6 +313,8 @@ open class DefaultComponents(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
icons.install(engine, this)
|
||||||
|
|
||||||
WebNotificationFeature(
|
WebNotificationFeature(
|
||||||
applicationContext,
|
applicationContext,
|
||||||
engine,
|
engine,
|
||||||
|
|||||||
+10
-4
@@ -87,6 +87,7 @@ class FlutterMozillaComponentsPlugin: FlutterPlugin, ActivityAware {
|
|||||||
private var activity: Activity? = null
|
private var activity: Activity? = null
|
||||||
|
|
||||||
private lateinit var _flutterPluginBinding: FlutterPlugin.FlutterPluginBinding;
|
private lateinit var _flutterPluginBinding: FlutterPlugin.FlutterPluginBinding;
|
||||||
|
private lateinit var _flutterEvents : GeckoStateEvents
|
||||||
|
|
||||||
init {
|
init {
|
||||||
Log.addSink(AndroidLogSink())
|
Log.addSink(AndroidLogSink())
|
||||||
@@ -95,14 +96,15 @@ class FlutterMozillaComponentsPlugin: FlutterPlugin, ActivityAware {
|
|||||||
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||||
_flutterPluginBinding = flutterPluginBinding
|
_flutterPluginBinding = flutterPluginBinding
|
||||||
|
|
||||||
val flutterEvents = GeckoStateEvents(_flutterPluginBinding.binaryMessenger)
|
_flutterEvents = GeckoStateEvents(_flutterPluginBinding.binaryMessenger)
|
||||||
|
|
||||||
val readerViewController =
|
val readerViewController =
|
||||||
ReaderViewController(_flutterPluginBinding.binaryMessenger)
|
ReaderViewController(_flutterPluginBinding.binaryMessenger)
|
||||||
val selectionActionDelegate = SelectionAction(_flutterPluginBinding.binaryMessenger)
|
val selectionActionDelegate = SelectionAction(_flutterPluginBinding.binaryMessenger)
|
||||||
|
|
||||||
GlobalComponents.setUp(
|
GlobalComponents.setUp(
|
||||||
flutterPluginBinding.applicationContext,
|
flutterPluginBinding.applicationContext,
|
||||||
flutterEvents,
|
_flutterEvents,
|
||||||
readerViewController,
|
readerViewController,
|
||||||
selectionActionDelegate
|
selectionActionDelegate
|
||||||
)
|
)
|
||||||
@@ -141,7 +143,6 @@ class FlutterMozillaComponentsPlugin: FlutterPlugin, ActivityAware {
|
|||||||
fm.beginTransaction()
|
fm.beginTransaction()
|
||||||
.replace(FRAGMENT_CONTAINER_ID, nativeFragment)
|
.replace(FRAGMENT_CONTAINER_ID, nativeFragment)
|
||||||
.commitAllowingStateLoss()
|
.commitAllowingStateLoss()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
|
||||||
@@ -152,7 +153,12 @@ class FlutterMozillaComponentsPlugin: FlutterPlugin, ActivityAware {
|
|||||||
this.activity = binding.activity
|
this.activity = binding.activity
|
||||||
|
|
||||||
_flutterPluginBinding.platformViewRegistry.registerViewFactory(
|
_flutterPluginBinding.platformViewRegistry.registerViewFactory(
|
||||||
"eu.lensai/gecko", GeckoViewFactory(binding.activity, FRAGMENT_CONTAINER_ID))
|
"eu.lensai/gecko", GeckoViewFactory(
|
||||||
|
binding.activity,
|
||||||
|
FRAGMENT_CONTAINER_ID,
|
||||||
|
_flutterEvents
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDetachedFromActivityForConfigChanges() {
|
override fun onDetachedFromActivityForConfigChanges() {
|
||||||
|
|||||||
+15
-4
@@ -5,20 +5,26 @@ import android.app.Activity
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoStateEvents
|
||||||
import io.flutter.plugin.common.StandardMessageCodec
|
import io.flutter.plugin.common.StandardMessageCodec
|
||||||
import io.flutter.plugin.platform.PlatformView
|
import io.flutter.plugin.platform.PlatformView
|
||||||
import io.flutter.plugin.platform.PlatformViewFactory
|
import io.flutter.plugin.platform.PlatformViewFactory
|
||||||
|
|
||||||
class GeckoViewFactory(private val activity: Activity, private val containerId: Int) : PlatformViewFactory(
|
class GeckoViewFactory(
|
||||||
|
private val activity: Activity,
|
||||||
|
private val containerId: Int,
|
||||||
|
private val flutterEvents: GeckoStateEvents
|
||||||
|
) : PlatformViewFactory(
|
||||||
StandardMessageCodec.INSTANCE) {
|
StandardMessageCodec.INSTANCE) {
|
||||||
override fun create(context: Context?, id: Int, args: Any?): PlatformView {
|
override fun create(context: Context?, id: Int, args: Any?): PlatformView {
|
||||||
return NativeFragmentView(this.activity, this.containerId)
|
return NativeFragmentView(this.activity, this.containerId, this.flutterEvents)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class NativeFragmentView(
|
private class NativeFragmentView(
|
||||||
private val activity: Activity?,
|
activity: Activity?,
|
||||||
private val containerId: Int
|
containerId: Int,
|
||||||
|
private val flutterEvents: GeckoStateEvents
|
||||||
) : PlatformView {
|
) : PlatformView {
|
||||||
private val container: View
|
private val container: View
|
||||||
|
|
||||||
@@ -32,6 +38,11 @@ private class NativeFragmentView(
|
|||||||
container.id = containerId
|
container.id = containerId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onFlutterViewAttached(flutterView: View) {
|
||||||
|
super.onFlutterViewAttached(flutterView)
|
||||||
|
flutterEvents.onFragmentReadyStateChange(true) { _ -> }
|
||||||
|
}
|
||||||
|
|
||||||
override fun getView(): View {
|
override fun getView(): View {
|
||||||
return container
|
return container
|
||||||
}
|
}
|
||||||
|
|||||||
+35
@@ -2,17 +2,35 @@ package eu.lensai.flutter_mozilla_components.api
|
|||||||
|
|
||||||
import android.util.Log
|
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.toWebPBytes
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.GeckoSessionApi
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoSessionApi
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoStateEvents
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.LoadUrlFlagsValue
|
import eu.lensai.flutter_mozilla_components.pigeons.LoadUrlFlagsValue
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import mozilla.components.browser.state.action.ContentAction
|
||||||
|
import mozilla.components.browser.state.selector.findTab
|
||||||
|
import mozilla.components.browser.state.selector.selectedTab
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.TranslationOptions as PigeonTranslationOptions
|
import eu.lensai.flutter_mozilla_components.pigeons.TranslationOptions as PigeonTranslationOptions
|
||||||
import mozilla.components.browser.state.state.BrowserState
|
import mozilla.components.browser.state.state.BrowserState
|
||||||
|
import mozilla.components.browser.state.store.BrowserStore
|
||||||
|
import mozilla.components.browser.thumbnails.storage.ThumbnailStorage
|
||||||
|
import mozilla.components.concept.base.images.ImageLoadRequest
|
||||||
import mozilla.components.concept.engine.EngineSession
|
import mozilla.components.concept.engine.EngineSession
|
||||||
|
import mozilla.components.concept.engine.EngineView
|
||||||
import mozilla.components.concept.engine.translate.TranslationOptions
|
import mozilla.components.concept.engine.translate.TranslationOptions
|
||||||
import mozilla.components.feature.session.SessionUseCases
|
import mozilla.components.feature.session.SessionUseCases
|
||||||
|
import org.mozilla.gecko.util.ThreadUtils.runOnUiThread
|
||||||
|
|
||||||
class GeckoSessionApiImpl : GeckoSessionApi {
|
class GeckoSessionApiImpl : GeckoSessionApi {
|
||||||
private val sessionUseCases: SessionUseCases by lazy { GlobalComponents.components!!.sessionUseCases }
|
private val sessionUseCases: SessionUseCases by lazy { GlobalComponents.components!!.sessionUseCases }
|
||||||
|
private val store: BrowserStore by lazy { GlobalComponents.components!!.store }
|
||||||
private val state: BrowserState by lazy { GlobalComponents.components!!.store.state }
|
private val state: BrowserState by lazy { GlobalComponents.components!!.store.state }
|
||||||
|
private val thumbnailStorage: ThumbnailStorage by lazy { GlobalComponents.components!!.thumbnailStorage }
|
||||||
|
private val events: GeckoStateEvents by lazy { GlobalComponents.components!!.flutterEvents }
|
||||||
|
private val engineView: EngineView? by lazy { GlobalComponents.components!!.engineView }
|
||||||
|
|
||||||
override fun loadUrl(
|
override fun loadUrl(
|
||||||
tabId: String?,
|
tabId: String?,
|
||||||
@@ -124,4 +142,21 @@ class GeckoSessionApiImpl : GeckoSessionApi {
|
|||||||
lastAccess = lastAccess ?: System.currentTimeMillis()
|
lastAccess = lastAccess ?: System.currentTimeMillis()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun requestScreenshot(callback: (Result<ByteArray?>) -> Unit) {
|
||||||
|
val tab = state.selectedTab
|
||||||
|
if (tab != null) {
|
||||||
|
engineView?.captureThumbnail { bitmap ->
|
||||||
|
if (bitmap != null) {
|
||||||
|
store.dispatch(ContentAction.UpdateThumbnailAction(tab.id, bitmap))
|
||||||
|
val compressed = bitmap.toWebPBytes()
|
||||||
|
callback(Result.success(compressed))
|
||||||
|
} else {
|
||||||
|
callback(Result.success(null))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(Result.failure(Exception("No selected tab for screenshot")))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+145
@@ -8,7 +8,18 @@ import eu.lensai.flutter_mozilla_components.pigeons.RestoreLocation as PigeonRes
|
|||||||
import eu.lensai.flutter_mozilla_components.pigeons.RecoverableTab as PigeonRecoverableTab
|
import eu.lensai.flutter_mozilla_components.pigeons.RecoverableTab as PigeonRecoverableTab
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.SourceValue
|
import eu.lensai.flutter_mozilla_components.pigeons.SourceValue
|
||||||
import eu.lensai.flutter_mozilla_components.GlobalComponents
|
import eu.lensai.flutter_mozilla_components.GlobalComponents
|
||||||
|
import eu.lensai.flutter_mozilla_components.ext.toWebPBytes
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.FindResultState
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.GeckoStateEvents
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.HistoryItem
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.HistoryState
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.ReaderableState
|
||||||
import eu.lensai.flutter_mozilla_components.pigeons.RestoreLocation
|
import eu.lensai.flutter_mozilla_components.pigeons.RestoreLocation
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.SecurityInfoState
|
||||||
|
import eu.lensai.flutter_mozilla_components.pigeons.TabContentState
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import mozilla.components.browser.session.storage.RecoverableBrowserState
|
import mozilla.components.browser.session.storage.RecoverableBrowserState
|
||||||
import mozilla.components.browser.state.action.TabListAction
|
import mozilla.components.browser.state.action.TabListAction
|
||||||
import mozilla.components.browser.state.selector.findTab
|
import mozilla.components.browser.state.selector.findTab
|
||||||
@@ -18,16 +29,21 @@ import mozilla.components.browser.state.state.ReaderState
|
|||||||
import mozilla.components.browser.state.state.SessionState
|
import mozilla.components.browser.state.state.SessionState
|
||||||
import mozilla.components.browser.state.state.recover.RecoverableTab
|
import mozilla.components.browser.state.state.recover.RecoverableTab
|
||||||
import mozilla.components.browser.state.state.recover.TabState
|
import mozilla.components.browser.state.state.recover.TabState
|
||||||
|
import mozilla.components.browser.thumbnails.storage.ThumbnailStorage
|
||||||
|
import mozilla.components.concept.base.images.ImageLoadRequest
|
||||||
import mozilla.components.concept.engine.Engine
|
import mozilla.components.concept.engine.Engine
|
||||||
import mozilla.components.concept.engine.EngineSession
|
import mozilla.components.concept.engine.EngineSession
|
||||||
import mozilla.components.concept.storage.HistoryMetadataKey
|
import mozilla.components.concept.storage.HistoryMetadataKey
|
||||||
import mozilla.components.feature.tabs.TabsUseCases
|
import mozilla.components.feature.tabs.TabsUseCases
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
import org.mozilla.gecko.util.ThreadUtils.runOnUiThread
|
||||||
|
|
||||||
class GeckoTabsApiImpl() : GeckoTabsApi {
|
class GeckoTabsApiImpl() : GeckoTabsApi {
|
||||||
private val tabsUseCases: TabsUseCases by lazy { GlobalComponents.components!!.tabsUseCases }
|
private val tabsUseCases: TabsUseCases by lazy { GlobalComponents.components!!.tabsUseCases }
|
||||||
private val engine: Engine by lazy { GlobalComponents.components!!.engine }
|
private val engine: Engine by lazy { GlobalComponents.components!!.engine }
|
||||||
private val state: BrowserState by lazy { GlobalComponents.components!!.store.state }
|
private val state: BrowserState by lazy { GlobalComponents.components!!.store.state }
|
||||||
|
private val thumbnailStorage: ThumbnailStorage by lazy { GlobalComponents.components!!.thumbnailStorage }
|
||||||
|
private val events: GeckoStateEvents by lazy { GlobalComponents.components!!.flutterEvents }
|
||||||
|
|
||||||
private fun restoreSource(source: SourceValue ) : SessionState.Source {
|
private fun restoreSource(source: SourceValue ) : SessionState.Source {
|
||||||
return SessionState.Source.restore(
|
return SessionState.Source.restore(
|
||||||
@@ -88,6 +104,135 @@ class GeckoTabsApiImpl() : GeckoTabsApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun syncEvents(
|
||||||
|
onSelectedTabChange: Boolean,
|
||||||
|
onTabListChange: Boolean,
|
||||||
|
onTabContentStateChange: Boolean,
|
||||||
|
onIconChange: Boolean,
|
||||||
|
onSecurityInfoStateChange: Boolean,
|
||||||
|
onReaderableStateChange: Boolean,
|
||||||
|
onHistoryStateChange: Boolean,
|
||||||
|
onFindResults: Boolean,
|
||||||
|
onThumbnailChange: Boolean,
|
||||||
|
) {
|
||||||
|
if(onSelectedTabChange) {
|
||||||
|
events.onSelectedTabChange(
|
||||||
|
state.selectedTabId
|
||||||
|
) { _ -> }
|
||||||
|
}
|
||||||
|
|
||||||
|
if(onTabListChange) {
|
||||||
|
events.onTabListChange(state.tabs.map {tab -> tab.id}) { _ -> }
|
||||||
|
}
|
||||||
|
|
||||||
|
if(onTabContentStateChange) {
|
||||||
|
state.tabs.forEach { tab ->
|
||||||
|
events.onTabContentStateChange(
|
||||||
|
TabContentState(
|
||||||
|
id = tab.id,
|
||||||
|
contextId = tab.contextId,
|
||||||
|
url = tab.content.url,
|
||||||
|
title = tab.content.title,
|
||||||
|
progress = tab.content.progress.toLong(),
|
||||||
|
isPrivate = tab.content.private,
|
||||||
|
isFullScreen = tab.content.fullScreen,
|
||||||
|
isLoading = tab.content.loading
|
||||||
|
)
|
||||||
|
) { _ -> }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(onIconChange) {
|
||||||
|
state.tabs.forEach { tab ->
|
||||||
|
if(tab.content.icon != null) {
|
||||||
|
val iconBytes = tab.content.icon?.toWebPBytes()
|
||||||
|
events.onIconChange(
|
||||||
|
tab.id,
|
||||||
|
iconBytes
|
||||||
|
) { _ -> }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(onSecurityInfoStateChange) {
|
||||||
|
state.tabs.forEach { tab ->
|
||||||
|
val iconBytes = tab.content.icon?.toWebPBytes()
|
||||||
|
events.onSecurityInfoStateChange(
|
||||||
|
tab.id,
|
||||||
|
SecurityInfoState(
|
||||||
|
tab.content.securityInfo.secure,
|
||||||
|
tab.content.securityInfo.host,
|
||||||
|
tab.content.securityInfo.issuer,
|
||||||
|
)
|
||||||
|
) { _ -> }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(onReaderableStateChange) {
|
||||||
|
state.tabs.forEach { tab ->
|
||||||
|
events.onReaderableStateChange(
|
||||||
|
tab.id,
|
||||||
|
ReaderableState(
|
||||||
|
tab.readerState.readerable,
|
||||||
|
tab.readerState.active,
|
||||||
|
)
|
||||||
|
) { _ -> }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(onHistoryStateChange) {
|
||||||
|
state.tabs.forEach { tab ->
|
||||||
|
events.onHistoryStateChange(
|
||||||
|
tab.id,
|
||||||
|
HistoryState(
|
||||||
|
items = tab.content.history.items.map { item -> HistoryItem(
|
||||||
|
url = item.uri,
|
||||||
|
title = item.title
|
||||||
|
) },
|
||||||
|
currentIndex = tab.content.history.currentIndex.toLong(),
|
||||||
|
canGoBack = tab.content.canGoBack,
|
||||||
|
canGoForward = tab.content.canGoForward,
|
||||||
|
)
|
||||||
|
) { _ -> }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(onFindResults) {
|
||||||
|
state.tabs.forEach { tab ->
|
||||||
|
events.onFindResults(
|
||||||
|
tab.id,
|
||||||
|
tab.content.findResults.map { result -> FindResultState(
|
||||||
|
activeMatchOrdinal = result.activeMatchOrdinal.toLong(),
|
||||||
|
numberOfMatches = result.numberOfMatches.toLong(),
|
||||||
|
isDoneCounting = result.isDoneCounting,
|
||||||
|
) }
|
||||||
|
) { _ -> }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(onThumbnailChange) {
|
||||||
|
state.tabs.forEach { tab ->
|
||||||
|
CoroutineScope(Dispatchers.Default).launch {
|
||||||
|
val bitmap = thumbnailStorage.loadThumbnail(
|
||||||
|
ImageLoadRequest(
|
||||||
|
id = tab.id,
|
||||||
|
//TODO: make this configurable
|
||||||
|
size = 600,
|
||||||
|
isPrivate = tab.content.private
|
||||||
|
)
|
||||||
|
).await()
|
||||||
|
|
||||||
|
if(bitmap != null) {
|
||||||
|
val bytes = bitmap.toWebPBytes()
|
||||||
|
runOnUiThread {
|
||||||
|
events.onThumbnailChange(tab.id, bytes) { _ -> }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun selectTab(tabId: String) {
|
override fun selectTab(tabId: String) {
|
||||||
tabsUseCases.selectTab(tabId = tabId)
|
tabsUseCases.selectTab(tabId = tabId)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -12,6 +12,7 @@ import mozilla.components.browser.state.action.ContentAction
|
|||||||
import mozilla.components.browser.state.state.BrowserState
|
import mozilla.components.browser.state.state.BrowserState
|
||||||
import mozilla.components.lib.state.Middleware
|
import mozilla.components.lib.state.Middleware
|
||||||
import mozilla.components.lib.state.MiddlewareContext
|
import mozilla.components.lib.state.MiddlewareContext
|
||||||
|
import org.mozilla.gecko.util.ThreadUtils.runOnUiThread
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
|
|
||||||
@@ -30,8 +31,10 @@ class FlutterEventMiddleware(private val flutterEvents: GeckoStateEvents) : Midd
|
|||||||
when (action) {
|
when (action) {
|
||||||
is ContentAction.UpdateThumbnailAction -> {
|
is ContentAction.UpdateThumbnailAction -> {
|
||||||
val bytes = action.thumbnail.toWebPBytes()
|
val bytes = action.thumbnail.toWebPBytes()
|
||||||
|
runOnUiThread {
|
||||||
flutterEvents.onThumbnailChange(action.sessionId, bytes) { _ -> }
|
flutterEvents.onThumbnailChange(action.sessionId, bytes) { _ -> }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|||||||
+64
-18
@@ -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
|
// See also: https://pub.dev/packages/pigeon
|
||||||
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass")
|
||||||
|
|
||||||
@@ -1239,6 +1239,7 @@ interface GeckoSessionApi {
|
|||||||
fun crashRecovery(tabIds: List<String>?)
|
fun crashRecovery(tabIds: List<String>?)
|
||||||
fun purgeHistory()
|
fun purgeHistory()
|
||||||
fun updateLastAccess(tabId: String?, lastAccess: Long?)
|
fun updateLastAccess(tabId: String?, lastAccess: Long?)
|
||||||
|
fun requestScreenshot(callback: (Result<ByteArray?>) -> Unit)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/** The codec used by GeckoSessionApi. */
|
/** The codec used by GeckoSessionApi. */
|
||||||
@@ -1550,11 +1551,30 @@ interface GeckoSessionApi {
|
|||||||
channel.setMessageHandler(null)
|
channel.setMessageHandler(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoSessionApi.requestScreenshot$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { _, reply ->
|
||||||
|
api.requestScreenshot{ result: Result<ByteArray?> ->
|
||||||
|
val error = result.exceptionOrNull()
|
||||||
|
if (error != null) {
|
||||||
|
reply.reply(wrapError(error))
|
||||||
|
} else {
|
||||||
|
val data = result.getOrNull()
|
||||||
|
reply.reply(wrapResult(data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/** 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 GeckoTabsApi {
|
interface GeckoTabsApi {
|
||||||
|
fun syncEvents(onSelectedTabChange: Boolean, onTabListChange: Boolean, onTabContentStateChange: Boolean, onIconChange: Boolean, onSecurityInfoStateChange: Boolean, onReaderableStateChange: Boolean, onHistoryStateChange: Boolean, onFindResults: Boolean, onThumbnailChange: Boolean)
|
||||||
fun selectTab(tabId: String)
|
fun selectTab(tabId: String)
|
||||||
fun removeTab(tabId: String)
|
fun removeTab(tabId: String)
|
||||||
fun addTab(url: String, selectTab: Boolean, startLoading: Boolean, parentId: String?, flags: LoadUrlFlagsValue, contextId: String?, source: SourceValue, private: Boolean, historyMetadata: HistoryMetadataKey?, additionalHeaders: Map<String, String>?): String
|
fun addTab(url: String, selectTab: Boolean, startLoading: Boolean, parentId: String?, flags: LoadUrlFlagsValue, contextId: String?, source: SourceValue, private: Boolean, historyMetadata: HistoryMetadataKey?, additionalHeaders: Map<String, String>?): String
|
||||||
@@ -1585,6 +1605,32 @@ interface GeckoTabsApi {
|
|||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun setUp(binaryMessenger: BinaryMessenger, api: GeckoTabsApi?, messageChannelSuffix: String = "") {
|
fun setUp(binaryMessenger: BinaryMessenger, api: GeckoTabsApi?, messageChannelSuffix: String = "") {
|
||||||
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||||
|
run {
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoTabsApi.syncEvents$separatedMessageChannelSuffix", codec)
|
||||||
|
if (api != null) {
|
||||||
|
channel.setMessageHandler { message, reply ->
|
||||||
|
val args = message as List<Any?>
|
||||||
|
val onSelectedTabChangeArg = args[0] as Boolean
|
||||||
|
val onTabListChangeArg = args[1] as Boolean
|
||||||
|
val onTabContentStateChangeArg = args[2] as Boolean
|
||||||
|
val onIconChangeArg = args[3] as Boolean
|
||||||
|
val onSecurityInfoStateChangeArg = args[4] as Boolean
|
||||||
|
val onReaderableStateChangeArg = args[5] as Boolean
|
||||||
|
val onHistoryStateChangeArg = args[6] as Boolean
|
||||||
|
val onFindResultsArg = args[7] as Boolean
|
||||||
|
val onThumbnailChangeArg = args[8] as Boolean
|
||||||
|
val wrapped: List<Any?> = try {
|
||||||
|
api.syncEvents(onSelectedTabChangeArg, onTabListChangeArg, onTabContentStateChangeArg, onIconChangeArg, onSecurityInfoStateChangeArg, onReaderableStateChangeArg, onHistoryStateChangeArg, onFindResultsArg, onThumbnailChangeArg)
|
||||||
|
listOf(null)
|
||||||
|
} catch (exception: Throwable) {
|
||||||
|
wrapError(exception)
|
||||||
|
}
|
||||||
|
reply.reply(wrapped)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
channel.setMessageHandler(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
run {
|
run {
|
||||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoTabsApi.selectTab$separatedMessageChannelSuffix", codec)
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.flutter_mozilla_components.GeckoTabsApi.selectTab$separatedMessageChannelSuffix", codec)
|
||||||
if (api != null) {
|
if (api != null) {
|
||||||
@@ -2107,6 +2153,23 @@ class GeckoStateEvents(private val binaryMessenger: BinaryMessenger, private val
|
|||||||
GeckoPigeonCodec()
|
GeckoPigeonCodec()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fun onFragmentReadyStateChange(stateArg: Boolean, callback: (Result<Unit>) -> Unit)
|
||||||
|
{
|
||||||
|
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||||
|
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onFragmentReadyStateChange$separatedMessageChannelSuffix"
|
||||||
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
||||||
|
channel.send(listOf(stateArg)) {
|
||||||
|
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)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
fun onTabListChange(tabIdsArg: List<String>, callback: (Result<Unit>) -> Unit)
|
fun onTabListChange(tabIdsArg: List<String>, callback: (Result<Unit>) -> Unit)
|
||||||
{
|
{
|
||||||
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
||||||
@@ -2337,23 +2400,6 @@ class ReaderViewController(private val binaryMessenger: BinaryMessenger, private
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun readerViewButtonVisibility(visibleArg: Boolean, callback: (Result<Unit>) -> Unit)
|
|
||||||
{
|
|
||||||
val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else ""
|
|
||||||
val channelName = "dev.flutter.pigeon.flutter_mozilla_components.ReaderViewController.readerViewButtonVisibility$separatedMessageChannelSuffix"
|
|
||||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, channelName, codec)
|
|
||||||
channel.send(listOf(visibleArg)) {
|
|
||||||
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 class from Pigeon that represents Flutter messages that can be called from Kotlin. */
|
/** Generated class from Pigeon that represents Flutter messages that can be called from Kotlin. */
|
||||||
class SelectionAction(private val binaryMessenger: BinaryMessenger, private val messageChannelSuffix: String = "") {
|
class SelectionAction(private val binaryMessenger: BinaryMessenger, private val messageChannelSuffix: String = "") {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
||||||
|
import 'package:rxdart/rxdart.dart';
|
||||||
|
|
||||||
// Typedefs for record types
|
// Typedefs for record types
|
||||||
typedef HistoryEvent = ({String tabId, HistoryState history});
|
typedef HistoryEvent = ({String tabId, HistoryState history});
|
||||||
@@ -12,74 +13,79 @@ typedef FindResultsEvent = ({String tabId, List<FindResultState> results});
|
|||||||
|
|
||||||
class GeckoEventService extends GeckoStateEvents {
|
class GeckoEventService extends GeckoStateEvents {
|
||||||
// Stream controllers
|
// Stream controllers
|
||||||
final _tabListController = StreamController<List<String>>.broadcast();
|
final _fragmentStateSubject = BehaviorSubject.seeded(false);
|
||||||
final _selectedTabController = StreamController<String?>.broadcast();
|
final _tabListSubject = BehaviorSubject<List<String>>();
|
||||||
final _tabContentController = StreamController<TabContentState>.broadcast();
|
final _selectedTabSubject = BehaviorSubject<String?>();
|
||||||
final _historyController = StreamController<HistoryEvent>.broadcast();
|
final _tabContentSubject = BehaviorSubject<TabContentState>();
|
||||||
final _readerableController = StreamController<ReaderableEvent>.broadcast();
|
final _historySubject = BehaviorSubject<HistoryEvent>();
|
||||||
final _securityInfoController =
|
final _readerableSubject = BehaviorSubject<ReaderableEvent>();
|
||||||
StreamController<SecurityInfoEvent>.broadcast();
|
final _securityInfoSubject = BehaviorSubject<SecurityInfoEvent>();
|
||||||
final _iconController = StreamController<IconEvent>.broadcast();
|
final _iconSubject = BehaviorSubject<IconEvent>();
|
||||||
final _thumbnailController = StreamController<ThumbnailEvent>.broadcast();
|
final _thumbnailSubject = BehaviorSubject<ThumbnailEvent>();
|
||||||
final _findResultsController = StreamController<FindResultsEvent>.broadcast();
|
final _findResultsSubject = BehaviorSubject<FindResultsEvent>();
|
||||||
|
|
||||||
// Event streams
|
// Event streams
|
||||||
Stream<List<String>> get tabListEvents => _tabListController.stream;
|
Stream<bool> get fragmentReadyStateEvents => _fragmentStateSubject.stream;
|
||||||
Stream<String?> get selectedTabEvents => _selectedTabController.stream;
|
Stream<List<String>> get tabListEvents => _tabListSubject.stream;
|
||||||
Stream<TabContentState> get tabContentEvents => _tabContentController.stream;
|
Stream<String?> get selectedTabEvents => _selectedTabSubject.stream;
|
||||||
Stream<HistoryEvent> get historyEvents => _historyController.stream;
|
Stream<TabContentState> get tabContentEvents => _tabContentSubject.stream;
|
||||||
Stream<ReaderableEvent> get readerableEvents => _readerableController.stream;
|
Stream<HistoryEvent> get historyEvents => _historySubject.stream;
|
||||||
|
Stream<ReaderableEvent> get readerableEvents => _readerableSubject.stream;
|
||||||
Stream<SecurityInfoEvent> get securityInfoEvents =>
|
Stream<SecurityInfoEvent> get securityInfoEvents =>
|
||||||
_securityInfoController.stream;
|
_securityInfoSubject.stream;
|
||||||
Stream<IconEvent> get iconEvents => _iconController.stream;
|
Stream<IconEvent> get iconEvents => _iconSubject.stream;
|
||||||
Stream<ThumbnailEvent> get thumbnailEvents => _thumbnailController.stream;
|
Stream<ThumbnailEvent> get thumbnailEvents => _thumbnailSubject.stream;
|
||||||
Stream<FindResultsEvent> get findResultsEvent =>
|
Stream<FindResultsEvent> get findResultsEvent => _findResultsSubject.stream;
|
||||||
_findResultsController.stream;
|
|
||||||
|
@override
|
||||||
|
void onFragmentReadyStateChange(bool state) {
|
||||||
|
_fragmentStateSubject.add(state);
|
||||||
|
}
|
||||||
|
|
||||||
// Overridden methods
|
// Overridden methods
|
||||||
@override
|
@override
|
||||||
void onTabListChange(List<String?> tabIds) {
|
void onTabListChange(List<String?> tabIds) {
|
||||||
_tabListController.add(tabIds.nonNulls.toList());
|
_tabListSubject.add(tabIds.nonNulls.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onSelectedTabChange(String? id) {
|
void onSelectedTabChange(String? id) {
|
||||||
_selectedTabController.add(id);
|
_selectedTabSubject.add(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onTabContentStateChange(TabContentState state) {
|
void onTabContentStateChange(TabContentState state) {
|
||||||
_tabContentController.add(state);
|
_tabContentSubject.add(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onHistoryStateChange(String id, HistoryState state) {
|
void onHistoryStateChange(String id, HistoryState state) {
|
||||||
_historyController.add((tabId: id, history: state));
|
_historySubject.add((tabId: id, history: state));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onReaderableStateChange(String id, ReaderableState state) {
|
void onReaderableStateChange(String id, ReaderableState state) {
|
||||||
_readerableController.add((tabId: id, readerable: state));
|
_readerableSubject.add((tabId: id, readerable: state));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onSecurityInfoStateChange(String id, SecurityInfoState state) {
|
void onSecurityInfoStateChange(String id, SecurityInfoState state) {
|
||||||
_securityInfoController.add((tabId: id, securityInfo: state));
|
_securityInfoSubject.add((tabId: id, securityInfo: state));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onIconChange(String id, Uint8List? bytes) {
|
void onIconChange(String id, Uint8List? bytes) {
|
||||||
_iconController.add((tabId: id, bytes: bytes));
|
_iconSubject.add((tabId: id, bytes: bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onThumbnailChange(String id, Uint8List? bytes) {
|
void onThumbnailChange(String id, Uint8List? bytes) {
|
||||||
_thumbnailController.add((tabId: id, bytes: bytes));
|
_thumbnailSubject.add((tabId: id, bytes: bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onFindResults(String id, List<FindResultState?> results) {
|
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({
|
GeckoEventService.setUp({
|
||||||
@@ -94,14 +100,14 @@ class GeckoEventService extends GeckoStateEvents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
unawaited(_tabListController.close());
|
unawaited(_tabListSubject.close());
|
||||||
unawaited(_selectedTabController.close());
|
unawaited(_selectedTabSubject.close());
|
||||||
unawaited(_tabContentController.close());
|
unawaited(_tabContentSubject.close());
|
||||||
unawaited(_historyController.close());
|
unawaited(_historySubject.close());
|
||||||
unawaited(_readerableController.close());
|
unawaited(_readerableSubject.close());
|
||||||
unawaited(_securityInfoController.close());
|
unawaited(_securityInfoSubject.close());
|
||||||
unawaited(_iconController.close());
|
unawaited(_iconSubject.close());
|
||||||
unawaited(_thumbnailController.close());
|
unawaited(_thumbnailSubject.close());
|
||||||
unawaited(_findResultsController.close());
|
unawaited(_findResultsSubject.close());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
||||||
|
import 'package:rxdart/rxdart.dart';
|
||||||
|
|
||||||
class GeckoReaderableService extends ReaderViewController {
|
class GeckoReaderableService extends ReaderViewController {
|
||||||
final ReaderViewEvents _events;
|
final ReaderViewEvents _events;
|
||||||
|
|
||||||
final _appearanceVisibility = StreamController<bool>.broadcast();
|
final _appearanceVisibility = BehaviorSubject<bool>();
|
||||||
final _readerVisibility = StreamController<bool>.broadcast();
|
final _readerVisibility = BehaviorSubject<bool>();
|
||||||
|
|
||||||
Stream<bool> get appearanceVisibility => _appearanceVisibility.stream;
|
Stream<bool> get appearanceVisibility => _appearanceVisibility.stream;
|
||||||
Stream<bool> get readerVisibility => _readerVisibility.stream;
|
|
||||||
|
|
||||||
Future<void> toggleReaderView(bool enable) {
|
Future<void> toggleReaderView(bool enable) {
|
||||||
return _events.onToggleReaderView(enable);
|
return _events.onToggleReaderView(enable);
|
||||||
@@ -25,11 +25,6 @@ class GeckoReaderableService extends ReaderViewController {
|
|||||||
_appearanceVisibility.add(visible);
|
_appearanceVisibility.add(visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void readerViewButtonVisibility(bool visible) {
|
|
||||||
_readerVisibility.add(visible);
|
|
||||||
}
|
|
||||||
|
|
||||||
GeckoReaderableService.setUp({
|
GeckoReaderableService.setUp({
|
||||||
ReaderViewEvents? readerEvents,
|
ReaderViewEvents? readerEvents,
|
||||||
BinaryMessenger? binaryMessenger,
|
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/data/models/load_url_flags.dart';
|
||||||
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
import 'package:flutter_mozilla_components/src/pigeons/gecko.g.dart';
|
||||||
|
|
||||||
@@ -118,6 +120,14 @@ class GeckoSessionService {
|
|||||||
return _api.purgeHistory();
|
return _api.purgeHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Uint8List?> requestScreenshot() {
|
||||||
|
if (tabId != null) {
|
||||||
|
throw Exception('Screenshot only allowed for selected (visible) tab.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return _api.requestScreenshot();
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> updateLastAccess({
|
Future<void> updateLastAccess({
|
||||||
String? tabId, //If null = current tab
|
String? tabId, //If null = current tab
|
||||||
DateTime? lastAccess, //If null datetime.now
|
DateTime? lastAccess, //If null datetime.now
|
||||||
|
|||||||
@@ -10,6 +10,29 @@ class GeckoTabService {
|
|||||||
|
|
||||||
GeckoTabService({GeckoTabsApi? api}) : _api = api ?? _apiInstance;
|
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}) {
|
Future<void> selectTab({required String tabId}) {
|
||||||
return _api.selectTab(tabId: tabId);
|
return _api.selectTab(tabId: tabId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/gestures.dart';
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.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';
|
import 'package:flutter_mozilla_components/src/domain/services/gecko_browser.dart';
|
||||||
|
|
||||||
class GeckoView extends StatelessWidget {
|
class GeckoView extends StatelessWidget {
|
||||||
const GeckoView({super.key});
|
final FutureOr<void> Function()? preInitializationStep;
|
||||||
|
|
||||||
|
const GeckoView({super.key, this.preInitializationStep});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -35,6 +39,7 @@ class GeckoView extends StatelessWidget {
|
|||||||
params.onPlatformViewCreated(value);
|
params.onPlatformViewCreated(value);
|
||||||
|
|
||||||
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
||||||
|
await preInitializationStep?.call();
|
||||||
await GeckoBrowserService().showNativeFragment();
|
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
|
// 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
|
// 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;
|
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 {
|
class GeckoTabsApi {
|
||||||
@@ -1604,6 +1626,28 @@ class GeckoTabsApi {
|
|||||||
|
|
||||||
final String pigeonVar_messageChannelSuffix;
|
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 {
|
Future<void> selectTab({required String tabId}) async {
|
||||||
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoTabsApi.selectTab$pigeonVar_messageChannelSuffix';
|
final String pigeonVar_channelName = 'dev.flutter.pigeon.flutter_mozilla_components.GeckoTabsApi.selectTab$pigeonVar_messageChannelSuffix';
|
||||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
@@ -2199,6 +2243,8 @@ class GeckoCookieApi {
|
|||||||
abstract class GeckoStateEvents {
|
abstract class GeckoStateEvents {
|
||||||
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
|
static const MessageCodec<Object?> pigeonChannelCodec = _PigeonCodec();
|
||||||
|
|
||||||
|
void onFragmentReadyStateChange(bool state);
|
||||||
|
|
||||||
void onTabListChange(List<String> tabIds);
|
void onTabListChange(List<String> tabIds);
|
||||||
|
|
||||||
void onSelectedTabChange(String? id);
|
void onSelectedTabChange(String? id);
|
||||||
@@ -2219,6 +2265,31 @@ abstract class GeckoStateEvents {
|
|||||||
|
|
||||||
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' : '';
|
||||||
|
{
|
||||||
|
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?>(
|
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
'dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onTabListChange$messageChannelSuffix', pigeonChannelCodec,
|
'dev.flutter.pigeon.flutter_mozilla_components.GeckoStateEvents.onTabListChange$messageChannelSuffix', pigeonChannelCodec,
|
||||||
@@ -2522,8 +2593,6 @@ abstract class ReaderViewController {
|
|||||||
|
|
||||||
void appearanceButtonVisibility(bool visible);
|
void appearanceButtonVisibility(bool visible);
|
||||||
|
|
||||||
void readerViewButtonVisibility(bool visible);
|
|
||||||
|
|
||||||
static void setUp(ReaderViewController? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) {
|
static void setUp(ReaderViewController? api, {BinaryMessenger? binaryMessenger, String messageChannelSuffix = '',}) {
|
||||||
messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$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()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -624,10 +624,25 @@ abstract class GeckoSessionApi {
|
|||||||
required String? tabId, //If null = current tab
|
required String? tabId, //If null = current tab
|
||||||
required int? lastAccess, //If null datetime.now
|
required int? lastAccess, //If null datetime.now
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@async
|
||||||
|
Uint8List? requestScreenshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostApi()
|
@HostApi()
|
||||||
abstract class GeckoTabsApi {
|
abstract class GeckoTabsApi {
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
|
||||||
void selectTab({required String tabId});
|
void selectTab({required String tabId});
|
||||||
|
|
||||||
void removeTab({required String tabId});
|
void removeTab({required String tabId});
|
||||||
@@ -767,6 +782,8 @@ abstract class GeckoCookieApi {
|
|||||||
|
|
||||||
@FlutterApi()
|
@FlutterApi()
|
||||||
abstract class GeckoStateEvents {
|
abstract class GeckoStateEvents {
|
||||||
|
void onFragmentReadyStateChange(bool state);
|
||||||
|
|
||||||
void onTabListChange(List<String> tabIds);
|
void onTabListChange(List<String> tabIds);
|
||||||
void onSelectedTabChange(String? id);
|
void onSelectedTabChange(String? id);
|
||||||
|
|
||||||
@@ -789,7 +806,6 @@ abstract class ReaderViewEvents {
|
|||||||
@FlutterApi()
|
@FlutterApi()
|
||||||
abstract class ReaderViewController {
|
abstract class ReaderViewController {
|
||||||
void appearanceButtonVisibility(bool visible);
|
void appearanceButtonVisibility(bool visible);
|
||||||
void readerViewButtonVisibility(bool visible);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@FlutterApi()
|
@FlutterApi()
|
||||||
|
|||||||
@@ -11,12 +11,13 @@ dependencies:
|
|||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
plugin_platform_interface: ^2.1.8
|
plugin_platform_interface: ^2.1.8
|
||||||
|
rxdart: ^0.28.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
lint: ^2.3.0
|
lint: ^2.3.0
|
||||||
pigeon: ^22.4.2
|
pigeon: ^22.5.0
|
||||||
|
|
||||||
# For information on the generic Dart part of this file, see the
|
# For information on the generic Dart part of this file, see the
|
||||||
# following page: https://dart.dev/tools/pub/pubspec
|
# following page: https://dart.dev/tools/pub/pubspec
|
||||||
|
|||||||
Reference in New Issue
Block a user