setting page, i18n

This commit is contained in:
DASHU
2025-01-21 21:36:18 +08:00
parent 37b6c6431f
commit d6cdf8937c
39 changed files with 1968 additions and 265 deletions

3
devtools_options.yaml Normal file
View File

@@ -0,0 +1,3 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:

View File

@@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:nowser/const/app_type.dart';
import '../../generated/l10n.dart';
import '../tag_component.dart';
class AppTypeComponent extends StatefulWidget {
@@ -15,13 +16,15 @@ class AppTypeComponent extends StatefulWidget {
}
class _AppTypeComponent extends State<AppTypeComponent> {
late S s;
@override
Widget build(BuildContext context) {
String typeName = "WEB";
String typeName = s.WEB;
if (widget.appType == AppType.ANDROID_APP) {
typeName = "Android";
typeName = s.Android;
} else if (widget.appType == AppType.REMOTE) {
typeName = "Remote";
typeName = s.Remote;
}
return TagComponent(typeName);

View File

@@ -9,6 +9,7 @@ import 'package:nowser/util/router_util.dart';
import '../../const/base.dart';
import '../../data/app.dart';
import '../../generated/l10n.dart';
class AuthAppConnectDialog extends StatefulWidget {
App app;
@@ -37,10 +38,12 @@ class _AuthAppConnectDialog extends State<AuthAppConnectDialog> {
bool showDetail = false;
late S s;
@override
Widget build(BuildContext context) {
var themeData = Theme.of(context);
var baseMargin = EdgeInsets.only(
var baseMargin = const EdgeInsets.only(
top: Base.BASE_PADDING_HALF,
bottom: Base.BASE_PADDING_HALF,
);
@@ -52,24 +55,24 @@ class _AuthAppConnectDialog extends State<AuthAppConnectDialog> {
value: ConnectType.FULLY_TRUST,
groupValue: connectType,
onChanged: onConnectTypeChange,
title: Text("I fully trust it"),
subtitle: Text("Auto-sign all requests (except payments)"),
title: Text(s.Full_trust_title),
subtitle: Text(s.Full_trust_des),
));
list.add(RadioListTile(
value: ConnectType.REASONABLE,
groupValue: connectType,
onChanged: onConnectTypeChange,
title: Text("Let's be reasonable"),
subtitle: Text("Auto-approve most common requests"),
title: Text(s.Reasonable_title),
subtitle: Text(s.Reasonable_des),
));
list.add(RadioListTile(
value: ConnectType.ALWAY_REJECT,
groupValue: connectType,
onChanged: onConnectTypeChange,
title: Text("I'm a bit paranoid"),
subtitle: Text("Do not sign anything without asking me!"),
title: Text(s.Always_reject_title),
subtitle: Text(s.Always_reject_des),
));
var child = Column(
@@ -79,7 +82,7 @@ class _AuthAppConnectDialog extends State<AuthAppConnectDialog> {
return AuthDialogBaseComponnet(
app: widget.app,
title: "App Connect",
title: s.App_Connect,
onConfirm: onConfirm,
child: child,
);

View File

@@ -8,6 +8,7 @@ import 'package:nowser/main.dart';
import 'package:nowser/util/router_util.dart';
import '../../const/base.dart';
import '../../generated/l10n.dart';
class AuthDialog extends StatefulWidget {
App app;
@@ -51,46 +52,49 @@ class _AuthDialog extends State<AuthDialog> {
bool always = false;
late S s;
@override
Widget build(BuildContext context) {
var themeData = Theme.of(context);
var baseMargin = EdgeInsets.only(
var baseMargin = const EdgeInsets.only(
top: Base.BASE_PADDING_HALF,
bottom: Base.BASE_PADDING_HALF,
);
var hintColor = themeData.hintColor;
s = S.of(context);
var appName = widget.app.name;
if (StringUtil.isNotBlank(widget.app.code)) {
appName = widget.app.code;
}
// handle this title and des with widget.authType
String authTitle = "Sign Event";
String authDes = "Allow $appName to ";
String authTitle = s.Sign_Event;
String authDes = "${s.Allow} $appName ${s.to} ";
if (widget.authType == AuthType.GET_PUBLIC_KEY) {
authTitle = "Get Public Key";
authDes += "get public key";
authTitle = s.Get_Public_Key;
authDes += s.Get_Public_Key;
} else if (widget.authType == AuthType.SIGN_EVENT) {
authTitle = "Sign Event";
authDes += "sign a ${widget.eventKind} event";
authTitle = s.Sign_Event;
authDes += "${s.sign} ${s.a} ${widget.eventKind} ${s.event}";
} else if (widget.authType == AuthType.GET_RELAYS) {
authTitle = "Get Relays";
authDes += "get relays";
authTitle = s.Get_Relays;
authDes += s.Get_Relays;
} else if (widget.authType == AuthType.NIP04_ENCRYPT) {
authTitle = "Encrypt (NIP-04)";
authDes += "Encrypt (NIP-04)";
authTitle = s.Encrypt04_name;
authDes += s.Encrypt04_name;
} else if (widget.authType == AuthType.NIP04_DECRYPT) {
authTitle = "Decrypt (NIP-04)";
authDes += "Decrypt (NIP-04)";
authTitle = s.Decrypt04_name;
authDes += s.Decrypt04_name;
} else if (widget.authType == AuthType.NIP44_ENCRYPT) {
authTitle = "Encrypt (NIP-44)";
authDes += "Encrypt (NIP-44)";
authTitle = s.Encrypt44_name;
authDes += s.Encrypt44_name;
} else if (widget.authType == AuthType.NIP44_DECRYPT) {
authTitle = "Decrypt (NIP-44)";
authDes += "Decrypt (NIP-44)";
authTitle = s.Decrypt44_name;
authDes += s.Decrypt44_name;
} else if (widget.authType == AuthType.DECRYPT_ZAP_EVENT) {
authTitle = "Decrypt zap event";
authDes += "Decrypt zap event";
authTitle = s.Decrypt_zap_event;
authDes += s.Decrypt_zap_event;
}
List<Widget> list = [];
@@ -112,7 +116,7 @@ class _AuthDialog extends State<AuthDialog> {
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text("detail"),
Text(s.detail),
showDetail ? Icon(Icons.expand_less) : Icon(Icons.expand_more),
],
),
@@ -165,7 +169,7 @@ class _AuthDialog extends State<AuthDialog> {
});
},
),
Text("Always"),
Text(s.Always),
],
),
),

View File

@@ -7,6 +7,7 @@ import 'package:nowser/provider/key_provider.dart';
import 'package:nowser/util/router_util.dart';
import 'package:provider/provider.dart';
import '../../generated/l10n.dart';
import '../app/simple_app_info_component.dart';
import '../logo_component.dart';
@@ -42,14 +43,17 @@ class AuthDialogBaseComponnet extends StatefulWidget {
}
class _AuthDialog extends State<AuthDialogBaseComponnet> {
late S s;
@override
Widget build(BuildContext context) {
var themeData = Theme.of(context);
var baseMargin = EdgeInsets.only(
var baseMargin = const EdgeInsets.only(
top: Base.BASE_PADDING_HALF,
bottom: Base.BASE_PADDING_HALF,
);
var hintColor = themeData.hintColor;
s = S.of(context);
List<Widget> list = [];
@@ -158,7 +162,7 @@ class _AuthDialog extends State<AuthDialogBaseComponnet> {
RouterUtil.back(context);
}
},
child: Text("Cancel"),
child: Text(s.Cancel),
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.red),
),
@@ -171,7 +175,7 @@ class _AuthDialog extends State<AuthDialogBaseComponnet> {
onPressed: () {
widget.onConfirm();
},
child: Text("Confirm"),
child: Text(s.Confirm),
),
)
],

View File

@@ -8,6 +8,7 @@ import 'package:nowser/data/bookmark_db.dart';
import 'package:quick_actions/quick_actions.dart';
import '../const/base.dart';
import '../generated/l10n.dart';
import '../main.dart';
import '../util/router_util.dart';
import '../util/table_mode_util.dart';
@@ -61,9 +62,12 @@ class _BookmarkEditDialog extends State<BookmarkEditDialog> {
}
}
late S s;
@override
Widget build(BuildContext context) {
var themeData = Theme.of(context);
s = S.of(context);
List<Widget> list = [];
list.add(Container(
@@ -71,7 +75,7 @@ class _BookmarkEditDialog extends State<BookmarkEditDialog> {
bottom: Base.BASE_PADDING,
),
child: Text(
"Add bookmark",
s.Add_bookmark,
style: TextStyle(
fontSize: themeData.textTheme.bodyLarge!.fontSize,
fontWeight: FontWeight.bold,
@@ -83,7 +87,7 @@ class _BookmarkEditDialog extends State<BookmarkEditDialog> {
child: TextField(
controller: nameTextController,
decoration: InputDecoration(
labelText: "Name",
labelText: s.Name,
),
),
));
@@ -92,7 +96,7 @@ class _BookmarkEditDialog extends State<BookmarkEditDialog> {
child: TextField(
controller: urlTextController,
decoration: InputDecoration(
labelText: "Url",
labelText: s.Url,
),
),
));
@@ -101,7 +105,7 @@ class _BookmarkEditDialog extends State<BookmarkEditDialog> {
margin: EdgeInsets.only(top: Base.BASE_PADDING_HALF),
child: Row(
children: [
Text("Add to index"),
Text(s.Add_to_index),
Expanded(
child: Checkbox(
value: addedToIndex,
@@ -122,7 +126,7 @@ class _BookmarkEditDialog extends State<BookmarkEditDialog> {
list.add(Container(
child: Row(
children: [
Text("Add to quick action"),
Text(s.Add_to_quick_action),
Expanded(
child: Checkbox(
value: addedToQa,
@@ -146,7 +150,7 @@ class _BookmarkEditDialog extends State<BookmarkEditDialog> {
bottom: Base.BASE_PADDING,
),
width: double.infinity,
child: FilledButton(onPressed: confirm, child: Text("Confirm")),
child: FilledButton(onPressed: confirm, child: Text(s.Confirm)),
));
Widget main = Container(
@@ -187,7 +191,7 @@ class _BookmarkEditDialog extends State<BookmarkEditDialog> {
if (StringUtil.isBlank(bookmark.title) ||
StringUtil.isBlank(bookmark.url)) {
BotToast.showText(text: "Input can't be null");
BotToast.showText(text: s.Input_can_not_be_null);
return;
}

View File

@@ -0,0 +1,148 @@
import 'package:flutter/material.dart';
import '../const/base.dart';
import '../const/base_consts.dart';
import '../util/router_util.dart';
class EnumSelectorComponent extends StatelessWidget {
final List<EnumObj> list;
Widget Function(BuildContext, EnumObj)? enumItemBuild;
EnumSelectorComponent({
required this.list,
this.enumItemBuild,
});
static Future<EnumObj?> show(BuildContext context, List<EnumObj> list) async {
return await showDialog<EnumObj?>(
context: context,
useRootNavigator: false,
builder: (_context) {
return EnumSelectorComponent(
list: list,
);
},
);
}
@override
Widget build(BuildContext context) {
var themeData = Theme.of(context);
Color cardColor = themeData.cardColor;
var maxHeight = MediaQuery.of(context).size.height;
List<Widget> widgets = [];
for (var i = 0; i < list.length; i++) {
var enumObj = list[i];
if (enumItemBuild != null) {
widgets.add(enumItemBuild!(context, enumObj));
} else {
widgets.add(EnumSelectorItemComponent(
enumObj: enumObj,
isLast: i == list.length - 1,
));
}
}
Widget main = Container(
width: double.infinity,
padding: const EdgeInsets.only(
left: Base.BASE_PADDING,
right: Base.BASE_PADDING,
top: Base.BASE_PADDING_HALF,
bottom: Base.BASE_PADDING_HALF,
),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(15)),
color: cardColor,
),
constraints: BoxConstraints(
maxHeight: maxHeight * 0.8,
),
child: SingleChildScrollView(
child: Column(
mainAxisSize: MainAxisSize.min,
children: widgets,
),
),
);
return Scaffold(
backgroundColor: Colors.black.withOpacity(0.2),
body: FocusScope(
// autofocus: true,
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
RouterUtil.back(context);
},
child: Container(
width: double.infinity,
height: double.infinity,
padding: const EdgeInsets.only(
left: Base.BASE_PADDING,
right: Base.BASE_PADDING,
),
child: GestureDetector(
onTap: () {},
child: main,
),
alignment: Alignment.center,
),
),
),
);
}
}
class EnumSelectorItemComponent extends StatelessWidget {
static const double HEIGHT = 44;
final EnumObj enumObj;
final bool isLast;
Function(EnumObj)? onTap;
Color? color;
EnumSelectorItemComponent({
required this.enumObj,
this.isLast = false,
this.onTap,
this.color,
});
@override
Widget build(BuildContext context) {
var themeData = Theme.of(context);
var dividerColor = themeData.dividerColor;
Widget main = Container(
padding: const EdgeInsets.only(
left: Base.BASE_PADDING + 5, right: Base.BASE_PADDING + 5),
child: Text(enumObj.name),
);
return GestureDetector(
onTap: () {
if (onTap != null) {
onTap!(enumObj);
} else {
RouterUtil.back(context, enumObj);
}
},
child: Container(
decoration: BoxDecoration(
color: color,
border:
isLast ? null : Border(bottom: BorderSide(color: dividerColor)),
),
alignment: Alignment.center,
height: HEIGHT,
child: main,
),
);
}
}

View File

@@ -36,12 +36,15 @@ class _TextInputDialogInnerComponent
controller = TextEditingController(text: widget.value);
}
late S s;
@override
Widget build(BuildContext context) {
var themeData = Theme.of(context);
Color cardColor = themeData.cardColor;
var mainColor = themeData.primaryColor;
var titleFontSize = themeData.textTheme.bodyLarge!.fontSize;
s = S.of(context);
List<Widget> list = [];
@@ -74,7 +77,7 @@ class _TextInputDialogInnerComponent
width: double.infinity,
child: FilledButton(
onPressed: _onConfirm,
child: Text("Confirm"),
child: Text(s.Confirm),
),
));

View File

@@ -6,6 +6,7 @@ import 'package:nowser/main.dart';
import 'package:nowser/util/router_util.dart';
import '../../const/base.dart';
import '../../generated/l10n.dart';
class UserLoginDialog extends StatefulWidget {
static Future<void> show(BuildContext context) async {
@@ -27,15 +28,18 @@ class _UserLoginDialog extends State<UserLoginDialog> {
TextEditingController controller = TextEditingController();
late S s;
@override
Widget build(BuildContext context) {
var themeData = Theme.of(context);
s = S.of(context);
List<Widget> list = [];
list.add(Container(
margin: EdgeInsets.only(bottom: Base.BASE_PADDING * 2),
child: Text(
"Login",
s.Login,
style: TextStyle(
fontSize: themeData.textTheme.bodyLarge!.fontSize,
fontWeight: FontWeight.bold,
@@ -74,7 +78,7 @@ class _UserLoginDialog extends State<UserLoginDialog> {
list.add(Container(
margin: EdgeInsets.only(bottom: Base.BASE_PADDING * 2),
width: double.infinity,
child: FilledButton(onPressed: confirm, child: Text("Confirm")),
child: FilledButton(onPressed: confirm, child: Text(s.Confirm)),
));
list.add(GestureDetector(
@@ -84,7 +88,7 @@ class _UserLoginDialog extends State<UserLoginDialog> {
},
child: Container(
child: Text(
"Generate a private key",
s.Generate_a_private_key,
style: TextStyle(
decoration: TextDecoration.underline,
),

View File

@@ -64,33 +64,33 @@ class _WebViewComponent extends State<WebViewComponent>
void initState() {
super.initState();
contextMenu = ContextMenu(
menuItems: [
ContextMenuItem(
id: 1,
title: "Special",
action: () async {
print("Menu item Special clicked!");
print(await webViewController?.getSelectedText());
await webViewController?.clearFocus();
})
],
settings: ContextMenuSettings(hideDefaultSystemContextMenuItems: false),
onCreateContextMenu: (hitTestResult) async {
print("onCreateContextMenu");
print(hitTestResult.extra);
print(await webViewController?.getSelectedText());
},
onHideContextMenu: () {
print("onHideContextMenu");
},
onContextMenuActionItemClicked: (contextMenuItemClicked) async {
var id = contextMenuItemClicked.id;
print("onContextMenuActionItemClicked: " +
id.toString() +
" " +
contextMenuItemClicked.title);
});
// contextMenu = ContextMenu(
// menuItems: [
// ContextMenuItem(
// id: 1,
// title: "Special",
// action: () async {
// print("Menu item Special clicked!");
// print(await webViewController?.getSelectedText());
// await webViewController?.clearFocus();
// })
// ],
// settings: ContextMenuSettings(hideDefaultSystemContextMenuItems: false),
// onCreateContextMenu: (hitTestResult) async {
// print("onCreateContextMenu");
// print(hitTestResult.extra);
// print(await webViewController?.getSelectedText());
// },
// onHideContextMenu: () {
// print("onHideContextMenu");
// },
// onContextMenuActionItemClicked: (contextMenuItemClicked) async {
// var id = contextMenuItemClicked.id;
// print("onContextMenuActionItemClicked: " +
// id.toString() +
// " " +
// contextMenuItemClicked.title);
// });
pullToRefreshController = kIsWeb ||
![TargetPlatform.iOS, TargetPlatform.android]

View File

@@ -10,4 +10,5 @@ class RouterPath {
static const String HISTORY = "/history";
static const String BOOKMARK = "/bookmark";
static const String AUTH_LOGS = "/authLogs";
static const String SETTING = "/setting";
}

View File

@@ -17,16 +17,20 @@ import 'package:intl/message_lookup_by_library.dart';
import 'package:intl/src/intl_helpers.dart';
import 'messages_en.dart' as messages_en;
import 'messages_zh.dart' as messages_zh;
typedef Future<dynamic> LibraryLoader();
Map<String, LibraryLoader> _deferredLibraries = {
'en': () => new SynchronousFuture(null),
'zh': () => new SynchronousFuture(null),
};
MessageLookupByLibrary? _findExact(String localeName) {
switch (localeName) {
case 'en':
return messages_en.messages;
case 'zh':
return messages_zh.messages;
default:
return null;
}

View File

@@ -21,5 +21,110 @@ class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'en';
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{};
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
"About": MessageLookupByLibrary.simpleMessage("About"),
"About_Me": MessageLookupByLibrary.simpleMessage("About Me"),
"Add_Remote_App":
MessageLookupByLibrary.simpleMessage("Add Remote App"),
"Add_bookmark": MessageLookupByLibrary.simpleMessage("Add bookmark"),
"Add_to_index": MessageLookupByLibrary.simpleMessage("Add to index"),
"Add_to_quick_action":
MessageLookupByLibrary.simpleMessage("Add to quick action"),
"Allow": MessageLookupByLibrary.simpleMessage("Allow"),
"Alway_reject": MessageLookupByLibrary.simpleMessage("Alway reject"),
"Always": MessageLookupByLibrary.simpleMessage("Always"),
"Always_Allow": MessageLookupByLibrary.simpleMessage("Always Allow"),
"Always_Reject": MessageLookupByLibrary.simpleMessage("Always Reject"),
"Always_reject_des": MessageLookupByLibrary.simpleMessage(
"Do not sign anything without asking me!"),
"Always_reject_title":
MessageLookupByLibrary.simpleMessage("I\'m a bit paranoid"),
"Android": MessageLookupByLibrary.simpleMessage("Android"),
"App_Connect": MessageLookupByLibrary.simpleMessage("App Connect"),
"App_Detail": MessageLookupByLibrary.simpleMessage("App Detail"),
"Approve": MessageLookupByLibrary.simpleMessage("Approve"),
"Apps_Manager": MessageLookupByLibrary.simpleMessage("Apps Manager"),
"Auth_Logs": MessageLookupByLibrary.simpleMessage("Auth Logs"),
"Back": MessageLookupByLibrary.simpleMessage("Back"),
"Bookmarks": MessageLookupByLibrary.simpleMessage("Bookmarks"),
"Cancel": MessageLookupByLibrary.simpleMessage("Cancel"),
"Click_and_Login":
MessageLookupByLibrary.simpleMessage("Click and Login"),
"Close_Edit": MessageLookupByLibrary.simpleMessage("Close Edit"),
"Comming_soon": MessageLookupByLibrary.simpleMessage("Comming soon..."),
"Confirm": MessageLookupByLibrary.simpleMessage("Confirm"),
"ConnectType": MessageLookupByLibrary.simpleMessage("ConnectType"),
"Connect_by": MessageLookupByLibrary.simpleMessage("Connect by"),
"Copy_success": MessageLookupByLibrary.simpleMessage("Copy success"),
"Dark": MessageLookupByLibrary.simpleMessage("Dark"),
"Decrypt04_name":
MessageLookupByLibrary.simpleMessage("Decrypt (NIP-04)"),
"Decrypt44_name":
MessageLookupByLibrary.simpleMessage("Decrypt (NIP-44)"),
"Decrypt_zap_event":
MessageLookupByLibrary.simpleMessage("Decrypt zap event"),
"Desktop": MessageLookupByLibrary.simpleMessage("Desktop"),
"Downloads": MessageLookupByLibrary.simpleMessage("Downloads"),
"Edit": MessageLookupByLibrary.simpleMessage("Edit"),
"Encrypt04_name":
MessageLookupByLibrary.simpleMessage("Encrypt (NIP-04)"),
"Encrypt44_name":
MessageLookupByLibrary.simpleMessage("Encrypt (NIP-44)"),
"EventKind": MessageLookupByLibrary.simpleMessage("EventKind"),
"Follow_System": MessageLookupByLibrary.simpleMessage("Follow System"),
"Forward": MessageLookupByLibrary.simpleMessage("Forward"),
"Full_trust_des": MessageLookupByLibrary.simpleMessage(
"Auto-sign all requests (except payments)"),
"Full_trust_title":
MessageLookupByLibrary.simpleMessage("I fully trust it"),
"Fully_trust": MessageLookupByLibrary.simpleMessage("Fully trust"),
"Generate_a_private_key":
MessageLookupByLibrary.simpleMessage("Generate a private key"),
"Get_Public_Key":
MessageLookupByLibrary.simpleMessage("Get Public Key"),
"Get_Relays": MessageLookupByLibrary.simpleMessage("Get Relays"),
"Historys": MessageLookupByLibrary.simpleMessage("Historys"),
"Input_can_not_be_null":
MessageLookupByLibrary.simpleMessage("Input can\'t be null"),
"Keys_Manager": MessageLookupByLibrary.simpleMessage("Keys Manager"),
"Language": MessageLookupByLibrary.simpleMessage("Language"),
"Light": MessageLookupByLibrary.simpleMessage("Light"),
"Local_Relay": MessageLookupByLibrary.simpleMessage("Local Relay"),
"Login": MessageLookupByLibrary.simpleMessage("Login"),
"Name": MessageLookupByLibrary.simpleMessage("Name"),
"Pendding_connect_remote_apps": MessageLookupByLibrary.simpleMessage(
"Pendding connect remote apps"),
"Privacy": MessageLookupByLibrary.simpleMessage("Privacy"),
"Pubkey": MessageLookupByLibrary.simpleMessage("Pubkey"),
"Reasonable": MessageLookupByLibrary.simpleMessage("Reasonable"),
"Reasonable_des": MessageLookupByLibrary.simpleMessage(
"Auto-approve most common requests"),
"Reasonable_title":
MessageLookupByLibrary.simpleMessage("Let\'s be reasonable"),
"Refresh": MessageLookupByLibrary.simpleMessage("Refresh"),
"Reject": MessageLookupByLibrary.simpleMessage("Reject"),
"Relay": MessageLookupByLibrary.simpleMessage("Relay"),
"Remote": MessageLookupByLibrary.simpleMessage("Remote"),
"Search_Engine": MessageLookupByLibrary.simpleMessage("Search Engine"),
"Secret": MessageLookupByLibrary.simpleMessage("Secret"),
"Setting": MessageLookupByLibrary.simpleMessage("Setting"),
"Show_more_apps":
MessageLookupByLibrary.simpleMessage("Show more apps"),
"Show_more_logs":
MessageLookupByLibrary.simpleMessage("Show more logs"),
"Sign_Event": MessageLookupByLibrary.simpleMessage("Sign Event"),
"Stars": MessageLookupByLibrary.simpleMessage("Stars"),
"Stealth": MessageLookupByLibrary.simpleMessage("Stealth"),
"ThemeStyle": MessageLookupByLibrary.simpleMessage("ThemeStyle"),
"Url": MessageLookupByLibrary.simpleMessage("Url"),
"WEB": MessageLookupByLibrary.simpleMessage("WEB"),
"a": MessageLookupByLibrary.simpleMessage("a"),
"auto": MessageLookupByLibrary.simpleMessage("auto"),
"detail": MessageLookupByLibrary.simpleMessage("detail"),
"event": MessageLookupByLibrary.simpleMessage("event"),
"no_apps_now": MessageLookupByLibrary.simpleMessage("no apps now"),
"no_logs_now": MessageLookupByLibrary.simpleMessage("no logs now"),
"sign": MessageLookupByLibrary.simpleMessage("sign"),
"to": MessageLookupByLibrary.simpleMessage("to")
};
}

View File

@@ -0,0 +1,114 @@
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
// This is a library that provides messages for a zh locale. All the
// messages from the main program should be duplicated here with the same
// function name.
// Ignore issues from commonly used lints in this file.
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
// ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes
// ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes
import 'package:intl/intl.dart';
import 'package:intl/message_lookup_by_library.dart';
final messages = new MessageLookup();
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
class MessageLookup extends MessageLookupByLibrary {
String get localeName => 'zh';
final messages = _notInlinedMessages(_notInlinedMessages);
static Map<String, Function> _notInlinedMessages(_) => <String, Function>{
"About": MessageLookupByLibrary.simpleMessage("关于"),
"About_Me": MessageLookupByLibrary.simpleMessage("关于我"),
"Add_Remote_App": MessageLookupByLibrary.simpleMessage("添加远程应用"),
"Add_bookmark": MessageLookupByLibrary.simpleMessage("添加书签"),
"Add_to_index": MessageLookupByLibrary.simpleMessage("添加到首页"),
"Add_to_quick_action": MessageLookupByLibrary.simpleMessage("添加到快捷方式"),
"Allow": MessageLookupByLibrary.simpleMessage("允许"),
"Alway_reject": MessageLookupByLibrary.simpleMessage("总是拒绝"),
"Always": MessageLookupByLibrary.simpleMessage("总是"),
"Always_Allow": MessageLookupByLibrary.simpleMessage("总是允许"),
"Always_Reject": MessageLookupByLibrary.simpleMessage("总是拒绝"),
"Always_reject_des":
MessageLookupByLibrary.simpleMessage("每一个请求都咨询是是否签名"),
"Always_reject_title": MessageLookupByLibrary.simpleMessage("我有一点偏执"),
"Android": MessageLookupByLibrary.simpleMessage("安卓"),
"App_Connect": MessageLookupByLibrary.simpleMessage("应用链接"),
"App_Detail": MessageLookupByLibrary.simpleMessage("应用详情"),
"Approve": MessageLookupByLibrary.simpleMessage("同意"),
"Apps_Manager": MessageLookupByLibrary.simpleMessage("应用管理"),
"Auth_Logs": MessageLookupByLibrary.simpleMessage("授权记录"),
"Back": MessageLookupByLibrary.simpleMessage("后退"),
"Bookmarks": MessageLookupByLibrary.simpleMessage("书签"),
"Cancel": MessageLookupByLibrary.simpleMessage("取消"),
"Click_and_Login": MessageLookupByLibrary.simpleMessage("点击登录"),
"Close_Edit": MessageLookupByLibrary.simpleMessage("关闭编辑"),
"Comming_soon": MessageLookupByLibrary.simpleMessage("很快到达..."),
"Confirm": MessageLookupByLibrary.simpleMessage("确认"),
"ConnectType": MessageLookupByLibrary.simpleMessage("链接类型"),
"Connect_by": MessageLookupByLibrary.simpleMessage("链接"),
"Copy_success": MessageLookupByLibrary.simpleMessage("复制成功"),
"Dark": MessageLookupByLibrary.simpleMessage("深色"),
"Decrypt04_name": MessageLookupByLibrary.simpleMessage("解密 (NIP-04)"),
"Decrypt44_name": MessageLookupByLibrary.simpleMessage("解密 (NIP-44)"),
"Decrypt_zap_event": MessageLookupByLibrary.simpleMessage("解密私密Zap"),
"Desktop": MessageLookupByLibrary.simpleMessage("桌面"),
"Downloads": MessageLookupByLibrary.simpleMessage("下载"),
"Edit": MessageLookupByLibrary.simpleMessage("编辑"),
"Encrypt04_name": MessageLookupByLibrary.simpleMessage("加密 (NIP-04)"),
"Encrypt44_name": MessageLookupByLibrary.simpleMessage("加密 (NIP-44)"),
"EventKind": MessageLookupByLibrary.simpleMessage("事件类型"),
"Follow_System": MessageLookupByLibrary.simpleMessage("跟随系统"),
"Forward": MessageLookupByLibrary.simpleMessage("前进"),
"Full_trust_des":
MessageLookupByLibrary.simpleMessage("自动签名所有事件 (除了支付)"),
"Full_trust_title": MessageLookupByLibrary.simpleMessage("我完全相信它"),
"Fully_trust": MessageLookupByLibrary.simpleMessage("完全信任"),
"Generate_a_private_key":
MessageLookupByLibrary.simpleMessage("生成一个秘钥"),
"Get_Public_Key": MessageLookupByLibrary.simpleMessage("获取公钥"),
"Get_Relays": MessageLookupByLibrary.simpleMessage("获取中继"),
"Historys": MessageLookupByLibrary.simpleMessage("历史"),
"Input_can_not_be_null": MessageLookupByLibrary.simpleMessage("输入不能为空"),
"Keys_Manager": MessageLookupByLibrary.simpleMessage("秘钥管理"),
"Language": MessageLookupByLibrary.simpleMessage("语言"),
"Light": MessageLookupByLibrary.simpleMessage("浅色"),
"Local_Relay": MessageLookupByLibrary.simpleMessage("本地中继"),
"Login": MessageLookupByLibrary.simpleMessage("登录"),
"Name": MessageLookupByLibrary.simpleMessage("名称"),
"Pendding_connect_remote_apps":
MessageLookupByLibrary.simpleMessage("待链接的远程应用"),
"Privacy": MessageLookupByLibrary.simpleMessage("隐私"),
"Pubkey": MessageLookupByLibrary.simpleMessage("公钥"),
"Reasonable": MessageLookupByLibrary.simpleMessage("合理的授权"),
"Reasonable_des": MessageLookupByLibrary.simpleMessage("自动通过常见的请求"),
"Reasonable_title": MessageLookupByLibrary.simpleMessage("合理地使用"),
"Refresh": MessageLookupByLibrary.simpleMessage("刷新"),
"Reject": MessageLookupByLibrary.simpleMessage("拒绝"),
"Relay": MessageLookupByLibrary.simpleMessage("中继"),
"Remote": MessageLookupByLibrary.simpleMessage("远处"),
"Search_Engine": MessageLookupByLibrary.simpleMessage("搜索引擎"),
"Secret": MessageLookupByLibrary.simpleMessage("密码"),
"Setting": MessageLookupByLibrary.simpleMessage("设置"),
"Show_more_apps": MessageLookupByLibrary.simpleMessage("显示更多应用"),
"Show_more_logs": MessageLookupByLibrary.simpleMessage("显示更多日志"),
"Sign_Event": MessageLookupByLibrary.simpleMessage("签名事件"),
"Stars": MessageLookupByLibrary.simpleMessage("保存书签"),
"Stealth": MessageLookupByLibrary.simpleMessage("隐身"),
"ThemeStyle": MessageLookupByLibrary.simpleMessage("主题类型"),
"Url": MessageLookupByLibrary.simpleMessage("链接"),
"WEB": MessageLookupByLibrary.simpleMessage("网页"),
"a": MessageLookupByLibrary.simpleMessage("一个"),
"auto": MessageLookupByLibrary.simpleMessage("自动"),
"detail": MessageLookupByLibrary.simpleMessage("详情"),
"event": MessageLookupByLibrary.simpleMessage("事件"),
"no_apps_now": MessageLookupByLibrary.simpleMessage("目前没有应用"),
"no_logs_now": MessageLookupByLibrary.simpleMessage("目前没有日志"),
"sign": MessageLookupByLibrary.simpleMessage("签名"),
"to": MessageLookupByLibrary.simpleMessage("")
};
}

View File

@@ -49,6 +49,846 @@ class S {
static S? maybeOf(BuildContext context) {
return Localizations.of<S>(context, S);
}
/// `Back`
String get Back {
return Intl.message(
'Back',
name: 'Back',
desc: '',
args: [],
);
}
/// `Forward`
String get Forward {
return Intl.message(
'Forward',
name: 'Forward',
desc: '',
args: [],
);
}
/// `Refresh`
String get Refresh {
return Intl.message(
'Refresh',
name: 'Refresh',
desc: '',
args: [],
);
}
/// `Stealth`
String get Stealth {
return Intl.message(
'Stealth',
name: 'Stealth',
desc: '',
args: [],
);
}
/// `Comming soon...`
String get Comming_soon {
return Intl.message(
'Comming soon...',
name: 'Comming_soon',
desc: '',
args: [],
);
}
/// `Bookmarks`
String get Bookmarks {
return Intl.message(
'Bookmarks',
name: 'Bookmarks',
desc: '',
args: [],
);
}
/// `Stars`
String get Stars {
return Intl.message(
'Stars',
name: 'Stars',
desc: '',
args: [],
);
}
/// `Historys`
String get Historys {
return Intl.message(
'Historys',
name: 'Historys',
desc: '',
args: [],
);
}
/// `Downloads`
String get Downloads {
return Intl.message(
'Downloads',
name: 'Downloads',
desc: '',
args: [],
);
}
/// `Keys Manager`
String get Keys_Manager {
return Intl.message(
'Keys Manager',
name: 'Keys_Manager',
desc: '',
args: [],
);
}
/// `Desktop`
String get Desktop {
return Intl.message(
'Desktop',
name: 'Desktop',
desc: '',
args: [],
);
}
/// `Edit`
String get Edit {
return Intl.message(
'Edit',
name: 'Edit',
desc: '',
args: [],
);
}
/// `Auth Logs`
String get Auth_Logs {
return Intl.message(
'Auth Logs',
name: 'Auth_Logs',
desc: '',
args: [],
);
}
/// `Pendding connect remote apps`
String get Pendding_connect_remote_apps {
return Intl.message(
'Pendding connect remote apps',
name: 'Pendding_connect_remote_apps',
desc: '',
args: [],
);
}
/// `Apps Manager`
String get Apps_Manager {
return Intl.message(
'Apps Manager',
name: 'Apps_Manager',
desc: '',
args: [],
);
}
/// `Copy success`
String get Copy_success {
return Intl.message(
'Copy success',
name: 'Copy_success',
desc: '',
args: [],
);
}
/// `Close Edit`
String get Close_Edit {
return Intl.message(
'Close Edit',
name: 'Close_Edit',
desc: '',
args: [],
);
}
/// `Local Relay`
String get Local_Relay {
return Intl.message(
'Local Relay',
name: 'Local_Relay',
desc: '',
args: [],
);
}
/// `Relay`
String get Relay {
return Intl.message(
'Relay',
name: 'Relay',
desc: '',
args: [],
);
}
/// `Secret`
String get Secret {
return Intl.message(
'Secret',
name: 'Secret',
desc: '',
args: [],
);
}
/// `Connect by`
String get Connect_by {
return Intl.message(
'Connect by',
name: 'Connect_by',
desc: '',
args: [],
);
}
/// `Confirm`
String get Confirm {
return Intl.message(
'Confirm',
name: 'Confirm',
desc: '',
args: [],
);
}
/// `Add Remote App`
String get Add_Remote_App {
return Intl.message(
'Add Remote App',
name: 'Add_Remote_App',
desc: '',
args: [],
);
}
/// `Name`
String get Name {
return Intl.message(
'Name',
name: 'Name',
desc: '',
args: [],
);
}
/// `Pubkey`
String get Pubkey {
return Intl.message(
'Pubkey',
name: 'Pubkey',
desc: '',
args: [],
);
}
/// `Fully trust`
String get Fully_trust {
return Intl.message(
'Fully trust',
name: 'Fully_trust',
desc: '',
args: [],
);
}
/// `Reasonable`
String get Reasonable {
return Intl.message(
'Reasonable',
name: 'Reasonable',
desc: '',
args: [],
);
}
/// `Alway reject`
String get Alway_reject {
return Intl.message(
'Alway reject',
name: 'Alway_reject',
desc: '',
args: [],
);
}
/// `ConnectType`
String get ConnectType {
return Intl.message(
'ConnectType',
name: 'ConnectType',
desc: '',
args: [],
);
}
/// `Always Allow`
String get Always_Allow {
return Intl.message(
'Always Allow',
name: 'Always_Allow',
desc: '',
args: [],
);
}
/// `Always Reject`
String get Always_Reject {
return Intl.message(
'Always Reject',
name: 'Always_Reject',
desc: '',
args: [],
);
}
/// `App Detail`
String get App_Detail {
return Intl.message(
'App Detail',
name: 'App_Detail',
desc: '',
args: [],
);
}
/// `EventKind`
String get EventKind {
return Intl.message(
'EventKind',
name: 'EventKind',
desc: '',
args: [],
);
}
/// `Approve`
String get Approve {
return Intl.message(
'Approve',
name: 'Approve',
desc: '',
args: [],
);
}
/// `Reject`
String get Reject {
return Intl.message(
'Reject',
name: 'Reject',
desc: '',
args: [],
);
}
/// `Click and Login`
String get Click_and_Login {
return Intl.message(
'Click and Login',
name: 'Click_and_Login',
desc: '',
args: [],
);
}
/// `no apps now`
String get no_apps_now {
return Intl.message(
'no apps now',
name: 'no_apps_now',
desc: '',
args: [],
);
}
/// `Show more apps`
String get Show_more_apps {
return Intl.message(
'Show more apps',
name: 'Show_more_apps',
desc: '',
args: [],
);
}
/// `no logs now`
String get no_logs_now {
return Intl.message(
'no logs now',
name: 'no_logs_now',
desc: '',
args: [],
);
}
/// `Show more logs`
String get Show_more_logs {
return Intl.message(
'Show more logs',
name: 'Show_more_logs',
desc: '',
args: [],
);
}
/// `Add bookmark`
String get Add_bookmark {
return Intl.message(
'Add bookmark',
name: 'Add_bookmark',
desc: '',
args: [],
);
}
/// `Url`
String get Url {
return Intl.message(
'Url',
name: 'Url',
desc: '',
args: [],
);
}
/// `Add to index`
String get Add_to_index {
return Intl.message(
'Add to index',
name: 'Add_to_index',
desc: '',
args: [],
);
}
/// `Add to quick action`
String get Add_to_quick_action {
return Intl.message(
'Add to quick action',
name: 'Add_to_quick_action',
desc: '',
args: [],
);
}
/// `Input can't be null`
String get Input_can_not_be_null {
return Intl.message(
'Input can\'t be null',
name: 'Input_can_not_be_null',
desc: '',
args: [],
);
}
/// `Login`
String get Login {
return Intl.message(
'Login',
name: 'Login',
desc: '',
args: [],
);
}
/// `Generate a private key`
String get Generate_a_private_key {
return Intl.message(
'Generate a private key',
name: 'Generate_a_private_key',
desc: '',
args: [],
);
}
/// `Sign Event`
String get Sign_Event {
return Intl.message(
'Sign Event',
name: 'Sign_Event',
desc: '',
args: [],
);
}
/// `Allow`
String get Allow {
return Intl.message(
'Allow',
name: 'Allow',
desc: '',
args: [],
);
}
/// `to`
String get to {
return Intl.message(
'to',
name: 'to',
desc: '',
args: [],
);
}
/// `Get Public Key`
String get Get_Public_Key {
return Intl.message(
'Get Public Key',
name: 'Get_Public_Key',
desc: '',
args: [],
);
}
/// `sign`
String get sign {
return Intl.message(
'sign',
name: 'sign',
desc: '',
args: [],
);
}
/// `a`
String get a {
return Intl.message(
'a',
name: 'a',
desc: '',
args: [],
);
}
/// `event`
String get event {
return Intl.message(
'event',
name: 'event',
desc: '',
args: [],
);
}
/// `Get Relays`
String get Get_Relays {
return Intl.message(
'Get Relays',
name: 'Get_Relays',
desc: '',
args: [],
);
}
/// `Encrypt (NIP-04)`
String get Encrypt04_name {
return Intl.message(
'Encrypt (NIP-04)',
name: 'Encrypt04_name',
desc: '',
args: [],
);
}
/// `Decrypt (NIP-04)`
String get Decrypt04_name {
return Intl.message(
'Decrypt (NIP-04)',
name: 'Decrypt04_name',
desc: '',
args: [],
);
}
/// `Encrypt (NIP-44)`
String get Encrypt44_name {
return Intl.message(
'Encrypt (NIP-44)',
name: 'Encrypt44_name',
desc: '',
args: [],
);
}
/// `Decrypt (NIP-44)`
String get Decrypt44_name {
return Intl.message(
'Decrypt (NIP-44)',
name: 'Decrypt44_name',
desc: '',
args: [],
);
}
/// `Decrypt zap event`
String get Decrypt_zap_event {
return Intl.message(
'Decrypt zap event',
name: 'Decrypt_zap_event',
desc: '',
args: [],
);
}
/// `detail`
String get detail {
return Intl.message(
'detail',
name: 'detail',
desc: '',
args: [],
);
}
/// `Always`
String get Always {
return Intl.message(
'Always',
name: 'Always',
desc: '',
args: [],
);
}
/// `Cancel`
String get Cancel {
return Intl.message(
'Cancel',
name: 'Cancel',
desc: '',
args: [],
);
}
/// `I fully trust it`
String get Full_trust_title {
return Intl.message(
'I fully trust it',
name: 'Full_trust_title',
desc: '',
args: [],
);
}
/// `Auto-sign all requests (except payments)`
String get Full_trust_des {
return Intl.message(
'Auto-sign all requests (except payments)',
name: 'Full_trust_des',
desc: '',
args: [],
);
}
/// `Let's be reasonable`
String get Reasonable_title {
return Intl.message(
'Let\'s be reasonable',
name: 'Reasonable_title',
desc: '',
args: [],
);
}
/// `Auto-approve most common requests`
String get Reasonable_des {
return Intl.message(
'Auto-approve most common requests',
name: 'Reasonable_des',
desc: '',
args: [],
);
}
/// `I'm a bit paranoid`
String get Always_reject_title {
return Intl.message(
'I\'m a bit paranoid',
name: 'Always_reject_title',
desc: '',
args: [],
);
}
/// `Do not sign anything without asking me!`
String get Always_reject_des {
return Intl.message(
'Do not sign anything without asking me!',
name: 'Always_reject_des',
desc: '',
args: [],
);
}
/// `App Connect`
String get App_Connect {
return Intl.message(
'App Connect',
name: 'App_Connect',
desc: '',
args: [],
);
}
/// `WEB`
String get WEB {
return Intl.message(
'WEB',
name: 'WEB',
desc: '',
args: [],
);
}
/// `Android`
String get Android {
return Intl.message(
'Android',
name: 'Android',
desc: '',
args: [],
);
}
/// `Remote`
String get Remote {
return Intl.message(
'Remote',
name: 'Remote',
desc: '',
args: [],
);
}
/// `auto`
String get auto {
return Intl.message(
'auto',
name: 'auto',
desc: '',
args: [],
);
}
/// `Follow System`
String get Follow_System {
return Intl.message(
'Follow System',
name: 'Follow_System',
desc: '',
args: [],
);
}
/// `Light`
String get Light {
return Intl.message(
'Light',
name: 'Light',
desc: '',
args: [],
);
}
/// `Dark`
String get Dark {
return Intl.message(
'Dark',
name: 'Dark',
desc: '',
args: [],
);
}
/// `Setting`
String get Setting {
return Intl.message(
'Setting',
name: 'Setting',
desc: '',
args: [],
);
}
/// `Language`
String get Language {
return Intl.message(
'Language',
name: 'Language',
desc: '',
args: [],
);
}
/// `ThemeStyle`
String get ThemeStyle {
return Intl.message(
'ThemeStyle',
name: 'ThemeStyle',
desc: '',
args: [],
);
}
/// `Search Engine`
String get Search_Engine {
return Intl.message(
'Search Engine',
name: 'Search_Engine',
desc: '',
args: [],
);
}
/// `About`
String get About {
return Intl.message(
'About',
name: 'About',
desc: '',
args: [],
);
}
/// `About Me`
String get About_Me {
return Intl.message(
'About Me',
name: 'About_Me',
desc: '',
args: [],
);
}
/// `Privacy`
String get Privacy {
return Intl.message(
'Privacy',
name: 'Privacy',
desc: '',
args: [],
);
}
}
class AppLocalizationDelegate extends LocalizationsDelegate<S> {
@@ -57,6 +897,7 @@ class AppLocalizationDelegate extends LocalizationsDelegate<S> {
List<Locale> get supportedLocales {
return const <Locale>[
Locale.fromSubtags(languageCode: 'en'),
Locale.fromSubtags(languageCode: 'zh'),
];
}

View File

@@ -1 +1,86 @@
{}
{
"Back": "Back",
"Forward": "Forward",
"Refresh": "Refresh",
"Stealth": "Stealth",
"Comming_soon": "Comming soon...",
"Bookmarks": "Bookmarks",
"Stars": "Stars",
"Historys": "Historys",
"Downloads": "Downloads",
"Keys_Manager": "Keys Manager",
"Desktop": "Desktop",
"Edit": "Edit",
"Auth_Logs": "Auth Logs",
"Pendding_connect_remote_apps": "Pendding connect remote apps",
"Apps_Manager": "Apps Manager",
"Copy_success": "Copy success",
"Close_Edit": "Close Edit",
"Local_Relay": "Local Relay",
"Relay": "Relay",
"Secret": "Secret",
"Connect_by": "Connect by",
"Confirm": "Confirm",
"Add_Remote_App": "Add Remote App",
"Name": "Name",
"Pubkey": "Pubkey",
"Fully_trust": "Fully trust",
"Reasonable": "Reasonable",
"Alway_reject": "Alway reject",
"ConnectType": "ConnectType",
"Always_Allow": "Always Allow",
"Always_Reject": "Always Reject",
"App_Detail": "App Detail",
"EventKind": "EventKind",
"Approve": "Approve",
"Reject": "Reject",
"Click_and_Login": "Click and Login",
"no_apps_now": "no apps now",
"Show_more_apps": "Show more apps",
"no_logs_now": "no logs now",
"Show_more_logs": "Show more logs",
"Add_bookmark": "Add bookmark",
"Url": "Url",
"Add_to_index": "Add to index",
"Add_to_quick_action": "Add to quick action",
"Input_can_not_be_null": "Input can't be null",
"Login": "Login",
"Generate_a_private_key": "Generate a private key",
"Sign_Event": "Sign Event",
"Allow": "Allow",
"to": "to",
"Get_Public_Key": "Get Public Key",
"sign": "sign",
"a": "a",
"event": "event",
"Get_Relays": "Get Relays",
"Encrypt04_name": "Encrypt (NIP-04)",
"Decrypt04_name": "Decrypt (NIP-04)",
"Encrypt44_name": "Encrypt (NIP-44)",
"Decrypt44_name": "Decrypt (NIP-44)",
"Decrypt_zap_event": "Decrypt zap event",
"detail": "detail",
"Always": "Always",
"Cancel": "Cancel",
"Full_trust_title": "I fully trust it",
"Full_trust_des": "Auto-sign all requests (except payments)",
"Reasonable_title": "Let's be reasonable",
"Reasonable_des": "Auto-approve most common requests",
"Always_reject_title": "I'm a bit paranoid",
"Always_reject_des": "Do not sign anything without asking me!",
"App_Connect": "App Connect",
"WEB": "WEB",
"Android": "Android",
"Remote": "Remote",
"auto": "auto",
"Follow_System": "Follow System",
"Light": "Light",
"Dark": "Dark",
"Setting": "Setting",
"Language": "Language",
"ThemeStyle": "ThemeStyle",
"Search_Engine": "Search Engine",
"About": "About",
"About_Me": "About Me",
"Privacy": "Privacy"
}

86
lib/l10n/intl_zh.arb Normal file
View File

@@ -0,0 +1,86 @@
{
"Back": "后退",
"Forward": "前进",
"Refresh": "刷新",
"Stealth": "隐身",
"Comming_soon": "很快到达...",
"Bookmarks": "书签",
"Stars": "保存书签",
"Historys": "历史",
"Downloads": "下载",
"Keys_Manager": "秘钥管理",
"Desktop": "桌面",
"Edit": "编辑",
"Auth_Logs": "授权记录",
"Pendding_connect_remote_apps": "待链接的远程应用",
"Apps_Manager": "应用管理",
"Copy_success": "复制成功",
"Close_Edit": "关闭编辑",
"Local_Relay": "本地中继",
"Relay": "中继",
"Secret": "密码",
"Connect_by": "链接",
"Confirm": "确认",
"Add_Remote_App": "添加远程应用",
"Name": "名称",
"Pubkey": "公钥",
"Fully_trust": "完全信任",
"Reasonable": "合理的授权",
"Alway_reject": "总是拒绝",
"ConnectType": "链接类型",
"Always_Allow": "总是允许",
"Always_Reject": "总是拒绝",
"App_Detail": "应用详情",
"EventKind": "事件类型",
"Approve": "同意",
"Reject": "拒绝",
"Click_and_Login": "点击登录",
"no_apps_now": "目前没有应用",
"Show_more_apps": "显示更多应用",
"no_logs_now": "目前没有日志",
"Show_more_logs": "显示更多日志",
"Add_bookmark": "添加书签",
"Url": "链接",
"Add_to_index": "添加到首页",
"Add_to_quick_action": "添加到快捷方式",
"Input_can_not_be_null": "输入不能为空",
"Login": "登录",
"Generate_a_private_key": "生成一个秘钥",
"Sign_Event": "签名事件",
"Allow": "允许",
"to": "做",
"Get_Public_Key": "获取公钥",
"sign": "签名",
"a": "一个",
"event": "事件",
"Get_Relays": "获取中继",
"Encrypt04_name": "加密 (NIP-04)",
"Decrypt04_name": "解密 (NIP-04)",
"Encrypt44_name": "加密 (NIP-44)",
"Decrypt44_name": "解密 (NIP-44)",
"Decrypt_zap_event": "解密私密Zap",
"detail": "详情",
"Always": "总是",
"Cancel": "取消",
"Full_trust_title": "我完全相信它",
"Full_trust_des": "自动签名所有事件 (除了支付)",
"Reasonable_title": "合理地使用",
"Reasonable_des": "自动通过常见的请求",
"Always_reject_title": "我有一点偏执",
"Always_reject_des": "每一个请求都咨询是是否签名",
"App_Connect": "应用链接",
"WEB": "网页",
"Android": "安卓",
"Remote": "远处",
"auto": "自动",
"Follow_System": "跟随系统",
"Light": "浅色",
"Dark": "深色",
"Setting": "设置",
"Language": "语言",
"ThemeStyle": "主题类型",
"Search_Engine": "搜索引擎",
"About": "关于",
"About_Me": "关于我",
"Privacy": "隐私"
}

View File

@@ -26,6 +26,7 @@ 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';
import 'package:nowser/router/setting/setting_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';
@@ -148,6 +149,15 @@ class _MyApp extends State<MyApp> {
@override
Widget build(BuildContext context) {
Locale? _locale;
if (StringUtil.isNotBlank(settingProvider.i18n)) {
for (var item in S.delegate.supportedLocales) {
if (item.languageCode == settingProvider.i18n &&
item.countryCode == settingProvider.i18nCC) {
_locale = Locale(settingProvider.i18n!, settingProvider.i18nCC);
break;
}
}
}
var lightTheme = getLightTheme();
var darkTheme = getDarkTheme();
@@ -167,6 +177,7 @@ class _MyApp extends State<MyApp> {
RouterPath.HISTORY: (context) => HistoryRouter(),
RouterPath.BOOKMARK: (context) => BookmarkRouter(),
RouterPath.AUTH_LOGS: (context) => AuthLogsRouter(),
RouterPath.SETTING: (context) => SettingRouter(indexReload: reload),
};
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
@@ -175,6 +186,9 @@ class _MyApp extends State<MyApp> {
return MultiProvider(
providers: [
ListenableProvider<SettingProvider>.value(
value: settingProvider,
),
ListenableProvider<WebProvider>.value(
value: webProvider,
),

View File

@@ -1,5 +1,4 @@
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart';
@@ -7,7 +6,6 @@ import 'package:nostr_sdk/utils/string_util.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../const/base.dart';
import '../const/base_consts.dart';
import '../const/theme_style.dart';
import 'data_util.dart';
@@ -49,13 +47,6 @@ class SettingProvider extends ChangeNotifier {
SettingData get settingData => _settingData!;
/// open lock
int get lockOpen => _settingData!.lockOpen;
String? get imageService => _settingData!.imageService;
String? get imageServiceAddr => _settingData!.imageServiceAddr;
/// i18n
String? get i18n => _settingData!.i18n;
@@ -88,31 +79,11 @@ class SettingProvider extends ChangeNotifier {
int? get tableMode => _settingData!.tableMode;
int? get relayMode => _settingData!.relayMode;
int? get eventSignCheck => _settingData!.eventSignCheck;
set settingData(SettingData o) {
_settingData = o;
saveAndNotifyListeners();
}
/// open lock
set lockOpen(int o) {
_settingData!.lockOpen = o;
saveAndNotifyListeners();
}
set imageService(String? o) {
_settingData!.imageService = o;
saveAndNotifyListeners();
}
set imageServiceAddr(String? o) {
_settingData!.imageServiceAddr = o;
saveAndNotifyListeners();
}
/// i18n
set i18n(String? o) {
_settingData!.i18n = o;
@@ -173,16 +144,6 @@ class SettingProvider extends ChangeNotifier {
saveAndNotifyListeners();
}
set relayMode(int? o) {
_settingData!.relayMode = o;
saveAndNotifyListeners();
}
set eventSignCheck(int? o) {
_settingData!.eventSignCheck = o;
saveAndNotifyListeners();
}
Future<void> saveAndNotifyListeners({bool updateUI = true}) async {
_settingData!.updatedTime = DateTime.now().millisecondsSinceEpoch;
var m = _settingData!.toJson();
@@ -197,13 +158,6 @@ class SettingProvider extends ChangeNotifier {
}
class SettingData {
/// open lock
late int lockOpen;
String? imageService;
String? imageServiceAddr;
/// i18n
String? i18n;
@@ -233,17 +187,10 @@ class SettingData {
int? tableMode;
int? relayMode;
int? eventSignCheck;
/// updated time
late int updatedTime;
SettingData({
this.lockOpen = OpenStatus.CLOSE,
this.imageService,
this.imageServiceAddr,
this.i18n,
this.i18nCC,
this.themeStyle = ThemeStyle.AUTO,
@@ -255,19 +202,10 @@ class SettingData {
this.fontFamily,
this.fontSize,
this.tableMode,
this.relayMode,
this.eventSignCheck,
this.updatedTime = 0,
});
SettingData.fromJson(Map<String, dynamic> json) {
if (json['lockOpen'] != null) {
lockOpen = json['lockOpen'];
} else {
lockOpen = OpenStatus.CLOSE;
}
imageService = json['imageService'];
imageServiceAddr = json['imageServiceAddr'];
i18n = json['i18n'];
i18nCC = json['i18nCC'];
if (json['themeStyle'] != null) {
@@ -282,8 +220,6 @@ class SettingData {
backgroundImage = json['backgroundImage'];
fontSize = json['fontSize'];
tableMode = json['tableMode'];
relayMode = json['relayMode'];
eventSignCheck = json['eventSignCheck'];
if (json['updatedTime'] != null) {
updatedTime = json['updatedTime'];
} else {
@@ -293,9 +229,6 @@ class SettingData {
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['lockOpen'] = this.lockOpen;
data['imageService'] = this.imageService;
data['imageServiceAddr'] = this.imageServiceAddr;
data['i18n'] = this.i18n;
data['i18nCC'] = this.i18nCC;
data['themeStyle'] = this.themeStyle;
@@ -307,8 +240,6 @@ class SettingData {
data['fontFamily'] = this.fontFamily;
data['fontSize'] = this.fontSize;
data['tableMode'] = this.tableMode;
data['relayMode'] = this.relayMode;
data['eventSignCheck'] = this.eventSignCheck;
data['updatedTime'] = this.updatedTime;
return data;
}

View File

@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:nowser/component/tag_component.dart';
import 'package:nowser/const/auth_type.dart';
import '../../generated/l10n.dart';
class AppDetailPermissionItemComponent extends StatefulWidget {
bool allow;
@@ -24,11 +26,13 @@ class _AppDetailPermissionItemComponent
extends State<AppDetailPermissionItemComponent> {
bool tapFirst = false;
late S s;
@override
Widget build(BuildContext context) {
var permissionText = AuthType.getAuthName(context, widget.authType);
if (widget.eventKind != null) {
permissionText += " (EventKind ${widget.eventKind})";
permissionText += " (${s.EventKind} ${widget.eventKind})";
}
var main = TagComponent(permissionText);

View File

@@ -12,6 +12,7 @@ import 'package:provider/provider.dart';
import '../../component/appbar_back_btn_component.dart';
import '../../const/base.dart';
import '../../generated/l10n.dart';
import '../../provider/key_provider.dart';
class AppDetailRouter extends StatefulWidget {
@@ -41,6 +42,8 @@ class _AppDetailRouter extends State<AppDetailRouter> {
bool changed = false;
late S s;
@override
Widget build(BuildContext context) {
var themeData = Theme.of(context);
@@ -60,9 +63,9 @@ class _AppDetailRouter extends State<AppDetailRouter> {
List<Widget> list = [];
var baseMargin = EdgeInsets.only(bottom: Base.BASE_PADDING);
var baseMargin = const EdgeInsets.only(bottom: Base.BASE_PADDING);
Widget imageWidget = Icon(
Widget imageWidget = const Icon(
Icons.image,
size: 80,
);
@@ -106,7 +109,7 @@ class _AppDetailRouter extends State<AppDetailRouter> {
margin: baseMargin,
child: TextField(
controller: nameController,
decoration: InputDecoration(hintText: "Name"),
decoration: InputDecoration(hintText: s.Name),
),
));
@@ -137,7 +140,7 @@ class _AppDetailRouter extends State<AppDetailRouter> {
children: [
Container(
margin: EdgeInsets.only(right: Base.BASE_PADDING),
child: Text("Pubkey:"),
child: Text("${s.Pubkey}:"),
),
Expanded(child: keyWidget),
],
@@ -146,18 +149,18 @@ class _AppDetailRouter extends State<AppDetailRouter> {
List<DropdownMenuItem<int>> connectTypeItems = [];
connectTypeItems.add(DropdownMenuItem(
child: Text("Fully trust"), value: ConnectType.FULLY_TRUST));
value: ConnectType.FULLY_TRUST, child: Text(s.Fully_trust)));
connectTypeItems.add(DropdownMenuItem(
child: Text("Reasonable"), value: ConnectType.REASONABLE));
value: ConnectType.REASONABLE, child: Text(s.Reasonable)));
connectTypeItems.add(DropdownMenuItem(
child: Text("Alway reject"), value: ConnectType.ALWAY_REJECT));
value: ConnectType.ALWAY_REJECT, child: Text(s.Alway_reject)));
list.add(Container(
margin: baseMargin,
child: Row(
children: [
Container(
margin: EdgeInsets.only(right: Base.BASE_PADDING),
child: Text("ConnectType:"),
margin: const EdgeInsets.only(right: Base.BASE_PADDING),
child: Text("${s.ConnectType}:"),
),
Expanded(
child: DropdownButton<int>(
@@ -187,7 +190,7 @@ class _AppDetailRouter extends State<AppDetailRouter> {
margin: baseMargin,
alignment: Alignment.centerLeft,
child: Text(
"Always Allow:",
"${s.Always_Allow}:",
),
));
list.add(Container(
@@ -211,7 +214,7 @@ class _AppDetailRouter extends State<AppDetailRouter> {
margin: baseMargin,
alignment: Alignment.centerLeft,
child: Text(
"Always Reject:",
"${s.Always_Reject}:",
),
));
list.add(Container(
@@ -241,7 +244,7 @@ class _AppDetailRouter extends State<AppDetailRouter> {
appBar: AppBar(
leading: AppbarBackBtnComponent(),
title: Text(
"App Detail",
s.App_Detail,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: themeData.textTheme.bodyLarge!.fontSize,

View File

@@ -58,8 +58,11 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
localIp = await IpUtil.getIp();
}
late S s;
@override
Widget doBuild(BuildContext context) {
s = S.of(context);
var themeData = Theme.of(context);
var textColor = themeData.textTheme.bodyMedium!.color;
var mainColor = themeData.primaryColor;
@@ -112,11 +115,11 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
});
},
behavior: HitTestBehavior.translucent,
child: const Row(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.expand_more),
Text("Edit"),
const Icon(Icons.expand_more),
Text(s.Edit),
],
),
),
@@ -131,11 +134,11 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
});
},
behavior: HitTestBehavior.translucent,
child: const Row(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.expand_less),
Text("Close Edit"),
const Icon(Icons.expand_less),
Text(s.Close_Edit),
],
),
),
@@ -151,10 +154,10 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
child: Row(
children: [
Container(
margin: EdgeInsets.only(
margin: const EdgeInsets.only(
right: Base.BASE_PADDING_HALF,
),
child: Text("Local Relay:"),
child: Text("${s.Local_Relay}:"),
),
Checkbox(
value: localRelay,
@@ -167,7 +170,7 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
Container(
child: TextField(
decoration: InputDecoration(
labelText: "Relay",
labelText: s.Relay,
enabled: !localRelay,
),
controller: relayAddrController,
@@ -176,7 +179,7 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
Container(
child: TextField(
decoration: InputDecoration(
labelText: "Secret",
labelText: s.Secret,
),
controller: secretController,
),
@@ -203,15 +206,15 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
tabs: [
GestureDetector(
child: Text(
"Connect by\nnostrconnect:// url",
"${s.Connect_by}\nnostrconnect:// url",
textAlign: TextAlign.center,
),
onTap: () {
BotToast.showText(text: "Coming...");
BotToast.showText(text: s.Comming_soon);
},
),
Text(
"Connect by\nbunker:// url",
"${s.Connect_by}\nbunker:// url",
textAlign: TextAlign.center,
),
],
@@ -222,21 +225,23 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
child: TabBarView(
children: [
Container(
padding: EdgeInsets.all(Base.BASE_PADDING),
padding: const EdgeInsets.all(Base.BASE_PADDING),
child: ListView(
children: [
Container(
margin: EdgeInsets.only(top: Base.BASE_PADDING_HALF),
margin:
const EdgeInsets.only(top: Base.BASE_PADDING_HALF),
child: TextField(
controller: nostrconnectConn,
decoration: InputDecoration(
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
maxLines: 4,
),
),
Container(
margin: EdgeInsets.only(top: Base.BASE_PADDING_HALF),
margin:
const EdgeInsets.only(top: Base.BASE_PADDING_HALF),
child: Row(
children: [
Expanded(child: Container()),
@@ -244,19 +249,19 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
onPressed: () {
scanNostrConnectQRCode();
},
icon: Icon(Icons.qr_code_scanner),
icon: const Icon(Icons.qr_code_scanner),
),
],
),
),
Container(
margin: EdgeInsets.only(top: Base.BASE_PADDING),
margin: const EdgeInsets.only(top: Base.BASE_PADDING),
width: double.infinity,
child: FilledButton(
onPressed: () {
BotToast.showText(text: "Coming...");
BotToast.showText(text: s.Comming_soon);
},
child: Text("Confirm"),
child: Text(s.Confirm),
),
),
],
@@ -301,7 +306,7 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
width: double.infinity,
child: FilledButton(
onPressed: confirmBunkerUrl,
child: Text("Confirm"),
child: Text(s.Confirm),
),
),
],
@@ -318,7 +323,7 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
appBar: AppBar(
leading: AppbarBackBtnComponent(),
title: Text(
"Add Remote App",
s.Add_Remote_App,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: themeData.textTheme.bodyLarge!.fontSize,
@@ -380,7 +385,7 @@ class _AddRemoteAppRouter extends CustState<AddRemoteAppRouter> {
void copyBunkerUrl() {
Clipboard.setData(ClipboardData(text: bunkerConn.text)).then((_) {
BotToast.showText(text: "Copy success");
BotToast.showText(text: S.of(context).Copy_success);
});
}

View File

@@ -22,6 +22,7 @@ import '../../component/app/app_type_component.dart';
import '../../component/appbar_back_btn_component.dart';
import '../../const/base.dart';
import '../../data/remote_signing_info.dart';
import '../../generated/l10n.dart';
import '../me/me_router_app_item_component.dart';
class AppsRouter extends StatefulWidget {
@@ -34,6 +35,7 @@ class AppsRouter extends StatefulWidget {
class _AppsRouter extends CustState<AppsRouter> {
@override
Widget doBuild(BuildContext context) {
var s = S.of(context);
var themeData = Theme.of(context);
var _appProvider = Provider.of<AppProvider>(context);
var appList = _appProvider.appList;
@@ -54,32 +56,6 @@ class _AppsRouter extends CustState<AppsRouter> {
motion: ScrollMotion(),
extentRatio: 0.25,
children: [
// GestureDetector(
// onTap: () {},
// child: Container(
// color: Colors.red,
// alignment: Alignment.center,
// padding: EdgeInsets.only(
// left: Base.BASE_PADDING,
// right: Base.BASE_PADDING,
// top: 3,
// bottom: 3,
// ),
// child: Row(
// // mainAxisSize: MainAxisSize.min,
// children: [
// Icon(
// Icons.delete_forever,
// color: Colors.white,
// ),
// Text(
// "Delete",
// style: TextStyle(color: Colors.white),
// )
// ],
// ),
// ),
// ),
SlidableAction(
onPressed: (context) {
var cancelFunc = BotToast.showLoading();
@@ -174,7 +150,7 @@ class _AppsRouter extends CustState<AppsRouter> {
child: Container(
margin: EdgeInsets.only(top: Base.BASE_PADDING),
child: Text(
"Pendding connect remote apps",
s.Pendding_connect_remote_apps,
style: TextStyle(
fontWeight: FontWeight.bold,
),
@@ -205,7 +181,7 @@ class _AppsRouter extends CustState<AppsRouter> {
appBar: AppBar(
leading: AppbarBackBtnComponent(),
title: Text(
"Apps Manager",
s.Apps_Manager,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: themeData.textTheme.bodyLarge!.fontSize,

View File

@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import '../../component/appbar_back_btn_component.dart';
import '../../component/deletable_list_mixin.dart';
import '../../generated/l10n.dart';
class AuthLogsRouter extends StatefulWidget {
@override
@@ -13,13 +14,14 @@ class AuthLogsRouter extends StatefulWidget {
class _AuthLogsRouter extends State<AuthLogsRouter> with DeletableListMixin {
@override
Widget build(BuildContext context) {
var s = S.of(context);
var themeData = Theme.of(context);
return Scaffold(
appBar: AppBar(
leading: AppbarBackBtnComponent(),
title: Text(
"Auth Logs",
s.Auth_Logs,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: themeData.textTheme.bodyLarge!.fontSize,

View File

@@ -17,6 +17,7 @@ import 'package:provider/provider.dart';
import '../../component/appbar_back_btn_component.dart';
import '../../data/bookmark.dart';
import '../../data/bookmark_db.dart';
import '../../generated/l10n.dart';
class BookmarkRouter extends StatefulWidget {
@override
@@ -34,6 +35,7 @@ class _BookmarkRouter extends CustState<BookmarkRouter>
@override
Widget doBuild(BuildContext context) {
var s = S.of(context);
var themeData = Theme.of(context);
var _bookmarkProvider = Provider.of<BookmarkProvider>(context);
var bookmarks = _bookmarkProvider.bookmarks;
@@ -42,7 +44,7 @@ class _BookmarkRouter extends CustState<BookmarkRouter>
appBar: AppBar(
leading: AppbarBackBtnComponent(),
title: Text(
"Bookmarks",
s.Bookmarks,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: themeData.textTheme.bodyLarge!.fontSize,
@@ -75,7 +77,7 @@ class _BookmarkRouter extends CustState<BookmarkRouter>
backgroundColor: Colors.green,
foregroundColor: Colors.white,
icon: Icons.add_home,
label: 'Desktop',
label: s.Desktop,
));
}
slidableActionList.add(SlidableAction(
@@ -85,7 +87,7 @@ class _BookmarkRouter extends CustState<BookmarkRouter>
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
icon: Icons.edit,
label: 'Edit',
label: s.Edit,
));
main = Slidable(

View File

@@ -1,4 +1,3 @@
import 'package:bot_toast/bot_toast.dart';
import 'package:flutter/material.dart';
import 'package:nowser/component/cust_state.dart';
import 'package:nowser/component/deletable_list_mixin.dart';
@@ -9,6 +8,7 @@ import 'package:nowser/util/router_util.dart';
import '../../component/appbar_back_btn_component.dart';
import '../../const/base.dart';
import '../../data/browser_history.dart';
import '../../generated/l10n.dart';
class HistoryRouter extends StatefulWidget {
@override
@@ -31,12 +31,13 @@ class _HistoryRouter extends CustState<HistoryRouter> with DeletableListMixin {
@override
Widget doBuild(BuildContext context) {
var themeData = Theme.of(context);
var s = S.of(context);
return Scaffold(
appBar: AppBar(
leading: AppbarBackBtnComponent(),
title: Text(
"Historys",
s.Historys,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: themeData.textTheme.bodyLarge!.fontSize,

View File

@@ -8,6 +8,8 @@ import 'package:nowser/router/index/web_control_btn_component.dart';
import 'package:nowser/util/router_util.dart';
import 'package:provider/provider.dart';
import '../../generated/l10n.dart';
class WebControlComponent extends StatefulWidget {
Function closeControl;
@@ -22,6 +24,7 @@ class WebControlComponent extends StatefulWidget {
class _WebControlComponent extends State<WebControlComponent> {
@override
Widget build(BuildContext context) {
var s = S.of(context);
var webProvider = Provider.of<WebProvider>(context);
var webInfo = webProvider.currentWebInfo;
@@ -30,7 +33,7 @@ class _WebControlComponent extends State<WebControlComponent> {
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: EdgeInsets.only(
padding: const EdgeInsets.only(
left: Base.BASE_PADDING,
right: Base.BASE_PADDING,
),
@@ -38,8 +41,8 @@ class _WebControlComponent extends State<WebControlComponent> {
children: [
Expanded(
child: WebControlBtnComponent(
name: "Back",
icon: Icon(
name: s.Back,
icon: const Icon(
Icons.chevron_left,
size: 30,
),
@@ -50,8 +53,8 @@ class _WebControlComponent extends State<WebControlComponent> {
),
Expanded(
child: WebControlBtnComponent(
name: "Forward",
icon: Icon(
name: s.Forward,
icon: const Icon(
Icons.chevron_right,
size: 30,
),
@@ -62,8 +65,8 @@ class _WebControlComponent extends State<WebControlComponent> {
),
Expanded(
child: WebControlBtnComponent(
name: "Refresh",
icon: Icon(
name: s.Refresh,
icon: const Icon(
Icons.refresh,
size: 30,
),
@@ -75,13 +78,13 @@ class _WebControlComponent extends State<WebControlComponent> {
),
Expanded(
child: WebControlBtnComponent(
name: "Stealth",
icon: Icon(
name: s.Stealth,
icon: const Icon(
Icons.disabled_visible_outlined,
size: 30,
),
onTap: () {
BotToast.showText(text: "Coming...");
BotToast.showText(text: s.Comming_soon);
},
),
),
@@ -89,13 +92,13 @@ class _WebControlComponent extends State<WebControlComponent> {
),
),
Container(
padding: EdgeInsets.all(Base.BASE_PADDING),
padding: const EdgeInsets.all(Base.BASE_PADDING),
child: Row(
children: [
Expanded(
child: WebControlBtnComponent(
name: "Bookmarks",
icon: Icon(
name: s.Bookmarks,
icon: const Icon(
Icons.bookmark_border,
size: 30,
),
@@ -110,8 +113,8 @@ class _WebControlComponent extends State<WebControlComponent> {
),
Expanded(
child: WebControlBtnComponent(
name: "Stars",
icon: Icon(
name: s.Stars,
icon: const Icon(
Icons.bookmark_add_outlined,
size: 30,
),
@@ -126,8 +129,8 @@ class _WebControlComponent extends State<WebControlComponent> {
),
Expanded(
child: WebControlBtnComponent(
name: "Historys",
icon: Icon(
name: s.Historys,
icon: const Icon(
Icons.history,
size: 30,
),
@@ -142,13 +145,13 @@ class _WebControlComponent extends State<WebControlComponent> {
),
Expanded(
child: WebControlBtnComponent(
name: "Downloads",
icon: Icon(
name: s.Downloads,
icon: const Icon(
Icons.download,
size: 30,
),
onTap: () {
BotToast.showText(text: "Coming...");
BotToast.showText(text: s.Comming_soon);
},
),
),

View File

@@ -27,7 +27,7 @@ class _KeysItemComponent extends State<KeysItemComponent> {
List<Widget> list = [];
list.add(Container(
margin: EdgeInsets.only(
margin: const EdgeInsets.only(
right: Base.BASE_PADDING_HALF,
),
child: UserPicComponent(
@@ -52,7 +52,7 @@ class _KeysItemComponent extends State<KeysItemComponent> {
));
return Container(
padding: EdgeInsets.all(Base.BASE_PADDING),
padding: const EdgeInsets.all(Base.BASE_PADDING),
decoration: BoxDecoration(
color:
widget.isDefault ? mainColor.withOpacity(0.5) : themeData.cardColor,

View File

@@ -7,6 +7,7 @@ import 'package:nowser/router/keys/keys_item_component.dart';
import 'package:provider/provider.dart';
import '../../component/user/user_login_dialog.dart';
import '../../generated/l10n.dart';
class KeysRouter extends StatefulWidget {
@override
@@ -22,8 +23,9 @@ class KeysRouter extends StatefulWidget {
class _KeysRouter extends State<KeysRouter> {
@override
Widget build(BuildContext context) {
var s = S.of(context);
var themeData = Theme.of(context);
var margin = EdgeInsets.only(
var margin = const EdgeInsets.only(
left: Base.BASE_PADDING,
right: Base.BASE_PADDING,
top: Base.BASE_PADDING,
@@ -58,7 +60,7 @@ class _KeysRouter extends State<KeysRouter> {
appBar: AppBar(
leading: AppbarBackBtnComponent(),
title: Text(
"Keys Manager",
s.Keys_Manager,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: themeData.textTheme.bodyLarge!.fontSize,

View File

@@ -18,6 +18,7 @@ import 'package:nowser/util/router_util.dart';
import 'package:provider/provider.dart';
import '../../data/auth_log.dart';
import '../../generated/l10n.dart';
import '../keys/keys_router.dart';
import 'me_router_app_item_component.dart';
@@ -31,6 +32,8 @@ class MeRouter extends StatefulWidget {
class _MeRouter extends CustState<MeRouter> {
List<AuthLog> authLogs = [];
late S s;
@override
Future<void> onReady(BuildContext context) async {
var list = await AuthLogDB.list(skip: 0, limit: 10);
@@ -58,6 +61,7 @@ class _MeRouter extends CustState<MeRouter> {
var mediaQueryData = MediaQuery.of(context);
var themeData = Theme.of(context);
var _appProvider = Provider.of<AppProvider>(context);
s = S.of(context);
var listWidgetMargin = const EdgeInsets.only(
top: Base.BASE_PADDING,
@@ -84,7 +88,7 @@ class _MeRouter extends CustState<MeRouter> {
onTap: () {
KeysRouter.addKey(context);
},
child: Text("Click and Login"),
child: Text(s.Click_and_Login),
);
},
selector: (context, _provider) {
@@ -97,7 +101,7 @@ class _MeRouter extends CustState<MeRouter> {
margin: const EdgeInsets.only(right: Base.BASE_PADDING),
child: GestureDetector(
onTap: () {
BotToast.showText(text: "Coming...");
RouterUtil.router(context, RouterPath.SETTING);
},
child: const Icon(Icons.settings),
),
@@ -157,7 +161,7 @@ class _MeRouter extends CustState<MeRouter> {
List<Widget> webItemList = [];
webItemList.add(MeRouterWebItemComponent(
num: bookmarkNum,
name: "Bookmark",
name: s.Bookmarks,
iconData: Icons.bookmark,
onTap: () async {
var url = await RouterUtil.router(context, RouterPath.BOOKMARK);
@@ -168,7 +172,7 @@ class _MeRouter extends CustState<MeRouter> {
));
webItemList.add(MeRouterWebItemComponent(
num: historyNum,
name: "History",
name: s.Historys,
iconData: Icons.history,
onTap: () async {
var url = await RouterUtil.router(context, RouterPath.HISTORY);
@@ -179,10 +183,10 @@ class _MeRouter extends CustState<MeRouter> {
));
webItemList.add(MeRouterWebItemComponent(
num: downloadNum,
name: "Download",
name: s.Downloads,
iconData: Icons.download,
onTap: () {
BotToast.showText(text: "Coming...");
BotToast.showText(text: s.Comming_soon);
},
));
// webItemList.add(MeRouterWebItemComponent(
@@ -215,7 +219,7 @@ class _MeRouter extends CustState<MeRouter> {
},
behavior: HitTestBehavior.translucent,
child: Container(
child: Text("no apps now"),
child: Text(s.no_apps_now),
),
));
appWidgetList.add(Divider());
@@ -228,7 +232,7 @@ class _MeRouter extends CustState<MeRouter> {
},
behavior: HitTestBehavior.translucent,
child: Text(
"Show more apps",
s.Show_more_apps,
style: TextStyle(
decoration: TextDecoration.underline,
),
@@ -261,14 +265,14 @@ class _MeRouter extends CustState<MeRouter> {
}
if (logList.isEmpty) {
logList.add(Container(
child: Text("no logs now"),
child: Text(s.no_logs_now),
));
logList.add(Divider());
}
logList.add(Container(
alignment: Alignment.center,
child: Text(
"Show more logs",
s.Show_more_logs,
style: TextStyle(
decoration: TextDecoration.underline,
),

View File

@@ -7,6 +7,8 @@ import 'package:nowser/data/auth_log.dart';
import 'package:nowser/provider/app_provider.dart';
import 'package:provider/provider.dart';
import '../../generated/l10n.dart';
class MeRouterLogItemComponent extends StatefulWidget {
AuthLog authLog;
@@ -19,8 +21,11 @@ class MeRouterLogItemComponent extends StatefulWidget {
}
class _MeRouterLogItemComponent extends State<MeRouterLogItemComponent> {
late S s;
@override
Widget build(BuildContext context) {
s = S.of(context);
var appProvider = Provider.of<AppProvider>(context);
var app = appProvider.getAppById(widget.authLog.appId!);
@@ -58,7 +63,7 @@ class _MeRouterLogItemComponent extends State<MeRouterLogItemComponent> {
bottom: 2,
),
child: Text(
"Approve",
s.Approve,
style: TextStyle(color: Colors.white),
),
),
@@ -67,12 +72,12 @@ class _MeRouterLogItemComponent extends State<MeRouterLogItemComponent> {
resultWidget = Card.filled(
color: Colors.red,
child: Container(
padding: EdgeInsets.only(
padding: const EdgeInsets.only(
left: Base.BASE_PADDING_HALF,
right: Base.BASE_PADDING_HALF,
),
child: Text(
"Reject",
s.Reject,
style: TextStyle(color: Colors.white),
),
),
@@ -84,7 +89,7 @@ class _MeRouterLogItemComponent extends State<MeRouterLogItemComponent> {
authContent += AuthType.getAuthName(context, authType);
if (authType == AuthType.SIGN_EVENT) {
authContent += " EventKind(${widget.authLog.eventKind})";
authContent += " ${s.EventKind}(${widget.authLog.eventKind})";
} else if (authType >= AuthType.NIP04_ENCRYPT) {
if (StringUtil.isNotBlank(widget.authLog.content)) {
authContent += widget.authLog.content!;

View File

@@ -0,0 +1,70 @@
import 'package:flutter/material.dart';
import 'package:nostr_sdk/utils/string_util.dart';
import '../../const/base.dart';
class SettingItemComponent extends StatelessWidget {
String title;
String? value;
Widget? child;
bool showTopBorder;
Function? onTap;
SettingItemComponent(
this.title, {
this.value,
this.child,
this.showTopBorder = false,
this.onTap,
});
@override
Widget build(BuildContext context) {
var themeData = Theme.of(context);
if (child == null && StringUtil.isNotBlank(value)) {
child = Text(value!);
}
child ??= Container();
return GestureDetector(
onTap: () {
if (onTap != null) {
onTap!();
}
},
child: Container(
padding: const EdgeInsets.only(
left: Base.BASE_PADDING_HALF,
right: Base.BASE_PADDING_HALF,
top: 10,
bottom: 10,
),
decoration: BoxDecoration(
border: showTopBorder
? Border(
top: BorderSide(
color: themeData.dividerColor,
),
)
: null,
),
child: Row(
children: [
Container(
child: Text(title),
),
Expanded(child: Container()),
Container(
child: child,
),
],
),
),
);
}
}

View File

@@ -1,6 +1,22 @@
import 'package:flutter/material.dart';
import '../../component/enum_selector_component.dart';
import '../../const/base.dart';
import '../../const/base_consts.dart';
import '../../const/theme_style.dart';
import '../../generated/l10n.dart';
import '../../main.dart';
import '../../util/locale_util.dart';
import '../../util/router_util.dart';
import 'setting_item_component.dart';
class SettingRouter extends StatefulWidget {
Function indexReload;
SettingRouter({
required this.indexReload,
});
@override
State<StatefulWidget> createState() {
return _SettingRouter();
@@ -8,8 +24,241 @@ class SettingRouter extends StatefulWidget {
}
class _SettingRouter extends State<SettingRouter> {
void resetTheme() {
widget.indexReload();
}
var listWidgetMargin = const EdgeInsets.only(
top: Base.BASE_PADDING,
bottom: Base.BASE_PADDING_HALF,
);
late S s;
@override
Widget build(BuildContext context) {
return Scaffold();
var mediaQueryData = MediaQuery.of(context);
var themeData = Theme.of(context);
s = S.of(context);
var moreWidget = Icon(Icons.chevron_right);
initI18nList(s);
initThemeStyleList(s);
Widget titleWidget = Container(
alignment: Alignment.topLeft,
padding: const EdgeInsets.only(
top: Base.BASE_PADDING + 10,
left: Base.BASE_PADDING,
),
child: Text(
s.Setting,
style: TextStyle(
fontSize: themeData.textTheme.bodyLarge!.fontSize! + 2,
fontWeight: FontWeight.bold,
),
),
);
List<Widget> configList = [];
configList.add(SettingItemComponent(
s.Language,
value: getI18nList(settingProvider.i18n, settingProvider.i18nCC).name,
onTap: pickI18N,
));
configList.add(SettingItemComponent(
s.ThemeStyle,
value: getThemeStyle(settingProvider.themeStyle).name,
showTopBorder: true,
onTap: pickThemeStyle,
));
configList.add(SettingItemComponent(
s.Search_Engine,
value: "https://www.baidu.com/",
showTopBorder: true,
));
var configListWidget = genConfigListWidget(configList, themeData);
Widget aboutTitleWidget = genTitle(s.About, themeData);
List<Widget> aboutList = [];
aboutList.add(SettingItemComponent("FAQ", child: moreWidget));
aboutList.add(SettingItemComponent(
s.About_Me,
child: moreWidget,
showTopBorder: true,
));
aboutList.add(SettingItemComponent(
s.Privacy,
child: moreWidget,
showTopBorder: true,
));
var aboutListWidget = genConfigListWidget(aboutList, themeData);
var main = SingleChildScrollView(
child: Container(
padding: EdgeInsets.only(
left: Base.BASE_PADDING,
right: Base.BASE_PADDING,
top: mediaQueryData.padding.top,
bottom: mediaQueryData.padding.bottom + Base.BASE_PADDING,
),
child: Column(
children: [
titleWidget,
configListWidget,
aboutTitleWidget,
aboutListWidget,
],
),
),
);
return Scaffold(
body: Stack(
children: [
Positioned.fill(
top: 0,
bottom: 0,
left: 0,
right: 0,
child: main,
),
Positioned(
top: mediaQueryData.padding.top + Base.BASE_PADDING,
right: 20,
child: GestureDetector(
onTap: () {
RouterUtil.back(context);
},
child: Container(
decoration: BoxDecoration(
// border: Border.all(),
borderRadius: BorderRadius.circular(4),
color: themeData.hintColor.withOpacity(0.2)),
padding: EdgeInsets.all(4),
child: Icon(Icons.close),
),
),
),
],
),
);
}
Widget genTitle(String title, ThemeData themeData) {
return Container(
alignment: Alignment.topLeft,
padding: const EdgeInsets.only(
top: Base.BASE_PADDING,
left: Base.BASE_PADDING,
),
child: Text(
s.About,
style: TextStyle(
fontSize: themeData.textTheme.bodyLarge!.fontSize!,
fontWeight: FontWeight.bold,
),
),
);
}
Widget genConfigListWidget(List<Widget> configList, ThemeData themeData) {
return Container(
margin: listWidgetMargin,
padding: const EdgeInsets.only(
left: Base.BASE_PADDING,
right: Base.BASE_PADDING,
top: 3,
bottom: 3,
),
decoration: BoxDecoration(
color: themeData.cardColor,
borderRadius: BorderRadius.circular(
Base.BASE_PADDING,
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: configList,
),
);
}
List<EnumObj>? i18nList;
void initI18nList(S s) {
if (i18nList == null) {
i18nList = [];
i18nList!.add(EnumObj("", s.auto));
for (var item in S.delegate.supportedLocales) {
var key = LocaleUtil.getLocaleKey(item);
i18nList!.add(EnumObj(key, key));
}
}
}
EnumObj getI18nList(String? i18n, String? i18nCC) {
var key = LocaleUtil.genLocaleKeyFromSring(i18n, i18nCC);
for (var eo in i18nList!) {
if (eo.value == key) {
return eo;
}
}
return EnumObj("", S.of(context).auto);
}
Future pickI18N() async {
EnumObj? resultEnumObj =
await EnumSelectorComponent.show(context, i18nList!);
if (resultEnumObj != null) {
if (resultEnumObj.value == "") {
settingProvider.setI18n(null, null);
} else {
for (var item in S.delegate.supportedLocales) {
var key = LocaleUtil.getLocaleKey(item);
if (resultEnumObj.value == key) {
settingProvider.setI18n(item.languageCode, item.countryCode);
}
}
}
resetTheme();
Future.delayed(Duration(seconds: 1), () {
setState(() {
// TODO others setting enumObjList
i18nList = null;
themeStyleList = null;
});
});
}
}
List<EnumObj>? themeStyleList;
void initThemeStyleList(S s) {
if (themeStyleList == null) {
themeStyleList = [];
themeStyleList?.add(EnumObj(ThemeStyle.AUTO, s.Follow_System));
themeStyleList?.add(EnumObj(ThemeStyle.LIGHT, s.Light));
themeStyleList?.add(EnumObj(ThemeStyle.DARK, s.Dark));
}
}
Future<void> pickThemeStyle() async {
EnumObj? resultEnumObj =
await EnumSelectorComponent.show(context, themeStyleList!);
if (resultEnumObj != null) {
settingProvider.themeStyle = resultEnumObj.value;
resetTheme();
}
}
EnumObj getThemeStyle(int themeStyle) {
for (var eo in themeStyleList!) {
if (eo.value == themeStyle) {
return eo;
}
}
return themeStyleList![0];
}
}

20
lib/util/locale_util.dart Normal file
View File

@@ -0,0 +1,20 @@
import 'package:flutter/material.dart';
import 'package:nostr_sdk/utils/string_util.dart';
class LocaleUtil {
static String getLocaleKey(Locale l) {
var key = l.languageCode;
if (StringUtil.isNotBlank(l.countryCode)) {
key += "_" + l.countryCode!;
}
return key;
}
static String? genLocaleKeyFromSring(String? i18n, String? i18nCC) {
var key = i18n;
if (StringUtil.isNotBlank(key) && StringUtil.isNotBlank(i18nCC)) {
key = key! + "_" + i18nCC!;
}
return key;
}
}

View File

@@ -7,16 +7,16 @@
#include "generated_plugin_registrant.h"
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
#include <screen_retriever/screen_retriever_plugin.h>
#include <screen_retriever_linux/screen_retriever_linux_plugin.h>
#include <window_manager/window_manager_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
g_autoptr(FlPluginRegistrar) screen_retriever_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverPlugin");
screen_retriever_plugin_register_with_registrar(screen_retriever_registrar);
g_autoptr(FlPluginRegistrar) screen_retriever_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "ScreenRetrieverLinuxPlugin");
screen_retriever_linux_plugin_register_with_registrar(screen_retriever_linux_registrar);
g_autoptr(FlPluginRegistrar) window_manager_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "WindowManagerPlugin");
window_manager_plugin_register_with_registrar(window_manager_registrar);

View File

@@ -4,7 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST
flutter_secure_storage_linux
screen_retriever
screen_retriever_linux
window_manager
)

View File

@@ -10,7 +10,7 @@ import device_info_plus
import flutter_inappwebview_macos
import flutter_secure_storage_macos
import path_provider_foundation
import screen_retriever
import screen_retriever_macos
import shared_preferences_foundation
import sqflite_darwin
import window_manager
@@ -21,7 +21,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
ScreenRetrieverPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverPlugin"))
ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin"))

View File

@@ -8,7 +8,7 @@
#include <flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h>
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
#include <screen_retriever/screen_retriever_plugin.h>
#include <screen_retriever_windows/screen_retriever_windows_plugin_c_api.h>
#include <window_manager/window_manager_plugin.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
@@ -16,8 +16,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi"));
FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
ScreenRetrieverPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ScreenRetrieverPlugin"));
ScreenRetrieverWindowsPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ScreenRetrieverWindowsPluginCApi"));
WindowManagerPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("WindowManagerPlugin"));
}

View File

@@ -5,7 +5,7 @@
list(APPEND FLUTTER_PLUGIN_LIST
flutter_inappwebview_windows
flutter_secure_storage_windows
screen_retriever
screen_retriever_windows
window_manager
)