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 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 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 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 indexWebviews = {}; List getIndexWebviews(BuildContext context, Function showControl) { List 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; } }