import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:riverpod_annotation/riverpod_annotation.dart'; import 'package:linkdy/screens/webview/ui/webview.dart'; import 'package:linkdy/screens/bookmarks/provider/bookmarks.provider.dart'; import 'package:linkdy/screens/bookmarks/provider/common_functions.dart'; import 'package:linkdy/screens/bookmarks/model/search_bookmarks.model.dart'; import 'package:linkdy/screens/webview/ui/invalid_bookmark.dart'; import 'package:linkdy/config/sizes.dart'; import 'package:linkdy/providers/app_status.provider.dart'; import 'package:linkdy/providers/router.provider.dart'; import 'package:linkdy/router/paths.dart'; import 'package:linkdy/utils/open_url.dart'; import 'package:linkdy/constants/global_keys.dart'; import 'package:linkdy/constants/enums.dart'; import 'package:linkdy/models/data/bookmarks.dart'; import 'package:linkdy/providers/api_client.provider.dart'; part 'search_bookmarks.provider.g.dart'; @riverpod FutureOr fetchSearchBookmarks(FetchSearchBookmarksRef ref, int limit) async { if (ref.watch(searchBookmarksProvider).searchTerm == "") return null; final result = await ref.read(apiClientProvider)!.fetchBookmarks( q: ref.watch(searchBookmarksProvider).searchTerm, limit: limit, offset: 0, ); if (result.successful == true) { ref.read(searchBookmarksProvider).bookmarks = result.content!.results!; ref.read(searchBookmarksProvider).maxNumber = result.content!.count!; ref.read(searchBookmarksProvider).currentPage = 0; ref.read(searchBookmarksProvider).loadingMore = false; ref.read(searchBookmarksProvider).inialLoadStatus = LoadStatus.loaded; } else { ref.read(searchBookmarksProvider).inialLoadStatus = LoadStatus.error; } ref.read(searchBookmarksProvider.notifier).notifyListeners(); } @riverpod FutureOr fetchSearchBookmarksLoadMore(FetchSearchBookmarksLoadMoreRef ref) async { final provider = ref.watch(searchBookmarksProvider); final newOffset = provider.limit * (provider.currentPage + 1); final result = await ref.watch(apiClientProvider)!.fetchBookmarks( q: provider.searchTerm, limit: provider.limit, offset: newOffset, ); if (result.successful == true) { provider.bookmarks = [...provider.bookmarks, ...result.content!.results!]; provider.maxNumber = result.content!.count!; provider.currentPage = provider.currentPage + 1; } ref.read(searchBookmarksProvider.notifier).setLoadingMore(false); } const _webViewRoute = "wb"; const _webViewRoutePath = "/wb"; @riverpod class SearchBookmarks extends _$SearchBookmarks { @override SearchBookmarksModel build() { final model = SearchBookmarksModel( searchController: TextEditingController(), bookmarks: [], webViewRouter: GoRouter( routes: [ GoRoute( path: "/", builder: (context, state) => const SizedBox(), routes: [ GoRoute( path: _webViewRoute, pageBuilder: (context, state) { final extra = state.extra; if (extra is Bookmark) { return CustomTransitionPage( child: WebViewScreen(bookmark: extra), transitionsBuilder: (context, animation, secondaryAnimation, child) => child, ); } else { return CustomTransitionPage( child: const InvalidBookmarkScreen(), transitionsBuilder: (context, animation, secondaryAnimation, child) => child, ); } }, ), ], ), ], ), ); ref.read(fetchSearchBookmarksProvider(model.limit)); return model; } void clearSearch() { state.searchController.clear(); state.searchTerm = ""; ref.notifyListeners(); } void notifyOnChange() { ref.notifyListeners(); } void setSearchTerm() { state.searchTerm = state.searchController.text; ref.notifyListeners(); } void setLoadingMore(bool value) { state.loadingMore = value; ref.notifyListeners(); } void setInitialLoadStatus(LoadStatus status) { state.inialLoadStatus = status; ref.notifyListeners(); } void notifyListeners() { ref.notifyListeners(); } void clearSelectedBookmark() { state.selectedBookmark = null; ref.notifyListeners(); } void selectBookmark(Bookmark bookmark, double width) { if (ref.watch(appStatusProvider).openLinksBrowser == OpenLinksBrowser.browserCustomTab) { openUrlCustomTab(bookmark.url!); } else if (ref.watch(appStatusProvider).openLinksBrowser == OpenLinksBrowser.systemBrowser) { openUrlSystemBrowser(bookmark.url!); } else { if (width <= Sizes.tabletBreakpoint) { ref.watch(routerProvider).push(RoutesPaths.webview, extra: bookmark); } else if (bookmark != state.selectedBookmark) { state.webViewRouter.go(_webViewRoutePath, extra: bookmark); } state.selectedBookmark = bookmark; ref.notifyListeners(); } } void deleteBookmark(Bookmark bookmark) async { final result = await BookmarkCommonFunctions.deleteBookmark( ref: ref, bookmark: bookmark, apiClient: ref.read(apiClientProvider)!, scaffoldMessengerKey: ScaffoldMessengerKeys.search, ); if (result == true) { state.bookmarks = state.bookmarks.where((b) => b.id != bookmark.id).toList(); ref.notifyListeners(); ref .read(bookmarksProvider.notifier) .setBookmarks(ref.read(bookmarksProvider).bookmarks.where((b) => b.id != bookmark.id).toList()); } } void markAsReadUnread(Bookmark bookmark) async { final result = await BookmarkCommonFunctions.markAsReadUnread( ref: ref, bookmark: bookmark, apiClient: ref.read(apiClientProvider)!, scaffoldMessengerKey: ScaffoldMessengerKeys.search, ); if (result != null) { state.bookmarks = state.bookmarks.map((b) => b.id == result.id ? result : b).toList(); ref.notifyListeners(); ref .read(bookmarksProvider.notifier) .setBookmarks(ref.read(bookmarksProvider).bookmarks.map((b) => b.id == result.id ? result : b).toList()); } } void archiveUnarchive(Bookmark bookmark) async { final result = await BookmarkCommonFunctions.archiveUnarchive( ref: ref, bookmark: bookmark, apiClient: ref.read(apiClientProvider)!, scaffoldMessengerKey: ScaffoldMessengerKeys.search, ); if (result == true) { // On this case the bookmark always will pass from unarchived to archived state.bookmarks = state.bookmarks.where((b) => b.id != bookmark.id).toList(); ref.notifyListeners(); ref .read(bookmarksProvider.notifier) .setBookmarks(ref.read(bookmarksProvider).bookmarks.where((b) => b.id != bookmark.id).toList()); } } void shareUnshare(Bookmark bookmark) async { final result = await BookmarkCommonFunctions.shareUnshare( scaffoldMessengerKey: ScaffoldMessengerKeys.search, ref: ref, bookmark: bookmark, apiClient: ref.read(apiClientProvider)!, ); if (result != null) { state.bookmarks = state.bookmarks.map((b) => b.id == result.id ? result : b).toList(); ref.notifyListeners(); ref .read(bookmarksProvider.notifier) .setBookmarks(ref.read(bookmarksProvider).bookmarks.map((b) => b.id == result.id ? result : b).toList()); } } }