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

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]