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_info.dart'; import '../data/bookmark.dart'; import '../data/browser_history.dart'; import '../data/browser_history_db.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(), "")); } } 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.clone(); break; } } notifyListeners(); } WebInfo? currentWebInfo() { return getWebInfo(index); } void goHome(WebInfo webInfo) { webInfo.url = ""; webInfo.title = 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--; } 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, ); BrowserHistoryDB.insert(browserHistory); webInfo.browserHistory = 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 { webInfo.clone(); updateWebInfo(webInfo); notifyListeners(); return true; } } return false; } } 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; } }