fix lints
This commit is contained in:
@@ -37,7 +37,6 @@ import 'package:weblibre/extensions/http_encoding.dart';
|
|||||||
import 'package:weblibre/features/geckoview/domain/entities/browser_icon.dart';
|
import 'package:weblibre/features/geckoview/domain/entities/browser_icon.dart';
|
||||||
import 'package:weblibre/features/user/domain/repositories/cache.dart';
|
import 'package:weblibre/features/user/domain/repositories/cache.dart';
|
||||||
import 'package:weblibre/features/web_feed/utils/feed_finder.dart';
|
import 'package:weblibre/features/web_feed/utils/feed_finder.dart';
|
||||||
import 'package:weblibre/presentation/controllers/website_title.dart';
|
|
||||||
import 'package:weblibre/utils/lru_cache.dart';
|
import 'package:weblibre/utils/lru_cache.dart';
|
||||||
|
|
||||||
part 'generic_website.g.dart';
|
part 'generic_website.g.dart';
|
||||||
@@ -87,6 +86,8 @@ class GenericWebsiteService extends _$GenericWebsiteService {
|
|||||||
late CacheRepository _cacheRepository;
|
late CacheRepository _cacheRepository;
|
||||||
//Local decoded icon cache
|
//Local decoded icon cache
|
||||||
late final LRUCache<String, BrowserIcon> _browserIconCache;
|
late final LRUCache<String, BrowserIcon> _browserIconCache;
|
||||||
|
//In-flight fetch deduplication
|
||||||
|
final _inFlightFetches = <Uri, Future<Result<WebPageInfo>>>{};
|
||||||
|
|
||||||
GenericWebsiteService()
|
GenericWebsiteService()
|
||||||
: _iconsService = GeckoIconService(),
|
: _iconsService = GeckoIconService(),
|
||||||
@@ -344,6 +345,13 @@ class GenericWebsiteService extends _$GenericWebsiteService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Result<WebPageInfo>> _deduplicatedFetchPageInfo(Uri url) {
|
||||||
|
return _inFlightFetches.putIfAbsent(url, () {
|
||||||
|
return fetchPageInfo(url: url, isImageRequest: true, proxyPort: null)
|
||||||
|
.whenComplete(() => _inFlightFetches.remove(url));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<BrowserIcon?> getUrlIcon(List<Uri> urlList) async {
|
Future<BrowserIcon?> getUrlIcon(List<Uri> urlList) async {
|
||||||
for (final url in urlList) {
|
for (final url in urlList) {
|
||||||
final cachedIcon = await getCachedIcon(url);
|
final cachedIcon = await getCachedIcon(url);
|
||||||
@@ -353,18 +361,17 @@ class GenericWebsiteService extends _$GenericWebsiteService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ref.mounted) {
|
if (ref.mounted) {
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
final result = await _deduplicatedFetchPageInfo(url);
|
||||||
final result = await ref.read(
|
|
||||||
pageInfoProvider(url, isImageRequest: true).future,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result.favicon case final BrowserIcon favicon) {
|
if (result.isSuccess) {
|
||||||
//If it was a `isImageRequest` hit, we need to cache it at this point
|
if (result.value.favicon case final BrowserIcon favicon) {
|
||||||
if (!_browserIconCache.contains(url.origin)) {
|
//If it was a `isImageRequest` hit, we need to cache it at this point
|
||||||
_browserIconCache.set(url.origin, favicon);
|
if (!_browserIconCache.contains(url.origin)) {
|
||||||
|
_browserIconCache.set(url.origin, favicon);
|
||||||
|
}
|
||||||
|
|
||||||
|
return favicon;
|
||||||
}
|
}
|
||||||
|
|
||||||
return favicon;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ final class GenericWebsiteServiceProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$genericWebsiteServiceHash() =>
|
String _$genericWebsiteServiceHash() =>
|
||||||
r'80b0f7113368bdd6fbe43fc27d2ab7332fe4b692';
|
r'437e1b11b6e63d38151354522deda755d9333c47';
|
||||||
|
|
||||||
abstract class _$GenericWebsiteService extends $Notifier<void> {
|
abstract class _$GenericWebsiteService extends $Notifier<void> {
|
||||||
void build();
|
void build();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import 'package:weblibre/features/about/domain/providers.dart';
|
|||||||
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||||
|
|
||||||
class AboutDialogScreen extends HookConsumerWidget {
|
class AboutDialogScreen extends HookConsumerWidget {
|
||||||
const AboutDialogScreen();
|
const AboutDialogScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ Future<bool> widgetPinnable(Ref ref) async {
|
|||||||
|
|
||||||
@Riverpod()
|
@Riverpod()
|
||||||
Raw<Stream<ReceivedIntentParameter>> appWidgetLaunchStream(Ref ref) {
|
Raw<Stream<ReceivedIntentParameter>> appWidgetLaunchStream(Ref ref) {
|
||||||
// ignore: discarded_futures is used as stream
|
|
||||||
final initialStream = HomeWidget.initiallyLaunchedFromHomeWidget().asStream();
|
final initialStream = HomeWidget.initiallyLaunchedFromHomeWidget().asStream();
|
||||||
|
|
||||||
return ConcatStream([
|
return ConcatStream([
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|||||||
import 'package:weblibre/core/routing/routes.dart';
|
import 'package:weblibre/core/routing/routes.dart';
|
||||||
|
|
||||||
class BangMenuScreen extends HookConsumerWidget {
|
class BangMenuScreen extends HookConsumerWidget {
|
||||||
const BangMenuScreen();
|
const BangMenuScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
|||||||
class UserBangs extends HookConsumerWidget {
|
class UserBangs extends HookConsumerWidget {
|
||||||
static const _userGroupFilter = [BangGroup.user];
|
static const _userGroupFilter = [BangGroup.user];
|
||||||
|
|
||||||
const UserBangs();
|
const UserBangs({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
|
import 'package:nullability/nullability.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
@@ -30,7 +31,7 @@ import 'package:weblibre/features/bangs/domain/providers/bangs.dart';
|
|||||||
import 'package:weblibre/features/geckoview/domain/providers/selected_tab.dart';
|
import 'package:weblibre/features/geckoview/domain/providers/selected_tab.dart';
|
||||||
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
|
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
|
||||||
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart';
|
import 'package:weblibre/features/geckoview/features/find_in_page/domain/repositories/find_in_page.dart';
|
||||||
import 'package:weblibre/features/user/domain/repositories/general_settings.dart';
|
import 'package:weblibre/features/user/domain/repositories/general_settings.dart';
|
||||||
|
|
||||||
part 'providers.g.dart';
|
part 'providers.g.dart';
|
||||||
@@ -46,11 +47,17 @@ GeckoSelectionActionService selectionActionService(Ref ref) {
|
|||||||
final router = await ref.read(routerProvider.future);
|
final router = await ref.read(routerProvider.future);
|
||||||
if (ref.mounted) {
|
if (ref.mounted) {
|
||||||
final settings = ref.read(generalSettingsWithDefaultsProvider);
|
final settings = ref.read(generalSettingsWithDefaultsProvider);
|
||||||
|
final selectedTabState = ref.read(
|
||||||
|
tabStatesProvider,
|
||||||
|
)[ref.read(selectedTabProvider)];
|
||||||
|
|
||||||
|
final isPrivate = selectedTabState?.isPrivate.mapNotNull(
|
||||||
|
(isCurrentPrivate) =>
|
||||||
|
isCurrentPrivate ? TabType.private : TabType.regular,
|
||||||
|
);
|
||||||
|
|
||||||
final route = SearchRoute(
|
final route = SearchRoute(
|
||||||
tabType:
|
tabType: isPrivate ?? settings.defaultCreateTabType,
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
|
||||||
ref.read(selectedTabTypeProvider) ??
|
|
||||||
settings.defaultCreateTabType,
|
|
||||||
searchText: text,
|
searchText: text,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -65,8 +72,10 @@ GeckoSelectionActionService selectionActionService(Ref ref) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (ref.mounted && defaultSearchBang != null) {
|
if (ref.mounted && defaultSearchBang != null) {
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
final currentTab = ref.read(
|
||||||
final currentTab = ref.read(selectedTabStateProvider);
|
tabStatesProvider,
|
||||||
|
)[ref.read(selectedTabProvider)];
|
||||||
|
|
||||||
final isPrivate =
|
final isPrivate =
|
||||||
currentTab?.isPrivate ??
|
currentTab?.isPrivate ??
|
||||||
ref
|
ref
|
||||||
@@ -91,10 +100,9 @@ GeckoSelectionActionService selectionActionService(Ref ref) {
|
|||||||
if (ref.mounted) {
|
if (ref.mounted) {
|
||||||
final tabId = ref.read(selectedTabProvider);
|
final tabId = ref.read(selectedTabProvider);
|
||||||
if (tabId != null) {
|
if (tabId != null) {
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
|
||||||
await ref
|
await ref
|
||||||
.read(findInPageControllerProvider(tabId).notifier)
|
.read(findInPageRepositoryProvider(tabId).notifier)
|
||||||
.findAll(text: text);
|
.findAll(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ final class SelectionActionServiceProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$selectionActionServiceHash() =>
|
String _$selectionActionServiceHash() =>
|
||||||
r'6250d2121375b2a41c2f0450512fc836c996f461';
|
r'75fa0fa770e74e49554d4098102fde9f9e531c4f';
|
||||||
|
|
||||||
@ProviderFor(eventService)
|
@ProviderFor(eventService)
|
||||||
final eventServiceProvider = EventServiceProvider._();
|
final eventServiceProvider = EventServiceProvider._();
|
||||||
|
|||||||
@@ -95,7 +95,6 @@ class TabRepository extends _$TabRepository {
|
|||||||
final assingedContainer =
|
final assingedContainer =
|
||||||
container ??
|
container ??
|
||||||
Value<ContainerData?>(
|
Value<ContainerData?>(
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
|
||||||
await ref.read(selectedContainerProvider.notifier).fetchData(),
|
await ref.read(selectedContainerProvider.notifier).fetchData(),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -295,8 +294,7 @@ class TabRepository extends _$TabRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _selectNextTab(String tabId) async {
|
Future<void> _selectNextTab(String tabId) async {
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
final tabState = ref.read(tabStatesProvider)[tabId];
|
||||||
final tabState = ref.read(tabStateProvider(tabId));
|
|
||||||
|
|
||||||
final currentContainerId = await ref
|
final currentContainerId = await ref
|
||||||
.read(tabDataRepositoryProvider.notifier)
|
.read(tabDataRepositoryProvider.notifier)
|
||||||
@@ -382,13 +380,12 @@ class TabRepository extends _$TabRepository {
|
|||||||
|
|
||||||
if (!ref.mounted) return;
|
if (!ref.mounted) return;
|
||||||
|
|
||||||
final nextContainerTabs = await nextAvailableContainer
|
final nextContainerTabs = await nextAvailableContainer.mapNotNull(
|
||||||
.mapNotNull(
|
(container) => ref
|
||||||
(container) => ref
|
.read(containerRepositoryProvider.notifier)
|
||||||
.read(containerRepositoryProvider.notifier)
|
.getContainerTabIds(container.id)
|
||||||
.getContainerTabIds(container.id)
|
.then((tabs) => tabs.where((tab) => tab != tabId).toList()),
|
||||||
.then((tabs) => tabs.where((tab) => tab != tabId).toList()),
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if (nextContainerTabs.isNotEmpty) {
|
if (nextContainerTabs.isNotEmpty) {
|
||||||
return _tabsService.selectTab(tabId: nextContainerTabs!.first);
|
return _tabsService.selectTab(tabId: nextContainerTabs!.first);
|
||||||
@@ -446,8 +443,7 @@ class TabRepository extends _$TabRepository {
|
|||||||
final containerSiteAssignementSub = eventSerivce.siteAssignementEvent.listen(
|
final containerSiteAssignementSub = eventSerivce.siteAssignementEvent.listen(
|
||||||
(event) async {
|
(event) async {
|
||||||
if (event.tabId != null) {
|
if (event.tabId != null) {
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
final tabState = ref.read(tabStatesProvider)[event.tabId];
|
||||||
final tabState = ref.read(tabStateProvider(event.tabId));
|
|
||||||
if (tabState != null) {
|
if (tabState != null) {
|
||||||
final uri = Uri.parse(event.url);
|
final uri = Uri.parse(event.url);
|
||||||
final originUri = event.originUrl.mapNotNull(Uri.parse);
|
final originUri = event.originUrl.mapNotNull(Uri.parse);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ final class TabRepositoryProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$tabRepositoryHash() => r'b300b88bc7817b533be46d8d0d933786b10212fb';
|
String _$tabRepositoryHash() => r'0a676c0513917e8853677ebd592954bde0f15f57';
|
||||||
|
|
||||||
abstract class _$TabRepository extends $Notifier<void> {
|
abstract class _$TabRepository extends $Notifier<void> {
|
||||||
void build();
|
void build();
|
||||||
|
|||||||
+1
@@ -35,6 +35,7 @@ class BookmarkEntryEditScreen extends HookConsumerWidget {
|
|||||||
final BookmarkEntry? exisitingEntry;
|
final BookmarkEntry? exisitingEntry;
|
||||||
|
|
||||||
const BookmarkEntryEditScreen({
|
const BookmarkEntryEditScreen({
|
||||||
|
super.key,
|
||||||
required this.exisitingEntry,
|
required this.exisitingEntry,
|
||||||
required this.initialInfo,
|
required this.initialInfo,
|
||||||
});
|
});
|
||||||
|
|||||||
+5
-1
@@ -32,7 +32,11 @@ class BookmarkFolderEditScreen extends HookConsumerWidget {
|
|||||||
final String? parentGuid;
|
final String? parentGuid;
|
||||||
final BookmarkFolder? folder;
|
final BookmarkFolder? folder;
|
||||||
|
|
||||||
const BookmarkFolderEditScreen({required this.folder, this.parentGuid});
|
const BookmarkFolderEditScreen({
|
||||||
|
super.key,
|
||||||
|
required this.folder,
|
||||||
|
this.parentGuid,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ EquatableValue<List<TabStateWirthContainer>> fifoTabStates(Ref ref) {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Riverpod(keepAlive: true)
|
@Riverpod()
|
||||||
EquatableValue<List<TabStateWirthContainer>>
|
EquatableValue<List<TabStateWirthContainer>>
|
||||||
selectedContainerTabStatesWithContainer(Ref ref) {
|
selectedContainerTabStatesWithContainer(Ref ref) {
|
||||||
final filter = ref.watch(
|
final filter = ref.watch(
|
||||||
|
|||||||
@@ -452,7 +452,7 @@ final class SelectedContainerTabStatesWithContainerProvider
|
|||||||
argument: null,
|
argument: null,
|
||||||
retry: null,
|
retry: null,
|
||||||
name: r'selectedContainerTabStatesWithContainerProvider',
|
name: r'selectedContainerTabStatesWithContainerProvider',
|
||||||
isAutoDispose: false,
|
isAutoDispose: true,
|
||||||
dependencies: null,
|
dependencies: null,
|
||||||
$allTransitiveDependencies: null,
|
$allTransitiveDependencies: null,
|
||||||
);
|
);
|
||||||
@@ -487,7 +487,7 @@ final class SelectedContainerTabStatesWithContainerProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$selectedContainerTabStatesWithContainerHash() =>
|
String _$selectedContainerTabStatesWithContainerHash() =>
|
||||||
r'd22d16eba89040fbcf7932e5334155f00312957f';
|
r'2fd5e12595b3aced1e235c9626073c34655d57fa';
|
||||||
|
|
||||||
@ProviderFor(suggestedTabEntities)
|
@ProviderFor(suggestedTabEntities)
|
||||||
final suggestedTabEntitiesProvider = SuggestedTabEntitiesFamily._();
|
final suggestedTabEntitiesProvider = SuggestedTabEntitiesFamily._();
|
||||||
|
|||||||
-6
@@ -221,7 +221,6 @@ class EngineSettingsReplicationService
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (previous.value?.enablePdfJs != settings.enablePdfJs) {
|
if (previous.value?.enablePdfJs != settings.enablePdfJs) {
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
|
||||||
await ref
|
await ref
|
||||||
.read(preferenceFixatorProvider.notifier)
|
.read(preferenceFixatorProvider.notifier)
|
||||||
.register('pdfjs.disabled', !settings.enablePdfJs);
|
.register('pdfjs.disabled', !settings.enablePdfJs);
|
||||||
@@ -230,7 +229,6 @@ class EngineSettingsReplicationService
|
|||||||
previous.value?.locales,
|
previous.value?.locales,
|
||||||
settings.locales,
|
settings.locales,
|
||||||
)) {
|
)) {
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
|
||||||
await ref
|
await ref
|
||||||
.read(preferenceFixatorProvider.notifier)
|
.read(preferenceFixatorProvider.notifier)
|
||||||
.register(
|
.register(
|
||||||
@@ -240,13 +238,9 @@ class EngineSettingsReplicationService
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await _service.setDefaultSettings(settings);
|
await _service.setDefaultSettings(settings);
|
||||||
|
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
|
||||||
await ref
|
await ref
|
||||||
.read(preferenceFixatorProvider.notifier)
|
.read(preferenceFixatorProvider.notifier)
|
||||||
.register('pdfjs.disabled', !settings.enablePdfJs);
|
.register('pdfjs.disabled', !settings.enablePdfJs);
|
||||||
|
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
|
||||||
await ref
|
await ref
|
||||||
.read(preferenceFixatorProvider.notifier)
|
.read(preferenceFixatorProvider.notifier)
|
||||||
.register('intl.accept_languages', settings.locales.join(','));
|
.register('intl.accept_languages', settings.locales.join(','));
|
||||||
|
|||||||
-1
@@ -135,7 +135,6 @@ class ProxySettingsReplication extends _$ProxySettingsReplication {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
|
||||||
ref.listen(watchAllAssignedSitesProvider, (previous, next) async {
|
ref.listen(watchAllAssignedSitesProvider, (previous, next) async {
|
||||||
if (next.hasValue) {
|
if (next.hasValue) {
|
||||||
await ref
|
await ref
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ import 'package:weblibre/utils/form_validators.dart';
|
|||||||
class OpenSharedContent extends HookConsumerWidget {
|
class OpenSharedContent extends HookConsumerWidget {
|
||||||
final Uri sharedUrl;
|
final Uri sharedUrl;
|
||||||
|
|
||||||
const OpenSharedContent({required this.sharedUrl});
|
const OpenSharedContent({super.key, required this.sharedUrl});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import 'package:weblibre/features/user/domain/repositories/general_settings.dart
|
|||||||
import 'package:weblibre/presentation/hooks/scroll_visibility.dart';
|
import 'package:weblibre/presentation/hooks/scroll_visibility.dart';
|
||||||
|
|
||||||
class TabViewScreen extends HookConsumerWidget {
|
class TabViewScreen extends HookConsumerWidget {
|
||||||
const TabViewScreen();
|
const TabViewScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
+5
-5
@@ -68,7 +68,7 @@ class BrowserTopAppBar extends HookConsumerWidget {
|
|||||||
late final BrowserTabBar _tabBar;
|
late final BrowserTabBar _tabBar;
|
||||||
late final _size = Size.fromHeight(_tabBar.getToolbarHeight());
|
late final _size = Size.fromHeight(_tabBar.getToolbarHeight());
|
||||||
|
|
||||||
BrowserTopAppBar({
|
BrowserTopAppBar({super.key,
|
||||||
required this.showMainToolbar,
|
required this.showMainToolbar,
|
||||||
required this.showContextualToolbar,
|
required this.showContextualToolbar,
|
||||||
required this.showQuickTabSwitcherBar,
|
required this.showQuickTabSwitcherBar,
|
||||||
@@ -103,7 +103,7 @@ class BrowserBottomAppBar extends HookConsumerWidget {
|
|||||||
late final BrowserTabBar _tabBar;
|
late final BrowserTabBar _tabBar;
|
||||||
late final _size = Size.fromHeight(_tabBar.getToolbarHeight());
|
late final _size = Size.fromHeight(_tabBar.getToolbarHeight());
|
||||||
|
|
||||||
BrowserBottomAppBar({
|
BrowserBottomAppBar({super.key,
|
||||||
required this.showMainToolbar,
|
required this.showMainToolbar,
|
||||||
required this.displayedSheet,
|
required this.displayedSheet,
|
||||||
required this.showContextualToolbar,
|
required this.showContextualToolbar,
|
||||||
@@ -148,7 +148,7 @@ class BrowserTabBar extends HookConsumerWidget {
|
|||||||
final bool showMainToolbarNavigationButton;
|
final bool showMainToolbarNavigationButton;
|
||||||
final bool showMainToolbarTabActionButton;
|
final bool showMainToolbarTabActionButton;
|
||||||
|
|
||||||
const BrowserTabBar({
|
const BrowserTabBar({super.key,
|
||||||
required this.showMainToolbar,
|
required this.showMainToolbar,
|
||||||
required this.displayedSheet,
|
required this.displayedSheet,
|
||||||
required this.showContextualToolbar,
|
required this.showContextualToolbar,
|
||||||
@@ -476,7 +476,7 @@ class ContextualToolbar extends HookConsumerWidget {
|
|||||||
class QuickTabSwitcher extends HookConsumerWidget {
|
class QuickTabSwitcher extends HookConsumerWidget {
|
||||||
final QuickTabSwitcherMode quickTabSwitcherMode;
|
final QuickTabSwitcherMode quickTabSwitcherMode;
|
||||||
|
|
||||||
const QuickTabSwitcher({required this.quickTabSwitcherMode});
|
const QuickTabSwitcher({super.key, required this.quickTabSwitcherMode});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
@@ -685,7 +685,7 @@ class NavigationMenuButton extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AddTabButton extends HookConsumerWidget {
|
class AddTabButton extends HookConsumerWidget {
|
||||||
const AddTabButton();
|
const AddTabButton({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
+1
-1
@@ -68,7 +68,7 @@ class BrowserView extends StatefulHookConsumerWidget {
|
|||||||
final Future<void> Function()? postInitializationStep;
|
final Future<void> Function()? postInitializationStep;
|
||||||
final StreamSink<Offset>? pointerMoveEventSink;
|
final StreamSink<Offset>? pointerMoveEventSink;
|
||||||
|
|
||||||
const BrowserView({
|
const BrowserView({super.key,
|
||||||
this.screenshotPeriod = const Duration(seconds: 10),
|
this.screenshotPeriod = const Duration(seconds: 10),
|
||||||
this.suggestionTimeout = const Duration(seconds: 30),
|
this.suggestionTimeout = const Duration(seconds: 30),
|
||||||
this.postInitializationStep,
|
this.postInitializationStep,
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ import 'package:skeletonizer/skeletonizer.dart';
|
|||||||
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
|
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
|
||||||
|
|
||||||
class CertificateTile extends HookConsumerWidget {
|
class CertificateTile extends HookConsumerWidget {
|
||||||
const CertificateTile();
|
const CertificateTile({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ import 'package:flutter/material.dart';
|
|||||||
class ErrorContainer extends StatelessWidget {
|
class ErrorContainer extends StatelessWidget {
|
||||||
final Widget content;
|
final Widget content;
|
||||||
|
|
||||||
const ErrorContainer({required this.content});
|
const ErrorContainer({super.key, required this.content});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ import 'package:weblibre/presentation/widgets/safe_raw_image.dart';
|
|||||||
class ExtensionBadgeIcon extends StatelessWidget {
|
class ExtensionBadgeIcon extends StatelessWidget {
|
||||||
final WebExtensionState state;
|
final WebExtensionState state;
|
||||||
|
|
||||||
const ExtensionBadgeIcon(this.state);
|
const ExtensionBadgeIcon(this.state, {super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ class ViewTabSheetWidget extends HookConsumerWidget {
|
|||||||
final double bottomAppBarHeight;
|
final double bottomAppBarHeight;
|
||||||
final ValueChanged<bool>? onClearSiteDataExpandedChanged;
|
final ValueChanged<bool>? onClearSiteDataExpandedChanged;
|
||||||
|
|
||||||
const ViewTabSheetWidget({
|
const ViewTabSheetWidget({super.key,
|
||||||
required this.initialTabState,
|
required this.initialTabState,
|
||||||
required this.sheetScrollController,
|
required this.sheetScrollController,
|
||||||
required this.draggableScrollableController,
|
required this.draggableScrollableController,
|
||||||
|
|||||||
+23
-3
@@ -44,6 +44,7 @@ import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/ta
|
|||||||
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab_search.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab_search.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/tabs/presentation/widgets/container_chips.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/presentation/widgets/container_chips.dart';
|
||||||
import 'package:weblibre/features/tor/presentation/controllers/start_tor_proxy.dart';
|
import 'package:weblibre/features/tor/presentation/controllers/start_tor_proxy.dart';
|
||||||
|
import 'package:weblibre/features/tor/presentation/widgets/tor_dialog.dart';
|
||||||
import 'package:weblibre/features/user/domain/repositories/general_settings.dart';
|
import 'package:weblibre/features/user/domain/repositories/general_settings.dart';
|
||||||
import 'package:weblibre/presentation/hooks/menu_controller.dart';
|
import 'package:weblibre/presentation/hooks/menu_controller.dart';
|
||||||
import 'package:weblibre/presentation/widgets/speech_to_text_button.dart';
|
import 'package:weblibre/presentation/widgets/speech_to_text_button.dart';
|
||||||
@@ -55,7 +56,11 @@ class TabViewHeader extends HookConsumerWidget {
|
|||||||
final TabsViewMode tabsViewMode;
|
final TabsViewMode tabsViewMode;
|
||||||
final VoidCallback onClose;
|
final VoidCallback onClose;
|
||||||
|
|
||||||
const TabViewHeader({required this.onClose, required this.tabsViewMode});
|
const TabViewHeader({
|
||||||
|
super.key,
|
||||||
|
required this.onClose,
|
||||||
|
required this.tabsViewMode,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
@@ -601,9 +606,24 @@ class TabViewHeader extends HookConsumerWidget {
|
|||||||
|
|
||||||
if (context.mounted &&
|
if (context.mounted &&
|
||||||
result == SetContainerResult.successHasProxy) {
|
result == SetContainerResult.successHasProxy) {
|
||||||
await ref
|
final shouldStartProxy = await ref
|
||||||
.read(startProxyControllerProvider.notifier)
|
.read(startProxyControllerProvider.notifier)
|
||||||
.maybeStartProxy(context);
|
.shouldPromptProxyStart();
|
||||||
|
|
||||||
|
if (!context.mounted || !shouldStartProxy) return;
|
||||||
|
|
||||||
|
final dialogResult = await showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return const TorDialog();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (dialogResult == true) {
|
||||||
|
await ref
|
||||||
|
.read(startProxyControllerProvider.notifier)
|
||||||
|
.startProxy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ref
|
ref
|
||||||
|
|||||||
+2
-2
@@ -25,7 +25,7 @@ import 'package:weblibre/features/geckoview/domain/providers.dart';
|
|||||||
|
|
||||||
part 'preference_observer.g.dart';
|
part 'preference_observer.g.dart';
|
||||||
|
|
||||||
@Riverpod()
|
@Riverpod(keepAlive: true)
|
||||||
class PreferenceChangeListener extends _$PreferenceChangeListener {
|
class PreferenceChangeListener extends _$PreferenceChangeListener {
|
||||||
@override
|
@override
|
||||||
Stream<GeckoPref> build() async* {
|
Stream<GeckoPref> build() async* {
|
||||||
@@ -41,7 +41,7 @@ class PreferenceChangeListener extends _$PreferenceChangeListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Riverpod()
|
@Riverpod(keepAlive: true)
|
||||||
class PreferenceFixator extends _$PreferenceFixator {
|
class PreferenceFixator extends _$PreferenceFixator {
|
||||||
Future<void> register(String name, Object value) async {
|
Future<void> register(String name, Object value) async {
|
||||||
state = {...state}
|
state = {...state}
|
||||||
|
|||||||
+4
-4
@@ -20,7 +20,7 @@ final class PreferenceChangeListenerProvider
|
|||||||
argument: null,
|
argument: null,
|
||||||
retry: null,
|
retry: null,
|
||||||
name: r'preferenceChangeListenerProvider',
|
name: r'preferenceChangeListenerProvider',
|
||||||
isAutoDispose: true,
|
isAutoDispose: false,
|
||||||
dependencies: null,
|
dependencies: null,
|
||||||
$allTransitiveDependencies: null,
|
$allTransitiveDependencies: null,
|
||||||
);
|
);
|
||||||
@@ -34,7 +34,7 @@ final class PreferenceChangeListenerProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$preferenceChangeListenerHash() =>
|
String _$preferenceChangeListenerHash() =>
|
||||||
r'668c1bcd0636ec515a5e92ee5ba4ea7a67fa7a6d';
|
r'de9759b32a6a6b9bab5656137a365da78633f866';
|
||||||
|
|
||||||
abstract class _$PreferenceChangeListener extends $StreamNotifier<GeckoPref> {
|
abstract class _$PreferenceChangeListener extends $StreamNotifier<GeckoPref> {
|
||||||
Stream<GeckoPref> build();
|
Stream<GeckoPref> build();
|
||||||
@@ -65,7 +65,7 @@ final class PreferenceFixatorProvider
|
|||||||
argument: null,
|
argument: null,
|
||||||
retry: null,
|
retry: null,
|
||||||
name: r'preferenceFixatorProvider',
|
name: r'preferenceFixatorProvider',
|
||||||
isAutoDispose: true,
|
isAutoDispose: false,
|
||||||
dependencies: null,
|
dependencies: null,
|
||||||
$allTransitiveDependencies: null,
|
$allTransitiveDependencies: null,
|
||||||
);
|
);
|
||||||
@@ -86,7 +86,7 @@ final class PreferenceFixatorProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$preferenceFixatorHash() => r'c76245d5c420e2e3f6c026f23c017c939b69ef59';
|
String _$preferenceFixatorHash() => r'c8d71966faf6b2feb9ac4e770297cd298edf5211';
|
||||||
|
|
||||||
abstract class _$PreferenceFixator extends $Notifier<Map<String, Object>> {
|
abstract class _$PreferenceFixator extends $Notifier<Map<String, Object>> {
|
||||||
Map<String, Object> build();
|
Map<String, Object> build();
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class SearchScreen extends HookConsumerWidget {
|
|||||||
/// When null, a new tab will be created.
|
/// When null, a new tab will be created.
|
||||||
final String? tabId;
|
final String? tabId;
|
||||||
|
|
||||||
const SearchScreen({
|
const SearchScreen({super.key,
|
||||||
required this.initialSearchText,
|
required this.initialSearchText,
|
||||||
required this.tabType,
|
required this.tabType,
|
||||||
this.launchedFromIntent = false,
|
this.launchedFromIntent = false,
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ class FeedSearch extends HookConsumerWidget {
|
|||||||
|
|
||||||
final ValueListenable<TextEditingValue> searchTextNotifier;
|
final ValueListenable<TextEditingValue> searchTextNotifier;
|
||||||
|
|
||||||
const FeedSearch({required this.searchTextNotifier});
|
const FeedSearch({super.key, required this.searchTextNotifier});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
+2
-2
@@ -50,7 +50,7 @@ class TabSearch extends HookConsumerWidget {
|
|||||||
|
|
||||||
final ValueListenable<TextEditingValue> searchTextListenable;
|
final ValueListenable<TextEditingValue> searchTextListenable;
|
||||||
|
|
||||||
const TabSearch({required this.searchTextListenable});
|
const TabSearch({super.key, required this.searchTextListenable});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
@@ -76,7 +76,7 @@ class TabSearch extends HookConsumerWidget {
|
|||||||
.fold(
|
.fold(
|
||||||
<String?, int>{},
|
<String?, int>{},
|
||||||
(map, id) =>
|
(map, id) =>
|
||||||
map..update(id, (value) => ++value, ifAbsent: () => 1),
|
map..update(id, (value) => value + 1, ifAbsent: () => 1),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
[tabSearchResults],
|
[tabSearchResults],
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ Stream<Map<String, String?>> watchTabsContainerId(
|
|||||||
.map(Map.fromEntries);
|
.map(Map.fromEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Riverpod()
|
@Riverpod(keepAlive: true)
|
||||||
Stream<List<SiteAssignment>> watchAllAssignedSites(Ref ref) {
|
Stream<List<SiteAssignment>> watchAllAssignedSites(Ref ref) {
|
||||||
final db = ref.watch(tabDatabaseProvider);
|
final db = ref.watch(tabDatabaseProvider);
|
||||||
return db.containerDao.allAssignedSites().watch();
|
return db.containerDao.allAssignedSites().watch();
|
||||||
|
|||||||
@@ -848,7 +848,7 @@ final class WatchAllAssignedSitesProvider
|
|||||||
argument: null,
|
argument: null,
|
||||||
retry: null,
|
retry: null,
|
||||||
name: r'watchAllAssignedSitesProvider',
|
name: r'watchAllAssignedSitesProvider',
|
||||||
isAutoDispose: true,
|
isAutoDispose: false,
|
||||||
dependencies: null,
|
dependencies: null,
|
||||||
$allTransitiveDependencies: null,
|
$allTransitiveDependencies: null,
|
||||||
);
|
);
|
||||||
@@ -869,7 +869,7 @@ final class WatchAllAssignedSitesProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$watchAllAssignedSitesHash() =>
|
String _$watchAllAssignedSitesHash() =>
|
||||||
r'0e06caeb4a53b5cf976b3f47d328ea238243438b';
|
r'5f658b5733ee20192eb86d3aeb79aa9678dafba8';
|
||||||
|
|
||||||
@ProviderFor(watchIsCurrentSiteAssignedToContainer)
|
@ProviderFor(watchIsCurrentSiteAssignedToContainer)
|
||||||
final watchIsCurrentSiteAssignedToContainerProvider =
|
final watchIsCurrentSiteAssignedToContainerProvider =
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class TabDataRepository extends _$TabDataRepository {
|
|||||||
.tabDao
|
.tabDao
|
||||||
.assignContainer(tabId, containerId: targetContainer.id);
|
.assignContainer(tabId, containerId: targetContainer.id);
|
||||||
} else {
|
} else {
|
||||||
final tabState = ref.read(tabStateProvider(tabId));
|
final tabState = ref.read(tabStatesProvider)[tabId];
|
||||||
if (tabState != null) {
|
if (tabState != null) {
|
||||||
if (closeOldTab) {
|
if (closeOldTab) {
|
||||||
await ref.read(tabRepositoryProvider.notifier).closeTab(tabId);
|
await ref.read(tabRepositoryProvider.notifier).closeTab(tabId);
|
||||||
@@ -76,7 +76,7 @@ class TabDataRepository extends _$TabDataRepository {
|
|||||||
.tabDao
|
.tabDao
|
||||||
.assignContainer(tabId, containerId: null);
|
.assignContainer(tabId, containerId: null);
|
||||||
} else {
|
} else {
|
||||||
final tabState = ref.read(tabStateProvider(tabId));
|
final tabState = ref.read(tabStatesProvider)[tabId];
|
||||||
if (tabState != null) {
|
if (tabState != null) {
|
||||||
await ref.read(tabRepositoryProvider.notifier).closeTab(tabId);
|
await ref.read(tabRepositoryProvider.notifier).closeTab(tabId);
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ final class TabDataRepositoryProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$tabDataRepositoryHash() => r'c3632e0a2d91811103b329659cb0c6d778b14cea';
|
String _$tabDataRepositoryHash() => r'c872509a70e4c0c029b468457e15c5e5bff10c65';
|
||||||
|
|
||||||
abstract class _$TabDataRepository extends $Notifier<void> {
|
abstract class _$TabDataRepository extends $Notifier<void> {
|
||||||
void build();
|
void build();
|
||||||
|
|||||||
+1
-1
@@ -37,7 +37,7 @@ class ContainerTopicController extends _$ContainerTopicController {
|
|||||||
return _predictFromTitles(titles);
|
return _predictFromTitles(titles);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> predictTopicFromTabIds(Set<String> tabIds) async {
|
Future<String?> predictTopicFromTabIds(Set<String> tabIds) {
|
||||||
final tabStates = ref.read(tabStatesProvider);
|
final tabStates = ref.read(tabStatesProvider);
|
||||||
final titles = tabIds
|
final titles = tabIds
|
||||||
.map((tabId) => tabStates[tabId]?.title)
|
.map((tabId) => tabStates[tabId]?.title)
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ final class ContainerTopicControllerProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$containerTopicControllerHash() =>
|
String _$containerTopicControllerHash() =>
|
||||||
r'0b54e0be899e2abb4defbd5614ba231917ad74e5';
|
r'41ee4b2a259eba17af49b3c877a9b10ea51281c8';
|
||||||
|
|
||||||
abstract class _$ContainerTopicController extends $Notifier<AsyncValue<void>> {
|
abstract class _$ContainerTopicController extends $Notifier<AsyncValue<void>> {
|
||||||
AsyncValue<void> build();
|
AsyncValue<void> build();
|
||||||
|
|||||||
@@ -31,10 +31,11 @@ import 'package:weblibre/features/geckoview/features/tabs/domain/providers/selec
|
|||||||
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/container.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/container.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/tabs/presentation/widgets/container_list_tile.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/presentation/widgets/container_list_tile.dart';
|
||||||
import 'package:weblibre/features/tor/presentation/controllers/start_tor_proxy.dart';
|
import 'package:weblibre/features/tor/presentation/controllers/start_tor_proxy.dart';
|
||||||
|
import 'package:weblibre/features/tor/presentation/widgets/tor_dialog.dart';
|
||||||
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
||||||
|
|
||||||
class ContainerListScreen extends HookConsumerWidget {
|
class ContainerListScreen extends HookConsumerWidget {
|
||||||
const ContainerListScreen();
|
const ContainerListScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
@@ -70,9 +71,28 @@ class ContainerListScreen extends HookConsumerWidget {
|
|||||||
if (context.mounted &&
|
if (context.mounted &&
|
||||||
result ==
|
result ==
|
||||||
SetContainerResult.successHasProxy) {
|
SetContainerResult.successHasProxy) {
|
||||||
await ref
|
final shouldStartProxy = await ref
|
||||||
.read(startProxyControllerProvider.notifier)
|
.read(startProxyControllerProvider.notifier)
|
||||||
.maybeStartProxy(context);
|
.shouldPromptProxyStart();
|
||||||
|
|
||||||
|
if (!context.mounted || !shouldStartProxy) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final dialogResult = await showDialog<bool>(
|
||||||
|
context: context,
|
||||||
|
builder: (context) {
|
||||||
|
return const TorDialog();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (dialogResult == true) {
|
||||||
|
await ref
|
||||||
|
.read(
|
||||||
|
startProxyControllerProvider.notifier,
|
||||||
|
)
|
||||||
|
.startProxy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
foregroundColor: Theme.of(
|
foregroundColor: Theme.of(
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ import 'package:weblibre/features/geckoview/features/tabs/presentation/widgets/c
|
|||||||
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
||||||
|
|
||||||
class ContainerSelectionScreen extends HookConsumerWidget {
|
class ContainerSelectionScreen extends HookConsumerWidget {
|
||||||
const ContainerSelectionScreen();
|
const ContainerSelectionScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@ import 'package:weblibre/features/geckoview/features/tabs/utils/container_colors
|
|||||||
class ColorPickerDialog extends HookWidget {
|
class ColorPickerDialog extends HookWidget {
|
||||||
final Color initialColor;
|
final Color initialColor;
|
||||||
|
|
||||||
const ColorPickerDialog(this.initialColor);
|
const ColorPickerDialog(this.initialColor, {super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ class ContainerChips extends HookConsumerWidget {
|
|||||||
|
|
||||||
final ValueListenable<TextEditingValue>? searchTextListenable;
|
final ValueListenable<TextEditingValue>? searchTextListenable;
|
||||||
|
|
||||||
const ContainerChips({
|
const ContainerChips({super.key,
|
||||||
required this.selectedContainer,
|
required this.selectedContainer,
|
||||||
required this.onSelected,
|
required this.onSelected,
|
||||||
required this.onDeleted,
|
required this.onDeleted,
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart';
|
|||||||
import 'package:weblibre/utils/ui_helper.dart' as ui_helper;
|
import 'package:weblibre/utils/ui_helper.dart' as ui_helper;
|
||||||
|
|
||||||
class QrScannerDialog extends HookWidget {
|
class QrScannerDialog extends HookWidget {
|
||||||
|
const QrScannerDialog({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final qrKey = useMemoized(() => GlobalKey(debugLabel: 'qr_scanner'));
|
final qrKey = useMemoized(() => GlobalKey(debugLabel: 'qr_scanner'));
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import 'package:weblibre/features/user/domain/repositories/engine_settings.dart'
|
|||||||
import 'package:weblibre/utils/form_validators.dart';
|
import 'package:weblibre/utils/form_validators.dart';
|
||||||
|
|
||||||
class DohSettingsScreen extends HookConsumerWidget {
|
class DohSettingsScreen extends HookConsumerWidget {
|
||||||
const DohSettingsScreen();
|
const DohSettingsScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import 'package:weblibre/features/user/domain/services/fingerprinting.dart';
|
|||||||
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
||||||
|
|
||||||
class FingerprintSettingsScreen extends HookConsumerWidget {
|
class FingerprintSettingsScreen extends HookConsumerWidget {
|
||||||
const FingerprintSettingsScreen();
|
const FingerprintSettingsScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import 'package:weblibre/features/user/data/models/engine_settings.dart';
|
|||||||
import 'package:weblibre/features/user/domain/repositories/engine_settings.dart';
|
import 'package:weblibre/features/user/domain/repositories/engine_settings.dart';
|
||||||
|
|
||||||
class LocaleSettingsScreen extends HookConsumerWidget {
|
class LocaleSettingsScreen extends HookConsumerWidget {
|
||||||
const LocaleSettingsScreen();
|
const LocaleSettingsScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import 'package:weblibre/features/settings/presentation/widgets/hardening_group_
|
|||||||
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
||||||
|
|
||||||
class WebEngineHardeningScreen extends HookConsumerWidget {
|
class WebEngineHardeningScreen extends HookConsumerWidget {
|
||||||
const WebEngineHardeningScreen();
|
const WebEngineHardeningScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import 'package:weblibre/presentation/widgets/selectable_chips.dart';
|
|||||||
import 'package:weblibre/presentation/widgets/url_icon.dart';
|
import 'package:weblibre/presentation/widgets/url_icon.dart';
|
||||||
|
|
||||||
class DefaultSearchSelector extends HookConsumerWidget {
|
class DefaultSearchSelector extends HookConsumerWidget {
|
||||||
const DefaultSearchSelector();
|
const DefaultSearchSelector({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import 'package:flutter/material.dart';
|
|||||||
class SettingSection extends StatelessWidget {
|
class SettingSection extends StatelessWidget {
|
||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
const SettingSection({required this.name});
|
const SettingSection({super.key, required this.name});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -43,7 +43,7 @@ class SettingSection extends StatelessWidget {
|
|||||||
class SettingSubSection extends StatelessWidget {
|
class SettingSubSection extends StatelessWidget {
|
||||||
final String name;
|
final String name;
|
||||||
|
|
||||||
const SettingSubSection({required this.name});
|
const SettingSubSection({super.key, required this.name});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class SyncDetailsTable extends StatelessWidget {
|
|||||||
final int? count;
|
final int? count;
|
||||||
final DateTime? lastSync;
|
final DateTime? lastSync;
|
||||||
|
|
||||||
const SyncDetailsTable(this.count, this.lastSync);
|
const SyncDetailsTable(this.count, this.lastSync, {super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
@@ -65,7 +65,6 @@ class TorProxyService extends _$TorProxyService {
|
|||||||
|
|
||||||
if (config == null && torSettings.requireBridge) {
|
if (config == null && torSettings.requireBridge) {
|
||||||
config = MoatService.convertBuiltinToSettings(
|
config = MoatService.convertBuiltinToSettings(
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
|
||||||
await ref
|
await ref
|
||||||
.read(builtinBridgesRepositoryProvider(moat).notifier)
|
.read(builtinBridgesRepositoryProvider(moat).notifier)
|
||||||
.getBridges(),
|
.getBridges(),
|
||||||
@@ -99,7 +98,6 @@ class TorProxyService extends _$TorProxyService {
|
|||||||
if (config == null &&
|
if (config == null &&
|
||||||
(torSettings.requireBridge || !torSettings.fetchRemoteBridges)) {
|
(torSettings.requireBridge || !torSettings.fetchRemoteBridges)) {
|
||||||
config = MoatService.convertBuiltinToSettings(
|
config = MoatService.convertBuiltinToSettings(
|
||||||
// ignore: only_use_keep_alive_inside_keep_alive
|
|
||||||
await ref
|
await ref
|
||||||
.read(builtinBridgesRepositoryProvider(moat).notifier)
|
.read(builtinBridgesRepositoryProvider(moat).notifier)
|
||||||
.getBridges(tryUpdate: torSettings.fetchRemoteBridges),
|
.getBridges(tryUpdate: torSettings.fetchRemoteBridges),
|
||||||
|
|||||||
@@ -17,51 +17,49 @@
|
|||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:weblibre/features/geckoview/domain/controllers/overlay.dart';
|
import 'package:weblibre/features/geckoview/domain/controllers/overlay.dart';
|
||||||
import 'package:weblibre/features/tor/domain/services/tor_proxy.dart';
|
import 'package:weblibre/features/tor/domain/services/tor_proxy.dart';
|
||||||
import 'package:weblibre/features/tor/presentation/widgets/tor_dialog.dart';
|
|
||||||
import 'package:weblibre/features/tor/presentation/widgets/tor_notification.dart';
|
import 'package:weblibre/features/tor/presentation/widgets/tor_notification.dart';
|
||||||
|
|
||||||
part 'start_tor_proxy.g.dart';
|
part 'start_tor_proxy.g.dart';
|
||||||
|
|
||||||
@Riverpod(keepAlive: true)
|
@Riverpod(keepAlive: true)
|
||||||
class StartProxyController extends _$StartProxyController {
|
class StartProxyController extends _$StartProxyController {
|
||||||
// ignore: document_ignores is used for dialog
|
Future<bool> shouldPromptProxyStart() async {
|
||||||
// ignore: avoid_build_context_in_providers
|
|
||||||
Future<void> maybeStartProxy(BuildContext context) async {
|
|
||||||
final currentStatus = await ref
|
final currentStatus = await ref
|
||||||
.read(torProxyServiceProvider.notifier)
|
.read(torProxyServiceProvider.notifier)
|
||||||
.requestSync();
|
.requestSync();
|
||||||
|
|
||||||
if (!currentStatus.isRunning) {
|
return !currentStatus.isRunning;
|
||||||
if (context.mounted) {
|
}
|
||||||
final result = await showDialog<bool>(
|
|
||||||
context: context,
|
|
||||||
builder: (context) {
|
|
||||||
return const TorDialog();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (result == true) {
|
Future<void> startProxy() async {
|
||||||
final connection = ref
|
if (state) return;
|
||||||
.read(torProxyServiceProvider.notifier)
|
|
||||||
.startOrReconfigure(reconfigureIfRunning: false);
|
|
||||||
|
|
||||||
ref
|
state = true;
|
||||||
.read(overlayControllerProvider.notifier)
|
|
||||||
.show(
|
|
||||||
(context) =>
|
|
||||||
Positioned(top: 0, left: 0, child: TorNotification()),
|
|
||||||
);
|
|
||||||
|
|
||||||
await connection;
|
try {
|
||||||
}
|
final connection = ref
|
||||||
}
|
.read(torProxyServiceProvider.notifier)
|
||||||
|
.startOrReconfigure(reconfigureIfRunning: false);
|
||||||
|
|
||||||
|
ref
|
||||||
|
.read(overlayControllerProvider.notifier)
|
||||||
|
.show(
|
||||||
|
(context) =>
|
||||||
|
const Positioned(top: 0, left: 0, child: TorNotification()),
|
||||||
|
);
|
||||||
|
|
||||||
|
await connection;
|
||||||
|
} finally {
|
||||||
|
state = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void build() {}
|
bool build() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ part of 'start_tor_proxy.dart';
|
|||||||
final startProxyControllerProvider = StartProxyControllerProvider._();
|
final startProxyControllerProvider = StartProxyControllerProvider._();
|
||||||
|
|
||||||
final class StartProxyControllerProvider
|
final class StartProxyControllerProvider
|
||||||
extends $NotifierProvider<StartProxyController, void> {
|
extends $NotifierProvider<StartProxyController, bool> {
|
||||||
StartProxyControllerProvider._()
|
StartProxyControllerProvider._()
|
||||||
: super(
|
: super(
|
||||||
from: null,
|
from: null,
|
||||||
@@ -33,28 +33,28 @@ final class StartProxyControllerProvider
|
|||||||
StartProxyController create() => StartProxyController();
|
StartProxyController create() => StartProxyController();
|
||||||
|
|
||||||
/// {@macro riverpod.override_with_value}
|
/// {@macro riverpod.override_with_value}
|
||||||
Override overrideWithValue(void value) {
|
Override overrideWithValue(bool value) {
|
||||||
return $ProviderOverride(
|
return $ProviderOverride(
|
||||||
origin: this,
|
origin: this,
|
||||||
providerOverride: $SyncValueProvider<void>(value),
|
providerOverride: $SyncValueProvider<bool>(value),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$startProxyControllerHash() =>
|
String _$startProxyControllerHash() =>
|
||||||
r'13c6ad9611a2f9525689d370a0511274aa9c0f03';
|
r'899b585bf7f220251ac92f11c79537cc07723241';
|
||||||
|
|
||||||
abstract class _$StartProxyController extends $Notifier<void> {
|
abstract class _$StartProxyController extends $Notifier<bool> {
|
||||||
void build();
|
bool build();
|
||||||
@$mustCallSuper
|
@$mustCallSuper
|
||||||
@override
|
@override
|
||||||
void runBuild() {
|
void runBuild() {
|
||||||
final ref = this.ref as $Ref<void, void>;
|
final ref = this.ref as $Ref<bool, bool>;
|
||||||
final element =
|
final element =
|
||||||
ref.element
|
ref.element
|
||||||
as $ClassProviderElement<
|
as $ClassProviderElement<
|
||||||
AnyNotifier<void, void>,
|
AnyNotifier<bool, bool>,
|
||||||
void,
|
bool,
|
||||||
Object?,
|
Object?,
|
||||||
Object?
|
Object?
|
||||||
>;
|
>;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ const automaticCountry = '';
|
|||||||
|
|
||||||
class CountryPickerScreen extends HookWidget {
|
class CountryPickerScreen extends HookWidget {
|
||||||
const CountryPickerScreen({
|
const CountryPickerScreen({
|
||||||
|
super.key,
|
||||||
required this.title,
|
required this.title,
|
||||||
this.selectedCountryCode,
|
this.selectedCountryCode,
|
||||||
});
|
});
|
||||||
@@ -51,20 +52,16 @@ class CountryPickerScreen extends HookWidget {
|
|||||||
country.countryCode ??
|
country.countryCode ??
|
||||||
'Unnamed Country';
|
'Unnamed Country';
|
||||||
return (alpha2Code: country.alpha2Code, label: label);
|
return (alpha2Code: country.alpha2Code, label: label);
|
||||||
}).toList()
|
}).toList()..sort((a, b) => a.label.compareTo(b.label));
|
||||||
..sort((a, b) => a.label.compareTo(b.label));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final filteredCountries = useMemoized(
|
final filteredCountries = useMemoized(() {
|
||||||
() {
|
if (searchQuery.value.isEmpty) return countries;
|
||||||
if (searchQuery.value.isEmpty) return countries;
|
final query = searchQuery.value.toLowerCase();
|
||||||
final query = searchQuery.value.toLowerCase();
|
return countries
|
||||||
return countries
|
.where((c) => c.label.toLowerCase().contains(query))
|
||||||
.where((c) => c.label.toLowerCase().contains(query))
|
.toList();
|
||||||
.toList();
|
}, [searchQuery.value, countries]);
|
||||||
},
|
|
||||||
[searchQuery.value, countries],
|
|
||||||
);
|
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
@@ -95,7 +92,7 @@ class CountryPickerScreen extends HookWidget {
|
|||||||
borderRadius: BorderRadius.circular(8),
|
borderRadius: BorderRadius.circular(8),
|
||||||
borderSide: BorderSide.none,
|
borderSide: BorderSide.none,
|
||||||
),
|
),
|
||||||
contentPadding: const EdgeInsets.symmetric(vertical: 0),
|
contentPadding: EdgeInsets.zero,
|
||||||
),
|
),
|
||||||
onChanged: (value) => searchQuery.value = value,
|
onChanged: (value) => searchQuery.value = value,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ 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:nullability/nullability.dart';
|
import 'package:nullability/nullability.dart';
|
||||||
import 'package:weblibre/core/design/app_colors.dart';
|
import 'package:weblibre/core/design/app_colors.dart';
|
||||||
|
import 'package:weblibre/core/routing/routes.dart';
|
||||||
import 'package:weblibre/features/settings/presentation/controllers/save_settings.dart';
|
import 'package:weblibre/features/settings/presentation/controllers/save_settings.dart';
|
||||||
import 'package:weblibre/features/tor/domain/services/tor_proxy.dart';
|
import 'package:weblibre/features/tor/domain/services/tor_proxy.dart';
|
||||||
import 'package:weblibre/core/routing/routes.dart';
|
|
||||||
import 'package:weblibre/features/tor/presentation/screens/country_picker.dart';
|
import 'package:weblibre/features/tor/presentation/screens/country_picker.dart';
|
||||||
import 'package:weblibre/features/user/data/models/tor_settings.dart';
|
import 'package:weblibre/features/user/data/models/tor_settings.dart';
|
||||||
import 'package:weblibre/features/user/domain/repositories/tor_settings.dart';
|
import 'package:weblibre/features/user/domain/repositories/tor_settings.dart';
|
||||||
@@ -34,7 +34,7 @@ import 'package:weblibre/presentation/hooks/on_initialization.dart';
|
|||||||
import 'package:weblibre/utils/ui_helper.dart';
|
import 'package:weblibre/utils/ui_helper.dart';
|
||||||
|
|
||||||
class TorProxyScreen extends HookConsumerWidget {
|
class TorProxyScreen extends HookConsumerWidget {
|
||||||
const TorProxyScreen();
|
const TorProxyScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
@@ -465,7 +465,8 @@ class TorProxyScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
enabled: !torIsBusy,
|
enabled: !torIsBusy,
|
||||||
leading: torSettings.entryNodeCountry.mapNotNull(
|
leading:
|
||||||
|
torSettings.entryNodeCountry.mapNotNull(
|
||||||
(code) => CountryFlag.fromCountryCode(
|
(code) => CountryFlag.fromCountryCode(
|
||||||
code,
|
code,
|
||||||
theme: const EmojiTheme(size: 28),
|
theme: const EmojiTheme(size: 28),
|
||||||
@@ -486,8 +487,9 @@ class TorProxyScreen extends HookConsumerWidget {
|
|||||||
$extra: torSettings.entryNodeCountry,
|
$extra: torSettings.entryNodeCountry,
|
||||||
).push<String>(context);
|
).push<String>(context);
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
final value =
|
final value = result == automaticCountry
|
||||||
result == automaticCountry ? null : result;
|
? null
|
||||||
|
: result;
|
||||||
await ref
|
await ref
|
||||||
.read(saveTorSettingsControllerProvider.notifier)
|
.read(saveTorSettingsControllerProvider.notifier)
|
||||||
.save(
|
.save(
|
||||||
@@ -498,7 +500,8 @@ class TorProxyScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
enabled: !torIsBusy,
|
enabled: !torIsBusy,
|
||||||
leading: torSettings.exitNodeCountry.mapNotNull(
|
leading:
|
||||||
|
torSettings.exitNodeCountry.mapNotNull(
|
||||||
(code) => CountryFlag.fromCountryCode(
|
(code) => CountryFlag.fromCountryCode(
|
||||||
code,
|
code,
|
||||||
theme: const EmojiTheme(size: 28),
|
theme: const EmojiTheme(size: 28),
|
||||||
@@ -519,8 +522,9 @@ class TorProxyScreen extends HookConsumerWidget {
|
|||||||
$extra: torSettings.exitNodeCountry,
|
$extra: torSettings.exitNodeCountry,
|
||||||
).push<String>(context);
|
).push<String>(context);
|
||||||
if (result == null) return;
|
if (result == null) return;
|
||||||
final value =
|
final value = result == automaticCountry
|
||||||
result == automaticCountry ? null : result;
|
? null
|
||||||
|
: result;
|
||||||
await ref
|
await ref
|
||||||
.read(saveTorSettingsControllerProvider.notifier)
|
.read(saveTorSettingsControllerProvider.notifier)
|
||||||
.save(
|
.save(
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import 'package:weblibre/core/design/app_colors.dart';
|
|||||||
import 'package:weblibre/presentation/icons/tor_icons.dart';
|
import 'package:weblibre/presentation/icons/tor_icons.dart';
|
||||||
|
|
||||||
class TorDialog extends StatelessWidget {
|
class TorDialog extends StatelessWidget {
|
||||||
const TorDialog();
|
const TorDialog({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ import 'package:weblibre/presentation/icons/tor_icons.dart';
|
|||||||
import 'package:weblibre/presentation/widgets/animate_gradient_shader.dart';
|
import 'package:weblibre/presentation/widgets/animate_gradient_shader.dart';
|
||||||
|
|
||||||
class TorNotification extends HookConsumerWidget {
|
class TorNotification extends HookConsumerWidget {
|
||||||
|
const TorNotification({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final appColors = AppColors.of(context);
|
final appColors = AppColors.of(context);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
|||||||
|
|
||||||
/// Bottom sheet widget to select a user profile.
|
/// Bottom sheet widget to select a user profile.
|
||||||
class SelectProfileDialog extends HookConsumerWidget {
|
class SelectProfileDialog extends HookConsumerWidget {
|
||||||
const SelectProfileDialog();
|
const SelectProfileDialog({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import 'package:weblibre/utils/ui_helper.dart';
|
|||||||
class ProfileBackupScreen extends HookConsumerWidget {
|
class ProfileBackupScreen extends HookConsumerWidget {
|
||||||
final Profile profile;
|
final Profile profile;
|
||||||
|
|
||||||
const ProfileBackupScreen({required this.profile});
|
const ProfileBackupScreen({super.key, required this.profile});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ final _filenamePattern = RegExp(
|
|||||||
);
|
);
|
||||||
|
|
||||||
class ProfileBackupListScreen extends HookConsumerWidget {
|
class ProfileBackupListScreen extends HookConsumerWidget {
|
||||||
const ProfileBackupListScreen();
|
const ProfileBackupListScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const _timeoutOptions = <DropdownMenuItem<Duration?>>[
|
|||||||
class ProfileEditScreen extends HookConsumerWidget {
|
class ProfileEditScreen extends HookConsumerWidget {
|
||||||
final Profile? profile;
|
final Profile? profile;
|
||||||
|
|
||||||
const ProfileEditScreen({required this.profile});
|
const ProfileEditScreen({super.key, required this.profile});
|
||||||
|
|
||||||
Future<void> _handleSave(
|
Future<void> _handleSave(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import 'package:weblibre/features/user/domain/repositories/profile.dart';
|
|||||||
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
||||||
|
|
||||||
class ProfileListScreen extends HookConsumerWidget {
|
class ProfileListScreen extends HookConsumerWidget {
|
||||||
const ProfileListScreen();
|
const ProfileListScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import 'package:weblibre/features/user/domain/providers/profile_auth.dart';
|
|||||||
import 'package:weblibre/presentation/hooks/on_initialization.dart';
|
import 'package:weblibre/presentation/hooks/on_initialization.dart';
|
||||||
|
|
||||||
class LockScreen extends HookConsumerWidget {
|
class LockScreen extends HookConsumerWidget {
|
||||||
const LockScreen();
|
const LockScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import 'package:weblibre/presentation/widgets/speech_to_text_button.dart';
|
|||||||
class FeedArticleListScreen extends HookConsumerWidget {
|
class FeedArticleListScreen extends HookConsumerWidget {
|
||||||
final Uri? feedId;
|
final Uri? feedId;
|
||||||
|
|
||||||
const FeedArticleListScreen({required this.feedId});
|
const FeedArticleListScreen({super.key, required this.feedId});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import 'package:weblibre/features/web_feed/presentation/widgets/feed_card.dart';
|
|||||||
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
||||||
|
|
||||||
class FeedListScreen extends HookConsumerWidget {
|
class FeedListScreen extends HookConsumerWidget {
|
||||||
const FeedListScreen();
|
const FeedListScreen({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
|||||||
class SelectFeedDialog extends HookConsumerWidget {
|
class SelectFeedDialog extends HookConsumerWidget {
|
||||||
final Set<Uri> feedUris;
|
final Set<Uri> feedUris;
|
||||||
|
|
||||||
const SelectFeedDialog({required this.feedUris});
|
const SelectFeedDialog({super.key, required this.feedUris});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import 'package:weblibre/features/web_feed/data/models/feed_author.dart';
|
|||||||
class AuthorsHorizontalList extends StatelessWidget {
|
class AuthorsHorizontalList extends StatelessWidget {
|
||||||
late final List<Widget> _authors;
|
late final List<Widget> _authors;
|
||||||
|
|
||||||
AuthorsHorizontalList({
|
AuthorsHorizontalList({super.key,
|
||||||
required List<FeedAuthor> authors,
|
required List<FeedAuthor> authors,
|
||||||
Set<String> selectedTags = const {},
|
Set<String> selectedTags = const {},
|
||||||
void Function(String tagId, bool value)? onTagSelected,
|
void Function(String tagId, bool value)? onTagSelected,
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import 'package:weblibre/features/web_feed/data/models/feed_category.dart';
|
|||||||
class TagsHorizontalList extends StatelessWidget {
|
class TagsHorizontalList extends StatelessWidget {
|
||||||
late final List<Widget> _tags;
|
late final List<Widget> _tags;
|
||||||
|
|
||||||
TagsHorizontalList({
|
TagsHorizontalList({super.key,
|
||||||
required List<FeedCategory> tags,
|
required List<FeedCategory> tags,
|
||||||
Set<String> selectedTags = const {},
|
Set<String> selectedTags = const {},
|
||||||
void Function(String tagId, bool value)? onTagSelected,
|
void Function(String tagId, bool value)? onTagSelected,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import 'package:weblibre/features/qr_scanner/presentation/dialogs/qr_scanner_dia
|
|||||||
class QrScannerButton extends HookConsumerWidget {
|
class QrScannerButton extends HookConsumerWidget {
|
||||||
final void Function(Barcode? scanResult) onScanResult;
|
final void Function(Barcode? scanResult) onScanResult;
|
||||||
|
|
||||||
const QrScannerButton({required this.onScanResult});
|
const QrScannerButton({super.key, required this.onScanResult});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
@@ -35,7 +35,7 @@ class QrScannerButton extends HookConsumerWidget {
|
|||||||
final result = await showDialog<Barcode>(
|
final result = await showDialog<Barcode>(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) {
|
builder: (context) {
|
||||||
return QrScannerDialog();
|
return const QrScannerDialog();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ dependencies:
|
|||||||
path: ../
|
path: ../
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
integration_test:
|
|
||||||
sdk: flutter
|
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
integration_test:
|
||||||
|
sdk: flutter
|
||||||
lint: ^2.8.0
|
lint: ^2.8.0
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
|
|||||||
@@ -6,9 +6,8 @@
|
|||||||
// tree, read text, and verify that the values of widget properties are correct.
|
// tree, read text, and verify that the values of widget properties are correct.
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
|
|
||||||
import 'package:flutter_mozilla_components_example/main.dart';
|
import 'package:flutter_mozilla_components_example/main.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Verify Platform version', (WidgetTester tester) async {
|
testWidgets('Verify Platform version', (WidgetTester tester) async {
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ dependencies:
|
|||||||
socks5_proxy: ^2.1.1
|
socks5_proxy: ^2.1.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
lint: ^2.8.0
|
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
integration_test:
|
integration_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
lint: ^2.8.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
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
|
export 'src/flutter_tor.dart';
|
||||||
export 'src/tor_api.g.dart'
|
export 'src/tor_api.g.dart'
|
||||||
show
|
show
|
||||||
TransportType,
|
IPtProxyController,
|
||||||
TorConfiguration,
|
TorConfiguration,
|
||||||
TorStatus,
|
|
||||||
TorLogMessage,
|
TorLogMessage,
|
||||||
IPtProxyController;
|
TorStatus,
|
||||||
|
TransportType;
|
||||||
export 'src/flutter_tor.dart';
|
|
||||||
|
|||||||
@@ -57,9 +57,9 @@ class FlutterTor {
|
|||||||
// Unregister the Flutter API handler
|
// Unregister the Flutter API handler
|
||||||
TorLogApi.setUp(null);
|
TorLogApi.setUp(null);
|
||||||
|
|
||||||
_logController.close();
|
unawaited(_logController.close());
|
||||||
_statusController.close();
|
unawaited(_statusController.close());
|
||||||
_bootstrapController.close();
|
unawaited(_bootstrapController.close());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,15 +26,11 @@ dependencies:
|
|||||||
# the parent directory to use the current plugin's version.
|
# the parent directory to use the current plugin's version.
|
||||||
path: ../
|
path: ../
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
|
||||||
cupertino_icons: ^1.0.8
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
integration_test:
|
|
||||||
sdk: flutter
|
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
integration_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
# The "flutter_lints" package below contains a set of recommended lints to
|
# The "flutter_lints" package below contains a set of recommended lints to
|
||||||
# encourage good coding practices. The lint set provided by the package is
|
# encourage good coding practices. The lint set provided by the package is
|
||||||
|
|||||||
@@ -42,6 +42,6 @@ class MyApp extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp();
|
return const MaterialApp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
logger: ^2.6.2
|
||||||
simple_intent_receiver:
|
simple_intent_receiver:
|
||||||
# When depending on this package from a real application you should use:
|
# When depending on this package from a real application you should use:
|
||||||
# simple_intent_receiver: ^x.y.z
|
# simple_intent_receiver: ^x.y.z
|
||||||
@@ -26,16 +26,11 @@ dependencies:
|
|||||||
# the parent directory to use the current plugin's version.
|
# the parent directory to use the current plugin's version.
|
||||||
path: ../
|
path: ../
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
|
||||||
cupertino_icons: ^1.0.8
|
|
||||||
logger: ^2.6.2
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
integration_test:
|
|
||||||
sdk: flutter
|
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
integration_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
# The "flutter_lints" package below contains a set of recommended lints to
|
# The "flutter_lints" package below contains a set of recommended lints to
|
||||||
# encourage good coding practices. The lint set provided by the package is
|
# encourage good coding practices. The lint set provided by the package is
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:speech_to_text_dialog/speech_to_text_dialog.dart';
|
import 'package:speech_to_text_dialog/speech_to_text_dialog.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@@ -50,7 +50,7 @@ class _MyAppState extends State<MyApp> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_textSubscription?.cancel();
|
unawaited(_textSubscription?.cancel());
|
||||||
_speechToTextDialog.dispose();
|
_speechToTextDialog.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,15 +26,11 @@ dependencies:
|
|||||||
# the parent directory to use the current plugin's version.
|
# the parent directory to use the current plugin's version.
|
||||||
path: ../
|
path: ../
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
|
||||||
cupertino_icons: ^1.0.8
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
integration_test:
|
|
||||||
sdk: flutter
|
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
integration_test:
|
||||||
|
sdk: flutter
|
||||||
|
|
||||||
# The "flutter_lints" package below contains a set of recommended lints to
|
# The "flutter_lints" package below contains a set of recommended lints to
|
||||||
# encourage good coding practices. The lint set provided by the package is
|
# encourage good coding practices. The lint set provided by the package is
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:flutter/services.dart' show BinaryMessenger;
|
import 'package:flutter/services.dart' show BinaryMessenger;
|
||||||
import 'src/pigeons/speech_to_text.g.dart';
|
import 'package:speech_to_text_dialog/src/pigeons/speech_to_text.g.dart';
|
||||||
|
|
||||||
/// Speech recognition dialog using Android's RecognizerIntent.
|
/// Speech recognition dialog using Android's RecognizerIntent.
|
||||||
///
|
///
|
||||||
@@ -82,7 +82,7 @@ class SpeechToTextDialog implements SpeechToTextEvents {
|
|||||||
/// print('Speech recognition not available');
|
/// print('Speech recognition not available');
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
Future<bool> showDialog({String? locale}) async {
|
Future<bool> showDialog({String? locale}) {
|
||||||
return _api.showDialog(locale: locale);
|
return _api.showDialog(locale: locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ class SpeechToTextDialog implements SpeechToTextEvents {
|
|||||||
if (!_disposed) {
|
if (!_disposed) {
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
SpeechToTextEvents.setUp(null, binaryMessenger: _binaryMessenger);
|
SpeechToTextEvents.setUp(null, binaryMessenger: _binaryMessenger);
|
||||||
_textStreamController.close();
|
unawaited(_textStreamController.close());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user