diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index a3464db..2cf18bb 100644 --- a/lib/i18n/strings.g.dart +++ b/lib/i18n/strings.g.dart @@ -6,7 +6,7 @@ /// Locales: 2 /// Strings: 350 (175 per locale) /// -/// Built on 2024-02-28 at 19:46 UTC +/// Built on 2024-02-29 at 10:47 UTC // coverage:ignore-file // ignore_for_file: type=lint diff --git a/lib/screens/bookmarks/model/bookmarks.model.dart b/lib/screens/bookmarks/model/bookmarks.model.dart index 761389c..7a3be17 100644 --- a/lib/screens/bookmarks/model/bookmarks.model.dart +++ b/lib/screens/bookmarks/model/bookmarks.model.dart @@ -1,3 +1,5 @@ +import 'package:go_router/go_router.dart'; + import 'package:linkdy/config/options.dart'; import 'package:linkdy/constants/enums.dart'; import 'package:linkdy/models/data/bookmarks.dart'; @@ -11,6 +13,7 @@ class BookmarksModel { int maxNumber; ReadStatus readStatus; Bookmark? selectedBookmark; + final GoRouter webViewRouter; BookmarksModel({ this.currentPage = 0, @@ -21,5 +24,6 @@ class BookmarksModel { this.maxNumber = 0, this.readStatus = ReadStatus.all, this.selectedBookmark, + required this.webViewRouter, }); } diff --git a/lib/screens/bookmarks/model/search_bookmarks.model.dart b/lib/screens/bookmarks/model/search_bookmarks.model.dart index 490b0b0..c2684a5 100644 --- a/lib/screens/bookmarks/model/search_bookmarks.model.dart +++ b/lib/screens/bookmarks/model/search_bookmarks.model.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:go_router/go_router.dart'; import 'package:linkdy/config/options.dart'; import 'package:linkdy/constants/enums.dart'; @@ -14,6 +15,7 @@ class SearchBookmarksModel { bool loadingMore; int maxNumber; Bookmark? selectedBookmark; + final GoRouter webViewRouter; SearchBookmarksModel({ required this.searchController, @@ -25,5 +27,6 @@ class SearchBookmarksModel { this.loadingMore = false, this.maxNumber = 0, this.selectedBookmark, + required this.webViewRouter, }); } diff --git a/lib/screens/bookmarks/provider/bookmarks.provider.dart b/lib/screens/bookmarks/provider/bookmarks.provider.dart index dd536a2..ef76558 100644 --- a/lib/screens/bookmarks/provider/bookmarks.provider.dart +++ b/lib/screens/bookmarks/provider/bookmarks.provider.dart @@ -1,5 +1,8 @@ +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/common_functions.dart'; import 'package:linkdy/screens/bookmarks/provider/favicon_loader.provider.dart'; import 'package:linkdy/screens/bookmarks/model/bookmarks.model.dart'; @@ -59,12 +62,29 @@ FutureOr bookmarksRequestLoadMore(BookmarksRequestLoadMoreRef ref) async { ref.read(bookmarksProvider.notifier).setLoadingMore(false); } +const _webViewRoute = "wb"; +const _webViewRoutePath = "/wb"; + @riverpod class Bookmarks extends _$Bookmarks { @override BookmarksModel build() { final model = BookmarksModel( bookmarks: [], + webViewRouter: GoRouter( + routes: [ + GoRoute( + path: "/", + builder: (context, state) => const SizedBox(), + routes: [ + GoRoute( + path: _webViewRoute, + builder: (context, state) => WebViewScreen(bookmark: state.extra as Bookmark), + ), + ], + ), + ], + ), ); ref.read(bookmarksRequestProvider(model.readStatus, model.limit)); return model; @@ -98,11 +118,27 @@ class Bookmarks extends _$Bookmarks { ref.notifyListeners(); } + void pushRoute(String path, bool splitMode) { + if (splitMode == true && state.webViewRouter.canPop()) { + state.selectedBookmark = null; + ref.notifyListeners(); + state.webViewRouter.pop(); + } + ref.read(routerProvider).push(path); + } + + void clearSelectedBookmark() { + state.selectedBookmark = null; + ref.notifyListeners(); + } + void selectBookmark(Bookmark bookmark, double width) { if (width <= Sizes.tabletBreakpoint && ref.watch(appStatusProvider).useInAppBrowser == true) { ref.watch(routerProvider).push(RoutesPaths.webview, extra: bookmark); } else if (width <= Sizes.tabletBreakpoint && ref.watch(appStatusProvider).useInAppBrowser == false) { openUrl(bookmark.url!); + } else if (bookmark != state.selectedBookmark) { + state.webViewRouter.go(_webViewRoutePath, extra: bookmark); } state.selectedBookmark = bookmark; ref.notifyListeners(); diff --git a/lib/screens/bookmarks/provider/bookmarks.provider.g.dart b/lib/screens/bookmarks/provider/bookmarks.provider.g.dart index c5272b1..fbc8cb8 100644 --- a/lib/screens/bookmarks/provider/bookmarks.provider.g.dart +++ b/lib/screens/bookmarks/provider/bookmarks.provider.g.dart @@ -189,7 +189,7 @@ final bookmarksRequestLoadMoreProvider = ); typedef BookmarksRequestLoadMoreRef = AutoDisposeFutureProviderRef; -String _$bookmarksHash() => r'80e94e586950b9072f229958f98c88069086d7ab'; +String _$bookmarksHash() => r'84c91bf9112343e4680040bfe25b5e17fb2f92d2'; /// See also [Bookmarks]. @ProviderFor(Bookmarks) diff --git a/lib/screens/bookmarks/provider/search_bookmarks.provider.dart b/lib/screens/bookmarks/provider/search_bookmarks.provider.dart index 464a5cd..6b3ad4e 100644 --- a/lib/screens/bookmarks/provider/search_bookmarks.provider.dart +++ b/lib/screens/bookmarks/provider/search_bookmarks.provider.dart @@ -1,6 +1,8 @@ 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/favicon_loader.provider.dart'; import 'package:linkdy/screens/bookmarks/provider/bookmarks.provider.dart'; import 'package:linkdy/screens/bookmarks/provider/common_functions.dart'; @@ -63,6 +65,9 @@ FutureOr fetchSearchBookmarksLoadMore(FetchSearchBookmarksLoadMoreRef ref) ref.read(searchBookmarksProvider.notifier).setLoadingMore(false); } +const _webViewRoute = "wb"; +const _webViewRoutePath = "/wb"; + @riverpod class SearchBookmarks extends _$SearchBookmarks { @override @@ -70,6 +75,20 @@ class SearchBookmarks extends _$SearchBookmarks { final model = SearchBookmarksModel( searchController: TextEditingController(), bookmarks: [], + webViewRouter: GoRouter( + routes: [ + GoRoute( + path: "/", + builder: (context, state) => const SizedBox(), + routes: [ + GoRoute( + path: _webViewRoute, + builder: (context, state) => WebViewScreen(bookmark: state.extra as Bookmark), + ), + ], + ), + ], + ), ); ref.read(fetchSearchBookmarksProvider(model.limit)); return model; @@ -109,6 +128,8 @@ class SearchBookmarks extends _$SearchBookmarks { ref.watch(routerProvider).push(RoutesPaths.webview, extra: bookmark); } else if (width <= Sizes.tabletBreakpoint && ref.watch(appStatusProvider).useInAppBrowser == false) { openUrl(bookmark.url!); + } else if (bookmark != state.selectedBookmark) { + state.webViewRouter.go(_webViewRoutePath, extra: bookmark); } state.selectedBookmark = bookmark; ref.notifyListeners(); diff --git a/lib/screens/bookmarks/provider/search_bookmarks.provider.g.dart b/lib/screens/bookmarks/provider/search_bookmarks.provider.g.dart index 90fd2f6..f36e40f 100644 --- a/lib/screens/bookmarks/provider/search_bookmarks.provider.g.dart +++ b/lib/screens/bookmarks/provider/search_bookmarks.provider.g.dart @@ -174,7 +174,7 @@ final fetchSearchBookmarksLoadMoreProvider = ); typedef FetchSearchBookmarksLoadMoreRef = AutoDisposeFutureProviderRef; -String _$searchBookmarksHash() => r'3daf460b8389e8bcf8498c4bdf3935e88f4ce156'; +String _$searchBookmarksHash() => r'5ebbd8dbfe705cbca9552fc60d251372c771d738'; /// See also [SearchBookmarks]. @ProviderFor(SearchBookmarks) diff --git a/lib/screens/bookmarks/ui/bookmarks.dart b/lib/screens/bookmarks/ui/bookmarks.dart index 5cbc523..b8f74bf 100644 --- a/lib/screens/bookmarks/ui/bookmarks.dart +++ b/lib/screens/bookmarks/ui/bookmarks.dart @@ -8,19 +8,19 @@ import 'package:linkdy/screens/bookmarks/ui/bookmark_item.dart'; import 'package:linkdy/screens/bookmarks/ui/bookmark_form_modal.dart'; import 'package:linkdy/screens/bookmarks/ui/delete_bookmark_modal.dart'; import 'package:linkdy/screens/bookmarks/ui/search_bookmarks.dart'; -import 'package:linkdy/screens/webview/ui/webview.dart'; import 'package:linkdy/widgets/circle_page_transition.dart'; import 'package:linkdy/widgets/error_screen.dart'; import 'package:linkdy/widgets/no_data_screen.dart'; import 'package:linkdy/config/sizes.dart'; import 'package:linkdy/constants/enums.dart'; -import 'package:linkdy/providers/router.provider.dart'; import 'package:linkdy/router/paths.dart'; import 'package:linkdy/constants/global_keys.dart'; import 'package:linkdy/i18n/strings.g.dart'; +import 'package:linkdy/widgets/system_overlay_style.dart'; final GlobalKey _searchButtonKey = GlobalKey(); +final webviewBookmarksKey = GlobalKey(); class BookmarksScreen extends ConsumerWidget { const BookmarksScreen({super.key}); @@ -35,16 +35,12 @@ class BookmarksScreen extends ConsumerWidget { return Row( children: [ const Expanded(flex: 2, child: _List(tabletMode: true)), - if (ref.watch(bookmarksProvider).selectedBookmark != null) - Expanded( - flex: 3, - child: WebViewScreen(bookmark: ref.watch(bookmarksProvider).selectedBookmark!), - ), - if (ref.watch(bookmarksProvider).selectedBookmark == null) - const Expanded( - flex: 3, - child: SizedBox(), + Expanded( + flex: 3, + child: Material( + child: Router.withConfig(config: ref.watch(bookmarksProvider).webViewRouter), ), + ), ], ); } else { @@ -71,6 +67,10 @@ class _List extends ConsumerWidget { void openSearchModal() { if (_searchButtonKey.currentContext == null) return; + if (tabletMode == true && ref.read(bookmarksProvider).webViewRouter.canPop()) { + ref.read(bookmarksProvider.notifier).clearSelectedBookmark(); + ref.read(bookmarksProvider).webViewRouter.pop(); + } RenderBox box = _searchButtonKey.currentContext!.findRenderObject() as RenderBox; Offset position = box.localToGlobal(Offset.zero); Navigator.of(context, rootNavigator: true).push( @@ -91,200 +91,204 @@ class _List extends ConsumerWidget { return false; } - return Scaffold( - body: NestedScrollView( - headerSliverBuilder: (context, innerBoxIsScrolled) => [ - SliverOverlapAbsorber( - handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), - sliver: SliverAppBar.large( - pinned: true, - floating: true, - centerTitle: false, - forceElevated: innerBoxIsScrolled, - title: Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Text(t.bookmarks.bookmarks), - if (bookmarks.readStatus == ReadStatus.read || bookmarks.readStatus == ReadStatus.unread) - Container( - margin: const EdgeInsets.only(left: 8), - padding: const EdgeInsets.symmetric( - horizontal: 8, - vertical: 4, - ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(20), - color: Theme.of(context).colorScheme.primaryContainer, - ), - child: Row( - children: [ - Icon( - bookmarks.readStatus == ReadStatus.read - ? Icons.mark_email_read_rounded - : Icons.mark_as_unread_rounded, - size: 14, - color: Theme.of(context).colorScheme.onPrimaryContainer, - ), - const SizedBox(width: 4), - Text( - bookmarks.readStatus == ReadStatus.read ? t.bookmarks.read : t.bookmarks.unread, - style: TextStyle( - fontSize: 12, + return OverlayStyle( + child: Scaffold( + body: NestedScrollView( + headerSliverBuilder: (context, innerBoxIsScrolled) => [ + SliverOverlapAbsorber( + handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), + sliver: SliverAppBar.large( + pinned: true, + floating: true, + centerTitle: false, + forceElevated: innerBoxIsScrolled, + title: Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text(t.bookmarks.bookmarks), + if (bookmarks.readStatus == ReadStatus.read || bookmarks.readStatus == ReadStatus.unread) + Container( + margin: const EdgeInsets.only(left: 8), + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 4, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20), + color: Theme.of(context).colorScheme.primaryContainer, + ), + child: Row( + children: [ + Icon( + bookmarks.readStatus == ReadStatus.read + ? Icons.mark_email_read_rounded + : Icons.mark_as_unread_rounded, + size: 14, color: Theme.of(context).colorScheme.onPrimaryContainer, - fontWeight: FontWeight.w700, ), - ), - ], + const SizedBox(width: 4), + Text( + bookmarks.readStatus == ReadStatus.read ? t.bookmarks.read : t.bookmarks.unread, + style: TextStyle( + fontSize: 12, + color: Theme.of(context).colorScheme.onPrimaryContainer, + fontWeight: FontWeight.w700, + ), + ), + ], + ), ), + ], + ), + actions: [ + IconButton( + key: _searchButtonKey, + onPressed: openSearchModal, + icon: const Icon(Icons.search_rounded), + tooltip: t.bookmarks.search.searchBookmarks, + ), + IconButton( + onPressed: () => showModalBottomSheet( + context: context, + useRootNavigator: true, + builder: (context) => const VisualizationModal(), + isScrollControlled: true, ), + icon: const Icon(Icons.sort_rounded), + tooltip: t.bookmarks.filterSort, + ), + PopupMenuButton( + itemBuilder: (context) => [ + PopupMenuItem( + onTap: () => + ref.read(bookmarksProvider.notifier).pushRoute(RoutesPaths.archivedBookmarks, tabletMode), + child: Row( + children: [ + const Icon(Icons.archive_rounded), + const SizedBox(width: 16), + Text(t.bookmarks.archived), + ], + ), + ), + PopupMenuItem( + onTap: () => + ref.read(bookmarksProvider.notifier).pushRoute(RoutesPaths.sharedBookmarks, tabletMode), + child: Row( + children: [ + const Icon(Icons.share_rounded), + const SizedBox(width: 16), + Text(t.bookmarks.shared), + ], + ), + ), + const PopupMenuDivider(height: 1), + PopupMenuItem( + onTap: () => ref.read(bookmarksProvider.notifier).pushRoute(RoutesPaths.tags, tabletMode), + child: Row( + children: [ + const Icon(Icons.label_rounded), + const SizedBox(width: 16), + Text(t.tags.tags), + ], + ), + ), + const PopupMenuDivider(height: 1), + PopupMenuItem( + onTap: () => ref.read(bookmarksProvider.notifier).pushRoute(RoutesPaths.settings, tabletMode), + child: Row( + children: [ + const Icon(Icons.settings_rounded), + const SizedBox(width: 16), + Text(t.settings.settings), + ], + ), + ), + ], + ), + const SizedBox(width: 8), ], ), - actions: [ - IconButton( - key: _searchButtonKey, - onPressed: openSearchModal, - icon: const Icon(Icons.search_rounded), - tooltip: t.bookmarks.search.searchBookmarks, - ), - IconButton( - onPressed: () => showModalBottomSheet( - context: context, - useRootNavigator: true, - builder: (context) => const VisualizationModal(), - isScrollControlled: true, - ), - icon: const Icon(Icons.sort_rounded), - tooltip: t.bookmarks.filterSort, - ), - PopupMenuButton( - itemBuilder: (context) => [ - PopupMenuItem( - onTap: () => ref.read(routerProvider).push(RoutesPaths.archivedBookmarks), - child: Row( - children: [ - const Icon(Icons.archive_rounded), - const SizedBox(width: 16), - Text(t.bookmarks.archived), - ], - ), - ), - PopupMenuItem( - onTap: () => ref.read(routerProvider).push(RoutesPaths.sharedBookmarks), - child: Row( - children: [ - const Icon(Icons.share_rounded), - const SizedBox(width: 16), - Text(t.bookmarks.shared), - ], - ), - ), - const PopupMenuDivider(height: 1), - PopupMenuItem( - onTap: () => ref.read(routerProvider).push(RoutesPaths.tags), - child: Row( - children: [ - const Icon(Icons.label_rounded), - const SizedBox(width: 16), - Text(t.tags.tags), - ], - ), - ), - const PopupMenuDivider(height: 1), - PopupMenuItem( - onTap: () => ref.read(routerProvider).push(RoutesPaths.settings), - child: Row( - children: [ - const Icon(Icons.settings_rounded), - const SizedBox(width: 16), - Text(t.settings.settings), - ], - ), - ), - ], - ), - const SizedBox(width: 8), - ], ), - ), - ], - body: SafeArea( - top: false, - bottom: true, - child: Builder( - builder: (context) => RefreshIndicator( - displacement: 120, - onRefresh: () => ref.read(bookmarksProvider.notifier).refresh(), - child: NotificationListener( - onNotification: scrollListener, - child: CustomScrollView( - slivers: [ - SliverOverlapInjector( - handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), - ), - if (bookmarks.inialLoadStatus == LoadStatus.loading) - const SliverFillRemaining( - child: Center(child: CircularProgressIndicator()), + ], + body: SafeArea( + top: false, + bottom: true, + child: Builder( + builder: (context) => RefreshIndicator( + displacement: 120, + onRefresh: () => ref.read(bookmarksProvider.notifier).refresh(), + child: NotificationListener( + onNotification: scrollListener, + child: CustomScrollView( + slivers: [ + SliverOverlapInjector( + handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context), ), - if (bookmarks.inialLoadStatus == LoadStatus.error) - SliverFillRemaining( - child: ErrorScreen( - error: t.bookmarks.cannotLoadBookmarks, + if (bookmarks.inialLoadStatus == LoadStatus.loading) + const SliverFillRemaining( + child: Center(child: CircularProgressIndicator()), ), - ), - if (bookmarks.bookmarks.isEmpty) - SliverFillRemaining( - child: NoDataScreen( - message: t.bookmarks.noBookmarksAdded, + if (bookmarks.inialLoadStatus == LoadStatus.error) + SliverFillRemaining( + child: ErrorScreen( + error: t.bookmarks.cannotLoadBookmarks, + ), ), - ), - if (bookmarks.bookmarks.isNotEmpty) - SlidableAutoCloseBehavior( - child: SliverList.builder( - itemCount: bookmarks.bookmarks.length + 1, - itemBuilder: (context, index) { - // index == bookmarks.value!.content!.results!.length -> itemCount + 1 - if (index == bookmarks.bookmarks.length) { - if (bookmarks.loadingMore) { - return const SizedBox( - height: 80, - child: Center( - child: CircularProgressIndicator(), - ), - ); + if (bookmarks.bookmarks.isEmpty) + SliverFillRemaining( + child: NoDataScreen( + message: t.bookmarks.noBookmarksAdded, + ), + ), + if (bookmarks.bookmarks.isNotEmpty) + SlidableAutoCloseBehavior( + child: SliverList.builder( + itemCount: bookmarks.bookmarks.length + 1, + itemBuilder: (context, index) { + // index == bookmarks.value!.content!.results!.length -> itemCount + 1 + if (index == bookmarks.bookmarks.length) { + if (bookmarks.loadingMore) { + return const SizedBox( + height: 80, + child: Center( + child: CircularProgressIndicator(), + ), + ); + } + // Bottom gap for FAB + return const SizedBox(height: 80); } - // Bottom gap for FAB - return const SizedBox(height: 80); - } - return BookmarkItem( - bookmark: bookmarks.bookmarks[index], - onSelect: (b) => ref.read(bookmarksProvider.notifier).selectBookmark(b, width), - onReadUnread: ref.read(bookmarksProvider.notifier).markAsReadUnread, - onDelete: (bookmark) => showDialog( - context: context, - builder: (context) => DeleteBookmarkModal( - bookmark: bookmark, - onDelete: ref.read(bookmarksProvider.notifier).deleteBookmark, + return BookmarkItem( + bookmark: bookmarks.bookmarks[index], + onSelect: (b) => ref.read(bookmarksProvider.notifier).selectBookmark(b, width), + onReadUnread: ref.read(bookmarksProvider.notifier).markAsReadUnread, + onDelete: (bookmark) => showDialog( + context: context, + builder: (context) => DeleteBookmarkModal( + bookmark: bookmark, + onDelete: ref.read(bookmarksProvider.notifier).deleteBookmark, + ), ), - ), - onArchiveUnarchive: ref.read(bookmarksProvider.notifier).archiveUnarchive, - onShareInternally: ref.read(bookmarksProvider.notifier).shareUnshare, - onEdit: (b) => openBookmarkFormModal(context: context, width: width, bookmark: b), - selected: bookmarks.bookmarks[index] == bookmarks.selectedBookmark, - tabletMode: tabletMode, - ); - }, + onArchiveUnarchive: ref.read(bookmarksProvider.notifier).archiveUnarchive, + onShareInternally: ref.read(bookmarksProvider.notifier).shareUnshare, + onEdit: (b) => openBookmarkFormModal(context: context, width: width, bookmark: b), + selected: bookmarks.bookmarks[index] == bookmarks.selectedBookmark, + tabletMode: tabletMode, + ); + }, + ), ), - ), - ], + ], + ), ), ), ), ), ), - ), - floatingActionButton: FloatingActionButton( - onPressed: () => openBookmarkFormModal(context: context, width: width), - child: const Icon(Icons.add_rounded), + floatingActionButton: FloatingActionButton( + onPressed: () => openBookmarkFormModal(context: context, width: width), + child: const Icon(Icons.add_rounded), + ), ), ); } diff --git a/lib/screens/bookmarks/ui/search_bookmarks.dart b/lib/screens/bookmarks/ui/search_bookmarks.dart index 8d37541..7390ba4 100644 --- a/lib/screens/bookmarks/ui/search_bookmarks.dart +++ b/lib/screens/bookmarks/ui/search_bookmarks.dart @@ -6,7 +6,6 @@ import 'package:linkdy/screens/bookmarks/provider/search_bookmarks.provider.dart import 'package:linkdy/screens/bookmarks/ui/bookmark_form_modal.dart'; import 'package:linkdy/screens/bookmarks/ui/bookmark_item.dart'; import 'package:linkdy/screens/bookmarks/ui/delete_bookmark_modal.dart'; -import 'package:linkdy/screens/webview/ui/webview.dart'; import 'package:linkdy/widgets/enter_search_term_screen.dart'; import 'package:linkdy/widgets/no_data_screen.dart'; import 'package:linkdy/widgets/error_screen.dart'; @@ -37,18 +36,13 @@ class SearchBookmarksModal extends ConsumerWidget { return Row( children: [ const Expanded(flex: 2, child: _List(tabletMode: true)), - if (ref.watch(searchBookmarksProvider).selectedBookmark != null) - Expanded( - flex: 3, - child: WebViewScreen(bookmark: ref.watch(searchBookmarksProvider).selectedBookmark!), - ), - if (ref.watch(searchBookmarksProvider).selectedBookmark == null) - Expanded( - flex: 3, - child: Container( - color: Theme.of(context).colorScheme.primaryContainer.withOpacity(0.2), - ), + Expanded( + flex: 3, + child: Material( + color: Theme.of(context).colorScheme.primaryContainer.withOpacity(0.2), + child: Router.withConfig(config: ref.watch(searchBookmarksProvider).webViewRouter), ), + ), ], ); } else { diff --git a/lib/screens/filtered_bookmarks/model/filtered_bookmarks.model.dart b/lib/screens/filtered_bookmarks/model/filtered_bookmarks.model.dart index 23d7a0a..02ec4e1 100644 --- a/lib/screens/filtered_bookmarks/model/filtered_bookmarks.model.dart +++ b/lib/screens/filtered_bookmarks/model/filtered_bookmarks.model.dart @@ -1,3 +1,5 @@ +import 'package:go_router/go_router.dart'; + import 'package:linkdy/config/options.dart'; import 'package:linkdy/constants/enums.dart'; import 'package:linkdy/models/data/bookmarks.dart'; @@ -14,6 +16,7 @@ class FilteredBookmarksModel { int maxNumber; bool loadingMore; Bookmark? selectedBookmark; + final GoRouter webViewRouter; FilteredBookmarksModel({ this.filteredBookmarksMode = FilteredBookmarksMode.shared, @@ -26,5 +29,6 @@ class FilteredBookmarksModel { this.maxNumber = 0, this.loadingMore = false, this.selectedBookmark, + required this.webViewRouter, }); } diff --git a/lib/screens/filtered_bookmarks/provider/filtered_bookmarks.provider.dart b/lib/screens/filtered_bookmarks/provider/filtered_bookmarks.provider.dart index 6834b17..fdcf6b2 100644 --- a/lib/screens/filtered_bookmarks/provider/filtered_bookmarks.provider.dart +++ b/lib/screens/filtered_bookmarks/provider/filtered_bookmarks.provider.dart @@ -1,5 +1,8 @@ +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/favicon_loader.provider.dart'; import 'package:linkdy/screens/bookmarks/provider/common_functions.dart'; import 'package:linkdy/screens/bookmarks/provider/bookmarks.provider.dart'; @@ -123,12 +126,29 @@ FutureOr filteredBookmarksRequestLoadMore(TagBookmarksRequestLoadMoreRef r ref.read(filteredBookmarksProvider.notifier).setLoadingMore(false); } +const _webViewRoute = "wb"; +const _webViewRoutePath = "/wb"; + @riverpod class FilteredBookmarks extends _$FilteredBookmarks { @override FilteredBookmarksModel build() { return FilteredBookmarksModel( bookmarks: [], + webViewRouter: GoRouter( + routes: [ + GoRoute( + path: "/", + builder: (context, state) => const SizedBox(), + routes: [ + GoRoute( + path: _webViewRoute, + builder: (context, state) => WebViewScreen(bookmark: state.extra as Bookmark), + ), + ], + ), + ], + ), ); } @@ -159,6 +179,8 @@ class FilteredBookmarks extends _$FilteredBookmarks { ref.watch(routerProvider).push(RoutesPaths.webview, extra: bookmark); } else if (width <= Sizes.tabletBreakpoint && ref.watch(appStatusProvider).useInAppBrowser == false) { openUrl(bookmark.url!); + } else if (bookmark != state.selectedBookmark) { + state.webViewRouter.go(_webViewRoutePath, extra: bookmark); } state.selectedBookmark = bookmark; ref.notifyListeners(); diff --git a/lib/screens/filtered_bookmarks/provider/filtered_bookmarks.provider.g.dart b/lib/screens/filtered_bookmarks/provider/filtered_bookmarks.provider.g.dart index 2bc0d1f..a447a95 100644 --- a/lib/screens/filtered_bookmarks/provider/filtered_bookmarks.provider.g.dart +++ b/lib/screens/filtered_bookmarks/provider/filtered_bookmarks.provider.g.dart @@ -372,7 +372,7 @@ final filteredBookmarksRequestLoadMoreProvider = typedef FilteredBookmarksRequestLoadMoreRef = AutoDisposeFutureProviderRef; -String _$filteredBookmarksHash() => r'584c9ee245200f653d43b10d807860dcbac68ff5'; +String _$filteredBookmarksHash() => r'e58baf5c41c61233e76edea16830f1a47d6a645a'; /// See also [FilteredBookmarks]. @ProviderFor(FilteredBookmarks) diff --git a/lib/screens/filtered_bookmarks/ui/filtered_bookmarks.dart b/lib/screens/filtered_bookmarks/ui/filtered_bookmarks.dart index edcba40..f3e2515 100644 --- a/lib/screens/filtered_bookmarks/ui/filtered_bookmarks.dart +++ b/lib/screens/filtered_bookmarks/ui/filtered_bookmarks.dart @@ -82,16 +82,12 @@ class FilteredBookmarksScreen extends HookConsumerWidget { tabletMode: true, ), ), - if (ref.watch(filteredBookmarksProvider).selectedBookmark != null) - Expanded( - flex: 3, - child: WebViewScreen(bookmark: ref.watch(filteredBookmarksProvider).selectedBookmark!), - ), - if (ref.watch(filteredBookmarksProvider).selectedBookmark == null) - const Expanded( - flex: 3, - child: SizedBox(), + Expanded( + flex: 3, + child: Material( + child: Router.withConfig(config: ref.watch(filteredBookmarksProvider).webViewRouter), ), + ), ], ), ); diff --git a/lib/screens/webview/provider/webview.provider.dart b/lib/screens/webview/provider/webview.provider.dart index f336e34..69a4433 100644 --- a/lib/screens/webview/provider/webview.provider.dart +++ b/lib/screens/webview/provider/webview.provider.dart @@ -46,4 +46,9 @@ class WebView extends _$WebView { state.canGoForward = value; ref.notifyListeners(); } + + void loadNewUrl(String url) { + ref.invalidateSelf(); + state.webViewController.loadRequest(Uri.parse(url)); + } } diff --git a/lib/screens/webview/provider/webview.provider.g.dart b/lib/screens/webview/provider/webview.provider.g.dart index e45e13a..ccd84d6 100644 --- a/lib/screens/webview/provider/webview.provider.g.dart +++ b/lib/screens/webview/provider/webview.provider.g.dart @@ -6,7 +6,7 @@ part of 'webview.provider.dart'; // RiverpodGenerator // ************************************************************************** -String _$webViewHash() => r'5b2504eb96acedfbc82e8c6747821db864221bee'; +String _$webViewHash() => r'ae307e7a5014a44777bd6af7fd9cae7f96970610'; /// See also [WebView]. @ProviderFor(WebView) diff --git a/lib/screens/webview/ui/webview.dart b/lib/screens/webview/ui/webview.dart index 3d19c4a..4e06c41 100644 --- a/lib/screens/webview/ui/webview.dart +++ b/lib/screens/webview/ui/webview.dart @@ -24,124 +24,121 @@ class WebViewScreen extends HookConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { useEffect( () { - ref.read(webViewProvider).webViewController.loadRequest(Uri.parse(bookmark.url!)); + ref.read(webViewProvider.notifier).loadNewUrl(bookmark.url!); return null; }, [bookmark], ); - return ScaffoldMessenger( - key: ScaffoldMessengerKeys.webview, - child: Scaffold( - appBar: AppBar( - elevation: 3, - title: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - bookmark.title != "" ? bookmark.title! : bookmark.websiteTitle!, - style: const TextStyle(fontSize: 14), + return Scaffold( + appBar: AppBar( + elevation: 3, + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + bookmark.title != "" ? bookmark.title! : bookmark.websiteTitle!, + style: const TextStyle(fontSize: 14), + ), + const SizedBox(height: 4), + Text( + bookmark.url!, + style: TextStyle( + fontSize: 12, + color: Theme.of(context).colorScheme.onSurfaceVariant, ), - const SizedBox(height: 4), - Text( - bookmark.url!, - style: TextStyle( - fontSize: 12, - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - ], - ), - bottom: PreferredSize( - preferredSize: const Size(double.maxFinite, 0), - child: ref.watch(webViewProvider).loadProgress < 100 - ? const LinearProgressIndicator() - : const SizedBox( - height: 4, - ), - ), + ), + ], ), - body: SafeArea( - child: Column( - children: [ - Expanded( - child: WebViewWidget( - controller: ref.watch(webViewProvider).webViewController, + bottom: PreferredSize( + preferredSize: const Size(double.maxFinite, 0), + child: ref.watch(webViewProvider).loadProgress < 100 + ? const LinearProgressIndicator() + : const SizedBox( + height: 4, ), + ), + ), + body: SafeArea( + child: Column( + children: [ + Expanded( + child: WebViewWidget( + controller: ref.watch(webViewProvider).webViewController, ), - Padding( - padding: const EdgeInsets.all(8.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - IconButton( - onPressed: ref.watch(webViewProvider).canGoBack == true - ? () => ref.watch(webViewProvider).webViewController.goBack() - : null, - icon: const Icon(Icons.arrow_back_rounded), - tooltip: t.webview.goForward, + ), + Padding( + padding: const EdgeInsets.all(8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + IconButton( + onPressed: ref.watch(webViewProvider).canGoBack == true + ? () => ref.watch(webViewProvider).webViewController.goBack() + : null, + icon: const Icon(Icons.arrow_back_rounded), + tooltip: t.webview.goForward, + ), + const SizedBox(width: 8), + IconButton( + onPressed: ref.watch(webViewProvider).canGoForward == true + ? () => ref.watch(webViewProvider).webViewController.goForward() + : null, + icon: const Icon(Icons.arrow_forward_rounded), + tooltip: t.webview.goForward, + ), + const SizedBox(width: 16), + IconButton( + onPressed: () => ref.watch(webViewProvider).webViewController.reload(), + icon: const Icon(Icons.refresh_rounded), + tooltip: t.webview.reload, + ), + ], + ), + PopupMenuButton( + itemBuilder: (context) => [ + PopupMenuItem( + onTap: () => Share.shareUri(Uri.parse(bookmark.url!)), + child: Row( + children: [ + const Icon(Icons.share_rounded), + const SizedBox(width: 12), + Flexible(child: Text(t.webview.share)), + ], ), - const SizedBox(width: 8), - IconButton( - onPressed: ref.watch(webViewProvider).canGoForward == true - ? () => ref.watch(webViewProvider).webViewController.goForward() - : null, - icon: const Icon(Icons.arrow_forward_rounded), - tooltip: t.webview.goForward, + ), + PopupMenuItem( + onTap: () => copyToClipboard( + key: ScaffoldMessengerKeys.webview, + value: bookmark.url!, + successMessage: t.webview.linkCopiedClipboard, ), - const SizedBox(width: 16), - IconButton( - onPressed: () => ref.watch(webViewProvider).webViewController.reload(), - icon: const Icon(Icons.refresh_rounded), - tooltip: t.webview.reload, + child: Row( + children: [ + const Icon(Icons.copy_rounded), + const SizedBox(width: 12), + Flexible(child: Text(t.webview.copyLinkClipboard)), + ], ), - ], - ), - PopupMenuButton( - itemBuilder: (context) => [ - PopupMenuItem( - onTap: () => Share.shareUri(Uri.parse(bookmark.url!)), - child: Row( - children: [ - const Icon(Icons.share_rounded), - const SizedBox(width: 12), - Flexible(child: Text(t.webview.share)), - ], - ), + ), + PopupMenuItem( + onTap: () => openUrl(bookmark.url!), + child: Row( + children: [ + const Icon(Icons.open_in_browser_rounded), + const SizedBox(width: 12), + Flexible(child: Text(t.webview.openInSystemBrowser)), + ], ), - PopupMenuItem( - onTap: () => copyToClipboard( - key: ScaffoldMessengerKeys.webview, - value: bookmark.url!, - successMessage: t.webview.linkCopiedClipboard, - ), - child: Row( - children: [ - const Icon(Icons.copy_rounded), - const SizedBox(width: 12), - Flexible(child: Text(t.webview.copyLinkClipboard)), - ], - ), - ), - PopupMenuItem( - onTap: () => openUrl(bookmark.url!), - child: Row( - children: [ - const Icon(Icons.open_in_browser_rounded), - const SizedBox(width: 12), - Flexible(child: Text(t.webview.openInSystemBrowser)), - ], - ), - ), - ], - ), - ], - ), + ), + ], + ), + ], ), - ], - ), + ), + ], ), ), );