diff --git a/app/lib/presentation/controllers/website_title.dart b/app/lib/presentation/controllers/website_title.dart
index a55e33e0..940bd7d6 100644
--- a/app/lib/presentation/controllers/website_title.dart
+++ b/app/lib/presentation/controllers/website_title.dart
@@ -17,6 +17,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
+import 'package:fast_equatable/fast_equatable.dart';
import 'package:nullability/nullability.dart';
import 'package:riverpod/riverpod.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
@@ -46,34 +47,6 @@ class CompletePageInfo extends _$CompletePageInfo {
return AsyncData(cached);
}
- // ref.listen(
- // fireImmediately: true,
- // pageInfoProvider(cached.url, isImageRequest: false),
- // (previous, next) {
- // if (next.hasValue) {
- // final current = stateOrNull?.value ?? cached;
-
- // state = AsyncData(
- // current.copyWith(
- // //Cached is preferred as this comes from gecko and is more likely to be correct compared to manual request
- // favicon: current.favicon ?? next.value!.favicon,
- // feeds: current.feeds ?? next.value!.feeds,
- // title: current.title.whenNotEmpty ?? next.value!.title,
- // ),
- // );
- // } else {
- // state = next;
- // }
- // },
- // onError: (error, stackTrace) {
- // logger.e(
- // 'Error listening to pageInfoProvider',
- // error: error,
- // stackTrace: stackTrace,
- // );
- // },
- // );
-
ref.listen(
fireImmediately: true,
tabStateProvider(cached.id).select((value) => value?.title),
@@ -150,3 +123,19 @@ Future pageInfo(
return result.value;
}
+
+@Riverpod()
+AsyncValue?>> websiteFeedProvider(
+ Ref ref,
+ String tabId,
+) {
+ final tabState = ref.watch(tabStateProvider(tabId))!;
+ final feeds = ref.watch(
+ pageInfoProvider(
+ tabState.url,
+ isImageRequest: false,
+ ).select((value) => value.whenData((data) => EquatableValue(data.feeds))),
+ );
+
+ return feeds;
+}
diff --git a/app/lib/presentation/controllers/website_title.g.dart b/app/lib/presentation/controllers/website_title.g.dart
index aefa4609..110c7a1c 100644
--- a/app/lib/presentation/controllers/website_title.g.dart
+++ b/app/lib/presentation/controllers/website_title.g.dart
@@ -189,3 +189,92 @@ final class PageInfoFamily extends $Family
@override
String toString() => r'pageInfoProvider';
}
+
+@ProviderFor(websiteFeedProvider)
+const websiteFeedProviderProvider = WebsiteFeedProviderFamily._();
+
+final class WebsiteFeedProviderProvider
+ extends
+ $FunctionalProvider<
+ AsyncValue?>>,
+ AsyncValue?>>,
+ AsyncValue?>>
+ >
+ with $Provider?>>> {
+ const WebsiteFeedProviderProvider._({
+ required WebsiteFeedProviderFamily super.from,
+ required String super.argument,
+ }) : super(
+ retry: null,
+ name: r'websiteFeedProviderProvider',
+ isAutoDispose: true,
+ dependencies: null,
+ $allTransitiveDependencies: null,
+ );
+
+ @override
+ String debugGetCreateSourceHash() => _$websiteFeedProviderHash();
+
+ @override
+ String toString() {
+ return r'websiteFeedProviderProvider'
+ ''
+ '($argument)';
+ }
+
+ @$internal
+ @override
+ $ProviderElement?>>> $createElement(
+ $ProviderPointer pointer,
+ ) => $ProviderElement(pointer);
+
+ @override
+ AsyncValue?>> create(Ref ref) {
+ final argument = this.argument as String;
+ return websiteFeedProvider(ref, argument);
+ }
+
+ /// {@macro riverpod.override_with_value}
+ Override overrideWithValue(AsyncValue?>> value) {
+ return $ProviderOverride(
+ origin: this,
+ providerOverride:
+ $SyncValueProvider?>>>(value),
+ );
+ }
+
+ @override
+ bool operator ==(Object other) {
+ return other is WebsiteFeedProviderProvider && other.argument == argument;
+ }
+
+ @override
+ int get hashCode {
+ return argument.hashCode;
+ }
+}
+
+String _$websiteFeedProviderHash() =>
+ r'b8ad81b883acee41f420af9aeca254fbd29b3107';
+
+final class WebsiteFeedProviderFamily extends $Family
+ with
+ $FunctionalFamilyOverride<
+ AsyncValue?>>,
+ String
+ > {
+ const WebsiteFeedProviderFamily._()
+ : super(
+ retry: null,
+ name: r'websiteFeedProviderProvider',
+ dependencies: null,
+ $allTransitiveDependencies: null,
+ isAutoDispose: true,
+ );
+
+ WebsiteFeedProviderProvider call(String tabId) =>
+ WebsiteFeedProviderProvider._(argument: tabId, from: this);
+
+ @override
+ String toString() => r'websiteFeedProviderProvider';
+}
diff --git a/app/lib/presentation/widgets/website_feed_tile.dart b/app/lib/presentation/widgets/website_feed_menu_button.dart
similarity index 67%
rename from app/lib/presentation/widgets/website_feed_tile.dart
rename to app/lib/presentation/widgets/website_feed_menu_button.dart
index 2269d11b..687c3dff 100644
--- a/app/lib/presentation/widgets/website_feed_tile.dart
+++ b/app/lib/presentation/widgets/website_feed_menu_button.dart
@@ -24,47 +24,47 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:nullability/nullability.dart';
import 'package:skeletonizer/skeletonizer.dart';
import 'package:weblibre/core/routing/routes.dart';
-import 'package:weblibre/features/geckoview/domain/entities/states/tab.dart';
import 'package:weblibre/presentation/controllers/website_title.dart';
import 'package:weblibre/presentation/widgets/rounded_text.dart';
-class WebsiteFeedTile extends HookConsumerWidget {
- final TabState initialTabState;
+class WebsiteFeedMenuButton extends HookConsumerWidget {
+ final String tabId;
- const WebsiteFeedTile(this.initialTabState, {super.key});
+ const WebsiteFeedMenuButton(this.tabId, {super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
- final pageInfoAsync = ref.watch(completePageInfoProvider(initialTabState));
+ final feedsAsync = ref.watch(websiteFeedProviderProvider(tabId));
return Skeletonizer(
- enabled: pageInfoAsync.isLoading && initialTabState.feeds == null,
- child: pageInfoAsync.when(
+ enabled: feedsAsync.isLoading && feedsAsync.value?.value == null,
+ child: feedsAsync.when(
skipLoadingOnReload: true,
- data: (info) {
- if (info.feeds.isEmpty) {
+ data: (feeds) {
+ if (feeds.value.isEmpty) {
return const SizedBox.shrink();
}
- return ListTile(
- leading: const Icon(Icons.rss_feed),
- title: const Text('Available Web Feeds'),
- trailing: RoundedBackground(
+ return MenuItemButton(
+ leadingIcon: const Icon(Icons.rss_feed),
+ closeOnActivate: false,
+ trailingIcon: RoundedBackground(
child: Text(
- info.feeds!.length.toString(),
+ feeds.value!.length.toString(),
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).colorScheme.onPrimary,
),
),
),
- onTap: () async {
+ onPressed: () async {
await SelectFeedDialogRoute(
feedsJson: jsonEncode(
- info.feeds!.map((feed) => feed.toString()).toList(),
+ feeds.value!.map((feed) => feed.toString()).toList(),
),
).push(context);
},
+ child: const Text('Available Web Feeds'),
);
},
error: (error, stackTrace) {
@@ -77,11 +77,10 @@ class WebsiteFeedTile extends HookConsumerWidget {
// onRetry: () => ref.refresh(pageInfoProvider(url)),
// );
},
- loading: () => const ListTile(
- leading: Icon(Icons.rss_feed),
- contentPadding: EdgeInsets.zero,
- title: Text('Available Web Feeds'),
- trailing: Bone.icon(),
+ loading: () => const MenuItemButton(
+ leadingIcon: Icon(Icons.rss_feed),
+ trailingIcon: Bone.icon(),
+ child: Text('Available Web Feeds'),
),
),
);