refactor: Migrate to flutter 2

This commit is contained in:
Christian Pauly 2021-03-04 12:28:06 +01:00
parent a553c049d7
commit bb97b1bca8
39 changed files with 257 additions and 315 deletions

View File

@ -25,7 +25,6 @@ test:
build_web: build_web:
stage: coverage stage: coverage
image: registry.gitlab.com/famedly/containers/flutter-dockerimages:beta
before_script: [sudo apt update && sudo apt install curl -y, ./scripts/prepare-web.sh] before_script: [sudo apt update && sudo apt install curl -y, ./scripts/prepare-web.sh]
script: [./scripts/build-web.sh] script: [./scripts/build-web.sh]
artifacts: artifacts:
@ -157,7 +156,6 @@ pages:
build_linux: build_linux:
stage: coverage stage: coverage
image: cirrusci/flutter:dev
before_script: [sudo apt update && sudo apt install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev -y] before_script: [sudo apt update && sudo apt install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev -y]
script: [./scripts/build-linux.sh] script: [./scripts/build-linux.sh]
artifacts: artifacts:
@ -260,7 +258,6 @@ upload-windows:
upload-playstore: upload-playstore:
extends: .release extends: .release
image: registry.gitlab.com/famedly/containers/flutter-dockerimages:stable
script: [./scripts/release-playstore.sh] script: [./scripts/release-playstore.sh]
resource_group: playstore_release resource_group: playstore_release

View File

@ -66,8 +66,8 @@ class ContentBanner extends StatelessWidget {
alignment: Alignment.bottomRight, alignment: Alignment.bottomRight,
child: FloatingActionButton( child: FloatingActionButton(
mini: true, mini: true,
child: Icon(Icons.camera_alt_outlined),
onPressed: onEdit, onPressed: onEdit,
child: Icon(Icons.camera_alt_outlined),
), ),
), ),
], ],

View File

@ -18,17 +18,17 @@ class AdaptiveFlatButton extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (PlatformInfos.isCupertinoStyle) { if (PlatformInfos.isCupertinoStyle) {
return CupertinoDialogAction( return CupertinoDialogAction(
child: Text(label),
onPressed: onPressed, onPressed: onPressed,
textStyle: textColor != null ? TextStyle(color: textColor) : null, textStyle: textColor != null ? TextStyle(color: textColor) : null,
child: Text(label),
); );
} }
return TextButton( return TextButton(
onPressed: onPressed,
child: Text( child: Text(
label, label,
style: TextStyle(color: textColor), style: TextStyle(color: textColor),
), ),
onPressed: onPressed,
); );
} }
} }

View File

@ -105,6 +105,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
body = Container( body = Container(
margin: EdgeInsets.only(left: 8.0, right: 8.0), margin: EdgeInsets.only(left: 8.0, right: 8.0),
child: Column( child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
Text(L10n.of(context).askSSSSSign, Text(L10n.of(context).askSSSSSign,
style: TextStyle(fontSize: 20)), style: TextStyle(fontSize: 20)),
@ -128,7 +129,6 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
), ),
), ),
], ],
mainAxisSize: MainAxisSize.min,
), ),
); );
buttons.add(AdaptiveFlatButton( buttons.add(AdaptiveFlatButton(
@ -145,10 +145,10 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
break; break;
case KeyVerificationState.askAccept: case KeyVerificationState.askAccept:
body = Container( body = Container(
margin: EdgeInsets.only(left: 8.0, right: 8.0),
child: Text( child: Text(
L10n.of(context).askVerificationRequest(widget.request.userId), L10n.of(context).askVerificationRequest(widget.request.userId),
style: TextStyle(fontSize: 20)), style: TextStyle(fontSize: 20)),
margin: EdgeInsets.only(left: 8.0, right: 8.0),
); );
buttons.add(AdaptiveFlatButton( buttons.add(AdaptiveFlatButton(
label: L10n.of(context).accept, label: L10n.of(context).accept,
@ -165,6 +165,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
break; break;
case KeyVerificationState.waitingAccept: case KeyVerificationState.waitingAccept:
body = Column( body = Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
PlatformInfos.isCupertinoStyle PlatformInfos.isCupertinoStyle
? CupertinoActivityIndicator() ? CupertinoActivityIndicator()
@ -175,7 +176,6 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
], ],
mainAxisSize: MainAxisSize.min,
); );
final key = widget.request.client.userDeviceKeys[widget.request.userId] final key = widget.request.client.userDeviceKeys[widget.request.userId]
.deviceKeys[widget.request.deviceId]; .deviceKeys[widget.request.deviceId];
@ -219,6 +219,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
TextSpan(text: numbstr, style: TextStyle(fontSize: 40)); TextSpan(text: numbstr, style: TextStyle(fontSize: 40));
} }
body = Column( body = Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
Center( Center(
child: Text( child: Text(
@ -233,7 +234,6 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
], ],
mainAxisSize: MainAxisSize.min,
); );
buttons.add(AdaptiveFlatButton( buttons.add(AdaptiveFlatButton(
textColor: Colors.red, textColor: Colors.red,
@ -250,6 +250,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
? L10n.of(context).waitingPartnerEmoji ? L10n.of(context).waitingPartnerEmoji
: L10n.of(context).waitingPartnerNumbers; : L10n.of(context).waitingPartnerNumbers;
body = Column( body = Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
PlatformInfos.isCupertinoStyle PlatformInfos.isCupertinoStyle
? CupertinoActivityIndicator() ? CupertinoActivityIndicator()
@ -260,11 +261,11 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
], ],
mainAxisSize: MainAxisSize.min,
); );
break; break;
case KeyVerificationState.done: case KeyVerificationState.done:
body = Column( body = Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
Icon(Icons.check_circle_outlined, color: Colors.green, size: 200.0), Icon(Icons.check_circle_outlined, color: Colors.green, size: 200.0),
SizedBox(height: 10), SizedBox(height: 10),
@ -273,7 +274,6 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
], ],
mainAxisSize: MainAxisSize.min,
); );
buttons.add(AdaptiveFlatButton( buttons.add(AdaptiveFlatButton(
label: L10n.of(context).close, label: L10n.of(context).close,
@ -282,6 +282,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
break; break;
case KeyVerificationState.error: case KeyVerificationState.error:
body = Column( body = Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
Icon(Icons.cancel, color: Colors.red, size: 200.0), Icon(Icons.cancel, color: Colors.red, size: 200.0),
SizedBox(height: 10), SizedBox(height: 10),
@ -290,7 +291,6 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
], ],
mainAxisSize: MainAxisSize.min,
); );
buttons.add(AdaptiveFlatButton( buttons.add(AdaptiveFlatButton(
label: L10n.of(context).close, label: L10n.of(context).close,
@ -318,6 +318,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
} }
final userNameTitle = Row( final userNameTitle = Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Text( Text(
otherName, otherName,
@ -336,7 +337,6 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
), ),
), ),
], ],
crossAxisAlignment: CrossAxisAlignment.start,
); );
final title = Text(L10n.of(context).verifyTitle); final title = Text(L10n.of(context).verifyTitle);
final content = Scrollbar( final content = Scrollbar(

View File

@ -108,15 +108,21 @@ class _RecordingDialogState extends State<RecordingDialog> {
), ),
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
onPressed: () => Navigator.of(context, rootNavigator: false).pop(),
child: Text( child: Text(
L10n.of(context).cancel.toUpperCase(), L10n.of(context).cancel.toUpperCase(),
style: TextStyle( style: TextStyle(
color: Theme.of(context).textTheme.bodyText2.color.withAlpha(150), color: Theme.of(context).textTheme.bodyText2.color.withAlpha(150),
), ),
), ),
onPressed: () => Navigator.of(context, rootNavigator: false).pop(),
), ),
TextButton( TextButton(
onPressed: () async {
await _recorderSubscription?.cancel();
await flutterSound.stopRecorder();
Navigator.of(context, rootNavigator: false)
.pop<String>(_recordedPath);
},
child: Row( child: Row(
children: <Widget>[ children: <Widget>[
Text(L10n.of(context).send.toUpperCase()), Text(L10n.of(context).send.toUpperCase()),
@ -124,12 +130,6 @@ class _RecordingDialogState extends State<RecordingDialog> {
Icon(Icons.send_outlined, size: 15), Icon(Icons.send_outlined, size: 15),
], ],
), ),
onPressed: () async {
await _recorderSubscription?.cancel();
await flutterSound.stopRecorder();
Navigator.of(context, rootNavigator: false)
.pop<String>(_recordedPath);
},
), ),
], ],
); );

View File

@ -78,14 +78,13 @@ class _SendFileDialogState extends State<SendFileDialog> {
content: contentWidget, content: contentWidget,
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
child: Text(L10n.of(context).cancel),
onPressed: () { onPressed: () {
// just close the dialog // just close the dialog
Navigator.of(context, rootNavigator: false).pop(); Navigator.of(context, rootNavigator: false).pop();
}, },
child: Text(L10n.of(context).cancel),
), ),
TextButton( TextButton(
child: Text(L10n.of(context).send),
onPressed: _isSending onPressed: _isSending
? null ? null
: () async { : () async {
@ -94,8 +93,9 @@ class _SendFileDialogState extends State<SendFileDialog> {
}); });
await showFutureLoadingDialog( await showFutureLoadingDialog(
context: context, future: () => _send()); context: context, future: () => _send());
await Navigator.of(context, rootNavigator: false).pop(); Navigator.of(context, rootNavigator: false).pop();
}, },
child: Text(L10n.of(context).send),
), ),
], ],
); );

View File

@ -231,25 +231,25 @@ class InputBar extends StatelessWidget {
} }
insertText = (isUnique insertText = (isUnique
? insertEmote ? insertEmote
: ':${insertPack}~${insertEmote.substring(1)}') + : ':$insertPack~${insertEmote.substring(1)}') +
' '; ' ';
startText = replaceText.replaceAllMapped( startText = replaceText.replaceAllMapped(
RegExp(r'(\s|^)(:(?:[-\w]+~)?[-\w]+)$'), RegExp(r'(\s|^)(:(?:[-\w]+~)?[-\w]+)$'),
(Match m) => '${m[1]}${insertText}', (Match m) => '${m[1]}$insertText',
); );
} }
if (suggestion['type'] == 'user') { if (suggestion['type'] == 'user') {
insertText = suggestion['mxid'] + ' '; insertText = suggestion['mxid'] + ' ';
startText = replaceText.replaceAllMapped( startText = replaceText.replaceAllMapped(
RegExp(r'(\s|^)(@[-\w]+)$'), RegExp(r'(\s|^)(@[-\w]+)$'),
(Match m) => '${m[1]}${insertText}', (Match m) => '${m[1]}$insertText',
); );
} }
if (suggestion['type'] == 'room') { if (suggestion['type'] == 'room') {
insertText = suggestion['mxid'] + ' '; insertText = suggestion['mxid'] + ' ';
startText = replaceText.replaceAllMapped( startText = replaceText.replaceAllMapped(
RegExp(r'(\s|^)(#[-\w]+)$'), RegExp(r'(\s|^)(#[-\w]+)$'),
(Match m) => '${m[1]}${insertText}', (Match m) => '${m[1]}$insertText',
); );
} }
if (insertText.isNotEmpty && startText.isNotEmpty) { if (insertText.isNotEmpty && startText.isNotEmpty) {

View File

@ -109,6 +109,11 @@ class Message extends StatelessWidget {
originServerTs: DateTime.now(), originServerTs: DateTime.now(),
); );
return InkWell( return InkWell(
onTap: () {
if (scrollToEventId != null) {
scrollToEventId(replyEvent.eventId);
}
},
child: AbsorbPointer( child: AbsorbPointer(
child: Container( child: Container(
margin: EdgeInsets.symmetric(vertical: 4.0), margin: EdgeInsets.symmetric(vertical: 4.0),
@ -116,11 +121,6 @@ class Message extends StatelessWidget {
lightText: ownMessage, timeline: timeline), lightText: ownMessage, timeline: timeline),
), ),
), ),
onTap: () {
if (scrollToEventId != null) {
scrollToEventId(replyEvent.eventId);
}
},
); );
}, },
), ),

View File

@ -123,42 +123,28 @@ class MessageContent extends StatelessWidget {
continue textmessage; continue textmessage;
case MessageTypes.BadEncrypted: case MessageTypes.BadEncrypted:
case EventTypes.Encrypted: case EventTypes.Encrypted:
return RaisedButton( return ElevatedButton.icon(
elevation: 7, style: ElevatedButton.styleFrom(
color: Theme.of(context).scaffoldBackgroundColor, primary: Theme.of(context).scaffoldBackgroundColor,
shape: RoundedRectangleBorder( onPrimary: Theme.of(context).textTheme.bodyText1.color,
borderRadius: BorderRadius.circular(6),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.lock_outline),
SizedBox(width: 8),
Text(L10n.of(context).encrypted),
],
), ),
onPressed: () => _verifyOrRequestKey(context), onPressed: () => _verifyOrRequestKey(context),
icon: Icon(Icons.lock_outline),
label: Text(L10n.of(context).encrypted),
); );
case MessageTypes.Location: case MessageTypes.Location:
case MessageTypes.None: case MessageTypes.None:
textmessage: textmessage:
default: default:
if (event.content['msgtype'] == Matrix.callNamespace) { if (event.content['msgtype'] == Matrix.callNamespace) {
return RaisedButton( return ElevatedButton.icon(
elevation: 7, style: ElevatedButton.styleFrom(
color: Theme.of(context).scaffoldBackgroundColor, primary: Theme.of(context).scaffoldBackgroundColor,
shape: RoundedRectangleBorder( onPrimary: Theme.of(context).textTheme.bodyText1.color,
borderRadius: BorderRadius.circular(6),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.phone_outlined, color: Colors.green),
SizedBox(width: 8),
Text(L10n.of(context).videoCall),
],
), ),
onPressed: () => launch(event.body), onPressed: () => launch(event.body),
icon: Icon(Icons.phone_outlined, color: Colors.green),
label: Text(L10n.of(context).videoCall),
); );
} }
if (event.redacted) { if (event.redacted) {

View File

@ -19,12 +19,12 @@ class MessageDownloadContent extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
RaisedButton( ElevatedButton(
elevation: 7, style: ElevatedButton.styleFrom(
color: Theme.of(context).scaffoldBackgroundColor, primary: Theme.of(context).scaffoldBackgroundColor,
shape: RoundedRectangleBorder( onPrimary: Theme.of(context).textTheme.bodyText1.color,
borderRadius: BorderRadius.circular(6),
), ),
onPressed: () => event.openFile(context),
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -38,7 +38,6 @@ class MessageDownloadContent extends StatelessWidget {
), ),
], ],
), ),
onPressed: () => event.openFile(context),
), ),
if (event.sizeString != null) if (event.sizeString != null)
Text( Text(

View File

@ -120,6 +120,7 @@ class _Reaction extends StatelessWidget {
)); ));
} }
return InkWell( return InkWell(
onTap: () => onTap != null ? onTap() : null,
child: Container( child: Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: color, color: color,
@ -132,7 +133,6 @@ class _Reaction extends StatelessWidget {
padding: EdgeInsets.all(padding), padding: EdgeInsets.all(padding),
child: content, child: content,
), ),
onTap: () => onTap != null ? onTap() : null,
); );
} }
} }

View File

@ -81,7 +81,7 @@ class UserBottomSheet extends StatelessWidget {
case 'message': case 'message':
final roomId = await user.startDirectChat(); final roomId = await user.startDirectChat();
await AdaptivePageLayout.of(context) await AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/rooms/${roomId}'); .pushNamedAndRemoveUntilIsFirst('/rooms/$roomId');
break; break;
} }
} }
@ -95,60 +95,66 @@ class UserBottomSheet extends StatelessWidget {
if (onMention != null) { if (onMention != null) {
items.add( items.add(
PopupMenuItem( PopupMenuItem(
child: _TextWithIcon( value: 'mention',
L10n.of(context).mention, child: _TextWithIcon(
Icons.alternate_email_outlined, L10n.of(context).mention,
), Icons.alternate_email_outlined,
value: 'mention'), ),
),
); );
} }
if (user.id != user.room.client.userID && !user.room.isDirectChat) { if (user.id != user.room.client.userID && !user.room.isDirectChat) {
items.add( items.add(
PopupMenuItem( PopupMenuItem(
child: _TextWithIcon( value: 'message',
L10n.of(context).sendAMessage, child: _TextWithIcon(
Icons.send_outlined, L10n.of(context).sendAMessage,
), Icons.send_outlined,
value: 'message'), ),
),
); );
} }
if (user.canChangePowerLevel) { if (user.canChangePowerLevel) {
items.add( items.add(
PopupMenuItem( PopupMenuItem(
child: _TextWithIcon( value: 'permission',
L10n.of(context).setPermissionsLevel, child: _TextWithIcon(
Icons.edit_attributes_outlined, L10n.of(context).setPermissionsLevel,
), Icons.edit_attributes_outlined,
value: 'permission'), ),
),
); );
} }
if (user.canKick) { if (user.canKick) {
items.add( items.add(
PopupMenuItem( PopupMenuItem(
child: _TextWithIcon( value: 'kick',
L10n.of(context).kickFromChat, child: _TextWithIcon(
Icons.exit_to_app_outlined, L10n.of(context).kickFromChat,
), Icons.exit_to_app_outlined,
value: 'kick'), ),
),
); );
} }
if (user.canBan && user.membership != Membership.ban) { if (user.canBan && user.membership != Membership.ban) {
items.add( items.add(
PopupMenuItem( PopupMenuItem(
child: _TextWithIcon( value: 'ban',
L10n.of(context).banFromChat, child: _TextWithIcon(
Icons.warning_sharp, L10n.of(context).banFromChat,
), Icons.warning_sharp,
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: _TextWithIcon( value: 'unban',
L10n.of(context).removeExile, child: _TextWithIcon(
Icons.warning_outlined, L10n.of(context).removeExile,
), Icons.warning_outlined,
value: 'unban'), ),
),
); );
} }
return Center( return Center(

View File

@ -28,6 +28,7 @@ abstract class FluffyThemes {
: TextTheme(); : TextTheme();
static ThemeData light = ThemeData( static ThemeData light = ThemeData(
visualDensity: VisualDensity.standard,
primaryColorDark: Colors.white, primaryColorDark: Colors.white,
primaryColorLight: Color(0xff121212), primaryColorLight: Color(0xff121212),
brightness: Brightness.light, brightness: Brightness.light,
@ -54,6 +55,17 @@ abstract class FluffyThemes {
backgroundColor: AppConfig.primaryColor, backgroundColor: AppConfig.primaryColor,
foregroundColor: Colors.white, foregroundColor: Colors.white,
), ),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
primary: AppConfig.primaryColor,
onPrimary: Colors.white,
elevation: 7,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
),
padding: EdgeInsets.all(12),
),
),
inputDecorationTheme: InputDecorationTheme( inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder( border: OutlineInputBorder(
borderRadius: BorderRadius.circular(AppConfig.borderRadius)), borderRadius: BorderRadius.circular(AppConfig.borderRadius)),
@ -80,6 +92,7 @@ abstract class FluffyThemes {
); );
static ThemeData dark = ThemeData.dark().copyWith( static ThemeData dark = ThemeData.dark().copyWith(
visualDensity: VisualDensity.standard,
primaryColorDark: Color(0xff121212), primaryColorDark: Color(0xff121212),
primaryColorLight: Colors.white, primaryColorLight: Colors.white,
primaryColor: AppConfig.primaryColor, primaryColor: AppConfig.primaryColor,

View File

@ -13,5 +13,5 @@ Future<Database> constructDb(
} }
Future<String> getLocalstorage(String key) async { Future<String> getLocalstorage(String key) async {
return await window.localStorage[key]; return window.localStorage[key];
} }

View File

@ -84,7 +84,7 @@ class Store {
if (!PlatformInfos.isMobile) { if (!PlatformInfos.isMobile) {
await _setupLocalStorage(); await _setupLocalStorage();
try { try {
return await storage.getItem(key)?.toString(); return storage.getItem(key)?.toString();
} catch (_) { } catch (_) {
return null; return null;
} }

View File

@ -46,13 +46,13 @@ abstract class PlatformInfos {
useRootNavigator: false, useRootNavigator: false,
children: [ children: [
Text('Version: $version'), Text('Version: $version'),
RaisedButton( OutlinedButton(
child: Text(L10n.of(context).sourceCode),
onPressed: () => launch(AppConfig.sourceCodeUrl), onPressed: () => launch(AppConfig.sourceCodeUrl),
child: Text(L10n.of(context).sourceCode),
), ),
RaisedButton( OutlinedButton(
child: Text(AppConfig.emojiFontName),
onPressed: () => launch(AppConfig.emojiFontUrl), onPressed: () => launch(AppConfig.emojiFontUrl),
child: Text(AppConfig.emojiFontName),
), ),
SentrySwitchListTile(label: L10n.of(context).sendBugReports), SentrySwitchListTile(label: L10n.of(context).sendBugReports),
], ],

View File

@ -99,7 +99,7 @@ class UrlLauncher {
} }
} else { } else {
await AdaptivePageLayout.of(context) await AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/discover/${roomIdOrAlias}'); .pushNamedAndRemoveUntilIsFirst('/discover/$roomIdOrAlias');
} }
} else if (identityParts.primaryIdentifier.sigil == '@') { } else if (identityParts.primaryIdentifier.sigil == '@') {
final user = User( final user = User(
@ -109,7 +109,7 @@ class UrlLauncher {
var roomId = matrix.client.getDirectChatFromUserId(user.id); var roomId = matrix.client.getDirectChatFromUserId(user.id);
if (roomId != null) { if (roomId != null) {
await AdaptivePageLayout.of(context) await AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/rooms/${roomId}'); .pushNamedAndRemoveUntilIsFirst('/rooms/$roomId');
return; return;
} }
@ -128,7 +128,7 @@ class UrlLauncher {
if (roomId != null) { if (roomId != null) {
await AdaptivePageLayout.of(context) await AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/rooms/${roomId}'); .pushNamedAndRemoveUntilIsFirst('/rooms/$roomId');
} }
} }
} }

View File

@ -636,24 +636,24 @@ class _ChatState extends State<Chat> {
}, },
itemBuilder: (_) => [ itemBuilder: (_) => [
PopupMenuItem( PopupMenuItem(
child: Text(L10n.of(context).copy),
value: 'copy', value: 'copy',
child: Text(L10n.of(context).copy),
), ),
if (canRedactSelectedEvents) if (canRedactSelectedEvents)
PopupMenuItem( PopupMenuItem(
value: 'redact',
child: Text( child: Text(
L10n.of(context).redactMessage, L10n.of(context).redactMessage,
style: TextStyle(color: Colors.orange), style: TextStyle(color: Colors.orange),
), ),
value: 'redact',
), ),
if (selectedEvents.length == 1) if (selectedEvents.length == 1)
PopupMenuItem( PopupMenuItem(
value: 'report',
child: Text( child: Text(
L10n.of(context).reportMessage, L10n.of(context).reportMessage,
style: TextStyle(color: Colors.red), style: TextStyle(color: Colors.red),
), ),
value: 'report',
), ),
], ],
), ),
@ -672,12 +672,12 @@ class _ChatState extends State<Chat> {
? Padding( ? Padding(
padding: const EdgeInsets.only(bottom: 56.0), padding: const EdgeInsets.only(bottom: 56.0),
child: FloatingActionButton( child: FloatingActionButton(
child: Icon(Icons.arrow_downward_outlined,
color: Theme.of(context).primaryColor),
onPressed: () => _scrollController.jumpTo(0), onPressed: () => _scrollController.jumpTo(0),
foregroundColor: Theme.of(context).textTheme.bodyText2.color, foregroundColor: Theme.of(context).textTheme.bodyText2.color,
backgroundColor: Theme.of(context).scaffoldBackgroundColor, backgroundColor: Theme.of(context).scaffoldBackgroundColor,
mini: true, mini: true,
child: Icon(Icons.arrow_downward_outlined,
color: Theme.of(context).primaryColor),
), ),
) )
: null, : null,
@ -756,6 +756,7 @@ class _ChatState extends State<Chat> {
) )
: _canLoadMore : _canLoadMore
? TextButton( ? TextButton(
onPressed: requestHistory,
child: Text( child: Text(
L10n.of(context).loadMore, L10n.of(context).loadMore,
style: TextStyle( style: TextStyle(
@ -766,7 +767,6 @@ class _ChatState extends State<Chat> {
TextDecoration.underline, TextDecoration.underline,
), ),
), ),
onPressed: requestHistory,
) )
: Container() : Container()
: i == 0 : i == 0
@ -790,6 +790,11 @@ class _ChatState extends State<Chat> {
client.userID client.userID
? Alignment.topRight ? Alignment.topRight
: Alignment.topLeft, : Alignment.topLeft,
padding: EdgeInsets.only(
left: 8,
right: 8,
bottom: 8,
),
child: Container( child: Container(
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: 4), horizontal: 4),
@ -810,11 +815,6 @@ class _ChatState extends State<Chat> {
), ),
), ),
), ),
padding: EdgeInsets.only(
left: 8,
right: 8,
bottom: 8,
),
); );
}, },
) )
@ -942,14 +942,14 @@ class _ChatState extends State<Chat> {
itemBuilder: (c, i) => i == emojis.length itemBuilder: (c, i) => i == emojis.length
? InkWell( ? InkWell(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
onTap: () => _pickEmojiAction(
context, allReactionEvents),
child: Container( child: Container(
width: 56, width: 56,
height: 56, height: 56,
alignment: Alignment.center, alignment: Alignment.center,
child: Icon(Icons.add_outlined), child: Icon(Icons.add_outlined),
), ),
onTap: () => _pickEmojiAction(
context, allReactionEvents),
) )
: InkWell( : InkWell(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),

View File

@ -249,8 +249,8 @@ class _ChatDetailsState extends State<ChatDetails> {
backgroundColor: Theme.of(context) backgroundColor: Theme.of(context)
.scaffoldBackgroundColor, .scaffoldBackgroundColor,
foregroundColor: Colors.grey, foregroundColor: Colors.grey,
child: Icon(Icons.edit_outlined),
radius: Avatar.defaultSize / 2, radius: Avatar.defaultSize / 2,
child: Icon(Icons.edit_outlined),
) )
: null, : null,
title: Text('${L10n.of(context).groupDescription}:', title: Text('${L10n.of(context).groupDescription}:',
@ -342,19 +342,6 @@ class _ChatDetailsState extends State<ChatDetails> {
}, },
), ),
PopupMenuButton( PopupMenuButton(
child: ListTile(
leading: CircleAvatar(
backgroundColor:
Theme.of(context).scaffoldBackgroundColor,
foregroundColor: Colors.grey,
child: Icon(Icons.public_outlined)),
title: Text(
L10n.of(context).whoIsAllowedToJoinThisGroup),
subtitle: Text(
room.joinRules.getLocalizedString(
MatrixLocals(L10n.of(context))),
),
),
onSelected: (JoinRules joinRule) => onSelected: (JoinRules joinRule) =>
showFutureLoadingDialog( showFutureLoadingDialog(
context: context, context: context,
@ -377,22 +364,21 @@ class _ChatDetailsState extends State<ChatDetails> {
MatrixLocals(L10n.of(context)))), MatrixLocals(L10n.of(context)))),
), ),
], ],
),
PopupMenuButton(
child: ListTile( child: ListTile(
leading: CircleAvatar( leading: CircleAvatar(
backgroundColor: backgroundColor:
Theme.of(context).scaffoldBackgroundColor, Theme.of(context).scaffoldBackgroundColor,
foregroundColor: Colors.grey, foregroundColor: Colors.grey,
child: Icon(Icons.visibility_outlined), child: Icon(Icons.public_outlined)),
),
title: Text( title: Text(
L10n.of(context).visibilityOfTheChatHistory), L10n.of(context).whoIsAllowedToJoinThisGroup),
subtitle: Text( subtitle: Text(
room.historyVisibility.getLocalizedString( room.joinRules.getLocalizedString(
MatrixLocals(L10n.of(context))), MatrixLocals(L10n.of(context))),
), ),
), ),
),
PopupMenuButton(
onSelected: (HistoryVisibility historyVisibility) => onSelected: (HistoryVisibility historyVisibility) =>
showFutureLoadingDialog( showFutureLoadingDialog(
context: context, context: context,
@ -430,23 +416,23 @@ class _ChatDetailsState extends State<ChatDetails> {
MatrixLocals(L10n.of(context)))), MatrixLocals(L10n.of(context)))),
), ),
], ],
child: ListTile(
leading: CircleAvatar(
backgroundColor:
Theme.of(context).scaffoldBackgroundColor,
foregroundColor: Colors.grey,
child: Icon(Icons.visibility_outlined),
),
title: Text(
L10n.of(context).visibilityOfTheChatHistory),
subtitle: Text(
room.historyVisibility.getLocalizedString(
MatrixLocals(L10n.of(context))),
),
),
), ),
if (room.joinRules == JoinRules.public) if (room.joinRules == JoinRules.public)
PopupMenuButton( PopupMenuButton(
child: ListTile(
leading: CircleAvatar(
backgroundColor:
Theme.of(context).scaffoldBackgroundColor,
foregroundColor: Colors.grey,
child: Icon(Icons.info_outline),
),
title: Text(
L10n.of(context).areGuestsAllowedToJoin),
subtitle: Text(
room.guestAccess.getLocalizedString(
MatrixLocals(L10n.of(context))),
),
),
onSelected: (GuestAccess guestAccess) => onSelected: (GuestAccess guestAccess) =>
showFutureLoadingDialog( showFutureLoadingDialog(
context: context, context: context,
@ -471,6 +457,20 @@ class _ChatDetailsState extends State<ChatDetails> {
), ),
), ),
], ],
child: ListTile(
leading: CircleAvatar(
backgroundColor:
Theme.of(context).scaffoldBackgroundColor,
foregroundColor: Colors.grey,
child: Icon(Icons.info_outline),
),
title: Text(
L10n.of(context).areGuestsAllowedToJoin),
subtitle: Text(
room.guestAccess.getLocalizedString(
MatrixLocals(L10n.of(context))),
),
),
), ),
ListTile( ListTile(
title: Text(L10n.of(context).editChatPermissions), title: Text(L10n.of(context).editChatPermissions),
@ -502,11 +502,11 @@ class _ChatDetailsState extends State<ChatDetails> {
? ListTile( ? ListTile(
title: Text(L10n.of(context).inviteContact), title: Text(L10n.of(context).inviteContact),
leading: CircleAvatar( leading: CircleAvatar(
child: Icon(Icons.add_outlined),
backgroundColor: backgroundColor:
Theme.of(context).primaryColor, Theme.of(context).primaryColor,
foregroundColor: Colors.white, foregroundColor: Colors.white,
radius: Avatar.defaultSize / 2, radius: Avatar.defaultSize / 2,
child: Icon(Icons.add_outlined),
), ),
onTap: () => AdaptivePageLayout.of(context) onTap: () => AdaptivePageLayout.of(context)
.pushNamed('/rooms/${room.id}/invite'), .pushNamed('/rooms/${room.id}/invite'),

View File

@ -115,8 +115,8 @@ class _ChatEncryptionSettingsState extends State<ChatEncryptionSettings> {
.verified == .verified ==
UserVerifiedStatus.unknown) { UserVerifiedStatus.unknown) {
items.add(PopupMenuItem( items.add(PopupMenuItem(
child: Text(L10n.of(context).verifyUser),
value: 'verify_user', value: 'verify_user',
child: Text(L10n.of(context).verifyUser),
)); ));
} }
return items; return items;
@ -162,22 +162,22 @@ class _ChatEncryptionSettingsState extends State<ChatEncryptionSettings> {
if (deviceKeys[i].blocked || if (deviceKeys[i].blocked ||
!deviceKeys[i].verified) { !deviceKeys[i].verified) {
items.add(PopupMenuItem( items.add(PopupMenuItem(
child: Text(L10n.of(context).verifyStart),
value: deviceKeys[i].userId == room.client.userID value: deviceKeys[i].userId == room.client.userID
? 'verify' ? 'verify'
: 'verify_user', : 'verify_user',
child: Text(L10n.of(context).verifyStart),
)); ));
} }
if (deviceKeys[i].blocked) { if (deviceKeys[i].blocked) {
items.add(PopupMenuItem( items.add(PopupMenuItem(
child: Text(L10n.of(context).unblockDevice),
value: 'unblock', value: 'unblock',
child: Text(L10n.of(context).unblockDevice),
)); ));
} }
if (!deviceKeys[i].blocked) { if (!deviceKeys[i].blocked) {
items.add(PopupMenuItem( items.add(PopupMenuItem(
child: Text(L10n.of(context).blockDevice),
value: 'block', value: 'block',
child: Text(L10n.of(context).blockDevice),
)); ));
} }
return items; return items;

View File

@ -192,6 +192,8 @@ class _ChatListState extends State<ChatList> {
? Center( ? Center(
child: InkWell( child: InkWell(
borderRadius: BorderRadius.circular(32), borderRadius: BorderRadius.circular(32),
onTap: () => AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/settings'),
child: FutureBuilder<Profile>( child: FutureBuilder<Profile>(
future: Matrix.of(context).client.ownProfile, future: Matrix.of(context).client.ownProfile,
builder: (_, snapshot) => Avatar( builder: (_, snapshot) => Avatar(
@ -201,8 +203,6 @@ class _ChatListState extends State<ChatList> {
size: 32, size: 32,
), ),
), ),
onTap: () => AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/settings'),
), ),
) )
: IconButton( : IconButton(
@ -378,9 +378,9 @@ class _ChatListState extends State<ChatList> {
]), ]),
floatingActionButton: selectMode == SelectMode.normal floatingActionButton: selectMode == SelectMode.normal
? FloatingActionButton( ? FloatingActionButton(
child: Icon(Icons.add_outlined),
onPressed: () => AdaptivePageLayout.of(context) onPressed: () => AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/newprivatechat'), .pushNamedAndRemoveUntilIsFirst('/newprivatechat'),
child: Icon(Icons.add_outlined),
) )
: null, : null,
bottomNavigationBar: selectMode == SelectMode.normal bottomNavigationBar: selectMode == SelectMode.normal

View File

@ -119,9 +119,9 @@ class _ContactsState extends State<Contacts> {
ListTile( ListTile(
leading: CircleAvatar( leading: CircleAvatar(
radius: Avatar.defaultSize / 2, radius: Avatar.defaultSize / 2,
child: Icon(Icons.person_add_outlined),
backgroundColor: Theme.of(context).primaryColor, backgroundColor: Theme.of(context).primaryColor,
foregroundColor: Colors.white, foregroundColor: Colors.white,
child: Icon(Icons.person_add_outlined),
), ),
title: Text(L10n.of(context).addNewFriend), title: Text(L10n.of(context).addNewFriend),
onTap: () => AdaptivePageLayout.of(context) onTap: () => AdaptivePageLayout.of(context)
@ -141,15 +141,15 @@ class _ContactsState extends State<Contacts> {
), ),
Center( Center(
child: OutlinedButton( child: OutlinedButton(
onPressed: () => FluffyShare.share(
L10n.of(context).inviteText(client.userID,
'https://matrix.to/#/${client.userID}'),
context),
child: Text( child: Text(
L10n.of(context).inviteContact, L10n.of(context).inviteContact,
style: TextStyle( style: TextStyle(
color: Theme.of(context).accentColor), color: Theme.of(context).accentColor),
), ),
onPressed: () => FluffyShare.share(
L10n.of(context).inviteText(client.userID,
'https://matrix.to/#/${client.userID}'),
context),
), ),
), ),
], ],

View File

@ -180,22 +180,16 @@ class _HomeserverPickerState extends State<HomeserverPicker> {
tag: 'loginButton', tag: 'loginButton',
child: Container( child: Container(
width: double.infinity, width: double.infinity,
height: 56,
padding: EdgeInsets.symmetric(horizontal: 12), padding: EdgeInsets.symmetric(horizontal: 12),
child: RaisedButton( child: ElevatedButton(
elevation: 7, onPressed:
color: Theme.of(context).primaryColor, _isLoading ? null : () => _checkHomeserverAction(context),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
),
child: _isLoading child: _isLoading
? LinearProgressIndicator() ? LinearProgressIndicator()
: Text( : Text(
L10n.of(context).connect.toUpperCase(), L10n.of(context).connect.toUpperCase(),
style: TextStyle(color: Colors.white, fontSize: 16), style: TextStyle(color: Colors.white, fontSize: 16),
), ),
onPressed:
_isLoading ? null : () => _checkHomeserverAction(context),
), ),
), ),
), ),
@ -203,6 +197,7 @@ class _HomeserverPickerState extends State<HomeserverPicker> {
alignment: WrapAlignment.center, alignment: WrapAlignment.center,
children: [ children: [
TextButton( TextButton(
onPressed: () => launch(AppConfig.privacyUrl),
child: Text( child: Text(
L10n.of(context).privacy, L10n.of(context).privacy,
style: TextStyle( style: TextStyle(
@ -210,9 +205,9 @@ class _HomeserverPickerState extends State<HomeserverPicker> {
color: Colors.blueGrey, color: Colors.blueGrey,
), ),
), ),
onPressed: () => launch(AppConfig.privacyUrl),
), ),
TextButton( TextButton(
onPressed: () => PlatformInfos.showDialog(context),
child: Text( child: Text(
L10n.of(context).about, L10n.of(context).about,
style: TextStyle( style: TextStyle(
@ -220,7 +215,6 @@ class _HomeserverPickerState extends State<HomeserverPicker> {
color: Colors.blueGrey, color: Colors.blueGrey,
), ),
), ),
onPressed: () => PlatformInfos.showDialog(context),
), ),
], ],
), ),

View File

@ -50,6 +50,15 @@ class ImageView extends StatelessWidget {
], ],
), ),
body: InteractiveViewer( body: InteractiveViewer(
minScale: 1.0,
maxScale: 10.0,
onInteractionEnd: (ScaleEndDetails endDetails) {
if (PlatformInfos.usesTouchscreen == false) {
if (endDetails.velocity.pixelsPerSecond.dy > calcVelocity) {
Navigator.of(context, rootNavigator: false).pop();
}
}
},
child: Center( child: Center(
child: ImageBubble( child: ImageBubble(
event, event,
@ -62,15 +71,6 @@ class ImageView extends StatelessWidget {
thumbnailOnly: false, thumbnailOnly: false,
), ),
), ),
minScale: 1.0,
maxScale: 10.0,
onInteractionEnd: (ScaleEndDetails endDetails) {
if (PlatformInfos.usesTouchscreen == false) {
if (endDetails.velocity.pixelsPerSecond.dy > calcVelocity) {
Navigator.of(context, rootNavigator: false).pop();
}
}
},
), ),
); );
} }

View File

@ -36,8 +36,8 @@ class _LogViewerState extends State<LogViewer> {
PopupMenuButton<Level>( PopupMenuButton<Level>(
itemBuilder: (context) => Level.values itemBuilder: (context) => Level.values
.map((level) => PopupMenuItem( .map((level) => PopupMenuItem(
child: Text(level.toString()),
value: level, value: level,
child: Text(level.toString()),
)) ))
.toList(), .toList(),
onSelected: (Level level) => setState(() => logLevel = level), onSelected: (Level level) => setState(() => logLevel = level),

View File

@ -10,8 +10,6 @@ import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import '../utils/platform_infos.dart'; import '../utils/platform_infos.dart';
import '../app_config.dart';
class Login extends StatefulWidget { class Login extends StatefulWidget {
@override @override
_LoginState createState() => _LoginState(); _LoginState createState() => _LoginState();
@ -226,27 +224,22 @@ class _LoginState extends State<Login> {
SizedBox(height: 12), SizedBox(height: 12),
Hero( Hero(
tag: 'loginButton', tag: 'loginButton',
child: Container( child: Padding(
height: 56,
padding: EdgeInsets.symmetric(horizontal: 12), padding: EdgeInsets.symmetric(horizontal: 12),
child: RaisedButton( child: ElevatedButton(
elevation: 7, onPressed: loading ? null : () => login(context),
color: Theme.of(context).primaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
),
child: loading child: loading
? LinearProgressIndicator() ? LinearProgressIndicator()
: Text( : Text(
L10n.of(context).login.toUpperCase(), L10n.of(context).login.toUpperCase(),
style: TextStyle(color: Colors.white, fontSize: 16), style: TextStyle(color: Colors.white, fontSize: 16),
), ),
onPressed: loading ? null : () => login(context),
), ),
), ),
), ),
Center( Center(
child: TextButton( child: TextButton(
onPressed: () => _passwordForgotten(context),
child: Text( child: Text(
L10n.of(context).passwordForgotten, L10n.of(context).passwordForgotten,
style: TextStyle( style: TextStyle(
@ -254,7 +247,6 @@ class _LoginState extends State<Login> {
decoration: TextDecoration.underline, decoration: TextDecoration.underline,
), ),
), ),
onPressed: () => _passwordForgotten(context),
), ),
), ),
], ],

View File

@ -91,12 +91,12 @@ class _NewPrivateChatState extends State<NewPrivateChat> {
elevation: 0, elevation: 0,
actions: [ actions: [
TextButton( TextButton(
onPressed: () => AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/newgroup'),
child: Text( child: Text(
L10n.of(context).createNewGroup, L10n.of(context).createNewGroup,
style: TextStyle(color: Theme.of(context).accentColor), style: TextStyle(color: Theme.of(context).accentColor),
), ),
onPressed: () => AdaptivePageLayout.of(context)
.pushNamedAndRemoveUntilIsFirst('/newgroup'),
) )
], ],
), ),

View File

@ -174,13 +174,13 @@ class _EmotesSettingsState extends State<EmotesSettings> {
), ),
floatingActionButton: showSave floatingActionButton: showSave
? FloatingActionButton( ? FloatingActionButton(
child: Icon(Icons.save_outlined, color: Colors.white),
onPressed: () async { onPressed: () async {
await _save(context); await _save(context);
setState(() { setState(() {
showSave = false; showSave = false;
}); });
}, },
child: Icon(Icons.save_outlined, color: Colors.white),
) )
: null, : null,
body: StreamBuilder( body: StreamBuilder(
@ -190,6 +190,9 @@ class _EmotesSettingsState extends State<EmotesSettings> {
children: <Widget>[ children: <Widget>[
if (!readonly) if (!readonly)
Container( Container(
padding: EdgeInsets.symmetric(
vertical: 8.0,
),
child: ListTile( child: ListTile(
leading: Container( leading: Container(
width: 180.0, width: 180.0,
@ -222,11 +225,6 @@ class _EmotesSettingsState extends State<EmotesSettings> {
), ),
title: _EmoteImagePicker(newMxcController), title: _EmoteImagePicker(newMxcController),
trailing: InkWell( trailing: InkWell(
child: Icon(
Icons.add_outlined,
color: Colors.green,
size: 32.0,
),
onTap: () async { onTap: () async {
if (newEmoteController.text == null || if (newEmoteController.text == null ||
newEmoteController.text.isEmpty || newEmoteController.text.isEmpty ||
@ -270,11 +268,13 @@ class _EmotesSettingsState extends State<EmotesSettings> {
showSave = false; showSave = false;
}); });
}, },
child: Icon(
Icons.add_outlined,
color: Colors.green,
size: 32.0,
),
), ),
), ),
padding: EdgeInsets.symmetric(
vertical: 8.0,
),
), ),
if (widget.room != null) if (widget.room != null)
ListTile( ListTile(
@ -346,7 +346,7 @@ class _EmotesSettingsState extends State<EmotesSettings> {
border: InputBorder.none, border: InputBorder.none,
), ),
onSubmitted: (s) { onSubmitted: (s) {
final emoteCode = ':${s}:'; final emoteCode = ':$s:';
if (emotes.indexWhere((e) => if (emotes.indexWhere((e) =>
e.emote == emoteCode && e.emote == emoteCode &&
e.mxc != emote.mxc) != e.mxc != emote.mxc) !=
@ -382,16 +382,16 @@ class _EmotesSettingsState extends State<EmotesSettings> {
trailing: readonly trailing: readonly
? null ? null
: InkWell( : InkWell(
child: Icon(
Icons.delete_forever_outlined,
color: Colors.red,
size: 32.0,
),
onTap: () => setState(() { onTap: () => setState(() {
emotes.removeWhere( emotes.removeWhere(
(e) => e.emote == emote.emote); (e) => e.emote == emote.emote);
showSave = true; showSave = true;
}), }),
child: Icon(
Icons.delete_forever_outlined,
color: Colors.red,
size: 32.0,
),
), ),
); );
}, },
@ -440,14 +440,7 @@ class _EmoteImagePickerState extends State<_EmoteImagePicker> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (widget.controller.text == null || widget.controller.text.isEmpty) { if (widget.controller.text == null || widget.controller.text.isEmpty) {
return RaisedButton( return ElevatedButton(
color: Theme.of(context).primaryColor,
elevation: 5,
textColor: Colors.white,
child: Text(L10n.of(context).pickImage),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
onPressed: () async { onPressed: () async {
if (kIsWeb) { if (kIsWeb) {
await FlushbarHelper.createError( await FlushbarHelper.createError(
@ -487,6 +480,7 @@ class _EmoteImagePickerState extends State<_EmoteImagePicker> {
}); });
} }
}, },
child: Text(L10n.of(context).pickImage),
); );
} else { } else {
return _EmoteImage(widget.controller.text); return _EmoteImage(widget.controller.text);

View File

@ -9,8 +9,6 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart';
import '../app_config.dart';
class SignUp extends StatefulWidget { class SignUp extends StatefulWidget {
@override @override
_SignUpState createState() => _SignUpState(); _SignUpState createState() => _SignUpState();
@ -138,27 +136,23 @@ class _SignUpState extends State<SignUp> {
SizedBox(height: 16), SizedBox(height: 16),
Hero( Hero(
tag: 'loginButton', tag: 'loginButton',
child: Container( child: Padding(
height: 56,
padding: EdgeInsets.symmetric(horizontal: 12), padding: EdgeInsets.symmetric(horizontal: 12),
child: RaisedButton( child: ElevatedButton(
elevation: 7, onPressed: loading ? null : () => signUpAction(context),
color: Theme.of(context).primaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
),
child: loading child: loading
? LinearProgressIndicator() ? LinearProgressIndicator()
: Text( : Text(
L10n.of(context).signUp.toUpperCase(), L10n.of(context).signUp.toUpperCase(),
style: TextStyle(color: Colors.white, fontSize: 16), style: TextStyle(color: Colors.white, fontSize: 16),
), ),
onPressed: loading ? null : () => signUpAction(context),
), ),
), ),
), ),
Center( Center(
child: TextButton( child: TextButton(
onPressed: () =>
AdaptivePageLayout.of(context).pushNamed('/login'),
child: Text( child: Text(
L10n.of(context).alreadyHaveAnAccount, L10n.of(context).alreadyHaveAnAccount,
style: TextStyle( style: TextStyle(
@ -167,8 +161,6 @@ class _SignUpState extends State<SignUp> {
fontSize: 16, fontSize: 16,
), ),
), ),
onPressed: () =>
AdaptivePageLayout.of(context).pushNamed('/login'),
), ),
), ),
]), ]),

View File

@ -10,8 +10,6 @@ import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../utils/platform_infos.dart'; import '../utils/platform_infos.dart';
import '../app_config.dart';
class SignUpPassword extends StatefulWidget { class SignUpPassword extends StatefulWidget {
final MatrixFile avatar; final MatrixFile avatar;
final String username; final String username;
@ -174,22 +172,16 @@ class _SignUpPasswordState extends State<SignUpPassword> {
SizedBox(height: 12), SizedBox(height: 12),
Hero( Hero(
tag: 'loginButton', tag: 'loginButton',
child: Container( child: Padding(
height: 56,
padding: EdgeInsets.symmetric(horizontal: 12), padding: EdgeInsets.symmetric(horizontal: 12),
child: RaisedButton( child: ElevatedButton(
elevation: 7, onPressed: loading ? null : () => _signUpAction(context),
color: Theme.of(context).primaryColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
),
child: loading child: loading
? LinearProgressIndicator() ? LinearProgressIndicator()
: Text( : Text(
L10n.of(context).createAccountNow.toUpperCase(), L10n.of(context).createAccountNow.toUpperCase(),
style: TextStyle(color: Colors.white, fontSize: 16), style: TextStyle(color: Colors.white, fontSize: 16),
), ),
onPressed: loading ? null : () => _signUpAction(context),
), ),
), ),
), ),

View File

@ -77,7 +77,7 @@ packages:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.5.0-nullsafety.1" version: "2.5.0"
base58check: base58check:
dependency: transitive dependency: transitive
description: description:
@ -91,7 +91,7 @@ packages:
name: boolean_selector name: boolean_selector
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0-nullsafety.1" version: "2.1.0"
cached_network_image: cached_network_image:
dependency: "direct main" dependency: "direct main"
description: description:
@ -112,14 +112,14 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0-nullsafety.3" version: "1.1.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0-nullsafety.1" version: "1.2.0"
circular_check_box: circular_check_box:
dependency: "direct main" dependency: "direct main"
description: description:
@ -140,14 +140,14 @@ packages:
name: clock name: clock
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0-nullsafety.1" version: "1.1.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.15.0-nullsafety.3" version: "1.15.0"
convert: convert:
dependency: transitive dependency: transitive
description: description:
@ -217,7 +217,7 @@ packages:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0-nullsafety.1" version: "1.2.0"
famedlysdk: famedlysdk:
dependency: "direct main" dependency: "direct main"
description: description:
@ -249,7 +249,7 @@ packages:
name: file name: file
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.2.1" version: "6.1.0"
file_chooser: file_chooser:
dependency: transitive dependency: transitive
description: description:
@ -386,19 +386,14 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_math:
dependency: transitive
description:
name: flutter_math
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0+2"
flutter_matrix_html: flutter_matrix_html:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_matrix_html path: "."
url: "https://pub.dartlang.org" ref: HEAD
source: hosted resolved-ref: b1505570660d2e4c212a67889fe260eca7fb136e
url: "https://github.com/ChristianPauly/flutter_matrix_html.git"
source: git
version: "0.2.0" version: "0.2.0"
flutter_olm: flutter_olm:
dependency: "direct main" dependency: "direct main"
@ -469,7 +464,7 @@ packages:
name: flutter_svg name: flutter_svg
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.19.1" version: "0.19.3"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -570,7 +565,7 @@ packages:
name: intl name: intl
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.16.1" version: "0.17.0"
io: io:
dependency: transitive dependency: transitive
description: description:
@ -591,7 +586,7 @@ packages:
name: js name: js
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.3-nullsafety.2" version: "0.6.3"
localstorage: localstorage:
dependency: "direct main" dependency: "direct main"
description: description:
@ -626,7 +621,7 @@ packages:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.10-nullsafety.1" version: "0.12.10"
matrix_api_lite: matrix_api_lite:
dependency: transitive dependency: transitive
description: description:
@ -654,7 +649,7 @@ packages:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0-nullsafety.3" version: "1.3.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
@ -768,7 +763,7 @@ packages:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0-nullsafety.1" version: "1.8.0"
path_drawing: path_drawing:
dependency: transitive dependency: transitive
description: description:
@ -824,7 +819,7 @@ packages:
name: pedantic name: pedantic
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.10.0-nullsafety.2" version: "1.11.0"
permission_handler: permission_handler:
dependency: "direct main" dependency: "direct main"
description: description:
@ -852,7 +847,7 @@ packages:
name: platform name: platform
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.1" version: "3.0.0"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -873,14 +868,14 @@ packages:
name: pool name: pool
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.5.0-nullsafety.2" version: "1.5.0"
process: process:
dependency: transitive dependency: transitive
description: description:
name: process name: process
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.13" version: "4.1.0"
provider: provider:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1032,21 +1027,21 @@ packages:
name: source_map_stack_trace name: source_map_stack_trace
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0-nullsafety.3" version: "2.1.0"
source_maps: source_maps:
dependency: transitive dependency: transitive
description: description:
name: source_maps name: source_maps
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.10.10-nullsafety.2" version: "0.10.10"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0-nullsafety.2" version: "1.8.0"
sqflite: sqflite:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1081,21 +1076,21 @@ packages:
name: stack_trace name: stack_trace
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.10.0-nullsafety.1" version: "1.10.0"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0-nullsafety.1" version: "2.1.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0-nullsafety.1" version: "1.1.0"
swipe_to_action: swipe_to_action:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1116,28 +1111,28 @@ packages:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0-nullsafety.1" version: "1.2.0"
test: test:
dependency: transitive dependency: transitive
description: description:
name: test name: test
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.16.0-nullsafety.5" version: "1.16.5"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.19-nullsafety.2" version: "0.2.19"
test_core: test_core:
dependency: transitive dependency: transitive
description: description:
name: test_core name: test_core
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.12-nullsafety.5" version: "0.3.15"
timezone: timezone:
dependency: transitive dependency: transitive
description: description:
@ -1145,20 +1140,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.9" version: "0.5.9"
tuple:
dependency: transitive
description:
name: tuple
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0-nullsafety.3" version: "1.3.0"
unifiedpush: unifiedpush:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1251,7 +1239,7 @@ packages:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0-nullsafety.3" version: "2.1.0"
vm_service: vm_service:
dependency: transitive dependency: transitive
description: description:
@ -1316,5 +1304,5 @@ packages:
source: hosted source: hosted
version: "0.1.2" version: "0.1.2"
sdks: sdks:
dart: ">=2.10.2 <2.11.0" dart: ">=2.12.0-0.0 <3.0.0"
flutter: ">=1.22.2 <2.0.0" flutter: ">=1.24.0-10.1.pre"

View File

@ -53,7 +53,9 @@ dependencies:
mime_type: ^0.3.2 mime_type: ^0.3.2
flushbar: ^1.10.4 flushbar: ^1.10.4
adaptive_dialog: ^0.9.3 adaptive_dialog: ^0.9.3
flutter_matrix_html: ^0.2.0 flutter_matrix_html:
git:
url: https://github.com/ChristianPauly/flutter_matrix_html.git
moor: ^3.4.0 moor: ^3.4.0
sqlite3_flutter_libs: ^0.3.0 sqlite3_flutter_libs: ^0.3.0
sqlite3: ^0.1.8 sqlite3: ^0.1.8
@ -73,7 +75,7 @@ dependencies:
sentry: ">=3.0.0 <4.0.0" sentry: ">=3.0.0 <4.0.0"
scroll_to_index: ^1.0.6 scroll_to_index: ^1.0.6
swipe_to_action: ^0.1.0 swipe_to_action: ^0.1.0
flutter_svg: 0.19.1 # Because fluffychat depends on flutter_svg >=0.19.2 which requires Flutter SDK version >=1.24.0-6.0.pre <2.0.0, version solving failed. flutter_svg: ^0.19.3
flutter_cache_manager: ^2.1.1 flutter_cache_manager: ^2.1.1
open_noti_settings: ^0.0.4 open_noti_settings: ^0.0.4
emoji_picker: ^0.1.0 emoji_picker: ^0.1.0

View File

@ -1,6 +1,4 @@
#!/usr/bin/env bash #!/usr/bin/env bash
flutter channel stable
flutter upgrade
flutter pub get flutter pub get
flutter build apk --release flutter build apk --release
mkdir -p build/android mkdir -p build/android

View File

@ -1,4 +1,2 @@
#!/usr/bin/env bash #!/usr/bin/env bash
flutter channel stable
flutter upgrade
flutter build apk --debug -v flutter build apk --debug -v

View File

@ -1,6 +1,4 @@
#!/bin/sh -ve #!/bin/sh -ve
flutter channel stable
flutter upgrade
flutter clean flutter clean
flutter pub get flutter pub get
cd ios cd ios

View File

@ -1,5 +1,4 @@
#!/bin/sh -ve #!/bin/sh -ve
flutter channel master && flutter upgrade
flutter config --enable-linux-desktop flutter config --enable-linux-desktop
flutter clean flutter clean
flutter pub get flutter pub get

View File

@ -1,6 +1,4 @@
#!/bin/sh -ve #!/bin/sh -ve
flutter channel dev
flutter upgrade
flutter config --enable-macos-desktop flutter config --enable-macos-desktop
flutter clean flutter clean
flutter pub get flutter pub get

View File

@ -1,6 +1,4 @@
#!/bin/sh -ve #!/bin/sh -ve
#flutter channel beta
#flutter upgrade
flutter config --enable-web flutter config --enable-web
flutter clean flutter clean
flutter pub get flutter pub get

View File

@ -1,6 +1,4 @@
#!/usr/bin/env bash #!/usr/bin/env bash
flutter channel stable
flutter upgrade
flutter pub get flutter pub get
flutter build appbundle --target-platform android-arm,android-arm64,android-x64 flutter build appbundle --target-platform android-arm,android-arm64,android-x64
mkdir -p build/android mkdir -p build/android