mirror of
https://github.com/haorendashu/nowser.git
synced 2025-12-17 01:44:19 +01:00
add quick action and desktop, bookmark add edit dialog
This commit is contained in:
BIN
assets/imgs/browser.png
Normal file
BIN
assets/imgs/browser.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
201
lib/component/bookmark_edit_dialog.dart
Normal file
201
lib/component/bookmark_edit_dialog.dart
Normal file
@@ -0,0 +1,201 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:nostr_sdk/utils/platform_util.dart';
|
||||
import 'package:nostr_sdk/utils/string_util.dart';
|
||||
import 'package:nowser/data/bookmark.dart';
|
||||
import 'package:nowser/data/bookmark_db.dart';
|
||||
import 'package:quick_actions/quick_actions.dart';
|
||||
|
||||
import '../const/base.dart';
|
||||
import '../main.dart';
|
||||
import '../util/router_util.dart';
|
||||
import '../util/table_mode_util.dart';
|
||||
import '../util/theme_util.dart';
|
||||
|
||||
class BookmarkEditDialog extends StatefulWidget {
|
||||
Bookmark bookmark;
|
||||
|
||||
BookmarkEditDialog(this.bookmark);
|
||||
|
||||
static Future<void> show(BuildContext context, Bookmark bookmark) async {
|
||||
await showDialog<String>(
|
||||
context: context,
|
||||
builder: (_context) {
|
||||
return BookmarkEditDialog(bookmark);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return _BookmarkEditDialog();
|
||||
}
|
||||
}
|
||||
|
||||
class _BookmarkEditDialog extends State<BookmarkEditDialog> {
|
||||
TextEditingController nameTextController = TextEditingController();
|
||||
|
||||
TextEditingController urlTextController = TextEditingController();
|
||||
|
||||
bool addedToIndex = false;
|
||||
|
||||
bool addedToQa = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (StringUtil.isNotBlank(widget.bookmark.title)) {
|
||||
nameTextController.text = widget.bookmark.title!;
|
||||
}
|
||||
if (StringUtil.isNotBlank(widget.bookmark.url)) {
|
||||
urlTextController.text = widget.bookmark.url!;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var themeData = Theme.of(context);
|
||||
|
||||
List<Widget> list = [];
|
||||
list.add(Container(
|
||||
margin: EdgeInsets.only(
|
||||
bottom: Base.BASE_PADDING,
|
||||
),
|
||||
child: Text(
|
||||
"Add bookmark",
|
||||
style: TextStyle(
|
||||
fontSize: themeData.textTheme.bodyLarge!.fontSize,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
list.add(Container(
|
||||
child: TextField(
|
||||
controller: nameTextController,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Name",
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
list.add(Container(
|
||||
child: TextField(
|
||||
controller: urlTextController,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Url",
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
list.add(Container(
|
||||
margin: EdgeInsets.only(top: Base.BASE_PADDING_HALF),
|
||||
child: Row(
|
||||
children: [
|
||||
Text("Add to index"),
|
||||
Expanded(
|
||||
child: Checkbox(
|
||||
value: addedToIndex,
|
||||
onChanged: (v) {
|
||||
if (v != null) {
|
||||
setState(() {
|
||||
addedToIndex = v;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
));
|
||||
|
||||
list.add(Container(
|
||||
child: Row(
|
||||
children: [
|
||||
Text("Add to quick action"),
|
||||
Expanded(
|
||||
child: Checkbox(
|
||||
value: addedToQa,
|
||||
onChanged: (v) {
|
||||
if (v != null) {
|
||||
setState(() {
|
||||
addedToQa = v;
|
||||
});
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
));
|
||||
|
||||
list.add(Container(
|
||||
margin: EdgeInsets.only(
|
||||
top: Base.BASE_PADDING * 2,
|
||||
bottom: Base.BASE_PADDING,
|
||||
),
|
||||
width: double.infinity,
|
||||
child: FilledButton(onPressed: confirm, child: Text("Confirm")),
|
||||
));
|
||||
|
||||
Widget main = Container(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: list,
|
||||
),
|
||||
);
|
||||
if (PlatformUtil.isPC() || TableModeUtil.isTableMode()) {
|
||||
main = Container(
|
||||
width: mediaDataCache.size.width / 2,
|
||||
child: main,
|
||||
);
|
||||
}
|
||||
|
||||
return Dialog(
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(Base.BASE_PADDING * 2),
|
||||
child: main,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> confirm() async {
|
||||
var title = nameTextController.text;
|
||||
var url = urlTextController.text;
|
||||
|
||||
var bookmark = Bookmark(
|
||||
title: title,
|
||||
url: url,
|
||||
id: widget.bookmark.id,
|
||||
favicon: widget.bookmark.favicon,
|
||||
weight: widget.bookmark.weight,
|
||||
createdAt: widget.bookmark.createdAt,
|
||||
addedToIndex: addedToIndex ? 1 : -1,
|
||||
addedToQa: addedToQa ? 1 : -1,
|
||||
);
|
||||
|
||||
if (bookmark.id == null) {
|
||||
await BookmarkDB.insert(bookmark);
|
||||
} else {
|
||||
await BookmarkDB.update(bookmark);
|
||||
}
|
||||
|
||||
try {
|
||||
var allQas = await BookmarkDB.allQas();
|
||||
List<ShortcutItem> qas = [];
|
||||
for (var bk in allQas) {
|
||||
if (StringUtil.isBlank(bk.title) || StringUtil.isBlank(bk.url)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
qas.add(ShortcutItem(
|
||||
type: bk.url!, localizedTitle: bk.title!, icon: 'ic_launcher'));
|
||||
quickActions.setShortcutItems(qas);
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
||||
RouterUtil.back(context);
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ class Bookmark {
|
||||
String? favicon;
|
||||
int? weight;
|
||||
int? addedToIndex;
|
||||
int? addedToQa;
|
||||
int? createdAt;
|
||||
|
||||
Bookmark(
|
||||
@@ -14,6 +15,7 @@ class Bookmark {
|
||||
this.favicon,
|
||||
this.weight,
|
||||
this.addedToIndex,
|
||||
this.addedToQa,
|
||||
this.createdAt});
|
||||
|
||||
Bookmark.fromJson(Map<String, dynamic> json) {
|
||||
@@ -23,6 +25,7 @@ class Bookmark {
|
||||
favicon = json['favicon'];
|
||||
weight = json['weight'];
|
||||
addedToIndex = json['added_to_index'];
|
||||
addedToQa = json['added_to_qa'];
|
||||
createdAt = json['created_at'];
|
||||
}
|
||||
|
||||
@@ -34,6 +37,7 @@ class Bookmark {
|
||||
data['favicon'] = this.favicon;
|
||||
data['weight'] = this.weight;
|
||||
data['added_to_index'] = this.addedToIndex;
|
||||
data['added_to_qa'] = this.addedToQa;
|
||||
data['created_at'] = this.createdAt;
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,20 @@ class BookmarkDB {
|
||||
return objs;
|
||||
}
|
||||
|
||||
static Future<List<Bookmark>> allQas({DatabaseExecutor? db}) async {
|
||||
List<Bookmark> objs = [];
|
||||
List<Object?>? arguments = [];
|
||||
db = await DB.getDB(db);
|
||||
var sql =
|
||||
"select * from bookmark where added_to_qa = 1 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(Bookmark.fromJson(json));
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
|
||||
static Future<void> deleteByIds(List<int> ids, {DatabaseExecutor? db}) async {
|
||||
var sql = "delete from bookmark where id in(";
|
||||
for (var id in ids) {
|
||||
@@ -39,4 +53,9 @@ class BookmarkDB {
|
||||
db = await DB.getDB(db);
|
||||
await db.execute(sql, ids);
|
||||
}
|
||||
|
||||
static Future update(Bookmark o, {DatabaseExecutor? db}) async {
|
||||
db = await DB.getDB(db);
|
||||
await db.update("bookmark", o.toJson(), where: "id = ?", whereArgs: [o.id]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import 'package:path/path.dart';
|
||||
import 'package:process_run/shell_run.dart';
|
||||
|
||||
class DB {
|
||||
static const _VERSION = 1;
|
||||
static const _VERSION = 2;
|
||||
|
||||
static const _dbName = "nowser.db";
|
||||
|
||||
@@ -21,14 +21,14 @@ class DB {
|
||||
}
|
||||
|
||||
try {
|
||||
_database =
|
||||
await openDatabase(path, version: _VERSION, onCreate: _onCreate);
|
||||
_database = await openDatabase(path,
|
||||
version: _VERSION, onCreate: _onCreate, onUpgrade: _onUpgrade);
|
||||
} catch (e) {
|
||||
if (Platform.isLinux) {
|
||||
// maybe it need install sqlite first, but this command need run by root.
|
||||
await run('sudo apt-get -y install libsqlite3-0 libsqlite3-dev');
|
||||
_database =
|
||||
await openDatabase(path, version: _VERSION, onCreate: _onCreate);
|
||||
_database = await openDatabase(path,
|
||||
version: _VERSION, onCreate: _onCreate, onUpgrade: _onUpgrade);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,11 +50,19 @@ class DB {
|
||||
db.execute("create index zap_log_index on zap_log (app_id);");
|
||||
|
||||
db.execute(
|
||||
"create table bookmark(id integer not null constraint bookmark_pk primary key autoincrement,title text,url text not null,favicon text,weight integer,added_to_index integer,created_at integer);");
|
||||
"create table bookmark(id integer not null constraint bookmark_pk primary key autoincrement,title text,url text not null,favicon text,weight integer,added_to_index integer, added_to_qa integer,created_at integer);");
|
||||
db.execute(
|
||||
"create table browser_history(id integer not null constraint browser_history_pk primary key autoincrement,title text,url text not null,favicon text,created_at integer);");
|
||||
}
|
||||
|
||||
static Future<void> _onUpgrade(
|
||||
Database db, int oldVersion, int newVersion) async {
|
||||
if (oldVersion == 1 && newVersion == 2) {
|
||||
db.execute(
|
||||
"alter table bookmark add added_to_qa integer after added_to_index");
|
||||
}
|
||||
}
|
||||
|
||||
static Future<Database> getCurrentDatabase() async {
|
||||
if (_database == null) {
|
||||
await init();
|
||||
|
||||
@@ -28,6 +28,7 @@ import 'package:nowser/router/me/me_router.dart';
|
||||
import 'package:nowser/router/web_tabs_select/web_tabs_select_router.dart';
|
||||
import 'package:nowser/router/web_url_input/web_url_input_router.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:quick_actions/quick_actions.dart';
|
||||
import 'package:receive_intent/receive_intent.dart' as receiveIntent;
|
||||
import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
||||
import 'package:window_manager/window_manager.dart';
|
||||
@@ -41,6 +42,7 @@ import 'provider/data_util.dart';
|
||||
import 'provider/remote_signing_provider.dart';
|
||||
import 'provider/setting_provider.dart';
|
||||
import 'util/colors_util.dart';
|
||||
import 'util/media_data_cache.dart';
|
||||
|
||||
late WebProvider webProvider;
|
||||
|
||||
@@ -58,6 +60,10 @@ late RootIsolateToken rootIsolateToken;
|
||||
|
||||
late BuildInRelayProvider buildInRelayProvider;
|
||||
|
||||
const QuickActions quickActions = QuickActions();
|
||||
|
||||
late MediaDataCache mediaDataCache;
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
|
||||
rootIsolateToken = RootIsolateToken.instance!;
|
||||
|
||||
@@ -38,15 +38,26 @@ mixin AndroidSignerMixin on PermissionCheckMixin {
|
||||
static const String PREFIX = "nostrsigner:";
|
||||
|
||||
Future<void> handleInitialIntent(BuildContext context) async {
|
||||
final intent = await receiveIntent.ReceiveIntent.getInitialIntent();
|
||||
if (intent != null) {
|
||||
// log(intent.toString());
|
||||
// log("from ${intent.fromPackageName}");
|
||||
// log("action ${intent.action}");
|
||||
// log("data ${intent.data}");
|
||||
// log("categories ${intent.categories}");
|
||||
// log("extra ${intent.extra}");
|
||||
var intent = await getInitialIntent();
|
||||
await dohandleInitialIntent(context, intent);
|
||||
}
|
||||
|
||||
Future<receiveIntent.Intent?> getInitialIntent() async {
|
||||
var intent = await receiveIntent.ReceiveIntent.getInitialIntent();
|
||||
if (intent != null) {
|
||||
log(intent.toString());
|
||||
log("from ${intent.fromPackageName}");
|
||||
log("action ${intent.action}");
|
||||
log("data ${intent.data}");
|
||||
log("categories ${intent.categories}");
|
||||
log("extra ${intent.extra}");
|
||||
}
|
||||
return intent;
|
||||
}
|
||||
|
||||
Future<void> dohandleInitialIntent(
|
||||
BuildContext context, receiveIntent.Intent? intent) async {
|
||||
if (intent != null) {
|
||||
if (StringUtil.isNotBlank(intent.data) &&
|
||||
intent.data!.startsWith(PREFIX)) {
|
||||
// This is an android signer intent
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:nostr_sdk/utils/string_util.dart';
|
||||
import 'package:nowser/component/bookmark_edit_dialog.dart';
|
||||
import 'package:nowser/data/bookmark_db.dart';
|
||||
import 'package:nowser/util/router_util.dart';
|
||||
|
||||
@@ -74,12 +75,42 @@ class WebProvider extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
void addTab() {
|
||||
webInfos.add(WebInfo(_rndId(), ""));
|
||||
void addTab({String url = ""}) {
|
||||
webInfos.add(WebInfo(_rndId(), url));
|
||||
index = webInfos.length - 1;
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void checkAndOpenUrl(String url) {
|
||||
if (!url.startsWith("http")) {
|
||||
return;
|
||||
}
|
||||
|
||||
int targetIndex = -1;
|
||||
for (var i = 0; i < webInfos.length; i++) {
|
||||
var webInfo = webInfos[i];
|
||||
if (webInfo.url.contains(url)) {
|
||||
targetIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (targetIndex > -1) {
|
||||
if (index != targetIndex) {
|
||||
index = targetIndex;
|
||||
notifyListeners();
|
||||
}
|
||||
} else {
|
||||
var _currentWebInfo = currentWebInfo();
|
||||
if (_currentWebInfo != null && _currentWebInfo.url == "") {
|
||||
_currentWebInfo.url = url;
|
||||
notifyListeners();
|
||||
} else {
|
||||
addTab(url: url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void changeIndex(WebInfo webInfo) {
|
||||
for (var i = 0; i < webInfos.length; i++) {
|
||||
var owi = webInfos[i];
|
||||
@@ -146,7 +177,7 @@ class WebProvider extends ChangeNotifier {
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
void addBookmark(WebInfo webInfo) {
|
||||
void addBookmark(BuildContext context, WebInfo webInfo) {
|
||||
if (webInfo.browserHistory == null) {
|
||||
return;
|
||||
}
|
||||
@@ -159,7 +190,8 @@ class WebProvider extends ChangeNotifier {
|
||||
bookmark.addedToIndex = -1;
|
||||
bookmark.createdAt = DateTime.now().millisecondsSinceEpoch ~/ 1000;
|
||||
|
||||
BookmarkDB.insert(bookmark);
|
||||
// BookmarkDB.insert(bookmark);
|
||||
BookmarkEditDialog.show(context, bookmark);
|
||||
}
|
||||
|
||||
void back(BuildContext context) {
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||
import 'package:flutter_pinned_shortcut_plus/flutter_pinned_shortcut_plus.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:nostr_sdk/utils/string_util.dart';
|
||||
import 'package:nowser/component/bookmark_edit_dialog.dart';
|
||||
import 'package:nowser/component/cust_state.dart';
|
||||
import 'package:nowser/component/deletable_list_mixin.dart';
|
||||
import 'package:nowser/component/url_list_item_componnet.dart';
|
||||
@@ -21,6 +28,10 @@ class _BookmarkRouter extends CustState<BookmarkRouter>
|
||||
|
||||
@override
|
||||
Future<void> onReady(BuildContext context) async {
|
||||
reload();
|
||||
}
|
||||
|
||||
Future<void> reload() async {
|
||||
bookmarks = await BookmarkDB.all();
|
||||
setState(() {});
|
||||
}
|
||||
@@ -59,6 +70,36 @@ class _BookmarkRouter extends CustState<BookmarkRouter>
|
||||
url: bookmark.url ?? "",
|
||||
);
|
||||
|
||||
List<Widget> slidableActionList = [];
|
||||
if (Platform.isAndroid) {
|
||||
slidableActionList.add(SlidableAction(
|
||||
onPressed: (context) {
|
||||
doAddPinnedShortcut(bookmark);
|
||||
},
|
||||
backgroundColor: Colors.green,
|
||||
foregroundColor: Colors.white,
|
||||
icon: Icons.add_home,
|
||||
label: 'Desktop',
|
||||
));
|
||||
}
|
||||
slidableActionList.add(SlidableAction(
|
||||
onPressed: (context) {
|
||||
doEdit(bookmark);
|
||||
},
|
||||
backgroundColor: Colors.blue,
|
||||
foregroundColor: Colors.white,
|
||||
icon: Icons.edit,
|
||||
label: 'Edit',
|
||||
));
|
||||
|
||||
main = Slidable(
|
||||
endActionPane: ActionPane(
|
||||
motion: ScrollMotion(),
|
||||
children: slidableActionList,
|
||||
),
|
||||
child: main,
|
||||
);
|
||||
|
||||
main = wrapListItem(main, onTap: () {
|
||||
RouterUtil.back(context, bookmark.url);
|
||||
}, onSelect: () {
|
||||
@@ -86,4 +127,36 @@ class _BookmarkRouter extends CustState<BookmarkRouter>
|
||||
selectedIds.clear();
|
||||
}
|
||||
}
|
||||
|
||||
final _flutterPinnedShortcutPlugin = FlutterPinnedShortcut();
|
||||
|
||||
Future<void> doAddPinnedShortcut(Bookmark bookmark) async {
|
||||
File? file;
|
||||
if (StringUtil.isNotBlank(bookmark.favicon)) {
|
||||
// use favicon as icon
|
||||
file = await DefaultCacheManager().getSingleFile(bookmark.favicon!);
|
||||
} else {
|
||||
// use default image as icon
|
||||
// file =
|
||||
print("favicon not found!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (StringUtil.isBlank(bookmark.title) ||
|
||||
StringUtil.isBlank(bookmark.url)) {
|
||||
return;
|
||||
}
|
||||
|
||||
_flutterPinnedShortcutPlugin.createPinnedShortcut(
|
||||
id: StringUtil.rndNameStr(10),
|
||||
label: bookmark.title!,
|
||||
action: bookmark.url!,
|
||||
iconAssetName: "assets/logo_android.png",
|
||||
iconUri: Uri.file(file.path).toString());
|
||||
}
|
||||
|
||||
Future<void> doEdit(Bookmark bookmark) async {
|
||||
await BookmarkEditDialog.show(context, bookmark);
|
||||
reload();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,15 +40,53 @@ class _IndexRouter extends CustState<IndexRouter>
|
||||
|
||||
// start build-in
|
||||
buildInRelayProvider.start();
|
||||
|
||||
if (PlatformUtil.isAndroid()) {
|
||||
var intent = await getInitialIntent();
|
||||
if (intent != null) {
|
||||
if (intent.categories != null &&
|
||||
intent.categories!.contains("android.intent.category.LAUNCHER") &&
|
||||
intent.extra != null &&
|
||||
intent.extra!["flutter_pinned_shortcuts"] != null) {
|
||||
var url = intent.extra!["flutter_pinned_shortcuts"];
|
||||
print("find url! $url");
|
||||
webProvider.checkAndOpenUrl(url);
|
||||
} else {
|
||||
dohandleInitialIntent(context, intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
quickActions.initialize((shortcutType) {
|
||||
print("find quickAction $shortcutType");
|
||||
webProvider.checkAndOpenUrl(shortcutType);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget doBuild(BuildContext context) {
|
||||
if (PlatformUtil.isAndroid()) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
handleInitialIntent(context);
|
||||
});
|
||||
}
|
||||
// if (PlatformUtil.isAndroid()) {
|
||||
// WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
// var intent = await getInitialIntent();
|
||||
// if (intent != null) {
|
||||
// if (intent.categories != null &&
|
||||
// intent.categories!.contains("android.intent.category.LAUNCHER") &&
|
||||
// intent.extra != null &&
|
||||
// intent.extra!["flutter_pinned_shortcuts"] != null) {
|
||||
// var url = intent.extra!["flutter_pinned_shortcuts"];
|
||||
// print("find url! $url");
|
||||
// webProvider.checkAndOpenUrl(url);
|
||||
// } else {
|
||||
// dohandleInitialIntent(context, intent);
|
||||
// }
|
||||
// }
|
||||
|
||||
// quickActions.initialize((shortcutType) {
|
||||
// print("find quickAction $shortcutType");
|
||||
// webProvider.checkAndOpenUrl(shortcutType);
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
remoteSigningProvider.updateContext(context);
|
||||
webProvider.checkBlank();
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ class _WebControlComponent extends State<WebControlComponent> {
|
||||
onTap: () {
|
||||
var webInfo = webProvider.currentWebInfo();
|
||||
if (webInfo != null) {
|
||||
webProvider.addBookmark(webInfo);
|
||||
webProvider.addBookmark(context, webInfo);
|
||||
widget.closeControl();
|
||||
}
|
||||
},
|
||||
|
||||
5
lib/util/desktop_shutcut_util.dart
Normal file
5
lib/util/desktop_shutcut_util.dart
Normal file
@@ -0,0 +1,5 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
class DesktopShutcutUtil {
|
||||
void create() {}
|
||||
}
|
||||
101
lib/util/dio_util.dart
Normal file
101
lib/util/dio_util.dart
Normal file
@@ -0,0 +1,101 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:dio/io.dart';
|
||||
import 'package:dio_cookie_manager/dio_cookie_manager.dart';
|
||||
import 'package:cookie_jar/cookie_jar.dart';
|
||||
import 'dart:convert' as convert;
|
||||
|
||||
Dio? _dio;
|
||||
var cookieJar = CookieJar();
|
||||
|
||||
class DioUtil {
|
||||
static Dio getDio() {
|
||||
if (_dio == null) {
|
||||
_dio = Dio();
|
||||
if (_dio!.httpClientAdapter is IOHttpClientAdapter) {
|
||||
(_dio!.httpClientAdapter as IOHttpClientAdapter).onHttpClientCreate =
|
||||
(client) {
|
||||
client.badCertificateCallback = (cert, host, port) {
|
||||
return true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// _dio!.options.connectTimeout = Duration(minutes: 1);
|
||||
// _dio!.options.receiveTimeout = Duration(minutes: 1);
|
||||
_dio!.options.headers["user-agent"] =
|
||||
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36";
|
||||
_dio!.options.headers["accept-encoding"] = "gzip";
|
||||
CookieManager cookieManager = CookieManager(cookieJar);
|
||||
_dio!.interceptors.add(cookieManager);
|
||||
}
|
||||
return _dio!;
|
||||
}
|
||||
|
||||
static setCookie(String link, String key, String value) {
|
||||
cookieJar.saveFromResponse(Uri.parse(link), [Cookie(key, value)]);
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>?> get(String link,
|
||||
[Map<String, dynamic>? queryParameters,
|
||||
Map<String, String>? header]) async {
|
||||
var dio = getDio();
|
||||
if (header != null) {
|
||||
dio.options.headers.addAll(header);
|
||||
}
|
||||
Response resp = await dio.get(link, queryParameters: queryParameters);
|
||||
if (resp.statusCode == 200) {
|
||||
if (resp.data is String) {
|
||||
return json.decode(resp.data);
|
||||
}
|
||||
return resp.data;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<String?> getStr(String link,
|
||||
[Map<String, dynamic>? queryParameters,
|
||||
Map<String, String>? header]) async {
|
||||
var dio = getDio();
|
||||
if (header != null) {
|
||||
dio.options.headers.addAll(header);
|
||||
}
|
||||
Response resp =
|
||||
await dio.get<String>(link, queryParameters: queryParameters);
|
||||
if (resp.statusCode == 200) {
|
||||
return resp.data;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<List<int>?> getBytes(String link,
|
||||
[Map<String, dynamic>? queryParameters,
|
||||
Map<String, String>? header]) async {
|
||||
var dio = getDio();
|
||||
if (header != null) {
|
||||
dio.options.headers.addAll(header);
|
||||
}
|
||||
Response resp =
|
||||
await dio.get<List<int>>(link, queryParameters: queryParameters);
|
||||
if (resp.statusCode == 200) {
|
||||
return resp.data;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> post(
|
||||
String link, Map<String, dynamic> parameters,
|
||||
[Map<String, String>? header]) async {
|
||||
var dio = getDio();
|
||||
if (header != null) {
|
||||
dio.options.headers.addAll(header);
|
||||
}
|
||||
Response resp = await dio.post(link, data: parameters);
|
||||
return resp.data;
|
||||
}
|
||||
}
|
||||
13
lib/util/media_data_cache.dart
Normal file
13
lib/util/media_data_cache.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class MediaDataCache {
|
||||
late Size size;
|
||||
|
||||
late EdgeInsets padding;
|
||||
|
||||
void update(BuildContext context) {
|
||||
var mediaData = MediaQuery.of(context);
|
||||
size = mediaData.size;
|
||||
padding = mediaData.padding;
|
||||
}
|
||||
}
|
||||
9
lib/util/theme_util.dart
Normal file
9
lib/util/theme_util.dart
Normal file
@@ -0,0 +1,9 @@
|
||||
// Add some support to get value from theme data.
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ThemeUtil {
|
||||
static Color getDialogCoverColor(ThemeData themeData) {
|
||||
return (themeData.textTheme.bodyMedium!.color ?? Colors.black)
|
||||
.withOpacity(0.2);
|
||||
}
|
||||
}
|
||||
42
pubspec.lock
42
pubspec.lock
@@ -271,7 +271,7 @@ packages:
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_cache_manager:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_cache_manager
|
||||
sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386"
|
||||
@@ -371,6 +371,14 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_pinned_shortcut_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_pinned_shortcut_plus
|
||||
sha256: "03d5e6bf8ca157e2b478e0b38a7bf6020b6646d8050e324fc1001f717b365e7c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.0.2"
|
||||
flutter_secure_storage:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -756,6 +764,38 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
quick_actions:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: quick_actions
|
||||
sha256: "2c1d9a91f3218b4e987a7e1e95ba0415b7f48a2cb3ffacc027a1e3d3c117223f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.8"
|
||||
quick_actions_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quick_actions_android
|
||||
sha256: "926e50d6f879287b34d21934e6c9457f0d851f554179f2a9e8136c4acd1b7062"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.18"
|
||||
quick_actions_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quick_actions_ios
|
||||
sha256: "402596dea62a1028960b93f7651ec22be0e2a91e4fbf92a1c62d3b95f8ff95a5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
quick_actions_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quick_actions_platform_interface
|
||||
sha256: "1fec7068db5122cd019e9340d3d7be5d36eab099695ef3402c7059ee058329a4"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
receive_intent:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
||||
@@ -52,6 +52,9 @@ dependencies:
|
||||
qr_code_scanner: ^1.0.1
|
||||
flutter_slidable: ^3.1.1
|
||||
window_manager: ^0.4.2
|
||||
quick_actions: ^1.0.8
|
||||
flutter_pinned_shortcut_plus: ^0.0.2
|
||||
flutter_cache_manager: ^3.4.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_launcher_icons: ^0.13.1
|
||||
|
||||
Reference in New Issue
Block a user