mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2025-02-23 09:40:40 +01:00
[Tests] Add login widget tests
[I18n] Make logic wisget test compatible Took 1 hour 5 minutes
This commit is contained in:
parent
ff02c581d1
commit
7a3ef82546
@ -43,15 +43,15 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
|||||||
widget.room.pushRuleState == PushRuleState.notify
|
widget.room.pushRuleState == PushRuleState.notify
|
||||||
? PopupMenuItem<String>(
|
? PopupMenuItem<String>(
|
||||||
value: "mute",
|
value: "mute",
|
||||||
child: Text(I18n.of(context).muteChat),
|
child: Text(I18n.tr(context).muteChat),
|
||||||
)
|
)
|
||||||
: PopupMenuItem<String>(
|
: PopupMenuItem<String>(
|
||||||
value: "unmute",
|
value: "unmute",
|
||||||
child: Text(I18n.of(context).unmuteChat),
|
child: Text(I18n.tr(context).unmuteChat),
|
||||||
),
|
),
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
value: "leave",
|
value: "leave",
|
||||||
child: Text(I18n.of(context).leave),
|
child: Text(I18n.tr(context).leave),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
if (widget.displayChatDetails) {
|
if (widget.displayChatDetails) {
|
||||||
@ -59,7 +59,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
|
|||||||
0,
|
0,
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
value: "details",
|
value: "details",
|
||||||
child: Text(I18n.of(context).chatDetails),
|
child: Text(I18n.tr(context).chatDetails),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class SimpleDialogs {
|
|||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (c) => AlertDialog(
|
builder: (c) => AlertDialog(
|
||||||
title: Text(titleText ?? I18n.of(context).enterAUsername),
|
title: Text(titleText ?? I18n.tr(context).enterAUsername),
|
||||||
content: TextField(
|
content: TextField(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
@ -48,14 +48,14 @@ class SimpleDialogs {
|
|||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text(
|
child: Text(
|
||||||
cancelText?.toUpperCase() ??
|
cancelText?.toUpperCase() ??
|
||||||
I18n.of(context).close.toUpperCase(),
|
I18n.tr(context).close.toUpperCase(),
|
||||||
style: TextStyle(color: Colors.blueGrey)),
|
style: TextStyle(color: Colors.blueGrey)),
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
),
|
),
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text(
|
child: Text(
|
||||||
confirmText?.toUpperCase() ??
|
confirmText?.toUpperCase() ??
|
||||||
I18n.of(context).confirm.toUpperCase(),
|
I18n.tr(context).confirm.toUpperCase(),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
input = controller.text;
|
input = controller.text;
|
||||||
@ -77,19 +77,19 @@ class SimpleDialogs {
|
|||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (c) => AlertDialog(
|
builder: (c) => AlertDialog(
|
||||||
title: Text(titleText ?? I18n.of(context).areYouSure),
|
title: Text(titleText ?? I18n.tr(context).areYouSure),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text(
|
child: Text(
|
||||||
cancelText?.toUpperCase() ??
|
cancelText?.toUpperCase() ??
|
||||||
I18n.of(context).close.toUpperCase(),
|
I18n.tr(context).close.toUpperCase(),
|
||||||
style: TextStyle(color: Colors.blueGrey)),
|
style: TextStyle(color: Colors.blueGrey)),
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
),
|
),
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text(
|
child: Text(
|
||||||
confirmText?.toUpperCase() ??
|
confirmText?.toUpperCase() ??
|
||||||
I18n.of(context).confirm.toUpperCase(),
|
I18n.tr(context).confirm.toUpperCase(),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
confirmed = true;
|
confirmed = true;
|
||||||
|
@ -32,7 +32,9 @@ class ChatListItem extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (room.membership == Membership.ban) {
|
if (room.membership == Membership.ban) {
|
||||||
Toast.show(I18n.of(context).youHaveBeenBannedFromThisChat, context,
|
Toast.show(
|
||||||
|
I18n.tr(context).youHaveBeenBannedFromThisChat,
|
||||||
|
context,
|
||||||
duration: 5);
|
duration: 5);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -41,16 +43,19 @@ class ChatListItem extends StatelessWidget {
|
|||||||
await showDialog(
|
await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) => AlertDialog(
|
builder: (BuildContext context) => AlertDialog(
|
||||||
title: Text(I18n.of(context).archivedRoom),
|
title: Text(I18n.tr(context).archivedRoom),
|
||||||
content: Text(I18n.of(context).thisRoomHasBeenArchived),
|
content: Text(
|
||||||
|
I18n.tr(context).thisRoomHasBeenArchived),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text(I18n.of(context).close.toUpperCase(),
|
child: Text(
|
||||||
|
I18n.tr(context).close.toUpperCase(),
|
||||||
style: TextStyle(color: Colors.blueGrey)),
|
style: TextStyle(color: Colors.blueGrey)),
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
),
|
),
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text(I18n.of(context).delete.toUpperCase(),
|
child: Text(
|
||||||
|
I18n.tr(context).delete.toUpperCase(),
|
||||||
style: TextStyle(color: Colors.red)),
|
style: TextStyle(color: Colors.red)),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await archiveAction(context);
|
await archiveAction(context);
|
||||||
@ -58,7 +63,8 @@ class ChatListItem extends StatelessWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: Text(I18n.of(context).rejoin.toUpperCase(),
|
child: Text(
|
||||||
|
I18n.tr(context).rejoin.toUpperCase(),
|
||||||
style: TextStyle(color: Colors.blue)),
|
style: TextStyle(color: Colors.blue)),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await Matrix.of(context)
|
await Matrix.of(context)
|
||||||
@ -115,14 +121,14 @@ class ChatListItem extends StatelessWidget {
|
|||||||
secondaryActions: <Widget>[
|
secondaryActions: <Widget>[
|
||||||
if ([Membership.join, Membership.invite].contains(room.membership))
|
if ([Membership.join, Membership.invite].contains(room.membership))
|
||||||
IconSlideAction(
|
IconSlideAction(
|
||||||
caption: I18n.of(context).leave,
|
caption: I18n.tr(context).leave,
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
icon: Icons.archive,
|
icon: Icons.archive,
|
||||||
onTap: () => archiveAction(context),
|
onTap: () => archiveAction(context),
|
||||||
),
|
),
|
||||||
if ([Membership.leave, Membership.ban].contains(room.membership))
|
if ([Membership.leave, Membership.ban].contains(room.membership))
|
||||||
IconSlideAction(
|
IconSlideAction(
|
||||||
caption: I18n.of(context).delete,
|
caption: I18n.tr(context).delete,
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
icon: Icons.delete_forever,
|
icon: Icons.delete_forever,
|
||||||
onTap: () => archiveAction(context),
|
onTap: () => archiveAction(context),
|
||||||
@ -170,7 +176,8 @@ class ChatListItem extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: room.membership == Membership.invite
|
child: room.membership == Membership.invite
|
||||||
? Text(
|
? Text(
|
||||||
I18n.of(context).youAreInvitedToThisChat,
|
I18n.tr(context)
|
||||||
|
.youAreInvitedToThisChat,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
),
|
),
|
||||||
|
@ -79,7 +79,7 @@ class Message extends StatelessWidget {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(
|
||||||
ownMessage
|
ownMessage
|
||||||
? I18n.of(context).you
|
? I18n.tr(context).you
|
||||||
: event.sender.calcDisplayname(),
|
: event.sender.calcDisplayname(),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: ownMessage
|
color: ownMessage
|
||||||
|
@ -62,19 +62,19 @@ class ParticipantListItem extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
Map<Membership, String> membershipBatch = {
|
Map<Membership, String> membershipBatch = {
|
||||||
Membership.join: "",
|
Membership.join: "",
|
||||||
Membership.ban: I18n.of(context).banned,
|
Membership.ban: I18n.tr(context).banned,
|
||||||
Membership.invite: I18n.of(context).invited,
|
Membership.invite: I18n.tr(context).invited,
|
||||||
Membership.leave: I18n.of(context).leftTheChat,
|
Membership.leave: I18n.tr(context).leftTheChat,
|
||||||
};
|
};
|
||||||
final String permissionBatch = user.powerLevel == 100
|
final String permissionBatch = user.powerLevel == 100
|
||||||
? I18n.of(context).admin
|
? I18n.tr(context).admin
|
||||||
: user.powerLevel >= 50 ? I18n.of(context).moderator : "";
|
: user.powerLevel >= 50 ? I18n.tr(context).moderator : "";
|
||||||
List<PopupMenuEntry<String>> items = <PopupMenuEntry<String>>[];
|
List<PopupMenuEntry<String>> items = <PopupMenuEntry<String>>[];
|
||||||
|
|
||||||
if (user.id != Matrix.of(context).client.userID) {
|
if (user.id != Matrix.of(context).client.userID) {
|
||||||
items.add(
|
items.add(
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Text(I18n.of(context).sendAMessage), value: "message"),
|
child: Text(I18n.tr(context).sendAMessage), value: "message"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (user.canChangePowerLevel &&
|
if (user.canChangePowerLevel &&
|
||||||
@ -82,7 +82,7 @@ class ParticipantListItem extends StatelessWidget {
|
|||||||
user.powerLevel != 100) {
|
user.powerLevel != 100) {
|
||||||
items.add(
|
items.add(
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Text(I18n.of(context).makeAnAdmin), value: "admin"),
|
child: Text(I18n.tr(context).makeAnAdmin), value: "admin"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (user.canChangePowerLevel &&
|
if (user.canChangePowerLevel &&
|
||||||
@ -90,29 +90,29 @@ class ParticipantListItem extends StatelessWidget {
|
|||||||
user.powerLevel != 50) {
|
user.powerLevel != 50) {
|
||||||
items.add(
|
items.add(
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Text(I18n.of(context).makeAModerator), value: "moderator"),
|
child: Text(I18n.tr(context).makeAModerator), value: "moderator"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (user.canChangePowerLevel && user.powerLevel != 0) {
|
if (user.canChangePowerLevel && user.powerLevel != 0) {
|
||||||
items.add(
|
items.add(
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Text(I18n.of(context).revokeAllPermissions), value: "user"),
|
child: Text(I18n.tr(context).revokeAllPermissions), value: "user"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (user.canKick) {
|
if (user.canKick) {
|
||||||
items.add(
|
items.add(
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Text(I18n.of(context).kickFromChat), value: "kick"),
|
child: Text(I18n.tr(context).kickFromChat), value: "kick"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (user.canBan && user.membership != Membership.ban) {
|
if (user.canBan && user.membership != Membership.ban) {
|
||||||
items.add(
|
items.add(
|
||||||
PopupMenuItem(child: Text(I18n.of(context).banFromChat), value: "ban"),
|
PopupMenuItem(child: Text(I18n.tr(context).banFromChat), value: "ban"),
|
||||||
);
|
);
|
||||||
} else if (user.canBan && user.membership == Membership.ban) {
|
} else if (user.canBan && user.membership == Membership.ban) {
|
||||||
items.add(
|
items.add(
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Text(I18n.of(context).removeExile), value: "unban"),
|
child: Text(I18n.tr(context).removeExile), value: "unban"),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return PopupMenuButton(
|
return PopupMenuButton(
|
||||||
|
@ -104,7 +104,7 @@ class MatrixState extends State<Matrix> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
CircularProgressIndicator(),
|
CircularProgressIndicator(),
|
||||||
SizedBox(width: 16),
|
SizedBox(width: 16),
|
||||||
Text(I18n.of(context).loadingPleaseWait),
|
Text(I18n.tr(context).loadingPleaseWait),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -140,7 +140,7 @@ class MatrixState extends State<Matrix> {
|
|||||||
final String token = await _firebaseMessaging.getToken();
|
final String token = await _firebaseMessaging.getToken();
|
||||||
if (token?.isEmpty ?? true) {
|
if (token?.isEmpty ?? true) {
|
||||||
return Toast.show(
|
return Toast.show(
|
||||||
I18n.of(context).noGoogleServicesWarning,
|
I18n.tr(context).noGoogleServicesWarning,
|
||||||
context,
|
context,
|
||||||
duration: 10,
|
duration: 10,
|
||||||
);
|
);
|
||||||
@ -233,9 +233,9 @@ class MatrixState extends State<Matrix> {
|
|||||||
|
|
||||||
// Calculate title
|
// Calculate title
|
||||||
final String title = unread > 1
|
final String title = unread > 1
|
||||||
? I18n.of(context).unreadMessagesInChats(
|
? I18n.tr(context).unreadMessagesInChats(
|
||||||
unreadEvents.toString(), unread.toString())
|
unreadEvents.toString(), unread.toString())
|
||||||
: I18n.of(context).unreadMessages(unreadEvents.toString());
|
: I18n.tr(context).unreadMessages(unreadEvents.toString());
|
||||||
|
|
||||||
// Calculate the body
|
// Calculate the body
|
||||||
final String body = event.getLocalizedBody(context,
|
final String body = event.getLocalizedBody(context,
|
||||||
@ -273,7 +273,7 @@ class MatrixState extends State<Matrix> {
|
|||||||
),
|
),
|
||||||
importance: Importance.Max,
|
importance: Importance.Max,
|
||||||
priority: Priority.High,
|
priority: Priority.High,
|
||||||
ticker: I18n.of(context).newMessageInFluffyChat);
|
ticker: I18n.tr(context).newMessageInFluffyChat);
|
||||||
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
|
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
|
||||||
var platformChannelSpecifics = NotificationDetails(
|
var platformChannelSpecifics = NotificationDetails(
|
||||||
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
|
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
|
||||||
|
@ -68,7 +68,7 @@ class MessageContent extends StatelessWidget {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Icon(Icons.play_arrow, color: Colors.white),
|
Icon(Icons.play_arrow, color: Colors.white),
|
||||||
Text(
|
Text(
|
||||||
I18n.of(context).play(event.body),
|
I18n.tr(context).play(event.body),
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
softWrap: false,
|
softWrap: false,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
@ -93,7 +93,7 @@ class MessageContent extends StatelessWidget {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Icon(Icons.play_arrow, color: Colors.white),
|
Icon(Icons.play_arrow, color: Colors.white),
|
||||||
Text(
|
Text(
|
||||||
I18n.of(context).play(event.body),
|
I18n.tr(context).play(event.body),
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
softWrap: false,
|
softWrap: false,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
@ -115,7 +115,7 @@ class MessageContent extends StatelessWidget {
|
|||||||
child: RaisedButton(
|
child: RaisedButton(
|
||||||
color: Colors.blueGrey,
|
color: Colors.blueGrey,
|
||||||
child: Text(
|
child: Text(
|
||||||
I18n.of(context).download(event.body),
|
I18n.tr(context).download(event.body),
|
||||||
overflow: TextOverflow.fade,
|
overflow: TextOverflow.fade,
|
||||||
softWrap: false,
|
softWrap: false,
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
@ -150,7 +150,7 @@ class MessageContent extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return Text(
|
return Text(
|
||||||
I18n.of(context).userSentUnknownEvent(
|
I18n.tr(context).userSentUnknownEvent(
|
||||||
event.sender.calcDisplayname(), event.typeKey),
|
event.sender.calcDisplayname(), event.typeKey),
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: textColor,
|
color: textColor,
|
||||||
|
@ -2,7 +2,8 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'messages_all.dart';
|
import 'messages_all.dart';
|
||||||
|
|
||||||
class AppLocalizationsDelegate extends LocalizationsDelegate<I18n> {
|
class AppLocalizationsDelegate
|
||||||
|
extends LocalizationsDelegate<FluffychatLocalizations> {
|
||||||
const AppLocalizationsDelegate();
|
const AppLocalizationsDelegate();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -11,36 +12,52 @@ class AppLocalizationsDelegate extends LocalizationsDelegate<I18n> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<I18n> load(Locale locale) {
|
Future<FluffychatLocalizations> load(Locale locale) {
|
||||||
return I18n.load(locale);
|
return FluffychatLocalizations.load(locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool shouldReload(LocalizationsDelegate<I18n> old) {
|
bool shouldReload(LocalizationsDelegate<FluffychatLocalizations> old) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class I18n {
|
class I18n {
|
||||||
I18n(this.localeName);
|
static FluffychatLocalizations tr(BuildContext context) {
|
||||||
|
FluffychatLocalizations fluffychatLocalizations =
|
||||||
|
FluffychatLocalizations.of(context);
|
||||||
|
if (fluffychatLocalizations != null) {
|
||||||
|
return fluffychatLocalizations;
|
||||||
|
} else {
|
||||||
|
return FluffychatLocalizations("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static Future<I18n> load(Locale locale) {
|
class FluffychatLocalizations {
|
||||||
|
FluffychatLocalizations(this.localeName);
|
||||||
|
|
||||||
|
static Future<FluffychatLocalizations> load(Locale locale) {
|
||||||
final String name =
|
final String name =
|
||||||
locale.countryCode == null ? locale.languageCode : locale.toString();
|
locale.countryCode == null ? locale.languageCode : locale.toString();
|
||||||
final String localeName = Intl.canonicalizedLocale(name);
|
final String localeName = Intl.canonicalizedLocale(name);
|
||||||
|
|
||||||
return initializeMessages(localeName).then((bool _) {
|
return initializeMessages(localeName).then((bool _) {
|
||||||
Intl.defaultLocale = localeName;
|
Intl.defaultLocale = localeName;
|
||||||
return I18n(localeName);
|
return FluffychatLocalizations(localeName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static I18n of(BuildContext context) {
|
static FluffychatLocalizations of(BuildContext context) {
|
||||||
return Localizations.of<I18n>(context, I18n);
|
return Localizations.of<FluffychatLocalizations>(
|
||||||
|
context, FluffychatLocalizations);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String localeName;
|
final String localeName;
|
||||||
|
|
||||||
|
// Dummy function to prevent loops
|
||||||
|
FluffychatLocalizations tr(BuildContext context) => this;
|
||||||
|
|
||||||
/* <=============> Translations <=============> */
|
/* <=============> Translations <=============> */
|
||||||
|
|
||||||
String get about => Intl.message("About");
|
String get about => Intl.message("About");
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
import 'package:universal_html/prefer_universal/html.dart' as html;
|
||||||
|
|
||||||
import 'i18n/i18n.dart';
|
import 'i18n/i18n.dart';
|
||||||
import 'views/sign_up.dart';
|
import 'views/sign_up.dart';
|
||||||
@ -28,14 +30,18 @@ class App extends StatelessWidget {
|
|||||||
theme: ThemeSwitcherWidget.of(context).themeData,
|
theme: ThemeSwitcherWidget.of(context).themeData,
|
||||||
localizationsDelegates: [
|
localizationsDelegates: [
|
||||||
AppLocalizationsDelegate(),
|
AppLocalizationsDelegate(),
|
||||||
GlobalMaterialLocalizations.delegate,
|
|
||||||
GlobalWidgetsLocalizations.delegate,
|
|
||||||
GlobalCupertinoLocalizations.delegate,
|
GlobalCupertinoLocalizations.delegate,
|
||||||
|
GlobalMaterialLocalizations.delegate,
|
||||||
|
GlobalCupertinoLocalizations.delegate,
|
||||||
|
GlobalWidgetsLocalizations.delegate,
|
||||||
],
|
],
|
||||||
supportedLocales: [
|
supportedLocales: [
|
||||||
const Locale('en'), // English
|
const Locale('en'), // English
|
||||||
const Locale('de'), // German
|
const Locale('de'), // German
|
||||||
],
|
],
|
||||||
|
locale: kIsWeb
|
||||||
|
? Locale(html.window.navigator.language.split("-").first)
|
||||||
|
: null,
|
||||||
home: FutureBuilder<LoginState>(
|
home: FutureBuilder<LoginState>(
|
||||||
future:
|
future:
|
||||||
Matrix.of(context).client.onLoginStateChanged.stream.first,
|
Matrix.of(context).client.onLoginStateChanged.stream.first,
|
||||||
|
@ -34,7 +34,7 @@ extension DateTimeExtension on DateTime {
|
|||||||
/// Returns a simple time String.
|
/// Returns a simple time String.
|
||||||
/// TODO: Add localization
|
/// TODO: Add localization
|
||||||
String localizedTimeOfDay(BuildContext context) {
|
String localizedTimeOfDay(BuildContext context) {
|
||||||
return I18n.of(context).timeOfDay(_z(this.hour % 12), _z(this.hour),
|
return I18n.tr(context).timeOfDay(_z(this.hour % 12), _z(this.hour),
|
||||||
_z(this.minute), this.hour > 11 ? 'pm' : 'am');
|
_z(this.minute), this.hour > 11 ? 'pm' : 'am');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,26 +57,26 @@ extension DateTimeExtension on DateTime {
|
|||||||
} else if (sameWeek) {
|
} else if (sameWeek) {
|
||||||
switch (this.weekday) {
|
switch (this.weekday) {
|
||||||
case 1:
|
case 1:
|
||||||
return I18n.of(context).monday;
|
return I18n.tr(context).monday;
|
||||||
case 2:
|
case 2:
|
||||||
return I18n.of(context).tuesday;
|
return I18n.tr(context).tuesday;
|
||||||
case 3:
|
case 3:
|
||||||
return I18n.of(context).wednesday;
|
return I18n.tr(context).wednesday;
|
||||||
case 4:
|
case 4:
|
||||||
return I18n.of(context).thursday;
|
return I18n.tr(context).thursday;
|
||||||
case 5:
|
case 5:
|
||||||
return I18n.of(context).friday;
|
return I18n.tr(context).friday;
|
||||||
case 6:
|
case 6:
|
||||||
return I18n.of(context).saturday;
|
return I18n.tr(context).saturday;
|
||||||
case 7:
|
case 7:
|
||||||
return I18n.of(context).sunday;
|
return I18n.tr(context).sunday;
|
||||||
}
|
}
|
||||||
} else if (sameYear) {
|
} else if (sameYear) {
|
||||||
return I18n.of(context).dateWithoutYear(
|
return I18n.tr(context).dateWithoutYear(
|
||||||
this.month.toString().padLeft(2, '0'),
|
this.month.toString().padLeft(2, '0'),
|
||||||
this.day.toString().padLeft(2, '0'));
|
this.day.toString().padLeft(2, '0'));
|
||||||
}
|
}
|
||||||
return I18n.of(context).dateWithYear(
|
return I18n.tr(context).dateWithYear(
|
||||||
this.year.toString(),
|
this.year.toString(),
|
||||||
this.month.toString().padLeft(2, '0'),
|
this.month.toString().padLeft(2, '0'),
|
||||||
this.day.toString().padLeft(2, '0'));
|
this.day.toString().padLeft(2, '0'));
|
||||||
@ -93,7 +93,7 @@ extension DateTimeExtension on DateTime {
|
|||||||
bool sameDay = sameYear && now.month == this.month && now.day == this.day;
|
bool sameDay = sameYear && now.month == this.month && now.day == this.day;
|
||||||
|
|
||||||
if (sameDay) return localizedTimeOfDay(context);
|
if (sameDay) return localizedTimeOfDay(context);
|
||||||
return I18n.of(context).dateAndTimeOfDay(
|
return I18n.tr(context).dateAndTimeOfDay(
|
||||||
localizedTimeShort(context), localizedTimeOfDay(context));
|
localizedTimeShort(context), localizedTimeOfDay(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,27 +15,27 @@ extension LocalizedBody on Event {
|
|||||||
String getLocalizedBody(BuildContext context,
|
String getLocalizedBody(BuildContext context,
|
||||||
{bool withSenderNamePrefix = false, bool hideQuotes = false}) {
|
{bool withSenderNamePrefix = false, bool hideQuotes = false}) {
|
||||||
if (this.redacted) {
|
if (this.redacted) {
|
||||||
return I18n.of(context)
|
return I18n.tr(context)
|
||||||
.removedBy(redactedBecause.sender.calcDisplayname());
|
.removedBy(redactedBecause.sender.calcDisplayname());
|
||||||
}
|
}
|
||||||
String localizedBody = body;
|
String localizedBody = body;
|
||||||
final String senderName = this.sender.calcDisplayname();
|
final String senderName = this.sender.calcDisplayname();
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case EventTypes.Sticker:
|
case EventTypes.Sticker:
|
||||||
localizedBody = I18n.of(context).sentASticker(senderName);
|
localizedBody = I18n.tr(context).sentASticker(senderName);
|
||||||
break;
|
break;
|
||||||
case EventTypes.Redaction:
|
case EventTypes.Redaction:
|
||||||
localizedBody = I18n.of(context).redactedAnEvent(senderName);
|
localizedBody = I18n.tr(context).redactedAnEvent(senderName);
|
||||||
break;
|
break;
|
||||||
case EventTypes.RoomAliases:
|
case EventTypes.RoomAliases:
|
||||||
localizedBody = I18n.of(context).changedTheRoomAliases(senderName);
|
localizedBody = I18n.tr(context).changedTheRoomAliases(senderName);
|
||||||
break;
|
break;
|
||||||
case EventTypes.RoomCanonicalAlias:
|
case EventTypes.RoomCanonicalAlias:
|
||||||
localizedBody =
|
localizedBody =
|
||||||
I18n.of(context).changedTheRoomInvitationLink(senderName);
|
I18n.tr(context).changedTheRoomInvitationLink(senderName);
|
||||||
break;
|
break;
|
||||||
case EventTypes.RoomCreate:
|
case EventTypes.RoomCreate:
|
||||||
localizedBody = I18n.of(context).createdTheChat(senderName);
|
localizedBody = I18n.tr(context).createdTheChat(senderName);
|
||||||
break;
|
break;
|
||||||
case EventTypes.RoomJoinRules:
|
case EventTypes.RoomJoinRules:
|
||||||
JoinRules joinRules = JoinRules.values.firstWhere(
|
JoinRules joinRules = JoinRules.values.firstWhere(
|
||||||
@ -44,9 +44,9 @@ extension LocalizedBody on Event {
|
|||||||
content["join_rule"],
|
content["join_rule"],
|
||||||
orElse: () => null);
|
orElse: () => null);
|
||||||
if (joinRules == null) {
|
if (joinRules == null) {
|
||||||
localizedBody = I18n.of(context).changedTheJoinRules(senderName);
|
localizedBody = I18n.tr(context).changedTheJoinRules(senderName);
|
||||||
} else {
|
} else {
|
||||||
localizedBody = I18n.of(context).changedTheJoinRulesTo(
|
localizedBody = I18n.tr(context).changedTheJoinRulesTo(
|
||||||
senderName, joinRules.getLocalizedString(context));
|
senderName, joinRules.getLocalizedString(context));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -61,36 +61,36 @@ extension LocalizedBody on Event {
|
|||||||
: "";
|
: "";
|
||||||
if (newMembership != oldMembership) {
|
if (newMembership != oldMembership) {
|
||||||
if (oldMembership == "invite" && newMembership == "join") {
|
if (oldMembership == "invite" && newMembership == "join") {
|
||||||
text = I18n.of(context).acceptedTheInvitation(targetName);
|
text = I18n.tr(context).acceptedTheInvitation(targetName);
|
||||||
} else if (oldMembership == "invite" && newMembership == "leave") {
|
} else if (oldMembership == "invite" && newMembership == "leave") {
|
||||||
if (this.stateKey == this.senderId) {
|
if (this.stateKey == this.senderId) {
|
||||||
text = I18n.of(context).rejectedTheInvitation(targetName);
|
text = I18n.tr(context).rejectedTheInvitation(targetName);
|
||||||
} else {
|
} else {
|
||||||
text = I18n.of(context)
|
text = I18n.tr(context)
|
||||||
.hasWithdrawnTheInvitationFor(senderName, targetName);
|
.hasWithdrawnTheInvitationFor(senderName, targetName);
|
||||||
}
|
}
|
||||||
} else if (oldMembership == "leave" && newMembership == "join") {
|
} else if (oldMembership == "leave" && newMembership == "join") {
|
||||||
text = I18n.of(context).joinedTheChat(targetName);
|
text = I18n.tr(context).joinedTheChat(targetName);
|
||||||
} else if (oldMembership == "join" && newMembership == "ban") {
|
} else if (oldMembership == "join" && newMembership == "ban") {
|
||||||
text = I18n.of(context).kickedAndBanned(senderName, targetName);
|
text = I18n.tr(context).kickedAndBanned(senderName, targetName);
|
||||||
} else if (oldMembership == "join" &&
|
} else if (oldMembership == "join" &&
|
||||||
newMembership == "leave" &&
|
newMembership == "leave" &&
|
||||||
this.stateKey != this.senderId) {
|
this.stateKey != this.senderId) {
|
||||||
text = I18n.of(context).kicked(senderName, targetName);
|
text = I18n.tr(context).kicked(senderName, targetName);
|
||||||
} else if (oldMembership == "join" &&
|
} else if (oldMembership == "join" &&
|
||||||
newMembership == "leave" &&
|
newMembership == "leave" &&
|
||||||
this.stateKey == this.senderId) {
|
this.stateKey == this.senderId) {
|
||||||
text = I18n.of(context).userLeftTheChat(targetName);
|
text = I18n.tr(context).userLeftTheChat(targetName);
|
||||||
} else if (oldMembership == "invite" && newMembership == "ban") {
|
} else if (oldMembership == "invite" && newMembership == "ban") {
|
||||||
text = I18n.of(context).bannedUser(senderName, targetName);
|
text = I18n.tr(context).bannedUser(senderName, targetName);
|
||||||
} else if (oldMembership == "leave" && newMembership == "ban") {
|
} else if (oldMembership == "leave" && newMembership == "ban") {
|
||||||
text = I18n.of(context).bannedUser(senderName, targetName);
|
text = I18n.tr(context).bannedUser(senderName, targetName);
|
||||||
} else if (oldMembership == "ban" && newMembership == "leave") {
|
} else if (oldMembership == "ban" && newMembership == "leave") {
|
||||||
text = I18n.of(context).unbannedUser(senderName, targetName);
|
text = I18n.tr(context).unbannedUser(senderName, targetName);
|
||||||
} else if (newMembership == "invite") {
|
} else if (newMembership == "invite") {
|
||||||
text = I18n.of(context).invitedUser(senderName, targetName);
|
text = I18n.tr(context).invitedUser(senderName, targetName);
|
||||||
} else if (newMembership == "join") {
|
} else if (newMembership == "join") {
|
||||||
text = I18n.of(context).joinedTheChat(targetName);
|
text = I18n.tr(context).joinedTheChat(targetName);
|
||||||
}
|
}
|
||||||
} else if (newMembership == "join") {
|
} else if (newMembership == "join") {
|
||||||
final String newAvatar = this.content["avatar_url"] ?? "";
|
final String newAvatar = this.content["avatar_url"] ?? "";
|
||||||
@ -107,29 +107,29 @@ extension LocalizedBody on Event {
|
|||||||
|
|
||||||
// Has the user avatar changed?
|
// Has the user avatar changed?
|
||||||
if (newAvatar != oldAvatar) {
|
if (newAvatar != oldAvatar) {
|
||||||
text = I18n.of(context).changedTheProfileAvatar(targetName);
|
text = I18n.tr(context).changedTheProfileAvatar(targetName);
|
||||||
}
|
}
|
||||||
// Has the user avatar changed?
|
// Has the user avatar changed?
|
||||||
else if (newDisplayname != oldDisplayname) {
|
else if (newDisplayname != oldDisplayname) {
|
||||||
text = I18n.of(context)
|
text = I18n.tr(context)
|
||||||
.changedTheDisplaynameTo(targetName, newDisplayname);
|
.changedTheDisplaynameTo(targetName, newDisplayname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
localizedBody = text;
|
localizedBody = text;
|
||||||
break;
|
break;
|
||||||
case EventTypes.RoomPowerLevels:
|
case EventTypes.RoomPowerLevels:
|
||||||
localizedBody = I18n.of(context).changedTheChatPermissions(senderName);
|
localizedBody = I18n.tr(context).changedTheChatPermissions(senderName);
|
||||||
break;
|
break;
|
||||||
case EventTypes.RoomName:
|
case EventTypes.RoomName:
|
||||||
localizedBody =
|
localizedBody =
|
||||||
I18n.of(context).changedTheChatNameTo(senderName, content["name"]);
|
I18n.tr(context).changedTheChatNameTo(senderName, content["name"]);
|
||||||
break;
|
break;
|
||||||
case EventTypes.RoomTopic:
|
case EventTypes.RoomTopic:
|
||||||
localizedBody = I18n.of(context)
|
localizedBody = I18n.tr(context)
|
||||||
.changedTheChatDescriptionTo(senderName, content["topic"]);
|
.changedTheChatDescriptionTo(senderName, content["topic"]);
|
||||||
break;
|
break;
|
||||||
case EventTypes.RoomAvatar:
|
case EventTypes.RoomAvatar:
|
||||||
localizedBody = I18n.of(context).changedTheChatAvatar(senderName);
|
localizedBody = I18n.tr(context).changedTheChatAvatar(senderName);
|
||||||
break;
|
break;
|
||||||
case EventTypes.GuestAccess:
|
case EventTypes.GuestAccess:
|
||||||
GuestAccess guestAccess = GuestAccess.values.firstWhere(
|
GuestAccess guestAccess = GuestAccess.values.firstWhere(
|
||||||
@ -139,9 +139,9 @@ extension LocalizedBody on Event {
|
|||||||
orElse: () => null);
|
orElse: () => null);
|
||||||
if (guestAccess == null) {
|
if (guestAccess == null) {
|
||||||
localizedBody =
|
localizedBody =
|
||||||
I18n.of(context).changedTheGuestAccessRules(senderName);
|
I18n.tr(context).changedTheGuestAccessRules(senderName);
|
||||||
} else {
|
} else {
|
||||||
localizedBody = I18n.of(context).changedTheGuestAccessRulesTo(
|
localizedBody = I18n.tr(context).changedTheGuestAccessRulesTo(
|
||||||
senderName, guestAccess.getLocalizedString(context));
|
senderName, guestAccess.getLocalizedString(context));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -154,48 +154,48 @@ extension LocalizedBody on Event {
|
|||||||
orElse: () => null);
|
orElse: () => null);
|
||||||
if (historyVisibility == null) {
|
if (historyVisibility == null) {
|
||||||
localizedBody =
|
localizedBody =
|
||||||
I18n.of(context).changedTheHistoryVisibility(senderName);
|
I18n.tr(context).changedTheHistoryVisibility(senderName);
|
||||||
} else {
|
} else {
|
||||||
localizedBody = I18n.of(context).changedTheHistoryVisibilityTo(
|
localizedBody = I18n.tr(context).changedTheHistoryVisibilityTo(
|
||||||
senderName, historyVisibility.getLocalizedString(context));
|
senderName, historyVisibility.getLocalizedString(context));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EventTypes.Encryption:
|
case EventTypes.Encryption:
|
||||||
localizedBody =
|
localizedBody =
|
||||||
I18n.of(context).activatedEndToEndEncryption(senderName);
|
I18n.tr(context).activatedEndToEndEncryption(senderName);
|
||||||
if (!room.client.encryptionEnabled) {
|
if (!room.client.encryptionEnabled) {
|
||||||
localizedBody += ". " + I18n.of(context).needPantalaimonWarning;
|
localizedBody += ". " + I18n.tr(context).needPantalaimonWarning;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EventTypes.Encrypted:
|
case EventTypes.Encrypted:
|
||||||
localizedBody = I18n.of(context).couldNotDecryptMessage;
|
localizedBody = I18n.tr(context).couldNotDecryptMessage;
|
||||||
break;
|
break;
|
||||||
case EventTypes.Message:
|
case EventTypes.Message:
|
||||||
switch (this.messageType) {
|
switch (this.messageType) {
|
||||||
case MessageTypes.Image:
|
case MessageTypes.Image:
|
||||||
localizedBody = I18n.of(context).sentAPicture(senderName);
|
localizedBody = I18n.tr(context).sentAPicture(senderName);
|
||||||
break;
|
break;
|
||||||
case MessageTypes.File:
|
case MessageTypes.File:
|
||||||
localizedBody = I18n.of(context).sentAFile(senderName);
|
localizedBody = I18n.tr(context).sentAFile(senderName);
|
||||||
break;
|
break;
|
||||||
case MessageTypes.Audio:
|
case MessageTypes.Audio:
|
||||||
localizedBody = I18n.of(context).sentAnAudio(senderName);
|
localizedBody = I18n.tr(context).sentAnAudio(senderName);
|
||||||
break;
|
break;
|
||||||
case MessageTypes.Video:
|
case MessageTypes.Video:
|
||||||
localizedBody = I18n.of(context).sentAVideo(senderName);
|
localizedBody = I18n.tr(context).sentAVideo(senderName);
|
||||||
break;
|
break;
|
||||||
case MessageTypes.Location:
|
case MessageTypes.Location:
|
||||||
localizedBody = I18n.of(context).sharedTheLocation(senderName);
|
localizedBody = I18n.tr(context).sharedTheLocation(senderName);
|
||||||
break;
|
break;
|
||||||
case MessageTypes.Sticker:
|
case MessageTypes.Sticker:
|
||||||
localizedBody = I18n.of(context).sentASticker(senderName);
|
localizedBody = I18n.tr(context).sentASticker(senderName);
|
||||||
break;
|
break;
|
||||||
case MessageTypes.Emote:
|
case MessageTypes.Emote:
|
||||||
localizedBody = "* $body";
|
localizedBody = "* $body";
|
||||||
break;
|
break;
|
||||||
case MessageTypes.BadEncrypted:
|
case MessageTypes.BadEncrypted:
|
||||||
localizedBody =
|
localizedBody =
|
||||||
"🔒 " + I18n.of(context).couldNotDecryptMessage + ": " + body;
|
"🔒 " + I18n.tr(context).couldNotDecryptMessage + ": " + body;
|
||||||
break;
|
break;
|
||||||
case MessageTypes.Text:
|
case MessageTypes.Text:
|
||||||
case MessageTypes.Notice:
|
case MessageTypes.Notice:
|
||||||
@ -206,7 +206,7 @@ extension LocalizedBody on Event {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
localizedBody = I18n.of(context).unknownEvent(this.typeKey);
|
localizedBody = I18n.tr(context).unknownEvent(this.typeKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide quotes
|
// Hide quotes
|
||||||
@ -221,7 +221,7 @@ extension LocalizedBody on Event {
|
|||||||
this.type == EventTypes.Message &&
|
this.type == EventTypes.Message &&
|
||||||
textOnlyMessageTypes.contains(this.messageType)) {
|
textOnlyMessageTypes.contains(this.messageType)) {
|
||||||
final String senderNameOrYou = this.senderId == room.client.userID
|
final String senderNameOrYou = this.senderId == room.client.userID
|
||||||
? I18n.of(context).you
|
? I18n.tr(context).you
|
||||||
: senderName;
|
: senderName;
|
||||||
localizedBody = "$senderNameOrYou: $localizedBody";
|
localizedBody = "$senderNameOrYou: $localizedBody";
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,13 @@ extension LocalizedRoomDisplayname on Room {
|
|||||||
(this.canonicalAlias?.isEmpty ?? true) &&
|
(this.canonicalAlias?.isEmpty ?? true) &&
|
||||||
!this.isDirectChat &&
|
!this.isDirectChat &&
|
||||||
(this.mHeroes != null && this.mHeroes.isNotEmpty)) {
|
(this.mHeroes != null && this.mHeroes.isNotEmpty)) {
|
||||||
return I18n.of(context).groupWith(this.displayname);
|
return I18n.tr(context).groupWith(this.displayname);
|
||||||
}
|
}
|
||||||
if ((this.name?.isEmpty ?? true) &&
|
if ((this.name?.isEmpty ?? true) &&
|
||||||
(this.canonicalAlias?.isEmpty ?? true) &&
|
(this.canonicalAlias?.isEmpty ?? true) &&
|
||||||
!this.isDirectChat &&
|
!this.isDirectChat &&
|
||||||
(this.mHeroes?.isEmpty ?? true)) {
|
(this.mHeroes?.isEmpty ?? true)) {
|
||||||
return I18n.of(context).emptyChat;
|
return I18n.tr(context).emptyChat;
|
||||||
}
|
}
|
||||||
return this.displayname;
|
return this.displayname;
|
||||||
}
|
}
|
||||||
|
@ -6,13 +6,13 @@ extension HistoryVisibilityDisplayString on HistoryVisibility {
|
|||||||
String getLocalizedString(BuildContext context) {
|
String getLocalizedString(BuildContext context) {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case HistoryVisibility.invited:
|
case HistoryVisibility.invited:
|
||||||
return I18n.of(context).fromTheInvitation;
|
return I18n.tr(context).fromTheInvitation;
|
||||||
case HistoryVisibility.joined:
|
case HistoryVisibility.joined:
|
||||||
return I18n.of(context).fromJoining;
|
return I18n.tr(context).fromJoining;
|
||||||
case HistoryVisibility.shared:
|
case HistoryVisibility.shared:
|
||||||
return I18n.of(context).visibleForAllParticipants;
|
return I18n.tr(context).visibleForAllParticipants;
|
||||||
case HistoryVisibility.world_readable:
|
case HistoryVisibility.world_readable:
|
||||||
return I18n.of(context).visibleForEveryone;
|
return I18n.tr(context).visibleForEveryone;
|
||||||
default:
|
default:
|
||||||
return this.toString().replaceAll("HistoryVisibility.", "");
|
return this.toString().replaceAll("HistoryVisibility.", "");
|
||||||
}
|
}
|
||||||
@ -23,9 +23,9 @@ extension GuestAccessDisplayString on GuestAccess {
|
|||||||
String getLocalizedString(BuildContext context) {
|
String getLocalizedString(BuildContext context) {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case GuestAccess.can_join:
|
case GuestAccess.can_join:
|
||||||
return I18n.of(context).guestsCanJoin;
|
return I18n.tr(context).guestsCanJoin;
|
||||||
case GuestAccess.forbidden:
|
case GuestAccess.forbidden:
|
||||||
return I18n.of(context).guestsAreForbidden;
|
return I18n.tr(context).guestsAreForbidden;
|
||||||
default:
|
default:
|
||||||
return this.toString().replaceAll("GuestAccess.", "");
|
return this.toString().replaceAll("GuestAccess.", "");
|
||||||
}
|
}
|
||||||
@ -36,9 +36,9 @@ extension JoinRulesDisplayString on JoinRules {
|
|||||||
String getLocalizedString(BuildContext context) {
|
String getLocalizedString(BuildContext context) {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case JoinRules.public:
|
case JoinRules.public:
|
||||||
return I18n.of(context).anyoneCanJoin;
|
return I18n.tr(context).anyoneCanJoin;
|
||||||
case JoinRules.invite:
|
case JoinRules.invite:
|
||||||
return I18n.of(context).invitedUsersOnly;
|
return I18n.tr(context).invitedUsersOnly;
|
||||||
default:
|
default:
|
||||||
return this.toString().replaceAll("JoinRules.", "");
|
return this.toString().replaceAll("JoinRules.", "");
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ class AppInfo extends StatelessWidget {
|
|||||||
body: ListView(
|
body: ListView(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(I18n.of(context).yourOwnUsername + ":"),
|
title: Text(I18n.tr(context).yourOwnUsername + ":"),
|
||||||
subtitle: Text(client.userID),
|
subtitle: Text(client.userID),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
|
@ -23,7 +23,7 @@ class _ArchiveState extends State<Archive> {
|
|||||||
return AdaptivePageLayout(
|
return AdaptivePageLayout(
|
||||||
firstScaffold: Scaffold(
|
firstScaffold: Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(I18n.of(context).archive),
|
title: Text(I18n.tr(context).archive),
|
||||||
),
|
),
|
||||||
body: FutureBuilder<List<Room>>(
|
body: FutureBuilder<List<Room>>(
|
||||||
future: getArchive(context),
|
future: getArchive(context),
|
||||||
|
@ -19,7 +19,7 @@ class AuthWebView extends StatelessWidget {
|
|||||||
if (kIsWeb) launch(url);
|
if (kIsWeb) launch(url);
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(I18n.of(context).authentication),
|
title: Text(I18n.tr(context).authentication),
|
||||||
leading: IconButton(
|
leading: IconButton(
|
||||||
icon: Icon(Icons.close),
|
icon: Icon(Icons.close),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
@ -120,14 +120,14 @@ class _ChatState extends State<_Chat> {
|
|||||||
r.user.id == room.client.userID ||
|
r.user.id == room.client.userID ||
|
||||||
r.user.id == timeline.events.first.senderId);
|
r.user.id == timeline.events.first.senderId);
|
||||||
if (lastReceipts.length == 1) {
|
if (lastReceipts.length == 1) {
|
||||||
seenByText = I18n.of(context)
|
seenByText = I18n.tr(context)
|
||||||
.seenByUser(lastReceipts.first.user.calcDisplayname());
|
.seenByUser(lastReceipts.first.user.calcDisplayname());
|
||||||
} else if (lastReceipts.length == 2) {
|
} else if (lastReceipts.length == 2) {
|
||||||
seenByText = seenByText = I18n.of(context).seenByUserAndUser(
|
seenByText = seenByText = I18n.tr(context).seenByUserAndUser(
|
||||||
lastReceipts.first.user.calcDisplayname(),
|
lastReceipts.first.user.calcDisplayname(),
|
||||||
lastReceipts[1].user.calcDisplayname());
|
lastReceipts[1].user.calcDisplayname());
|
||||||
} else if (lastReceipts.length > 2) {
|
} else if (lastReceipts.length > 2) {
|
||||||
seenByText = I18n.of(context).seenByUserAndCountOthers(
|
seenByText = I18n.tr(context).seenByUserAndCountOthers(
|
||||||
lastReceipts.first.user.calcDisplayname(),
|
lastReceipts.first.user.calcDisplayname(),
|
||||||
(lastReceipts.length - 1).toString());
|
(lastReceipts.length - 1).toString());
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ class _ChatState extends State<_Chat> {
|
|||||||
|
|
||||||
void sendFileAction(BuildContext context) async {
|
void sendFileAction(BuildContext context) async {
|
||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
return Toast.show(I18n.of(context).notSupportedInWeb, context);
|
return Toast.show(I18n.tr(context).notSupportedInWeb, context);
|
||||||
}
|
}
|
||||||
File file = await FilePicker.getFile();
|
File file = await FilePicker.getFile();
|
||||||
if (file == null) return;
|
if (file == null) return;
|
||||||
@ -187,7 +187,7 @@ class _ChatState extends State<_Chat> {
|
|||||||
|
|
||||||
void sendImageAction(BuildContext context) async {
|
void sendImageAction(BuildContext context) async {
|
||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
return Toast.show(I18n.of(context).notSupportedInWeb, context);
|
return Toast.show(I18n.tr(context).notSupportedInWeb, context);
|
||||||
}
|
}
|
||||||
File file = await ImagePicker.pickImage(
|
File file = await ImagePicker.pickImage(
|
||||||
source: ImageSource.gallery,
|
source: ImageSource.gallery,
|
||||||
@ -204,7 +204,7 @@ class _ChatState extends State<_Chat> {
|
|||||||
|
|
||||||
void openCameraAction(BuildContext context) async {
|
void openCameraAction(BuildContext context) async {
|
||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
return Toast.show(I18n.of(context).notSupportedInWeb, context);
|
return Toast.show(I18n.tr(context).notSupportedInWeb, context);
|
||||||
}
|
}
|
||||||
File file = await ImagePicker.pickImage(
|
File file = await ImagePicker.pickImage(
|
||||||
source: ImageSource.camera,
|
source: ImageSource.camera,
|
||||||
@ -235,8 +235,8 @@ class _ChatState extends State<_Chat> {
|
|||||||
|
|
||||||
void redactEventsAction(BuildContext context) async {
|
void redactEventsAction(BuildContext context) async {
|
||||||
bool confirmed = await SimpleDialogs(context).askConfirmation(
|
bool confirmed = await SimpleDialogs(context).askConfirmation(
|
||||||
titleText: I18n.of(context).messageWillBeRemovedWarning,
|
titleText: I18n.tr(context).messageWillBeRemovedWarning,
|
||||||
confirmText: I18n.of(context).remove,
|
confirmText: I18n.tr(context).remove,
|
||||||
);
|
);
|
||||||
if (!confirmed) return;
|
if (!confirmed) return;
|
||||||
for (Event event in selectedEvents) {
|
for (Event event in selectedEvents) {
|
||||||
@ -287,10 +287,10 @@ class _ChatState extends State<_Chat> {
|
|||||||
if (room == null) {
|
if (room == null) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(I18n.of(context).oopsSomethingWentWrong),
|
title: Text(I18n.tr(context).oopsSomethingWentWrong),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Text(I18n.of(context).youAreNoLongerParticipatingInThisChat),
|
child: Text(I18n.tr(context).youAreNoLongerParticipatingInThisChat),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -305,17 +305,17 @@ class _ChatState extends State<_Chat> {
|
|||||||
typingUsers.removeWhere((User u) => u.id == client.userID);
|
typingUsers.removeWhere((User u) => u.id == client.userID);
|
||||||
|
|
||||||
if (typingUsers.length == 1) {
|
if (typingUsers.length == 1) {
|
||||||
typingText = I18n.of(context).isTyping;
|
typingText = I18n.tr(context).isTyping;
|
||||||
if (typingUsers.first.id != room.directChatMatrixID) {
|
if (typingUsers.first.id != room.directChatMatrixID) {
|
||||||
typingText =
|
typingText =
|
||||||
I18n.of(context).userIsTyping(typingUsers.first.calcDisplayname());
|
I18n.tr(context).userIsTyping(typingUsers.first.calcDisplayname());
|
||||||
}
|
}
|
||||||
} else if (typingUsers.length == 2) {
|
} else if (typingUsers.length == 2) {
|
||||||
typingText = I18n.of(context).userAndUserAreTyping(
|
typingText = I18n.tr(context).userAndUserAreTyping(
|
||||||
typingUsers.first.calcDisplayname(),
|
typingUsers.first.calcDisplayname(),
|
||||||
typingUsers[1].calcDisplayname());
|
typingUsers[1].calcDisplayname());
|
||||||
} else if (typingUsers.length > 2) {
|
} else if (typingUsers.length > 2) {
|
||||||
typingText = I18n.of(context).userAndOthersAreTyping(
|
typingText = I18n.tr(context).userAndOthersAreTyping(
|
||||||
typingUsers.first.calcDisplayname(),
|
typingUsers.first.calcDisplayname(),
|
||||||
(typingUsers.length - 1).toString());
|
(typingUsers.length - 1).toString());
|
||||||
}
|
}
|
||||||
@ -358,7 +358,7 @@ class _ChatState extends State<_Chat> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: Text(I18n.of(context)
|
: Text(I18n.tr(context)
|
||||||
.numberSelected(selectedEvents.length.toString())),
|
.numberSelected(selectedEvents.length.toString())),
|
||||||
actions: selectMode
|
actions: selectMode
|
||||||
? <Widget>[
|
? <Widget>[
|
||||||
@ -511,7 +511,7 @@ class _ChatState extends State<_Chat> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Icon(Icons.keyboard_arrow_left),
|
Icon(Icons.keyboard_arrow_left),
|
||||||
Text(I18n.of(context).forward),
|
Text(I18n.tr(context).forward),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -524,8 +524,9 @@ class _ChatState extends State<_Chat> {
|
|||||||
onPressed: () => replyAction(),
|
onPressed: () => replyAction(),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(
|
Text(FluffychatLocalizations
|
||||||
I18n.of(context).reply),
|
.of(context)
|
||||||
|
.reply),
|
||||||
Icon(Icons
|
Icon(Icons
|
||||||
.keyboard_arrow_right),
|
.keyboard_arrow_right),
|
||||||
],
|
],
|
||||||
@ -539,7 +540,8 @@ class _ChatState extends State<_Chat> {
|
|||||||
sendAgainAction(),
|
sendAgainAction(),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text(I18n.of(context)
|
Text(FluffychatLocalizations
|
||||||
|
.of(context)
|
||||||
.tryToSendAgain),
|
.tryToSendAgain),
|
||||||
SizedBox(width: 4),
|
SizedBox(width: 4),
|
||||||
Icon(Icons.send, size: 16),
|
Icon(Icons.send, size: 16),
|
||||||
@ -575,7 +577,7 @@ class _ChatState extends State<_Chat> {
|
|||||||
child: Icon(Icons.attachment),
|
child: Icon(Icons.attachment),
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).sendFile),
|
I18n.tr(context).sendFile),
|
||||||
contentPadding:
|
contentPadding:
|
||||||
EdgeInsets.all(0),
|
EdgeInsets.all(0),
|
||||||
),
|
),
|
||||||
@ -589,7 +591,7 @@ class _ChatState extends State<_Chat> {
|
|||||||
child: Icon(Icons.image),
|
child: Icon(Icons.image),
|
||||||
),
|
),
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).sendImage),
|
I18n.tr(context).sendImage),
|
||||||
contentPadding:
|
contentPadding:
|
||||||
EdgeInsets.all(0),
|
EdgeInsets.all(0),
|
||||||
),
|
),
|
||||||
@ -603,7 +605,7 @@ class _ChatState extends State<_Chat> {
|
|||||||
foregroundColor: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
child: Icon(Icons.camera_alt),
|
child: Icon(Icons.camera_alt),
|
||||||
),
|
),
|
||||||
title: Text(I18n.of(context)
|
title: Text(I18n.tr(context)
|
||||||
.openCamera),
|
.openCamera),
|
||||||
contentPadding:
|
contentPadding:
|
||||||
EdgeInsets.all(0),
|
EdgeInsets.all(0),
|
||||||
@ -630,7 +632,7 @@ class _ChatState extends State<_Chat> {
|
|||||||
controller: sendController,
|
controller: sendController,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText:
|
hintText:
|
||||||
I18n.of(context).writeAMessage,
|
I18n.tr(context).writeAMessage,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
prefixIcon:
|
prefixIcon:
|
||||||
sendController.text.isEmpty
|
sendController.text.isEmpty
|
||||||
|
@ -34,8 +34,8 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
List<User> members;
|
List<User> members;
|
||||||
void setDisplaynameAction(BuildContext context) async {
|
void setDisplaynameAction(BuildContext context) async {
|
||||||
final String displayname = await SimpleDialogs(context).enterText(
|
final String displayname = await SimpleDialogs(context).enterText(
|
||||||
titleText: I18n.of(context).changeTheNameOfTheGroup,
|
titleText: I18n.tr(context).changeTheNameOfTheGroup,
|
||||||
labelText: I18n.of(context).changeTheNameOfTheGroup,
|
labelText: I18n.tr(context).changeTheNameOfTheGroup,
|
||||||
hintText: widget.room.getLocalizedDisplayname(context),
|
hintText: widget.room.getLocalizedDisplayname(context),
|
||||||
);
|
);
|
||||||
if (displayname == null) return;
|
if (displayname == null) return;
|
||||||
@ -45,7 +45,7 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
);
|
);
|
||||||
if (success != false) {
|
if (success != false) {
|
||||||
Toast.show(
|
Toast.show(
|
||||||
I18n.of(context).displaynameHasBeenChanged,
|
I18n.tr(context).displaynameHasBeenChanged,
|
||||||
context,
|
context,
|
||||||
duration: Toast.LENGTH_LONG,
|
duration: Toast.LENGTH_LONG,
|
||||||
);
|
);
|
||||||
@ -54,9 +54,9 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
|
|
||||||
void setCanonicalAliasAction(context) async {
|
void setCanonicalAliasAction(context) async {
|
||||||
final String s = await SimpleDialogs(context).enterText(
|
final String s = await SimpleDialogs(context).enterText(
|
||||||
titleText: I18n.of(context).setInvitationLink,
|
titleText: I18n.tr(context).setInvitationLink,
|
||||||
labelText: I18n.of(context).setInvitationLink,
|
labelText: I18n.tr(context).setInvitationLink,
|
||||||
hintText: I18n.of(context).alias.toLowerCase(),
|
hintText: I18n.tr(context).alias.toLowerCase(),
|
||||||
prefixText: "#",
|
prefixText: "#",
|
||||||
suffixText: ":" + widget.room.client.userID.domain,
|
suffixText: ":" + widget.room.client.userID.domain,
|
||||||
);
|
);
|
||||||
@ -96,11 +96,11 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
|
|
||||||
void setTopicAction(BuildContext context) async {
|
void setTopicAction(BuildContext context) async {
|
||||||
final String displayname = await SimpleDialogs(context).enterText(
|
final String displayname = await SimpleDialogs(context).enterText(
|
||||||
titleText: I18n.of(context).setGroupDescription,
|
titleText: I18n.tr(context).setGroupDescription,
|
||||||
labelText: I18n.of(context).setGroupDescription,
|
labelText: I18n.tr(context).setGroupDescription,
|
||||||
hintText: (widget.room.topic?.isNotEmpty ?? false)
|
hintText: (widget.room.topic?.isNotEmpty ?? false)
|
||||||
? widget.room.topic
|
? widget.room.topic
|
||||||
: I18n.of(context).addGroupDescription,
|
: I18n.tr(context).addGroupDescription,
|
||||||
multiLine: true,
|
multiLine: true,
|
||||||
);
|
);
|
||||||
if (displayname == null) return;
|
if (displayname == null) return;
|
||||||
@ -110,7 +110,7 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
);
|
);
|
||||||
if (success != false) {
|
if (success != false) {
|
||||||
Toast.show(
|
Toast.show(
|
||||||
I18n.of(context).groupDescriptionHasBeenChanged,
|
I18n.tr(context).groupDescriptionHasBeenChanged,
|
||||||
context,
|
context,
|
||||||
duration: Toast.LENGTH_LONG,
|
duration: Toast.LENGTH_LONG,
|
||||||
);
|
);
|
||||||
@ -135,7 +135,7 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
);
|
);
|
||||||
if (success != false) {
|
if (success != false) {
|
||||||
Toast.show(
|
Toast.show(
|
||||||
I18n.of(context).avatarHasBeenChanged,
|
I18n.tr(context).avatarHasBeenChanged,
|
||||||
context,
|
context,
|
||||||
duration: Toast.LENGTH_LONG,
|
duration: Toast.LENGTH_LONG,
|
||||||
);
|
);
|
||||||
@ -161,10 +161,10 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
if (widget.room == null) {
|
if (widget.room == null) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(I18n.of(context).oopsSomethingWentWrong),
|
title: Text(I18n.tr(context).oopsSomethingWentWrong),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Center(
|
||||||
child: Text(I18n.of(context).youAreNoLongerParticipatingInThisChat),
|
child: Text(I18n.tr(context).youAreNoLongerParticipatingInThisChat),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -195,7 +195,7 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
Clipboard.setData(
|
Clipboard.setData(
|
||||||
ClipboardData(text: widget.room.canonicalAlias),
|
ClipboardData(text: widget.room.canonicalAlias),
|
||||||
);
|
);
|
||||||
Toast.show(I18n.of(context).copiedToClipboard, context,
|
Toast.show(I18n.tr(context).copiedToClipboard, context,
|
||||||
duration: 5);
|
duration: 5);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -229,13 +229,13 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
child: Icon(Icons.edit),
|
child: Icon(Icons.edit),
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
title: Text("${I18n.of(context).groupDescription}:",
|
title: Text("${I18n.tr(context).groupDescription}:",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
fontWeight: FontWeight.bold)),
|
fontWeight: FontWeight.bold)),
|
||||||
subtitle: LinkText(
|
subtitle: LinkText(
|
||||||
text: widget.room.topic?.isEmpty ?? true
|
text: widget.room.topic?.isEmpty ?? true
|
||||||
? I18n.of(context).addGroupDescription
|
? I18n.tr(context).addGroupDescription
|
||||||
: widget.room.topic,
|
: widget.room.topic,
|
||||||
linkStyle: TextStyle(color: Colors.blueAccent),
|
linkStyle: TextStyle(color: Colors.blueAccent),
|
||||||
textStyle: TextStyle(
|
textStyle: TextStyle(
|
||||||
@ -250,7 +250,7 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
Divider(thickness: 1),
|
Divider(thickness: 1),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).settings,
|
I18n.tr(context).settings,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@ -265,7 +265,7 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
foregroundColor: Colors.grey,
|
foregroundColor: Colors.grey,
|
||||||
child: Icon(Icons.people),
|
child: Icon(Icons.people),
|
||||||
),
|
),
|
||||||
title: Text(I18n.of(context).changeTheNameOfTheGroup),
|
title: Text(I18n.tr(context).changeTheNameOfTheGroup),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
widget.room.getLocalizedDisplayname(context)),
|
widget.room.getLocalizedDisplayname(context)),
|
||||||
onTap: () => setDisplaynameAction(context),
|
onTap: () => setDisplaynameAction(context),
|
||||||
@ -280,11 +280,11 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
child: Icon(Icons.link),
|
child: Icon(Icons.link),
|
||||||
),
|
),
|
||||||
onTap: () => setCanonicalAliasAction(context),
|
onTap: () => setCanonicalAliasAction(context),
|
||||||
title: Text(I18n.of(context).setInvitationLink),
|
title: Text(I18n.tr(context).setInvitationLink),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
(widget.room.canonicalAlias?.isNotEmpty ?? false)
|
(widget.room.canonicalAlias?.isNotEmpty ?? false)
|
||||||
? widget.room.canonicalAlias
|
? widget.room.canonicalAlias
|
||||||
: I18n.of(context).none),
|
: I18n.tr(context).none),
|
||||||
),
|
),
|
||||||
PopupMenuButton(
|
PopupMenuButton(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
@ -294,7 +294,7 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
foregroundColor: Colors.grey,
|
foregroundColor: Colors.grey,
|
||||||
child: Icon(Icons.public)),
|
child: Icon(Icons.public)),
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).whoIsAllowedToJoinThisGroup),
|
I18n.tr(context).whoIsAllowedToJoinThisGroup),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
widget.room.joinRules.getLocalizedString(context),
|
widget.room.joinRules.getLocalizedString(context),
|
||||||
),
|
),
|
||||||
@ -328,7 +328,7 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
child: Icon(Icons.visibility),
|
child: Icon(Icons.visibility),
|
||||||
),
|
),
|
||||||
title:
|
title:
|
||||||
Text(I18n.of(context).visibilityOfTheChatHistory),
|
Text(I18n.tr(context).visibilityOfTheChatHistory),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
widget.room.historyVisibility
|
widget.room.historyVisibility
|
||||||
.getLocalizedString(context),
|
.getLocalizedString(context),
|
||||||
@ -376,7 +376,7 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
child: Icon(Icons.info_outline),
|
child: Icon(Icons.info_outline),
|
||||||
),
|
),
|
||||||
title:
|
title:
|
||||||
Text(I18n.of(context).areGuestsAllowedToJoin),
|
Text(I18n.tr(context).areGuestsAllowedToJoin),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
widget.room.guestAccess
|
widget.room.guestAccess
|
||||||
.getLocalizedString(context),
|
.getLocalizedString(context),
|
||||||
@ -410,9 +410,9 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
actualMembersCount > 1
|
actualMembersCount > 1
|
||||||
? I18n.of(context).countParticipants(
|
? I18n.tr(context).countParticipants(
|
||||||
actualMembersCount.toString())
|
actualMembersCount.toString())
|
||||||
: I18n.of(context).emptyChat,
|
: I18n.tr(context).emptyChat,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@ -422,7 +422,7 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
Divider(height: 1),
|
Divider(height: 1),
|
||||||
widget.room.canInvite
|
widget.room.canInvite
|
||||||
? ListTile(
|
? ListTile(
|
||||||
title: Text(I18n.of(context).inviteContact),
|
title: Text(I18n.tr(context).inviteContact),
|
||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
child: Icon(Icons.add),
|
child: Icon(Icons.add),
|
||||||
backgroundColor: Theme.of(context).primaryColor,
|
backgroundColor: Theme.of(context).primaryColor,
|
||||||
@ -441,7 +441,7 @@ class _ChatDetailsState extends State<ChatDetails> {
|
|||||||
: i < members.length + 1
|
: i < members.length + 1
|
||||||
? ParticipantListItem(members[i - 1])
|
? ParticipantListItem(members[i - 1])
|
||||||
: ListTile(
|
: ListTile(
|
||||||
title: Text(I18n.of(context).loadCountMoreParticipants(
|
title: Text(I18n.tr(context).loadCountMoreParticipants(
|
||||||
(actualMembersCount - members.length).toString())),
|
(actualMembersCount - members.length).toString())),
|
||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
|
@ -53,25 +53,25 @@ class _ChatEncryptionSettingsState extends State<ChatEncryptionSettings> {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(I18n.of(context).end2endEncryptionSettings),
|
title: Text(I18n.tr(context).end2endEncryptionSettings),
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(I18n.of(context).encryptionAlgorithm),
|
title: Text(I18n.tr(context).encryptionAlgorithm),
|
||||||
subtitle: Text(room.encryptionAlgorithm ?? I18n.of(context).none),
|
subtitle: Text(room.encryptionAlgorithm ?? I18n.tr(context).none),
|
||||||
trailing: Icon(room.encrypted ? Icons.lock : Icons.lock_open,
|
trailing: Icon(room.encrypted ? Icons.lock : Icons.lock_open,
|
||||||
color: room.encrypted ? Colors.green : Colors.red),
|
color: room.encrypted ? Colors.green : Colors.red),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (room.encrypted) return;
|
if (room.encrypted) return;
|
||||||
if (!room.client.encryptionEnabled) {
|
if (!room.client.encryptionEnabled) {
|
||||||
Toast.show(I18n.of(context).needPantalaimonWarning, context,
|
Toast.show(I18n.tr(context).needPantalaimonWarning, context,
|
||||||
duration: 8);
|
duration: 8);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (await SimpleDialogs(context).askConfirmation(
|
if (await SimpleDialogs(context).askConfirmation(
|
||||||
titleText: I18n.of(context).enableEncryptionWarning,
|
titleText: I18n.tr(context).enableEncryptionWarning,
|
||||||
confirmText: I18n.of(context).yes) ==
|
confirmText: I18n.tr(context).yes) ==
|
||||||
true) {
|
true) {
|
||||||
await Matrix.of(context).tryRequestWithLoadingDialog(
|
await Matrix.of(context).tryRequestWithLoadingDialog(
|
||||||
room.enableEncryption(),
|
room.enableEncryption(),
|
||||||
@ -83,15 +83,15 @@ class _ChatEncryptionSettingsState extends State<ChatEncryptionSettings> {
|
|||||||
trailing: Icon(Icons.info),
|
trailing: Icon(Icons.info),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
room.client.encryptionEnabled
|
room.client.encryptionEnabled
|
||||||
? I18n.of(context).warningEncryptionInBeta
|
? I18n.tr(context).warningEncryptionInBeta
|
||||||
: I18n.of(context).needPantalaimonWarning,
|
: I18n.tr(context).needPantalaimonWarning,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Divider(height: 1),
|
Divider(height: 1),
|
||||||
if (room.encrypted)
|
if (room.encrypted)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
"${I18n.of(context).participatingUserDevices}:",
|
"${I18n.tr(context).participatingUserDevices}:",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
@ -104,7 +104,7 @@ class _ChatEncryptionSettingsState extends State<ChatEncryptionSettings> {
|
|||||||
builder: (BuildContext context, snapshot) {
|
builder: (BuildContext context, snapshot) {
|
||||||
if (snapshot.hasError) {
|
if (snapshot.hasError) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text(I18n.of(context).oopsSomethingWentWrong +
|
child: Text(I18n.tr(context).oopsSomethingWentWrong +
|
||||||
": " +
|
": " +
|
||||||
snapshot.error.toString()),
|
snapshot.error.toString()),
|
||||||
);
|
);
|
||||||
|
@ -89,7 +89,9 @@ class _ChatListState extends State<ChatList> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onError: (error) => Toast.show(
|
onError: (error) => Toast.show(
|
||||||
I18n.of(context).oopsSomethingWentWrong + " " + error.toString(),
|
I18n.tr(context).oopsSomethingWentWrong +
|
||||||
|
" " +
|
||||||
|
error.toString(),
|
||||||
context,
|
context,
|
||||||
duration: 5),
|
duration: 5),
|
||||||
);
|
);
|
||||||
@ -122,13 +124,13 @@ class _ChatListState extends State<ChatList> {
|
|||||||
controller: searchController,
|
controller: searchController,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
hintText: I18n.of(context).searchForAChat,
|
hintText: I18n.tr(context).searchForAChat,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: Text(
|
: Text(
|
||||||
selectMode == SelectMode.share
|
selectMode == SelectMode.share
|
||||||
? I18n.of(context).share
|
? I18n.tr(context).share
|
||||||
: I18n.of(context).fluffychat,
|
: I18n.tr(context).fluffychat,
|
||||||
),
|
),
|
||||||
leading: searchMode
|
leading: searchMode
|
||||||
? IconButton(
|
? IconButton(
|
||||||
@ -180,11 +182,13 @@ class _ChatListState extends State<ChatList> {
|
|||||||
<PopupMenuEntry<String>>[
|
<PopupMenuEntry<String>>[
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
value: "archive",
|
value: "archive",
|
||||||
child: Text(I18n.of(context).archive),
|
child:
|
||||||
|
Text(I18n.tr(context).archive),
|
||||||
),
|
),
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
value: "settings",
|
value: "settings",
|
||||||
child: Text(I18n.of(context).settings),
|
child:
|
||||||
|
Text(I18n.tr(context).settings),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -200,9 +204,8 @@ class _ChatListState extends State<ChatList> {
|
|||||||
child: Icon(Icons.people_outline),
|
child: Icon(Icons.people_outline),
|
||||||
foregroundColor: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
backgroundColor: Colors.blue,
|
backgroundColor: Colors.blue,
|
||||||
label: I18n.of(context).createNewGroup,
|
label: I18n.tr(context).createNewGroup,
|
||||||
labelStyle:
|
labelStyle: TextStyle(fontSize: 18.0, color: Colors.black),
|
||||||
TextStyle(fontSize: 18.0, color: Colors.black),
|
|
||||||
onTap: () => Navigator.of(context).pushAndRemoveUntil(
|
onTap: () => Navigator.of(context).pushAndRemoveUntil(
|
||||||
AppRoute.defaultRoute(context, NewGroupView()),
|
AppRoute.defaultRoute(context, NewGroupView()),
|
||||||
(r) => r.isFirst),
|
(r) => r.isFirst),
|
||||||
@ -211,10 +214,8 @@ class _ChatListState extends State<ChatList> {
|
|||||||
child: Icon(Icons.person_add),
|
child: Icon(Icons.person_add),
|
||||||
foregroundColor: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
backgroundColor: Colors.green,
|
backgroundColor: Colors.green,
|
||||||
label: I18n.of(context).newPrivateChat,
|
label: I18n.tr(context).newPrivateChat,
|
||||||
labelStyle: TextStyle(
|
labelStyle: TextStyle(fontSize: 18.0, color: Colors.black),
|
||||||
fontSize: 18.0,
|
|
||||||
color: Colors.black),
|
|
||||||
onTap: () => Navigator.of(context).pushAndRemoveUntil(
|
onTap: () => Navigator.of(context).pushAndRemoveUntil(
|
||||||
AppRoute.defaultRoute(context, NewPrivateChatView()),
|
AppRoute.defaultRoute(context, NewPrivateChatView()),
|
||||||
(r) => r.isFirst),
|
(r) => r.isFirst),
|
||||||
@ -242,8 +243,9 @@ class _ChatListState extends State<ChatList> {
|
|||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
Text(searchMode
|
Text(searchMode
|
||||||
? I18n.of(context).noRoomsFound
|
? I18n.tr(context).noRoomsFound
|
||||||
: I18n.of(context).startYourFirstChat),
|
: I18n.tr(context)
|
||||||
|
.startYourFirstChat),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -16,7 +16,7 @@ class ContentWebView extends StatelessWidget {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).contentViewer,
|
I18n.tr(context).contentViewer,
|
||||||
),
|
),
|
||||||
actions: <Widget>[
|
actions: <Widget>[
|
||||||
IconButton(
|
IconButton(
|
||||||
|
@ -53,7 +53,7 @@ class _InvitationSelectionState extends State<InvitationSelection> {
|
|||||||
);
|
);
|
||||||
if (success != false) {
|
if (success != false) {
|
||||||
Toast.show(
|
Toast.show(
|
||||||
I18n.of(context).contactHasBeenInvitedToTheGroup,
|
I18n.tr(context).contactHasBeenInvitedToTheGroup,
|
||||||
context,
|
context,
|
||||||
duration: Toast.LENGTH_LONG,
|
duration: Toast.LENGTH_LONG,
|
||||||
);
|
);
|
||||||
@ -114,14 +114,14 @@ class _InvitationSelectionState extends State<InvitationSelection> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final String groupName = widget.room.name?.isEmpty ?? false
|
final String groupName = widget.room.name?.isEmpty ?? false
|
||||||
? I18n.of(context).group
|
? I18n.tr(context).group
|
||||||
: widget.room.name;
|
: widget.room.name;
|
||||||
return AdaptivePageLayout(
|
return AdaptivePageLayout(
|
||||||
primaryPage: FocusPage.SECOND,
|
primaryPage: FocusPage.SECOND,
|
||||||
firstScaffold: ChatList(activeChat: widget.room.id),
|
firstScaffold: ChatList(activeChat: widget.room.id),
|
||||||
secondScaffold: Scaffold(
|
secondScaffold: Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(I18n.of(context).inviteContact),
|
title: Text(I18n.tr(context).inviteContact),
|
||||||
bottom: PreferredSize(
|
bottom: PreferredSize(
|
||||||
preferredSize: Size.fromHeight(68),
|
preferredSize: Size.fromHeight(68),
|
||||||
child: Padding(
|
child: Padding(
|
||||||
@ -137,8 +137,8 @@ class _InvitationSelectionState extends State<InvitationSelection> {
|
|||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
prefixText: "@",
|
prefixText: "@",
|
||||||
hintText: I18n.of(context).username,
|
hintText: I18n.tr(context).username,
|
||||||
labelText: I18n.of(context).inviteContactToGroup(groupName),
|
labelText: I18n.tr(context).inviteContactToGroup(groupName),
|
||||||
suffixIcon: loading
|
suffixIcon: loading
|
||||||
? Container(
|
? Container(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
@ -28,12 +28,12 @@ class _LoginState extends State<Login> {
|
|||||||
void login(BuildContext context) async {
|
void login(BuildContext context) async {
|
||||||
MatrixState matrix = Matrix.of(context);
|
MatrixState matrix = Matrix.of(context);
|
||||||
if (usernameController.text.isEmpty) {
|
if (usernameController.text.isEmpty) {
|
||||||
setState(() => usernameError = I18n.of(context).pleaseEnterYourUsername);
|
setState(() => usernameError = I18n.tr(context).pleaseEnterYourUsername);
|
||||||
} else {
|
} else {
|
||||||
setState(() => usernameError = null);
|
setState(() => usernameError = null);
|
||||||
}
|
}
|
||||||
if (passwordController.text.isEmpty) {
|
if (passwordController.text.isEmpty) {
|
||||||
setState(() => passwordError = I18n.of(context).pleaseEnterYourPassword);
|
setState(() => passwordError = I18n.tr(context).pleaseEnterYourPassword);
|
||||||
} else {
|
} else {
|
||||||
setState(() => passwordError = null);
|
setState(() => passwordError = null);
|
||||||
}
|
}
|
||||||
@ -53,12 +53,12 @@ class _LoginState extends State<Login> {
|
|||||||
setState(() => loading = true);
|
setState(() => loading = true);
|
||||||
if (!await matrix.client.checkServer(homeserver)) {
|
if (!await matrix.client.checkServer(homeserver)) {
|
||||||
setState(
|
setState(
|
||||||
() => serverError = I18n.of(context).homeserverIsNotCompatible);
|
() => serverError = I18n.tr(context).homeserverIsNotCompatible);
|
||||||
|
|
||||||
return setState(() => loading = false);
|
return setState(() => loading = false);
|
||||||
}
|
}
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
setState(() => serverError = I18n.of(context).connectionAttemptFailed);
|
setState(() => serverError = I18n.tr(context).connectionAttemptFailed);
|
||||||
return setState(() => loading = false);
|
return setState(() => loading = false);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -93,6 +93,7 @@ class _LoginState extends State<Login> {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
leading: loading ? Container() : null,
|
leading: loading ? Container() : null,
|
||||||
title: TextField(
|
title: TextField(
|
||||||
|
key: Key("serverField"),
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
controller: serverController,
|
controller: serverController,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
@ -124,14 +125,15 @@ class _LoginState extends State<Login> {
|
|||||||
color: Theme.of(context).primaryColor),
|
color: Theme.of(context).primaryColor),
|
||||||
),
|
),
|
||||||
title: TextField(
|
title: TextField(
|
||||||
|
key: Key("usernameField"),
|
||||||
readOnly: loading,
|
readOnly: loading,
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
controller: usernameController,
|
controller: usernameController,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText:
|
hintText:
|
||||||
"@${I18n.of(context).username.toLowerCase()}:domain",
|
"@${I18n.tr(context).username.toLowerCase()}:domain",
|
||||||
errorText: usernameError,
|
errorText: usernameError,
|
||||||
labelText: I18n.of(context).username),
|
labelText: I18n.tr(context).username),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
@ -142,6 +144,7 @@ class _LoginState extends State<Login> {
|
|||||||
child: Icon(Icons.lock, color: Theme.of(context).primaryColor),
|
child: Icon(Icons.lock, color: Theme.of(context).primaryColor),
|
||||||
),
|
),
|
||||||
title: TextField(
|
title: TextField(
|
||||||
|
key: Key("passwordField"),
|
||||||
readOnly: loading,
|
readOnly: loading,
|
||||||
autocorrect: false,
|
autocorrect: false,
|
||||||
controller: passwordController,
|
controller: passwordController,
|
||||||
@ -156,7 +159,7 @@ class _LoginState extends State<Login> {
|
|||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
setState(() => showPassword = !showPassword),
|
setState(() => showPassword = !showPassword),
|
||||||
),
|
),
|
||||||
labelText: I18n.of(context).password),
|
labelText: I18n.tr(context).password),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
@ -164,6 +167,7 @@ class _LoginState extends State<Login> {
|
|||||||
height: 50,
|
height: 50,
|
||||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||||
child: RaisedButton(
|
child: RaisedButton(
|
||||||
|
key: Key("loginButton"),
|
||||||
elevation: 7,
|
elevation: 7,
|
||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
@ -172,7 +176,7 @@ class _LoginState extends State<Login> {
|
|||||||
child: loading
|
child: loading
|
||||||
? CircularProgressIndicator()
|
? CircularProgressIndicator()
|
||||||
: Text(
|
: Text(
|
||||||
I18n.of(context).login.toUpperCase(),
|
I18n.tr(context).login.toUpperCase(),
|
||||||
style: TextStyle(color: Colors.white, fontSize: 16),
|
style: TextStyle(color: Colors.white, fontSize: 16),
|
||||||
),
|
),
|
||||||
onPressed: () => loading ? null : login(context),
|
onPressed: () => loading ? null : login(context),
|
||||||
|
@ -69,7 +69,7 @@ class _NewGroupState extends State<_NewGroup> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(I18n.of(context).createNewGroup),
|
title: Text(I18n.tr(context).createNewGroup),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
@ -85,13 +85,13 @@ class _NewGroupState extends State<_NewGroup> {
|
|||||||
onSubmitted: (s) => submitAction(context),
|
onSubmitted: (s) => submitAction(context),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
labelText: I18n.of(context).optionalGroupName,
|
labelText: I18n.tr(context).optionalGroupName,
|
||||||
prefixIcon: Icon(Icons.people),
|
prefixIcon: Icon(Icons.people),
|
||||||
hintText: I18n.of(context).enterAGroupName),
|
hintText: I18n.tr(context).enterAGroupName),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
title: Text(I18n.of(context).groupIsPublic),
|
title: Text(I18n.tr(context).groupIsPublic),
|
||||||
value: publicGroup,
|
value: publicGroup,
|
||||||
onChanged: (bool b) => setState(() => publicGroup = b),
|
onChanged: (bool b) => setState(() => publicGroup = b),
|
||||||
),
|
),
|
||||||
|
@ -106,7 +106,7 @@ class _NewPrivateChatState extends State<_NewPrivateChat> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(I18n.of(context).newPrivateChat),
|
title: Text(I18n.tr(context).newPrivateChat),
|
||||||
elevation: 0,
|
elevation: 0,
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
@ -125,24 +125,24 @@ class _NewPrivateChatState extends State<_NewPrivateChat> {
|
|||||||
onFieldSubmitted: (s) => submitAction(context),
|
onFieldSubmitted: (s) => submitAction(context),
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value.isEmpty) {
|
if (value.isEmpty) {
|
||||||
return I18n.of(context).pleaseEnterAMatrixIdentifier;
|
return I18n.tr(context).pleaseEnterAMatrixIdentifier;
|
||||||
}
|
}
|
||||||
final MatrixState matrix = Matrix.of(context);
|
final MatrixState matrix = Matrix.of(context);
|
||||||
String mxid = "@" + controller.text.trim();
|
String mxid = "@" + controller.text.trim();
|
||||||
if (mxid == matrix.client.userID) {
|
if (mxid == matrix.client.userID) {
|
||||||
return I18n.of(context).youCannotInviteYourself;
|
return I18n.tr(context).youCannotInviteYourself;
|
||||||
}
|
}
|
||||||
if (!mxid.contains("@")) {
|
if (!mxid.contains("@")) {
|
||||||
return I18n.of(context).makeSureTheIdentifierIsValid;
|
return I18n.tr(context).makeSureTheIdentifierIsValid;
|
||||||
}
|
}
|
||||||
if (!mxid.contains(":")) {
|
if (!mxid.contains(":")) {
|
||||||
return I18n.of(context).makeSureTheIdentifierIsValid;
|
return I18n.tr(context).makeSureTheIdentifierIsValid;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
labelText: I18n.of(context).enterAUsername,
|
labelText: I18n.tr(context).enterAUsername,
|
||||||
prefixIcon: loading
|
prefixIcon: loading
|
||||||
? Container(
|
? Container(
|
||||||
padding: const EdgeInsets.all(8.0),
|
padding: const EdgeInsets.all(8.0),
|
||||||
@ -162,7 +162,7 @@ class _NewPrivateChatState extends State<_NewPrivateChat> {
|
|||||||
)
|
)
|
||||||
: Icon(Icons.account_circle),
|
: Icon(Icons.account_circle),
|
||||||
prefixText: "@",
|
prefixText: "@",
|
||||||
hintText: "${I18n.of(context).username.toLowerCase()}",
|
hintText: "${I18n.tr(context).username.toLowerCase()}",
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -209,11 +209,11 @@ class _NewPrivateChatState extends State<_NewPrivateChat> {
|
|||||||
Icons.share,
|
Icons.share,
|
||||||
size: 16,
|
size: 16,
|
||||||
),
|
),
|
||||||
onTap: () => Share.share(I18n.of(context).inviteText(
|
onTap: () => Share.share(I18n.tr(context).inviteText(
|
||||||
Matrix.of(context).client.userID,
|
Matrix.of(context).client.userID,
|
||||||
"https://matrix.to/#/${Matrix.of(context).client.userID}")),
|
"https://matrix.to/#/${Matrix.of(context).client.userID}")),
|
||||||
title: Text(
|
title: Text(
|
||||||
"${I18n.of(context).yourOwnUsername}:",
|
"${I18n.tr(context).yourOwnUsername}:",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontStyle: FontStyle.italic,
|
fontStyle: FontStyle.italic,
|
||||||
),
|
),
|
||||||
|
@ -51,10 +51,10 @@ class _SettingsState extends State<Settings> {
|
|||||||
|
|
||||||
void setDisplaynameAction(BuildContext context) async {
|
void setDisplaynameAction(BuildContext context) async {
|
||||||
final String displayname = await SimpleDialogs(context).enterText(
|
final String displayname = await SimpleDialogs(context).enterText(
|
||||||
titleText: I18n.of(context).editDisplayname,
|
titleText: I18n.tr(context).editDisplayname,
|
||||||
hintText:
|
hintText:
|
||||||
profile?.displayname ?? Matrix.of(context).client.userID.localpart,
|
profile?.displayname ?? Matrix.of(context).client.userID.localpart,
|
||||||
labelText: I18n.of(context).enterAUsername,
|
labelText: I18n.tr(context).enterAUsername,
|
||||||
);
|
);
|
||||||
if (displayname == null) return;
|
if (displayname == null) return;
|
||||||
final MatrixState matrix = Matrix.of(context);
|
final MatrixState matrix = Matrix.of(context);
|
||||||
@ -87,7 +87,7 @@ class _SettingsState extends State<Settings> {
|
|||||||
);
|
);
|
||||||
if (success != false) {
|
if (success != false) {
|
||||||
Toast.show(
|
Toast.show(
|
||||||
I18n.of(context).avatarHasBeenChanged,
|
I18n.tr(context).avatarHasBeenChanged,
|
||||||
context,
|
context,
|
||||||
duration: Toast.LENGTH_LONG,
|
duration: Toast.LENGTH_LONG,
|
||||||
);
|
);
|
||||||
@ -116,7 +116,7 @@ class _SettingsState extends State<Settings> {
|
|||||||
backgroundColor: Theme.of(context).appBarTheme.color,
|
backgroundColor: Theme.of(context).appBarTheme.color,
|
||||||
flexibleSpace: FlexibleSpaceBar(
|
flexibleSpace: FlexibleSpaceBar(
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).settings,
|
I18n.tr(context).settings,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).appBarTheme.textTheme.title.color),
|
color: Theme.of(context).appBarTheme.textTheme.title.color),
|
||||||
),
|
),
|
||||||
@ -134,7 +134,7 @@ class _SettingsState extends State<Settings> {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).account,
|
I18n.tr(context).account,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@ -143,13 +143,13 @@ class _SettingsState extends State<Settings> {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
trailing: Icon(Icons.edit),
|
trailing: Icon(Icons.edit),
|
||||||
title: Text(I18n.of(context).editDisplayname),
|
title: Text(I18n.tr(context).editDisplayname),
|
||||||
subtitle: Text(profile?.displayname ?? client.userID.localpart),
|
subtitle: Text(profile?.displayname ?? client.userID.localpart),
|
||||||
onTap: () => setDisplaynameAction(context),
|
onTap: () => setDisplaynameAction(context),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
trailing: Icon(Icons.color_lens),
|
trailing: Icon(Icons.color_lens),
|
||||||
title: Text(I18n.of(context).changeTheme),
|
title: Text(I18n.tr(context).changeTheme),
|
||||||
onTap: () async => await Navigator.of(context).push(
|
onTap: () async => await Navigator.of(context).push(
|
||||||
AppRoute.defaultRoute(
|
AppRoute.defaultRoute(
|
||||||
context,
|
context,
|
||||||
@ -159,7 +159,7 @@ class _SettingsState extends State<Settings> {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
trailing: Icon(Icons.devices_other),
|
trailing: Icon(Icons.devices_other),
|
||||||
title: Text(I18n.of(context).devices),
|
title: Text(I18n.tr(context).devices),
|
||||||
onTap: () async => await Navigator.of(context).push(
|
onTap: () async => await Navigator.of(context).push(
|
||||||
AppRoute.defaultRoute(
|
AppRoute.defaultRoute(
|
||||||
context,
|
context,
|
||||||
@ -169,13 +169,13 @@ class _SettingsState extends State<Settings> {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
trailing: Icon(Icons.exit_to_app),
|
trailing: Icon(Icons.exit_to_app),
|
||||||
title: Text(I18n.of(context).logout),
|
title: Text(I18n.tr(context).logout),
|
||||||
onTap: () => logoutAction(context),
|
onTap: () => logoutAction(context),
|
||||||
),
|
),
|
||||||
Divider(thickness: 1),
|
Divider(thickness: 1),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).about,
|
I18n.tr(context).about,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
@ -191,19 +191,19 @@ class _SettingsState extends State<Settings> {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.donut_large),
|
leading: Icon(Icons.donut_large),
|
||||||
title: Text("Liberapay " + I18n.of(context).donate),
|
title: Text("Liberapay " + I18n.tr(context).donate),
|
||||||
onTap: () =>
|
onTap: () =>
|
||||||
launch("https://liberapay.com/KrilleChritzelius/donate"),
|
launch("https://liberapay.com/KrilleChritzelius/donate"),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.help),
|
leading: Icon(Icons.help),
|
||||||
title: Text(I18n.of(context).help),
|
title: Text(I18n.tr(context).help),
|
||||||
onTap: () => launch(
|
onTap: () => launch(
|
||||||
"https://gitlab.com/ChristianPauly/fluffychat-flutter/issues"),
|
"https://gitlab.com/ChristianPauly/fluffychat-flutter/issues"),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.account_circle),
|
leading: Icon(Icons.account_circle),
|
||||||
title: Text(I18n.of(context).accountInformations),
|
title: Text(I18n.tr(context).accountInformations),
|
||||||
onTap: () => Navigator.of(context).push(
|
onTap: () => Navigator.of(context).push(
|
||||||
AppRoute.defaultRoute(
|
AppRoute.defaultRoute(
|
||||||
context,
|
context,
|
||||||
@ -213,19 +213,19 @@ class _SettingsState extends State<Settings> {
|
|||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.list),
|
leading: Icon(Icons.list),
|
||||||
title: Text(I18n.of(context).changelog),
|
title: Text(I18n.tr(context).changelog),
|
||||||
onTap: () => launch(
|
onTap: () => launch(
|
||||||
"https://gitlab.com/ChristianPauly/fluffychat-flutter/blob/master/CHANGELOG.md"),
|
"https://gitlab.com/ChristianPauly/fluffychat-flutter/blob/master/CHANGELOG.md"),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.link),
|
leading: Icon(Icons.link),
|
||||||
title: Text(I18n.of(context).license),
|
title: Text(I18n.tr(context).license),
|
||||||
onTap: () => launch(
|
onTap: () => launch(
|
||||||
"https://gitlab.com/ChristianPauly/fluffychat-flutter/raw/master/LICENSE"),
|
"https://gitlab.com/ChristianPauly/fluffychat-flutter/raw/master/LICENSE"),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.code),
|
leading: Icon(Icons.code),
|
||||||
title: Text(I18n.of(context).sourceCode),
|
title: Text(I18n.tr(context).sourceCode),
|
||||||
onTap: () => launch(
|
onTap: () => launch(
|
||||||
"https://gitlab.com/ChristianPauly/fluffychat-flutter"),
|
"https://gitlab.com/ChristianPauly/fluffychat-flutter"),
|
||||||
),
|
),
|
||||||
|
@ -46,8 +46,8 @@ class DevicesSettingsState extends State<DevicesSettings> {
|
|||||||
.tryRequestWithLoadingDialog(matrix.client.deleteDevices(deviceIds),
|
.tryRequestWithLoadingDialog(matrix.client.deleteDevices(deviceIds),
|
||||||
onAdditionalAuth: (MatrixException exception) async {
|
onAdditionalAuth: (MatrixException exception) async {
|
||||||
final String password = await SimpleDialogs(context).enterText(
|
final String password = await SimpleDialogs(context).enterText(
|
||||||
titleText: I18n.of(context).pleaseEnterYourPassword,
|
titleText: I18n.tr(context).pleaseEnterYourPassword,
|
||||||
labelText: I18n.of(context).pleaseEnterYourPassword,
|
labelText: I18n.tr(context).pleaseEnterYourPassword,
|
||||||
hintText: "******",
|
hintText: "******",
|
||||||
password: true);
|
password: true);
|
||||||
if (password == null) return;
|
if (password == null) return;
|
||||||
@ -63,7 +63,7 @@ class DevicesSettingsState extends State<DevicesSettings> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: Text(I18n.of(context).devices)),
|
appBar: AppBar(title: Text(I18n.tr(context).devices)),
|
||||||
body: FutureBuilder<bool>(
|
body: FutureBuilder<bool>(
|
||||||
future: _loadUserDevices(context),
|
future: _loadUserDevices(context),
|
||||||
builder: (BuildContext context, snapshot) {
|
builder: (BuildContext context, snapshot) {
|
||||||
@ -98,7 +98,7 @@ class DevicesSettingsState extends State<DevicesSettings> {
|
|||||||
if (devices.isNotEmpty)
|
if (devices.isNotEmpty)
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).removeAllOtherDevices,
|
I18n.tr(context).removeAllOtherDevices,
|
||||||
style: TextStyle(color: Colors.red),
|
style: TextStyle(color: Colors.red),
|
||||||
),
|
),
|
||||||
trailing: Icon(Icons.delete_outline),
|
trailing: Icon(Icons.delete_outline),
|
||||||
@ -151,7 +151,7 @@ class UserDeviceListItem extends StatelessWidget {
|
|||||||
itemBuilder: (BuildContext context) => [
|
itemBuilder: (BuildContext context) => [
|
||||||
PopupMenuItem<String>(
|
PopupMenuItem<String>(
|
||||||
value: "remove",
|
value: "remove",
|
||||||
child: Text(I18n.of(context).removeDevice,
|
child: Text(I18n.tr(context).removeDevice,
|
||||||
style: TextStyle(color: Colors.red)),
|
style: TextStyle(color: Colors.red)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -161,7 +161,7 @@ class UserDeviceListItem extends StatelessWidget {
|
|||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text((userDevice.displayName?.isNotEmpty ?? false)
|
Text((userDevice.displayName?.isNotEmpty ?? false)
|
||||||
? userDevice.displayName
|
? userDevice.displayName
|
||||||
: I18n.of(context).unknownDevice),
|
: I18n.tr(context).unknownDevice),
|
||||||
Spacer(),
|
Spacer(),
|
||||||
Text(userDevice.lastSeenTs.localizedTimeShort(context)),
|
Text(userDevice.lastSeenTs.localizedTimeShort(context)),
|
||||||
],
|
],
|
||||||
@ -169,8 +169,8 @@ class UserDeviceListItem extends StatelessWidget {
|
|||||||
subtitle: Column(
|
subtitle: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Text("${I18n.of(context).id}: ${userDevice.deviceId}"),
|
Text("${I18n.tr(context).id}: ${userDevice.deviceId}"),
|
||||||
Text("${I18n.of(context).lastSeenIp}: ${userDevice.lastSeenIp}"),
|
Text("${I18n.tr(context).lastSeenIp}: ${userDevice.lastSeenIp}"),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -36,13 +36,13 @@ class ThemesSettingsState extends State<ThemesSettings> {
|
|||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(I18n.of(context).changeTheme),
|
title: Text(I18n.tr(context).changeTheme),
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
RadioListTile<Themes>(
|
RadioListTile<Themes>(
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).systemTheme,
|
I18n.tr(context).systemTheme,
|
||||||
),
|
),
|
||||||
value: Themes.system,
|
value: Themes.system,
|
||||||
groupValue: _selectedTheme,
|
groupValue: _selectedTheme,
|
||||||
@ -56,7 +56,7 @@ class ThemesSettingsState extends State<ThemesSettings> {
|
|||||||
),
|
),
|
||||||
RadioListTile<Themes>(
|
RadioListTile<Themes>(
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).lightTheme,
|
I18n.tr(context).lightTheme,
|
||||||
),
|
),
|
||||||
value: Themes.light,
|
value: Themes.light,
|
||||||
groupValue: _selectedTheme,
|
groupValue: _selectedTheme,
|
||||||
@ -70,7 +70,7 @@ class ThemesSettingsState extends State<ThemesSettings> {
|
|||||||
),
|
),
|
||||||
RadioListTile<Themes>(
|
RadioListTile<Themes>(
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).darkTheme,
|
I18n.tr(context).darkTheme,
|
||||||
),
|
),
|
||||||
value: Themes.dark,
|
value: Themes.dark,
|
||||||
groupValue: _selectedTheme,
|
groupValue: _selectedTheme,
|
||||||
@ -85,7 +85,7 @@ class ThemesSettingsState extends State<ThemesSettings> {
|
|||||||
Divider(thickness: 1),
|
Divider(thickness: 1),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
I18n.of(context).useAmoledTheme,
|
I18n.tr(context).useAmoledTheme,
|
||||||
),
|
),
|
||||||
trailing: Switch(
|
trailing: Switch(
|
||||||
value: _amoledEnabled,
|
value: _amoledEnabled,
|
||||||
|
@ -38,7 +38,7 @@ class _SignUpState extends State<SignUp> {
|
|||||||
void signUpAction(BuildContext context) async {
|
void signUpAction(BuildContext context) async {
|
||||||
MatrixState matrix = Matrix.of(context);
|
MatrixState matrix = Matrix.of(context);
|
||||||
if (usernameController.text.isEmpty) {
|
if (usernameController.text.isEmpty) {
|
||||||
setState(() => usernameError = I18n.of(context).pleaseChooseAUsername);
|
setState(() => usernameError = I18n.tr(context).pleaseChooseAUsername);
|
||||||
} else {
|
} else {
|
||||||
setState(() => usernameError = null);
|
setState(() => usernameError = null);
|
||||||
}
|
}
|
||||||
@ -61,12 +61,12 @@ class _SignUpState extends State<SignUp> {
|
|||||||
setState(() => loading = true);
|
setState(() => loading = true);
|
||||||
if (!await matrix.client.checkServer(homeserver)) {
|
if (!await matrix.client.checkServer(homeserver)) {
|
||||||
setState(
|
setState(
|
||||||
() => serverError = I18n.of(context).homeserverIsNotCompatible);
|
() => serverError = I18n.tr(context).homeserverIsNotCompatible);
|
||||||
|
|
||||||
return setState(() => loading = false);
|
return setState(() => loading = false);
|
||||||
}
|
}
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
setState(() => serverError = I18n.of(context).connectionAttemptFailed);
|
setState(() => serverError = I18n.tr(context).connectionAttemptFailed);
|
||||||
return setState(() => loading = false);
|
return setState(() => loading = false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,7 +116,9 @@ class _SignUpState extends State<SignUp> {
|
|||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
backgroundImage: avatar == null ? null : FileImage(avatar),
|
backgroundImage: avatar == null ? null : FileImage(avatar),
|
||||||
backgroundColor: avatar == null
|
backgroundColor: avatar == null
|
||||||
? Theme.of(context).brightness == Brightness.dark ? Color(0xff121212) : Colors.white
|
? Theme.of(context).brightness == Brightness.dark
|
||||||
|
? Color(0xff121212)
|
||||||
|
: Colors.white
|
||||||
: Theme.of(context).secondaryHeaderColor,
|
: Theme.of(context).secondaryHeaderColor,
|
||||||
child: avatar == null
|
child: avatar == null
|
||||||
? Icon(Icons.camera_alt,
|
? Icon(Icons.camera_alt,
|
||||||
@ -130,15 +132,17 @@ class _SignUpState extends State<SignUp> {
|
|||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
),
|
),
|
||||||
title: Text(avatar == null
|
title: Text(avatar == null
|
||||||
? I18n.of(context).setAProfilePicture
|
? I18n.tr(context).setAProfilePicture
|
||||||
: I18n.of(context).discardPicture),
|
: I18n.tr(context).discardPicture),
|
||||||
onTap: avatar == null
|
onTap: avatar == null
|
||||||
? setAvatarAction
|
? setAvatarAction
|
||||||
: () => setState(() => avatar = null),
|
: () => setState(() => avatar = null),
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
backgroundColor: Theme.of(context).brightness == Brightness.dark ? Color(0xff121212) : Colors.white,
|
backgroundColor: Theme.of(context).brightness == Brightness.dark
|
||||||
|
? Color(0xff121212)
|
||||||
|
: Colors.white,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.account_circle,
|
Icons.account_circle,
|
||||||
color: Theme.of(context).primaryColor,
|
color: Theme.of(context).primaryColor,
|
||||||
@ -149,9 +153,9 @@ class _SignUpState extends State<SignUp> {
|
|||||||
controller: usernameController,
|
controller: usernameController,
|
||||||
onSubmitted: (s) => signUpAction(context),
|
onSubmitted: (s) => signUpAction(context),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: I18n.of(context).username,
|
hintText: I18n.tr(context).username,
|
||||||
errorText: usernameError,
|
errorText: usernameError,
|
||||||
labelText: I18n.of(context).chooseAUsername),
|
labelText: I18n.tr(context).chooseAUsername),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
@ -167,7 +171,7 @@ class _SignUpState extends State<SignUp> {
|
|||||||
child: loading
|
child: loading
|
||||||
? CircularProgressIndicator()
|
? CircularProgressIndicator()
|
||||||
: Text(
|
: Text(
|
||||||
I18n.of(context).signUp.toUpperCase(),
|
I18n.tr(context).signUp.toUpperCase(),
|
||||||
style: TextStyle(color: Colors.white, fontSize: 16),
|
style: TextStyle(color: Colors.white, fontSize: 16),
|
||||||
),
|
),
|
||||||
onPressed: () => signUpAction(context),
|
onPressed: () => signUpAction(context),
|
||||||
@ -176,7 +180,7 @@ class _SignUpState extends State<SignUp> {
|
|||||||
Center(
|
Center(
|
||||||
child: FlatButton(
|
child: FlatButton(
|
||||||
child: Text(
|
child: Text(
|
||||||
I18n.of(context).alreadyHaveAnAccount,
|
I18n.tr(context).alreadyHaveAnAccount,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
decoration: TextDecoration.underline,
|
decoration: TextDecoration.underline,
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
|
@ -29,7 +29,7 @@ class _SignUpPasswordState extends State<SignUpPassword> {
|
|||||||
void _signUpAction(BuildContext context, {Map<String, dynamic> auth}) async {
|
void _signUpAction(BuildContext context, {Map<String, dynamic> auth}) async {
|
||||||
MatrixState matrix = Matrix.of(context);
|
MatrixState matrix = Matrix.of(context);
|
||||||
if (passwordController.text.isEmpty) {
|
if (passwordController.text.isEmpty) {
|
||||||
setState(() => passwordError = I18n.of(context).pleaseEnterYourPassword);
|
setState(() => passwordError = I18n.tr(context).pleaseEnterYourPassword);
|
||||||
} else {
|
} else {
|
||||||
setState(() => passwordError = null);
|
setState(() => passwordError = null);
|
||||||
}
|
}
|
||||||
@ -96,7 +96,7 @@ class _SignUpPasswordState extends State<SignUpPassword> {
|
|||||||
try {
|
try {
|
||||||
await matrix.client.setDisplayname(widget.displayname);
|
await matrix.client.setDisplayname(widget.displayname);
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
Toast.show(I18n.of(context).couldNotSetDisplayname, context, duration: 5);
|
Toast.show(I18n.tr(context).couldNotSetDisplayname, context, duration: 5);
|
||||||
}
|
}
|
||||||
if (widget.avatar != null) {
|
if (widget.avatar != null) {
|
||||||
try {
|
try {
|
||||||
@ -107,7 +107,7 @@ class _SignUpPasswordState extends State<SignUpPassword> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} catch (exception) {
|
} catch (exception) {
|
||||||
Toast.show(I18n.of(context).couldNotSetAvatar, context, duration: 5);
|
Toast.show(I18n.tr(context).couldNotSetAvatar, context, duration: 5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await Navigator.of(context).pushAndRemoveUntil(
|
await Navigator.of(context).pushAndRemoveUntil(
|
||||||
@ -119,7 +119,7 @@ class _SignUpPasswordState extends State<SignUpPassword> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(I18n.of(context).secureYourAccountWithAPassword),
|
title: Text(I18n.tr(context).secureYourAccountWithAPassword),
|
||||||
),
|
),
|
||||||
body: ListView(
|
body: ListView(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.symmetric(
|
||||||
@ -156,7 +156,7 @@ class _SignUpPasswordState extends State<SignUpPassword> {
|
|||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
setState(() => showPassword = !showPassword),
|
setState(() => showPassword = !showPassword),
|
||||||
),
|
),
|
||||||
labelText: I18n.of(context).password),
|
labelText: I18n.tr(context).password),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 20),
|
SizedBox(height: 20),
|
||||||
@ -172,7 +172,7 @@ class _SignUpPasswordState extends State<SignUpPassword> {
|
|||||||
child: loading
|
child: loading
|
||||||
? CircularProgressIndicator()
|
? CircularProgressIndicator()
|
||||||
: Text(
|
: Text(
|
||||||
I18n.of(context).createAccountNow.toUpperCase(),
|
I18n.tr(context).createAccountNow.toUpperCase(),
|
||||||
style: TextStyle(color: Colors.white, fontSize: 16),
|
style: TextStyle(color: Colors.white, fontSize: 16),
|
||||||
),
|
),
|
||||||
onPressed: () => loading ? null : _signUpAction(context),
|
onPressed: () => loading ? null : _signUpAction(context),
|
||||||
|
@ -124,8 +124,8 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "6dd3b879b6cfcf1c7da9dedfa62626237afa6d9a"
|
ref: "5a4c484db62234ac8c782bf03f121e8687a07836"
|
||||||
resolved-ref: "6dd3b879b6cfcf1c7da9dedfa62626237afa6d9a"
|
resolved-ref: "5a4c484db62234ac8c782bf03f121e8687a07836"
|
||||||
url: "https://gitlab.com/famedly/famedlysdk.git"
|
url: "https://gitlab.com/famedly/famedlysdk.git"
|
||||||
source: git
|
source: git
|
||||||
version: "0.0.1"
|
version: "0.0.1"
|
||||||
|
257
test/fake_matrix_api.dart
Normal file
257
test/fake_matrix_api.dart
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
import 'package:http/testing.dart';
|
||||||
|
import 'dart:convert';
|
||||||
|
import 'dart:core';
|
||||||
|
import 'dart:math';
|
||||||
|
import 'package:http/http.dart';
|
||||||
|
|
||||||
|
class FakeMatrixApi extends MockClient {
|
||||||
|
FakeMatrixApi()
|
||||||
|
: super((request) async {
|
||||||
|
// Collect data from Request
|
||||||
|
final String action = request.url.path.split("/_matrix")[1];
|
||||||
|
final String method = request.method;
|
||||||
|
final dynamic data =
|
||||||
|
method == "GET" ? request.url.queryParameters : request.body;
|
||||||
|
var res = {};
|
||||||
|
|
||||||
|
//print("$method request to $action with Data: $data");
|
||||||
|
|
||||||
|
// Sync requests with timeout
|
||||||
|
if (data is Map<String, dynamic> && data["timeout"] is String) {
|
||||||
|
await Future.delayed(Duration(seconds: 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call API
|
||||||
|
if (api.containsKey(method) && api[method].containsKey(action)) {
|
||||||
|
res = api[method][action](data);
|
||||||
|
} else if (method == "GET" &&
|
||||||
|
action.contains("/client/r0/rooms/") &&
|
||||||
|
action.contains("/state/m.room.member/")) {
|
||||||
|
res = {"displayname": ""};
|
||||||
|
return Response(json.encode(res), 200);
|
||||||
|
} else {
|
||||||
|
res = {
|
||||||
|
"errcode": "M_UNRECOGNIZED",
|
||||||
|
"error": "Unrecognized request"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response(json.encode(res), 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
static final Map<String, Map<String, dynamic>> api = {
|
||||||
|
"GET": {
|
||||||
|
"/client/versions": (var req) => {
|
||||||
|
"versions": ["r0.0.1", "r0.1.0", "r0.2.0", "r0.3.0", "r0.4.0"],
|
||||||
|
"unstable_features": {"m.lazy_load_members": true},
|
||||||
|
},
|
||||||
|
"/client/r0/account/whoami": (var req) =>
|
||||||
|
{"user_id": "@test:fakeServer.notExisting"},
|
||||||
|
"/client/r0/login": (var req) => {
|
||||||
|
"flows": [
|
||||||
|
{"type": "m.login.password"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"/client/r0/sync": (var req) => {
|
||||||
|
"next_batch": Random().nextDouble().toString(),
|
||||||
|
"presence": {
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"sender": "@alice:example.com",
|
||||||
|
"type": "m.presence",
|
||||||
|
"content": {"presence": "online"}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"account_data": {
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"type": "org.example.custom.config",
|
||||||
|
"content": {"custom_config_key": "custom_config_value"}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"to_device": {
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"sender": "@alice:example.com",
|
||||||
|
"type": "m.new_device",
|
||||||
|
"content": {
|
||||||
|
"device_id": "XYZABCDE",
|
||||||
|
"rooms": ["!726s6s6q:example.com"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rooms": {
|
||||||
|
"join": {
|
||||||
|
"!726s6s6q:example.com": {
|
||||||
|
"unread_notifications": {
|
||||||
|
"highlight_count": 2,
|
||||||
|
"notification_count": 2,
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"sender": "@alice:example.com",
|
||||||
|
"type": "m.room.member",
|
||||||
|
"state_key": "@alice:example.com",
|
||||||
|
"content": {"membership": "join"},
|
||||||
|
"origin_server_ts": 1417731086795,
|
||||||
|
"event_id": "66697273743031:example.com"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"timeline": {
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"sender": "@bob:example.com",
|
||||||
|
"type": "m.room.member",
|
||||||
|
"state_key": "@bob:example.com",
|
||||||
|
"content": {"membership": "join"},
|
||||||
|
"prev_content": {"membership": "invite"},
|
||||||
|
"origin_server_ts": 1417731086795,
|
||||||
|
"event_id": "7365636s6r6432:example.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sender": "@alice:example.com",
|
||||||
|
"type": "m.room.message",
|
||||||
|
"txn_id": "1234",
|
||||||
|
"content": {"body": "I am a fish", "msgtype": "m.text"},
|
||||||
|
"origin_server_ts": 1417731086797,
|
||||||
|
"event_id": "74686972643033:example.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"limited": true,
|
||||||
|
"prev_batch": "t34-23535_0_0"
|
||||||
|
},
|
||||||
|
"ephemeral": {
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"type": "m.typing",
|
||||||
|
"content": {
|
||||||
|
"user_ids": ["@alice:example.com"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"account_data": {
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"type": "m.tag",
|
||||||
|
"content": {
|
||||||
|
"tags": {
|
||||||
|
"work": {"order": 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "org.example.custom.room.config",
|
||||||
|
"content": {"custom_config_key": "custom_config_value"}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"invite": {
|
||||||
|
"!696r7674:example.com": {
|
||||||
|
"invite_state": {
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"sender": "@alice:example.com",
|
||||||
|
"type": "m.room.name",
|
||||||
|
"state_key": "",
|
||||||
|
"content": {"name": "My Room Name"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"sender": "@alice:example.com",
|
||||||
|
"type": "m.room.member",
|
||||||
|
"state_key": "@bob:example.com",
|
||||||
|
"content": {"membership": "invite"}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"leave": {
|
||||||
|
"!5345234234:example.com": {
|
||||||
|
"timeline": {"events": []}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"POST": {
|
||||||
|
"/client/r0/keys/claim": (var req) => {
|
||||||
|
"failures": {},
|
||||||
|
"one_time_keys": {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"JLAFKJWSCS": {
|
||||||
|
"signed_curve25519:AAAAHg": {
|
||||||
|
"key": "zKbLg+NrIjpnagy+pIY6uPL4ZwEG2v+8F9lmgsnlZzs",
|
||||||
|
"signatures": {
|
||||||
|
"@alice:example.com": {
|
||||||
|
"ed25519:JLAFKJWSCS":
|
||||||
|
"FLWxXqGbwrb8SM3Y795eB6OA8bwBcoMZFXBqnTn58AYWZSqiD45tlBVcDa2L7RwdKXebW/VzDlnfVJ+9jok1Bw"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/client/r0/keys/upload": (var req) => {
|
||||||
|
"one_time_key_counts": {
|
||||||
|
"curve25519": 10,
|
||||||
|
"signed_curve25519": 100,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/client/r0/keys/query": (var req) => {
|
||||||
|
"failures": {},
|
||||||
|
"device_keys": {
|
||||||
|
"@test:fakeServer.notExisting": {
|
||||||
|
"JLAFKJWSCS": {
|
||||||
|
"user_id": "@test:fakeServer.notExisting",
|
||||||
|
"device_id": "JLAFKJWSCS",
|
||||||
|
"algorithms": [
|
||||||
|
"m.olm.v1.curve25519-aes-sha2",
|
||||||
|
"m.megolm.v1.aes-sha2"
|
||||||
|
],
|
||||||
|
"keys": {
|
||||||
|
"curve25519:JLAFKJWSCS":
|
||||||
|
"3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI",
|
||||||
|
"ed25519:JLAFKJWSCS":
|
||||||
|
"lEuiRJBit0IG6nUf5pUzWTUEsRVVe/HJkoKuEww9ULI"
|
||||||
|
},
|
||||||
|
"signatures": {
|
||||||
|
"@test:fakeServer.notExisting": {
|
||||||
|
"ed25519:JLAFKJWSCS":
|
||||||
|
"dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"unsigned": {"device_display_name": "Alice's mobile phone"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/client/r0/login": (var req) => {
|
||||||
|
"user_id": "@test:fakeServer.notExisting",
|
||||||
|
"access_token": "abc123",
|
||||||
|
"device_id": "GHTYAJCE"
|
||||||
|
},
|
||||||
|
"/client/r0/logout": (var reqI) => {},
|
||||||
|
"/client/r0/logout/all": (var reqI) => {},
|
||||||
|
},
|
||||||
|
"PUT": {
|
||||||
|
"/client/r0/rooms/!request:localhost/state/com.famedly.app.request_state":
|
||||||
|
(var req) => {"event_id": "1234"},
|
||||||
|
"/client/r0/user/null/account_data/com.famedly.talk.tasks": (var req) =>
|
||||||
|
{},
|
||||||
|
"/client/r0/rooms/1234/typing/@test:fakeServer.notExisting": (var req) =>
|
||||||
|
{},
|
||||||
|
},
|
||||||
|
"DELETE": {
|
||||||
|
"/unknown/token": (var req) => {"errcode": "M_UNKNOWN_TOKEN"},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
35
test/login_test.dart
Normal file
35
test/login_test.dart
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import 'package:fluffychat/views/login.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import 'utils.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
/// All Tests related to the Login
|
||||||
|
group("LoginPage", () {
|
||||||
|
/// Check if all Elements get created
|
||||||
|
testWidgets('should get created', (WidgetTester tester) async {
|
||||||
|
await tester.runAsync(() async {
|
||||||
|
final TestObserver observer = TestObserver()
|
||||||
|
..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {}
|
||||||
|
..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) {};
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
Utils.getWidgetWrapper(
|
||||||
|
Login(),
|
||||||
|
observer,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.pump(Duration.zero);
|
||||||
|
|
||||||
|
expect(find.byKey(Key("serverField")), findsOneWidget); // Server field
|
||||||
|
expect(
|
||||||
|
find.byKey(Key("usernameField")), findsOneWidget); // Username Input
|
||||||
|
expect(
|
||||||
|
find.byKey(Key("passwordField")), findsOneWidget); // Password Input
|
||||||
|
expect(find.byKey(Key("loginButton")), findsOneWidget); // Login Button
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
128
test/utils.dart
Normal file
128
test/utils.dart
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
|
import 'package:fluffychat/components/matrix.dart';
|
||||||
|
import 'package:fluffychat/components/theme_switcher.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
import 'fake_matrix_api.dart';
|
||||||
|
|
||||||
|
class Utils {
|
||||||
|
static printWidgets(WidgetTester tester) {
|
||||||
|
debugPrint(tester.allWidgets.toList().join("\n").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
static Client get defaultClient {
|
||||||
|
Client client = Client("testclient", debug: true);
|
||||||
|
client.httpClient = FakeMatrixApi();
|
||||||
|
client.onUserEvent.stream.listen(client.handleUserUpdate);
|
||||||
|
client.connect(
|
||||||
|
newHomeserver: "https://fakeServer.notExisting",
|
||||||
|
newDeviceID: "GHTYAJCE",
|
||||||
|
newToken: "abc123",
|
||||||
|
newUserID: "@test:fakeServer.notExisting");
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Widget getWidgetWrapper(Widget child, TestObserver routeObserver,
|
||||||
|
{Client client}) {
|
||||||
|
return Matrix(
|
||||||
|
client: client ?? Utils.defaultClient,
|
||||||
|
child: MaterialApp(
|
||||||
|
title: "Fluffychat",
|
||||||
|
theme: lightTheme,
|
||||||
|
navigatorObservers: <NavigatorObserver>[routeObserver],
|
||||||
|
home: child,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double getOpacity(WidgetTester tester, String textValue) {
|
||||||
|
final FadeTransition opacityWidget = tester.widget<FadeTransition>(find
|
||||||
|
.ancestor(
|
||||||
|
of: find.text(textValue),
|
||||||
|
matching: find.byType(FadeTransition),
|
||||||
|
)
|
||||||
|
.first);
|
||||||
|
return opacityWidget.opacity.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<Null> tapItem(WidgetTester tester, Key key) async {
|
||||||
|
/// Tap the button which should open the PopupMenu.
|
||||||
|
/// By calling tester.pumpAndSettle(), we ensure that all animations
|
||||||
|
/// have completed before we continue further.
|
||||||
|
await tester.tap(find.byKey(key));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef OnObservation = void Function(
|
||||||
|
Route<dynamic> route, Route<dynamic> previousRoute);
|
||||||
|
|
||||||
|
/// Example Usage:
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// bool isPushed = false;
|
||||||
|
// bool isPopped = false;
|
||||||
|
//
|
||||||
|
// final TestObserver observer = TestObserver()
|
||||||
|
// ..onPushed = (Route<dynamic> route, Route<dynamic> previousRoute) {
|
||||||
|
// // Pushes the initial route.
|
||||||
|
// expect(route is PageRoute && route.settings.name == '/', isTrue);
|
||||||
|
// expect(previousRoute, isNull);
|
||||||
|
// isPushed = true;
|
||||||
|
// }
|
||||||
|
// ..onPopped = (Route<dynamic> route, Route<dynamic> previousRoute) {
|
||||||
|
// isPopped = true;
|
||||||
|
// };
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
class TestObserver extends NavigatorObserver {
|
||||||
|
OnObservation onPushed;
|
||||||
|
OnObservation onPopped;
|
||||||
|
OnObservation onRemoved;
|
||||||
|
OnObservation onReplaced;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
|
||||||
|
if (onPushed != null) {
|
||||||
|
onPushed(route, previousRoute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
|
||||||
|
if (onPopped != null) {
|
||||||
|
onPopped(route, previousRoute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didRemove(Route<dynamic> route, Route<dynamic> previousRoute) {
|
||||||
|
if (onRemoved != null) onRemoved(route, previousRoute);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didReplace({Route<dynamic> oldRoute, Route<dynamic> newRoute}) {
|
||||||
|
if (onReplaced != null) onReplaced(newRoute, oldRoute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RouteMatcher extends Matcher {
|
||||||
|
final String expected;
|
||||||
|
bool contains = false;
|
||||||
|
|
||||||
|
RouteMatcher(this.expected, {this.contains});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Description describe(Description description) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool matches(covariant String item, Map matchState) {
|
||||||
|
if (contains) {
|
||||||
|
return item.toString().contains(expected);
|
||||||
|
}
|
||||||
|
return item == expected;
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +0,0 @@
|
|||||||
// This is a basic Flutter widget test.
|
|
||||||
//
|
|
||||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
|
||||||
// utility that Flutter provides. For example, you can send tap and scroll
|
|
||||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
|
||||||
// tree, read text, and verify that the values of widget properties are correct.
|
|
||||||
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
testWidgets('Test if the app starts', (WidgetTester tester) async {
|
|
||||||
// Build our app and trigger a frame.
|
|
||||||
//await tester.pumpWidget(App());
|
|
||||||
});
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user