some code about history

This commit is contained in:
DASHU
2024-09-18 07:39:50 +08:00
parent 2c7629ab3f
commit 73e8182d7b
14 changed files with 537 additions and 55 deletions

View File

@@ -5,20 +5,20 @@ import 'package:nowser/const/app_type.dart';
import 'package:nowser/const/base.dart';
import 'package:nowser/data/app.dart';
import '../app/app_type_component.dart';
import 'app_type_component.dart';
class AuthAppInfoComponent extends StatefulWidget {
class SimpleAppInfoComponent extends StatefulWidget {
App app;
AuthAppInfoComponent({required this.app});
SimpleAppInfoComponent({required this.app});
@override
State<StatefulWidget> createState() {
return _AuthAppInfoComponent();
return _SimpleAppInfoComponent();
}
}
class _AuthAppInfoComponent extends State<AuthAppInfoComponent> {
class _SimpleAppInfoComponent extends State<SimpleAppInfoComponent> {
@override
Widget build(BuildContext context) {
var themeData = Theme.of(context);

View File

@@ -7,8 +7,8 @@ import 'package:nowser/provider/key_provider.dart';
import 'package:nowser/util/router_util.dart';
import 'package:provider/provider.dart';
import '../app/simple_app_info_component.dart';
import '../logo_component.dart';
import 'auth_app_info_component.dart';
class AuthDialogBaseComponnet extends StatefulWidget {
App app;
@@ -122,7 +122,7 @@ class _AuthDialog extends State<AuthDialogBaseComponnet> {
list.add(Container(
margin: baseMargin,
child: AuthAppInfoComponent(
child: SimpleAppInfoComponent(
app: widget.app,
),
));

View File

@@ -0,0 +1,123 @@
import 'package:flutter/material.dart';
import 'package:nowser/component/image_component.dart';
import 'package:nowser/const/base.dart';
class UrlListItemComponnet extends StatefulWidget {
String? image;
String title;
String url;
int? dateTime;
UrlListItemComponnet({
this.image,
required this.title,
required this.url,
this.dateTime,
});
@override
State<StatefulWidget> createState() {
return _UrlListItemComponnet();
}
}
class _UrlListItemComponnet extends State<UrlListItemComponnet> {
@override
Widget build(BuildContext context) {
var themeData = Theme.of(context);
var smallFontSize = themeData.textTheme.bodySmall!.fontSize;
Widget iconWidget = Icon(
Icons.image,
weight: 60,
);
if (widget.image != null) {
iconWidget = ImageComponent(
imageUrl: widget.image!,
width: 36,
height: 36,
fit: BoxFit.cover,
);
}
String host = widget.url;
try {
var uri = Uri.parse(widget.url);
host = uri.host;
} catch (e) {}
String time = "";
if (widget.dateTime != null) {
var dt = DateTime.fromMillisecondsSinceEpoch(widget.dateTime! * 1000);
time = "${dt.hour}:${dt.minute}";
}
return Container(
padding: EdgeInsets.only(
left: Base.BASE_PADDING,
right: Base.BASE_PADDING,
),
child: Row(
children: [
Container(
width: 60,
height: 60,
alignment: Alignment.center,
child: iconWidget,
),
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1, color: themeData.hintColor.withOpacity(0.5)),
),
),
child: Row(
children: [
Expanded(
child: Container(
margin: EdgeInsets.only(
top: Base.BASE_PADDING_HALF,
bottom: Base.BASE_PADDING_HALF,
),
padding: EdgeInsets.only(right: Base.BASE_PADDING_HALF),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
widget.title,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Text(
host,
style: TextStyle(
fontSize: smallFontSize,
color: themeData.hintColor,
),
),
],
),
),
),
Container(
child: Text(
time,
style: TextStyle(
color: themeData.hintColor,
),
),
),
],
),
),
),
],
),
);
}
}

View File

@@ -74,10 +74,10 @@ class _WebHomeComponent extends State<WebHomeComponent> {
), onTap: () {
RouterUtil.router(context, RouterPath.WEB_TABS);
}),
wrapBottomBtn(const Icon(Icons.space_dashboard), onTap: () {
// AuthDialog.show(context);
// AuthAppConnectDialog.show(context);
}),
// wrapBottomBtn(const Icon(Icons.space_dashboard), onTap: () {
// // AuthDialog.show(context);
// // AuthAppConnectDialog.show(context);
// }),
wrapBottomBtn(const Icon(Icons.segment), onTap: () {
// AuthDialog.show(context);
RouterUtil.router(context, RouterPath.ME);

View File

@@ -7,4 +7,5 @@ class RouterPath {
static const String APPS = "/apps";
static const String ADD_REMOTE_APP = "/addRemoteApp";
static const String APP_DETAIL = "/appDetail";
static const String HISTORY = "/history";
}

View File

@@ -14,4 +14,17 @@ class BrowserHistoryDB {
var sql = "select count(1) from browser_history";
return Sqflite.firstIntValue(await db.rawQuery(sql));
}
static Future<List<BrowserHistory>> all({DatabaseExecutor? db}) async {
List<BrowserHistory> objs = [];
List<Object?>? arguments = [];
db = await DB.getDB(db);
var sql = "select * from browser_history order by created_at desc";
List<Map<String, dynamic>> list = await db.rawQuery(sql, arguments);
for (var i = 0; i < list.length; i++) {
var json = list[i];
objs.add(BrowserHistory.fromJson(json));
}
return objs;
}
}

View File

@@ -16,6 +16,7 @@ import 'package:nowser/provider/web_provider.dart';
import 'package:nowser/router/app_detail/app_detail_router.dart';
import 'package:nowser/router/apps/add_remote_app_router.dart';
import 'package:nowser/router/apps/apps_router.dart';
import 'package:nowser/router/history/history_router.dart';
import 'package:nowser/router/index/index_router.dart';
import 'package:nowser/router/keys/keys_router.dart';
import 'package:nowser/router/me/me_router.dart';
@@ -102,6 +103,7 @@ class _MyApp extends State<MyApp> {
RouterPath.APPS: (context) => AppsRouter(),
RouterPath.ADD_REMOTE_APP: (context) => AddRemoteAppRouter(),
RouterPath.APP_DETAIL: (context) => AppDetailRouter(),
RouterPath.HISTORY: (context) => HistoryRouter(),
};
return MultiProvider(
@@ -211,6 +213,7 @@ ThemeData getLightTheme() {
labelColor: Colors.white,
unselectedLabelColor: Colors.grey[200],
),
bottomSheetTheme: BottomSheetThemeData(modalBarrierColor: Colors.red),
);
}

View File

@@ -1,6 +1,8 @@
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';
@@ -148,6 +150,55 @@ class WebProvider extends ChangeNotifier {
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 {

View File

@@ -0,0 +1,103 @@
import 'package:flutter/material.dart';
import 'package:nowser/component/cust_state.dart';
import 'package:nowser/component/url_list_item_componnet.dart';
import 'package:nowser/data/browser_history_db.dart';
import 'package:nowser/util/router_util.dart';
import '../../component/appbar_back_btn_component.dart';
import '../../const/base.dart';
import '../../data/browser_history.dart';
class HistoryRouter extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _HistoryRouter();
}
}
class _HistoryRouter extends CustState<HistoryRouter> {
List<BrowserHistory> historys = [];
@override
Future<void> onReady(BuildContext context) async {
historys = await BrowserHistoryDB.all();
setState(() {});
}
@override
Widget doBuild(BuildContext context) {
var themeData = Theme.of(context);
return Scaffold(
appBar: AppBar(
leading: AppbarBackBtnComponent(),
title: Text(
"Historys",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: themeData.textTheme.bodyLarge!.fontSize,
),
),
actions: [
// GestureDetector(
// onTap: () {},
// child: Container(
// padding: const EdgeInsets.all(Base.BASE_PADDING),
// child: Icon(Icons.delete_sweep_outlined),
// ),
// ),
],
),
body: ListView.builder(
itemBuilder: (context, index) {
if (index >= historys.length) {
return null;
}
Widget? dateWidget;
var history = historys[index];
if (index > 0) {
var preHistory = historys[index - 1];
var preDate = DateTime.fromMillisecondsSinceEpoch(
preHistory.createdAt! * 1000);
var currentDate =
DateTime.fromMillisecondsSinceEpoch(history.createdAt! * 1000);
if (preDate.day != currentDate.day) {
dateWidget = Container(
padding: EdgeInsets.only(
top: Base.BASE_PADDING, left: Base.BASE_PADDING * 2),
alignment: Alignment.centerLeft,
child: Text("${currentDate.month}-${currentDate.day}"),
);
}
}
var main = Container(
child: GestureDetector(
onTap: () {
RouterUtil.back(context, history.url);
},
child: UrlListItemComponnet(
image: history.favicon,
title: history.title ?? "",
url: history.url ?? "",
dateTime: history.createdAt,
),
),
);
if (dateWidget != null) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [dateWidget, main],
);
}
return main;
},
itemCount: historys.length,
),
);
}
}

View File

@@ -12,6 +12,7 @@ import 'package:provider/provider.dart';
import '../../component/webview/web_home_component.dart';
import '../../component/webview/webview_number_component.dart';
import 'web_control_component.dart';
class IndexWebComponent extends StatefulWidget {
int index;
@@ -97,18 +98,8 @@ class _IndexWebComponent extends State<IndexWebComponent> {
var url = await webInfo.controller!.getUrl();
var value = await RouterUtil.router(context,
RouterPath.WEB_URL_INPUT, url.toString());
if (value != null &&
value is String &&
value.startsWith("http")) {
webInfo.url = value;
webInfo.title = null;
if (webInfo.controller != null) {
webInfo.controller!.loadUrl(
urlRequest: URLRequest(
url: WebUri(value),
));
}
if (value != null && value is String) {
webProvider.goTo(webInfo, value);
}
},
behavior: HitTestBehavior.translucent,
@@ -140,7 +131,7 @@ class _IndexWebComponent extends State<IndexWebComponent> {
),
),
wrapBottomBtn(const Icon(Icons.space_dashboard),
left: 8, right: 8),
onTap: showControl, left: 8, right: 8),
wrapBottomBtn(const Icon(Icons.segment), left: 8, right: 13,
onTap: () {
RouterUtil.router(context, RouterPath.ME);
@@ -175,4 +166,14 @@ class _IndexWebComponent extends State<IndexWebComponent> {
),
);
}
showControl() {
showBottomSheet(
context: context,
showDragHandle: true,
builder: (context) {
return WebControlComponent();
},
);
}
}

View File

@@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
class WebControlBtnComponent extends StatefulWidget {
String name;
Widget icon;
Function? onTap;
WebControlBtnComponent({
required this.name,
required this.icon,
this.onTap,
});
@override
State<StatefulWidget> createState() {
return _WebControlBtnComponent();
}
}
class _WebControlBtnComponent extends State<WebControlBtnComponent> {
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
if (widget.onTap != null) {
widget.onTap!();
}
},
behavior: HitTestBehavior.translucent,
child: Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
widget.icon,
Text(widget.name),
],
),
),
);
}
}

View File

@@ -0,0 +1,126 @@
import 'package:flutter/material.dart';
import 'package:nowser/const/base.dart';
import 'package:nowser/provider/web_provider.dart';
import 'package:nowser/router/index/web_control_btn_component.dart';
import 'package:provider/provider.dart';
class WebControlComponent extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _WebControlComponent();
}
}
class _WebControlComponent extends State<WebControlComponent> {
@override
Widget build(BuildContext context) {
var webProvider = Provider.of<WebProvider>(context);
var webInfo = webProvider.currentWebInfo;
return Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: EdgeInsets.only(
left: Base.BASE_PADDING,
right: Base.BASE_PADDING,
),
child: Row(
children: [
Expanded(
child: WebControlBtnComponent(
name: "Back",
icon: Icon(
Icons.chevron_left,
size: 30,
),
onTap: () {
webProvider.back(context);
},
),
),
Expanded(
child: WebControlBtnComponent(
name: "Forward",
icon: Icon(
Icons.chevron_right,
size: 30,
),
onTap: () {
webProvider.forward(context);
},
),
),
Expanded(
child: WebControlBtnComponent(
name: "Refresh",
icon: Icon(
Icons.refresh,
size: 30,
),
onTap: () {
webProvider.refresh(context);
},
),
),
Expanded(
child: WebControlBtnComponent(
name: "Stealth",
icon: Icon(
Icons.disabled_visible_outlined,
size: 30,
),
),
),
],
),
),
Container(
padding: EdgeInsets.all(Base.BASE_PADDING),
child: Row(
children: [
Expanded(
child: WebControlBtnComponent(
name: "Bookmarks",
icon: Icon(
Icons.bookmark_border,
size: 30,
),
),
),
Expanded(
child: WebControlBtnComponent(
name: "Stars",
icon: Icon(
Icons.bookmark_add_outlined,
size: 30,
),
),
),
Expanded(
child: WebControlBtnComponent(
name: "Historys",
icon: Icon(
Icons.history,
size: 30,
),
),
),
Expanded(
child: WebControlBtnComponent(
name: "Downloads",
icon: Icon(
Icons.download,
size: 30,
),
),
),
],
),
),
],
),
);
}
}

View File

@@ -8,6 +8,7 @@ import 'package:nowser/const/router_path.dart';
import 'package:nowser/data/auth_log_db.dart';
import 'package:nowser/data/bookmark_db.dart';
import 'package:nowser/data/browser_history_db.dart';
import 'package:nowser/main.dart';
import 'package:nowser/provider/app_provider.dart';
import 'package:nowser/provider/key_provider.dart';
import 'package:nowser/router/me/me_router_log_item_component.dart';
@@ -157,6 +158,13 @@ class _MeRouter extends CustState<MeRouter> {
num: historyNum,
name: "History",
iconData: Icons.history,
onTap: () async {
var url = await RouterUtil.router(context, RouterPath.HISTORY);
print("url $url");
if (webProvider.currentGoTo(url)) {
RouterUtil.back(context);
}
},
));
webItemList.add(MeRouterWebItemComponent(
num: downloadNum,

View File

@@ -8,10 +8,13 @@ class MeRouterWebItemComponent extends StatefulWidget {
IconData iconData;
Function? onTap;
MeRouterWebItemComponent({
this.num,
required this.name,
required this.iconData,
this.onTap,
});
@override
@@ -26,7 +29,13 @@ class _MeRouterWebItemComponent extends State<MeRouterWebItemComponent> {
var themeData = Theme.of(context);
var cardColor = themeData.cardColor;
return Container(
return GestureDetector(
onTap: () {
if (widget.onTap != null) {
widget.onTap!();
}
},
child: Container(
alignment: Alignment.center,
// margin: widget.margin,
child: Container(
@@ -61,6 +70,7 @@ class _MeRouterWebItemComponent extends State<MeRouterWebItemComponent> {
],
),
),
),
);
}
}