Files
nowser/lib/provider/web_provider.dart
2024-09-20 09:41:11 +08:00

250 lines
5.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:nostr_sdk/utils/string_util.dart';
import 'package:nowser/data/bookmark_db.dart';
import 'package:nowser/util/router_util.dart';
import '../component/webview/web_home_component.dart';
import '../component/webview/web_info.dart';
import '../data/bookmark.dart';
import '../data/browser_history.dart';
import '../data/browser_history_db.dart';
import '../router/index/index_web_component.dart';
class WebProvider extends ChangeNotifier {
int index = 0;
List<WebInfo> webInfos = [];
WebInfo? getWebInfo(int i) {
if (webInfos.length <= i) {
return null;
}
return webInfos[i];
}
WebNumInfo getWebNumInfo() {
return WebNumInfo(index, webInfos.length);
}
void checkBlank() {
if (webInfos.isEmpty) {
webInfos.add(WebInfo(_rndId(), ""));
// webInfos.add(WebInfo(_rndId(), "https://www.oschina.net/"));
// webInfos.add(WebInfo(_rndId(), "https://github.com/"));
}
}
String _rndId() {
return StringUtil.rndNameStr(10);
}
void updateWebInfo(WebInfo webInfo) {
for (var i = 0; i < webInfos.length; i++) {
var owi = webInfos[i];
if (owi.id == webInfo.id) {
webInfos[i] = webInfo;
break;
}
}
notifyListeners();
}
WebInfo? currentWebInfo() {
return getWebInfo(index);
}
void goHome(WebInfo webInfo) {
webInfo.url = "";
webInfo.title = null;
webInfo.controller = null;
webInfo.browserHistory = null;
updateWebInfo(webInfo);
}
Future<void> goBack(WebInfo webInfo) async {
if (webInfo.controller != null) {
if (await webInfo.controller!.canGoBack()) {
webInfo.controller!.goBack();
updateWebInfo(webInfo);
} else {
goHome(webInfo);
}
}
}
void addTab() {
webInfos.add(WebInfo(_rndId(), ""));
index = webInfos.length - 1;
notifyListeners();
}
void changeIndex(WebInfo webInfo) {
for (var i = 0; i < webInfos.length; i++) {
var owi = webInfos[i];
if (owi.id == webInfo.id) {
index = i;
break;
}
}
notifyListeners();
}
void closeTab(WebInfo webInfo) {
int i = 0;
for (; i < webInfos.length; i++) {
var owi = webInfos[i];
if (owi.id == webInfo.id) {
break;
}
}
if (i < index) {
index--;
}
indexWebviews.remove(webInfo.id);
webInfos.removeAt(i);
checkBlank();
notifyListeners();
}
Future<void> onLoadStop(WebInfo webInfo) async {
if (webInfo.controller == null) {
return;
}
try {
var url = await webInfo.controller!.getUrl();
if (url == null) {
return;
}
var title = await webInfo.controller!.getTitle();
var favicons = await webInfo.controller!.getFavicons();
String? favicon;
if (favicons.isNotEmpty) {
favicon = favicons.first.url.toString();
}
var browserHistory = BrowserHistory(
title: title,
favicon: favicon,
url: url.toString(),
createdAt: DateTime.now().millisecondsSinceEpoch ~/ 1000,
);
if (webInfo.browserHistory != null &&
webInfo.browserHistory!.url == url.toString()) {
return;
}
webInfo.browserHistory = browserHistory;
BrowserHistoryDB.insert(browserHistory);
updateWebInfo(webInfo);
} catch (e) {}
}
void addBookmark(WebInfo webInfo) {
if (webInfo.browserHistory == null) {
return;
}
var bookmark = Bookmark();
bookmark.title = webInfo.title;
bookmark.url = webInfo.browserHistory!.url;
bookmark.favicon = webInfo.browserHistory!.favicon;
bookmark.weight = 0;
bookmark.addedToIndex = -1;
bookmark.createdAt = DateTime.now().millisecondsSinceEpoch ~/ 1000;
BookmarkDB.insert(bookmark);
}
void back(BuildContext context) {
var webInfo = currentWebInfo();
if (webInfo != null && webInfo.controller != null) {
webInfo.controller!.goBack();
}
}
void forward(BuildContext context) {
var webInfo = currentWebInfo();
if (webInfo != null && webInfo.controller != null) {
webInfo.controller!.goForward();
}
}
void refresh(BuildContext context) {
var webInfo = currentWebInfo();
if (webInfo != null && webInfo.controller != null) {
webInfo.controller!.reload();
}
}
bool currentGoTo(String? url) {
var webInfo = currentWebInfo();
if (webInfo != null) {
return goTo(webInfo, url);
}
return false;
}
bool goTo(WebInfo webInfo, String? url) {
if (url != null && url.startsWith("http")) {
webInfo.url = url;
webInfo.title = null;
if (webInfo.controller != null) {
webInfo.controller!.loadUrl(urlRequest: URLRequest(url: WebUri(url)));
return true;
} else {
updateWebInfo(webInfo);
notifyListeners();
return true;
}
}
return false;
}
Map<String, IndexWebComponent> indexWebviews = {};
List<Widget> getIndexWebviews(BuildContext context, Function showControl) {
List<Widget> list = [];
for (var webInfo in webInfos) {
if (StringUtil.isBlank(webInfo.url)) {
list.add(WebHomeComponent(webInfo));
} else {
var indexWebComp = indexWebviews[webInfo.id];
if (indexWebComp == null) {
indexWebComp =
IndexWebComponent(webInfo, showControl, key: GlobalKey());
indexWebviews[webInfo.id] = indexWebComp;
}
list.add(indexWebComp);
}
}
return list;
}
}
class WebNumInfo {
final int index;
final int length;
WebNumInfo(this.index, this.length);
@override
bool operator ==(Object other) {
if (other is WebNumInfo) {
return other.index == index && other.length == length;
}
return false;
}
}