first implementation finished
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
class ReceivedParameter {
|
||||
final String? content;
|
||||
final String? tool;
|
||||
|
||||
ReceivedParameter(this.content, this.tool);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
|
||||
class WebPageInfo {
|
||||
final Uri url;
|
||||
final String? title;
|
||||
final Favicon? favicon;
|
||||
|
||||
WebPageInfo({
|
||||
required this.url,
|
||||
required this.title,
|
||||
required this.favicon,
|
||||
});
|
||||
|
||||
factory WebPageInfo.fromJson(Map<String, dynamic> json) {
|
||||
return WebPageInfo(
|
||||
url: Uri.parse(json['url'] as String),
|
||||
title: json['title'] as String?,
|
||||
favicon: switch (json['favicon']) {
|
||||
final Map<String, dynamic> favicon => Favicon.fromMap(favicon),
|
||||
_ => null
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'url': url.toString(),
|
||||
'title': title,
|
||||
'favicon': favicon?.toJson(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import 'package:exceptions/exceptions.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:html/dom.dart';
|
||||
import 'package:html/parser.dart' as html_parser;
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:kagi_bang_bang/core/http_error_handler.dart';
|
||||
import 'package:kagi_bang_bang/domain/entities/web_page_info.dart';
|
||||
import 'package:kagi_bang_bang/features/web_view/utils/favicon_helper.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
part 'generic_website.g.dart';
|
||||
|
||||
@Riverpod(keepAlive: true)
|
||||
class GenericWebsiteService extends _$GenericWebsiteService {
|
||||
late http.Client _client;
|
||||
|
||||
@override
|
||||
void build() {
|
||||
_client = http.Client();
|
||||
}
|
||||
|
||||
static Iterable<Favicon> _extractFavicons(Uri url, Document document) sync* {
|
||||
final links = document.querySelectorAll(
|
||||
'link[rel="icon"], link[rel="shortcut icon"], link[rel="apple-touch-icon"]',
|
||||
);
|
||||
|
||||
for (final link in links) {
|
||||
final href = link.attributes['href'];
|
||||
if (href != null) {
|
||||
// Attempt to parse height and width if available
|
||||
int? height;
|
||||
int? width;
|
||||
if (link.attributes['sizes'] case final String sizes) {
|
||||
final dimensions = sizes.split('x');
|
||||
if (dimensions.length == 2) {
|
||||
height = int.tryParse(dimensions[0]);
|
||||
width = int.tryParse(dimensions[1]);
|
||||
}
|
||||
}
|
||||
|
||||
yield Favicon(
|
||||
url: WebUri.uri(url.resolve(href)),
|
||||
rel: link.attributes['rel'],
|
||||
width: width,
|
||||
height: height,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<Result<WebPageInfo>> getInfo(Uri url) async {
|
||||
return Result.fromAsync(
|
||||
() async {
|
||||
final response = await _client.get(url);
|
||||
return await compute(
|
||||
(args) {
|
||||
final document = html_parser.parse(args[0]);
|
||||
final url = Uri.parse(args[1]);
|
||||
|
||||
final title = document.querySelector('title')?.text;
|
||||
final favicon = choseFavicon(_extractFavicons(url, document));
|
||||
|
||||
return WebPageInfo(url: url, title: title, favicon: favicon)
|
||||
.toJson();
|
||||
},
|
||||
[response.body, url.toString()],
|
||||
).then(WebPageInfo.fromJson);
|
||||
},
|
||||
exceptionHandler: handleHttpError,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'generic_website.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// RiverpodGenerator
|
||||
// **************************************************************************
|
||||
|
||||
String _$genericWebsiteServiceHash() =>
|
||||
r'd3d5ec8600842eb2b7fa40f248e5e448c96e987f';
|
||||
|
||||
/// See also [GenericWebsiteService].
|
||||
@ProviderFor(GenericWebsiteService)
|
||||
final genericWebsiteServiceProvider =
|
||||
NotifierProvider<GenericWebsiteService, void>.internal(
|
||||
GenericWebsiteService.new,
|
||||
name: r'genericWebsiteServiceProvider',
|
||||
debugGetCreateSourceHash: const bool.fromEnvironment('dart.vm.product')
|
||||
? null
|
||||
: _$genericWebsiteServiceHash,
|
||||
dependencies: null,
|
||||
allTransitiveDependencies: null,
|
||||
);
|
||||
|
||||
typedef _$GenericWebsiteService = Notifier<void>;
|
||||
// ignore_for_file: type=lint
|
||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member
|
||||
Reference in New Issue
Block a user