New set homeserver ux
This commit is contained in:
parent
266916255b
commit
6b3dc6eb33
|
@ -1,5 +1,8 @@
|
|||
# Version 0.12.2 - 2020-04-12
|
||||
### Fixes:
|
||||
### Changes:
|
||||
- New set homeserver UX
|
||||
### Fixed
|
||||
- Fix toasts when switching views
|
||||
- Fix image flickering
|
||||
- Fix login without google services
|
||||
- Fix toasts
|
||||
|
@ -65,7 +68,6 @@
|
|||
- Replies on replies fixed
|
||||
|
||||
# Version 0.7.1 - 2020-02-10
|
||||
### Fixed
|
||||
- Replies with correct sender id
|
||||
|
||||
# Version 0.7.0 - 2020-02-10
|
||||
|
|
|
@ -24,6 +24,7 @@ import 'avatar.dart';
|
|||
|
||||
class Matrix extends StatefulWidget {
|
||||
static const String callNamespace = 'chat.fluffy.jitsi_call';
|
||||
static const String defaultHomeserver = 'tchncs.de';
|
||||
|
||||
final Widget child;
|
||||
|
||||
|
|
|
@ -94,6 +94,12 @@ class I18n {
|
|||
args: [username, targetName],
|
||||
);
|
||||
|
||||
String byDefaultYouWillBeConnectedTo(String homeserver) => Intl.message(
|
||||
'By default you will be connected to $homeserver',
|
||||
name: 'byDefaultYouWillBeConnectedTo',
|
||||
args: [homeserver],
|
||||
);
|
||||
|
||||
String get cancel => Intl.message("Cancel");
|
||||
|
||||
String changedTheChatAvatar(String username) => Intl.message(
|
||||
|
@ -128,6 +134,8 @@ class I18n {
|
|||
args: [username, displayname],
|
||||
);
|
||||
|
||||
String get changeTheHomeserver => Intl.message('Change the homeserver');
|
||||
|
||||
String changedTheGuestAccessRules(String username) => Intl.message(
|
||||
"$username changed the guest access rules",
|
||||
name: "changedTheGuestAccessRules",
|
||||
|
@ -199,12 +207,16 @@ class I18n {
|
|||
|
||||
String get chatDetails => Intl.message('Chat details');
|
||||
|
||||
String get chooseAStrongPassword => Intl.message("Choose a strong password");
|
||||
|
||||
String get chooseAUsername => Intl.message("Choose a username");
|
||||
|
||||
String get close => Intl.message("Close");
|
||||
|
||||
String get confirm => Intl.message("Confirm");
|
||||
|
||||
String get connect => Intl.message('Connect');
|
||||
|
||||
String get connectionAttemptFailed =>
|
||||
Intl.message("Connection attempt failed");
|
||||
|
||||
|
@ -296,6 +308,8 @@ class I18n {
|
|||
|
||||
String get enterAUsername => Intl.message("Enter a username");
|
||||
|
||||
String get enterYourHomeserver => Intl.message('Enter your homeserver');
|
||||
|
||||
String get fileName => Intl.message("File name");
|
||||
|
||||
String get fileSize => Intl.message("File size");
|
||||
|
@ -419,6 +433,12 @@ class I18n {
|
|||
|
||||
String get login => Intl.message("Login");
|
||||
|
||||
String logInTo(String homeserver) => Intl.message(
|
||||
'Log in to $homeserver',
|
||||
name: 'logInTo',
|
||||
args: [homeserver],
|
||||
);
|
||||
|
||||
String get makeAModerator => Intl.message("Make a moderator");
|
||||
|
||||
String get makeAnAdmin => Intl.message("Make an admin");
|
||||
|
@ -541,9 +561,6 @@ class I18n {
|
|||
|
||||
String get searchForAChat => Intl.message("Search for a chat");
|
||||
|
||||
String get secureYourAccountWithAPassword =>
|
||||
Intl.message("Secure your account with a password");
|
||||
|
||||
String seenByUser(String username) => Intl.message(
|
||||
"Seen by $username",
|
||||
name: "seenByUser",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:famedlysdk/famedlysdk.dart';
|
||||
import 'package:fluffychat/views/homeserver_picker.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
@ -8,7 +9,6 @@ import 'package:flutter_localizations/flutter_localizations.dart';
|
|||
import 'package:flutter_styled_toast/flutter_styled_toast.dart';
|
||||
|
||||
import 'i18n/i18n.dart';
|
||||
import 'views/sign_up.dart';
|
||||
import 'components/theme_switcher.dart';
|
||||
import 'components/matrix.dart';
|
||||
import 'views/chat_list.dart';
|
||||
|
@ -63,7 +63,7 @@ class App extends StatelessWidget {
|
|||
if (Matrix.of(context).client.isLogged()) {
|
||||
return ChatListView();
|
||||
}
|
||||
return SignUp();
|
||||
return HomeserverPicker();
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
110
lib/views/homeserver_picker.dart
Normal file
110
lib/views/homeserver_picker.dart
Normal file
|
@ -0,0 +1,110 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:fluffychat/components/dialogs/simple_dialogs.dart';
|
||||
import 'package:fluffychat/components/matrix.dart';
|
||||
import 'package:fluffychat/i18n/i18n.dart';
|
||||
import 'package:fluffychat/utils/app_route.dart';
|
||||
import 'package:fluffychat/views/sign_up.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class HomeserverPicker extends StatelessWidget {
|
||||
_setHomeserverAction(BuildContext context) async {
|
||||
final homeserver = await SimpleDialogs(context).enterText(
|
||||
titleText: I18n.of(context).enterYourHomeserver,
|
||||
hintText: Matrix.defaultHomeserver,
|
||||
prefixText: 'https://');
|
||||
if (homeserver?.isEmpty ?? true) return;
|
||||
_checkHomeserverAction(homeserver, context);
|
||||
}
|
||||
|
||||
_checkHomeserverAction(String homeserver, BuildContext context) async {
|
||||
if (!homeserver.startsWith('https://')) {
|
||||
homeserver = 'https://$homeserver';
|
||||
}
|
||||
final success = await Matrix.of(context).tryRequestWithLoadingDialog(
|
||||
Matrix.of(context).client.checkServer(homeserver));
|
||||
if (success != false) {
|
||||
await Navigator.of(context).push(AppRoute(SignUp()));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal:
|
||||
max((MediaQuery.of(context).size.width - 600) / 2, 0)),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Hero(
|
||||
tag: 'loginBanner',
|
||||
child: Image.asset("assets/fluffychat-banner.png"),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Text(
|
||||
'Welcome to the cutest instant messaging solution for all platforms.',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
Hero(
|
||||
tag: 'loginButton',
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
height: 50,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
child: RaisedButton(
|
||||
elevation: 7,
|
||||
color: Theme.of(context).primaryColor,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
I18n.of(context).connect,
|
||||
style: TextStyle(color: Colors.white, fontSize: 16),
|
||||
),
|
||||
onPressed: () => _checkHomeserverAction(
|
||||
Matrix.defaultHomeserver, context),
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(left: 16.0, right: 16.0, top: 16.0),
|
||||
child: Opacity(
|
||||
opacity: 0.75,
|
||||
child: Text(
|
||||
I18n.of(context).byDefaultYouWillBeConnectedTo(
|
||||
Matrix.defaultHomeserver),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
FlatButton(
|
||||
child: Text(
|
||||
I18n.of(context).changeTheHomeserver,
|
||||
style: TextStyle(
|
||||
decoration: TextDecoration.underline,
|
||||
color: Colors.blue,
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
onPressed: () => _setHomeserverAction(context),
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -17,11 +17,8 @@ class Login extends StatefulWidget {
|
|||
class _LoginState extends State<Login> {
|
||||
final TextEditingController usernameController = TextEditingController();
|
||||
final TextEditingController passwordController = TextEditingController();
|
||||
final TextEditingController serverController =
|
||||
TextEditingController(text: "tchncs.de");
|
||||
String usernameError;
|
||||
String passwordError;
|
||||
String serverError;
|
||||
bool loading = false;
|
||||
bool showPassword = false;
|
||||
|
||||
|
@ -37,30 +34,12 @@ class _LoginState extends State<Login> {
|
|||
} else {
|
||||
setState(() => passwordError = null);
|
||||
}
|
||||
serverError = null;
|
||||
|
||||
if (usernameController.text.isEmpty || passwordController.text.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
String homeserver = serverController.text;
|
||||
if (homeserver.isEmpty) homeserver = "tchncs.de";
|
||||
if (!homeserver.startsWith("https://")) {
|
||||
homeserver = "https://" + homeserver;
|
||||
}
|
||||
|
||||
try {
|
||||
setState(() => loading = true);
|
||||
if (!await matrix.client.checkServer(homeserver)) {
|
||||
setState(
|
||||
() => serverError = I18n.of(context).homeserverIsNotCompatible);
|
||||
|
||||
return setState(() => loading = false);
|
||||
}
|
||||
} catch (exception) {
|
||||
setState(() => serverError = I18n.of(context).connectionAttemptFailed);
|
||||
return setState(() => loading = false);
|
||||
}
|
||||
try {
|
||||
await matrix.client.login(
|
||||
usernameController.text, passwordController.text,
|
||||
|
@ -92,16 +71,12 @@ class _LoginState extends State<Login> {
|
|||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: loading ? Container() : null,
|
||||
title: TextField(
|
||||
autocorrect: false,
|
||||
controller: serverController,
|
||||
decoration: InputDecoration(
|
||||
icon: Icon(Icons.domain),
|
||||
hintText: "matrix-client.matrix.org",
|
||||
errorText: serverError,
|
||||
errorMaxLines: 1,
|
||||
prefixText: "https://",
|
||||
labelText: serverError == null ? "Homeserver" : serverError),
|
||||
elevation: 0,
|
||||
title: Text(
|
||||
I18n.of(context).logInTo(Matrix.of(context)
|
||||
.client
|
||||
.homeserver
|
||||
.replaceFirst('https://', '')),
|
||||
),
|
||||
),
|
||||
body: Builder(builder: (context) {
|
||||
|
@ -110,16 +85,6 @@ class _LoginState extends State<Login> {
|
|||
horizontal:
|
||||
max((MediaQuery.of(context).size.width - 600) / 2, 0)),
|
||||
children: <Widget>[
|
||||
Container(
|
||||
height: 150,
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.vpn_key,
|
||||
size: 60,
|
||||
),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
leading: CircleAvatar(
|
||||
child: Icon(Icons.account_box,
|
||||
|
@ -128,6 +93,7 @@ class _LoginState extends State<Login> {
|
|||
title: TextField(
|
||||
readOnly: loading,
|
||||
autocorrect: false,
|
||||
autofocus: true,
|
||||
controller: usernameController,
|
||||
decoration: InputDecoration(
|
||||
hintText:
|
||||
|
@ -163,7 +129,9 @@ class _LoginState extends State<Login> {
|
|||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Container(
|
||||
Hero(
|
||||
tag: 'loginButton',
|
||||
child: Container(
|
||||
height: 50,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
child: RaisedButton(
|
||||
|
@ -181,6 +149,7 @@ class _LoginState extends State<Login> {
|
|||
onPressed: () => loading ? null : login(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
|
|
|
@ -2,6 +2,7 @@ import 'dart:io';
|
|||
|
||||
import 'package:famedlysdk/famedlysdk.dart';
|
||||
import 'package:fluffychat/components/settings_themes.dart';
|
||||
import 'package:fluffychat/views/homeserver_picker.dart';
|
||||
import 'package:fluffychat/views/settings_devices.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
@ -11,7 +12,6 @@ import 'package:url_launcher/url_launcher.dart';
|
|||
import 'app_info.dart';
|
||||
import 'chat_list.dart';
|
||||
import '../components/adaptive_page_layout.dart';
|
||||
import 'sign_up.dart';
|
||||
import '../components/dialogs/simple_dialogs.dart';
|
||||
import '../components/content_banner.dart';
|
||||
import '../components/matrix.dart';
|
||||
|
@ -46,7 +46,7 @@ class _SettingsState extends State<Settings> {
|
|||
await matrix.tryRequestWithLoadingDialog(matrix.client.logout());
|
||||
matrix.clean();
|
||||
await Navigator.of(context).pushAndRemoveUntil(
|
||||
AppRoute.defaultRoute(context, SignUp()), (r) => false);
|
||||
AppRoute.defaultRoute(context, HomeserverPicker()), (r) => false);
|
||||
}
|
||||
|
||||
void setJitsiInstanceAction(BuildContext context) async {
|
||||
|
|
|
@ -18,10 +18,7 @@ class SignUp extends StatefulWidget {
|
|||
|
||||
class _SignUpState extends State<SignUp> {
|
||||
final TextEditingController usernameController = TextEditingController();
|
||||
final TextEditingController serverController =
|
||||
TextEditingController(text: "tchncs.de");
|
||||
String usernameError;
|
||||
String serverError;
|
||||
bool loading = false;
|
||||
File avatar;
|
||||
|
||||
|
@ -42,34 +39,15 @@ class _SignUpState extends State<SignUp> {
|
|||
} else {
|
||||
setState(() => usernameError = null);
|
||||
}
|
||||
serverError = null;
|
||||
|
||||
if (usernameController.text.isEmpty) {
|
||||
return;
|
||||
}
|
||||
setState(() => loading = true);
|
||||
|
||||
final String preferredUsername =
|
||||
usernameController.text.toLowerCase().replaceAll(" ", "-");
|
||||
|
||||
String homeserver = serverController.text;
|
||||
if (homeserver.isEmpty) homeserver = "tchncs.de";
|
||||
if (!homeserver.startsWith("https://")) {
|
||||
homeserver = "https://" + homeserver;
|
||||
}
|
||||
|
||||
try {
|
||||
setState(() => loading = true);
|
||||
if (!await matrix.client.checkServer(homeserver)) {
|
||||
setState(
|
||||
() => serverError = I18n.of(context).homeserverIsNotCompatible);
|
||||
|
||||
return setState(() => loading = false);
|
||||
}
|
||||
} catch (exception) {
|
||||
setState(() => serverError = I18n.of(context).connectionAttemptFailed);
|
||||
return setState(() => loading = false);
|
||||
}
|
||||
|
||||
try {
|
||||
await matrix.client.usernameAvailable(preferredUsername);
|
||||
} on MatrixException catch (exception) {
|
||||
|
@ -81,8 +59,7 @@ class _SignUpState extends State<SignUp> {
|
|||
}
|
||||
setState(() => loading = false);
|
||||
await Navigator.of(context).push(
|
||||
AppRoute.defaultRoute(
|
||||
context,
|
||||
AppRoute(
|
||||
SignUpPassword(preferredUsername,
|
||||
avatar: avatar, displayname: usernameController.text),
|
||||
),
|
||||
|
@ -93,17 +70,10 @@ class _SignUpState extends State<SignUp> {
|
|||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: TextField(
|
||||
autocorrect: false,
|
||||
controller: serverController,
|
||||
decoration: InputDecoration(
|
||||
icon: Icon(Icons.domain),
|
||||
hintText: "matrix-client.matrix.org",
|
||||
errorText: serverError,
|
||||
errorMaxLines: 1,
|
||||
prefixText: "https://",
|
||||
labelText: serverError == null ? "Homeserver" : serverError,
|
||||
),
|
||||
elevation: 0,
|
||||
leading: loading ? Container() : null,
|
||||
title: Text(
|
||||
Matrix.of(context).client.homeserver.replaceFirst('https://', ''),
|
||||
),
|
||||
),
|
||||
body: ListView(
|
||||
|
@ -111,12 +81,17 @@ class _SignUpState extends State<SignUp> {
|
|||
horizontal:
|
||||
max((MediaQuery.of(context).size.width - 600) / 2, 0)),
|
||||
children: <Widget>[
|
||||
Image.asset("assets/fluffychat-banner.png"),
|
||||
Hero(
|
||||
tag: 'loginBanner',
|
||||
child: Image.asset("assets/fluffychat-banner.png"),
|
||||
),
|
||||
ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundImage: avatar == null ? null : FileImage(avatar),
|
||||
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,
|
||||
child: avatar == null
|
||||
? Icon(Icons.camera_alt,
|
||||
|
@ -138,7 +113,9 @@ class _SignUpState extends State<SignUp> {
|
|||
),
|
||||
ListTile(
|
||||
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(
|
||||
Icons.account_circle,
|
||||
color: Theme.of(context).primaryColor,
|
||||
|
@ -155,7 +132,9 @@ class _SignUpState extends State<SignUp> {
|
|||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Container(
|
||||
Hero(
|
||||
tag: 'loginButton',
|
||||
child: Container(
|
||||
height: 50,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
child: RaisedButton(
|
||||
|
@ -170,7 +149,8 @@ class _SignUpState extends State<SignUp> {
|
|||
I18n.of(context).signUp.toUpperCase(),
|
||||
style: TextStyle(color: Colors.white, fontSize: 16),
|
||||
),
|
||||
onPressed: () => signUpAction(context),
|
||||
onPressed: () => loading ? null : signUpAction(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
Center(
|
||||
|
@ -184,10 +164,7 @@ class _SignUpState extends State<SignUp> {
|
|||
),
|
||||
),
|
||||
onPressed: () => Navigator.of(context).push(
|
||||
AppRoute.defaultRoute(
|
||||
context,
|
||||
Login(),
|
||||
),
|
||||
AppRoute(Login()),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -119,23 +119,16 @@ class _SignUpPasswordState extends State<SignUpPassword> {
|
|||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(I18n.of(context).secureYourAccountWithAPassword),
|
||||
elevation: 0,
|
||||
leading: loading ? Container() : null,
|
||||
title: Text(
|
||||
I18n.of(context).chooseAStrongPassword,
|
||||
),
|
||||
),
|
||||
body: ListView(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: max((MediaQuery.of(context).size.width - 600) / 2, 0)),
|
||||
children: <Widget>[
|
||||
Container(
|
||||
height: 150,
|
||||
color: Theme.of(context).secondaryHeaderColor,
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.vpn_key,
|
||||
color: Theme.of(context).primaryColor,
|
||||
size: 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: Colors.white,
|
||||
|
@ -160,7 +153,9 @@ class _SignUpPasswordState extends State<SignUpPassword> {
|
|||
),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
Container(
|
||||
Hero(
|
||||
tag: 'loginButton',
|
||||
child: Container(
|
||||
height: 50,
|
||||
padding: EdgeInsets.symmetric(horizontal: 12),
|
||||
child: RaisedButton(
|
||||
|
@ -178,6 +173,7 @@ class _SignUpPasswordState extends State<SignUpPassword> {
|
|||
onPressed: () => loading ? null : _signUpAction(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue