diff --git a/app/lib/domain/services/generic_website.dart b/app/lib/domain/services/generic_website.dart index f74d8ae4..20cb16c0 100644 --- a/app/lib/domain/services/generic_website.dart +++ b/app/lib/domain/services/generic_website.dart @@ -1,5 +1,6 @@ import 'package:bang_navigator/core/http_error_handler.dart'; import 'package:bang_navigator/domain/entities/web_page_info.dart'; +import 'package:bang_navigator/extensions/web_uri_favicon.dart'; import 'package:bang_navigator/features/web_view/utils/favicon_helper.dart'; import 'package:exceptions/exceptions.dart'; import 'package:flutter/foundation.dart'; @@ -59,7 +60,12 @@ class GenericWebsiteService extends _$GenericWebsiteService { final url = Uri.parse(args[1]); final title = document.querySelector('title')?.text; - final favicon = choseFavicon(_extractFavicons(url, document)); + final favicon = choseFavicon(_extractFavicons(url, document)) ?? + //In case the icon can not get extracted, we use the resolver + //of duckduckgo + Favicon( + url: WebUri.uri(url.genericFavicon()), + ); return WebPageInfo(url: url, title: title, favicon: favicon) .toJson(); @@ -70,4 +76,21 @@ class GenericWebsiteService extends _$GenericWebsiteService { exceptionHandler: handleHttpError, ); } + + Future> getFaviconBytes(Uri url) { + return getInfo(url).then( + (result) => result.flatMapAsync( + (info) async { + if (info.favicon != null) { + return _client + .get(info.favicon!.url) + .then((response) => response.bodyBytes); + } + + return null; + }, + exceptionHandler: handleHttpError, + ), + ); + } } diff --git a/app/lib/domain/services/generic_website.g.dart b/app/lib/domain/services/generic_website.g.dart index 0360a9c1..243fad87 100644 --- a/app/lib/domain/services/generic_website.g.dart +++ b/app/lib/domain/services/generic_website.g.dart @@ -7,7 +7,7 @@ part of 'generic_website.dart'; // ************************************************************************** String _$genericWebsiteServiceHash() => - r'd3d5ec8600842eb2b7fa40f248e5e448c96e987f'; + r'bb36adc96b55531772554e79e4f72a6f5b038c52'; /// See also [GenericWebsiteService]. @ProviderFor(GenericWebsiteService) diff --git a/app/lib/extensions/web_uri_favicon.dart b/app/lib/extensions/web_uri_favicon.dart index 4cd1ebfd..7689db60 100644 --- a/app/lib/extensions/web_uri_favicon.dart +++ b/app/lib/extensions/web_uri_favicon.dart @@ -1,6 +1,4 @@ -extension WebUriFavicon on Uri { - Uri guessFavicon() => removeFragment().replace( - path: 'favicon.ico', - queryParameters: {}, - ); +extension UriFavicon on Uri { + Uri genericFavicon() => + Uri.parse('https://icons.duckduckgo.com/ip3/$host.ico'); } diff --git a/app/lib/features/web_view/presentation/widgets/favicon.dart b/app/lib/features/web_view/presentation/widgets/favicon.dart index 2f2ff065..3402480c 100644 --- a/app/lib/features/web_view/presentation/widgets/favicon.dart +++ b/app/lib/features/web_view/presentation/widgets/favicon.dart @@ -23,7 +23,7 @@ class FaviconImage extends StatelessWidget { if (webPageInfo.favicon != null) { return FadeInImage( placeholder: NetworkImage( - webPageInfo.url.guessFavicon().toString(), + webPageInfo.url.genericFavicon().toString(), ), image: NetworkImage(webPageInfo.favicon!.url.toString()), placeholderErrorBuilder: (_, __, ___) => _iconPlaceholder, @@ -33,7 +33,7 @@ class FaviconImage extends StatelessWidget { ); } else { return Image.network( - webPageInfo.url.guessFavicon().toString(), + webPageInfo.url.genericFavicon().toString(), errorBuilder: (_, __, ___) => _iconPlaceholder, height: size, width: size,