[Choose User, Advanced Options] QA fixes, theme changes

Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
Sahil Kumar
2021-01-06 18:23:39 +05:30
parent b55d8bd2a8
commit 14a35205cf
5 changed files with 231 additions and 253 deletions
+203 -243
View File
@@ -60,15 +60,11 @@ class _AdvancedOptionsPageState extends State<AdvancedOptionsPage> {
body: Builder( body: Builder(
builder: (context) { builder: (context) {
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB( padding: const EdgeInsets.fromLTRB(16, 16, 16, 0),
16,
16,
16,
0,
),
child: Form( child: Form(
key: _formKey, key: _formKey,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
TextFormField( TextFormField(
controller: _apiKeyController, controller: _apiKeyController,
@@ -93,16 +89,13 @@ class _AdvancedOptionsPageState extends State<AdvancedOptionsPage> {
color: StreamChatTheme.of(context).colorTheme.black, color: StreamChatTheme.of(context).colorTheme.black,
), ),
decoration: InputDecoration( decoration: InputDecoration(
errorStyle: TextStyle(fontSize: 0), errorStyle: TextStyle(height: 0, fontSize: 0),
labelStyle: TextStyle( labelStyle: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
color: _apiKeyError != null color: _apiKeyError != null
? StreamChatTheme.of(context).colorTheme.accentRed ? StreamChatTheme.of(context).colorTheme.accentRed
: StreamChatTheme.of(context) : StreamChatTheme.of(context).colorTheme.grey,
.colorTheme
.black
.withOpacity(.5),
), ),
border: UnderlineInputBorder( border: UnderlineInputBorder(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
@@ -112,264 +105,231 @@ class _AdvancedOptionsPageState extends State<AdvancedOptionsPage> {
StreamChatTheme.of(context).colorTheme.whiteSmoke, StreamChatTheme.of(context).colorTheme.whiteSmoke,
filled: true, filled: true,
labelText: labelText:
'Chat API Key ${_apiKeyError != null ? ':$_apiKeyError' : ''}', 'Chat API Key ${_apiKeyError != null ? ': $_apiKeyError' : ''}',
), ),
textInputAction: TextInputAction.next, textInputAction: TextInputAction.next,
), ),
Padding( SizedBox(height: 8),
padding: const EdgeInsets.only(top: 8.0), TextFormField(
child: TextFormField( controller: _userIdController,
controller: _userIdController, onChanged: (_) {
onChanged: (_) { if (_userIdError != null) {
if (_userIdError != null) { setState(() {
setState(() { _userIdError = null;
_userIdError = null; });
}); }
} },
}, validator: (value) {
validator: (value) { if (value.isEmpty) {
if (value.isEmpty) { setState(() {
setState(() { _userIdError = 'Please enter the User ID';
_userIdError = 'Please enter the User ID'; });
}); return _userIdError;
return _userIdError; }
} return null;
return null; },
}, style: TextStyle(
style: TextStyle( fontSize: 14,
color: StreamChatTheme.of(context).colorTheme.black,
),
textInputAction: TextInputAction.next,
decoration: InputDecoration(
errorStyle: TextStyle(height: 0, fontSize: 0),
labelStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14, fontSize: 14,
color: StreamChatTheme.of(context).colorTheme.black, color: _userIdError != null
? StreamChatTheme.of(context).colorTheme.accentRed
: StreamChatTheme.of(context).colorTheme.grey,
), ),
textInputAction: TextInputAction.next, border: UnderlineInputBorder(
decoration: InputDecoration( borderRadius: BorderRadius.circular(8),
errorStyle: TextStyle(fontSize: 0), borderSide: BorderSide.none,
labelStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
color: _userIdError != null
? StreamChatTheme.of(context).colorTheme.accentRed
: StreamChatTheme.of(context)
.colorTheme
.black
.withOpacity(.5),
),
border: UnderlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide.none,
),
fillColor:
StreamChatTheme.of(context).colorTheme.whiteSmoke,
filled: true,
labelText:
'User ID ${_userIdError != null ? ':$_userIdError' : ''}',
), ),
fillColor:
StreamChatTheme.of(context).colorTheme.whiteSmoke,
filled: true,
labelText:
'User ID ${_userIdError != null ? ': $_userIdError' : ''}',
), ),
), ),
Padding( SizedBox(height: 8),
padding: const EdgeInsets.only(top: 8.0), TextFormField(
child: TextFormField( onChanged: (_) {
onChanged: (_) { if (_userTokenError != null) {
if (_userTokenError != null) { setState(() {
setState(() { _userTokenError = null;
_userTokenError = null; });
}); }
} },
}, controller: _userTokenController,
controller: _userTokenController, validator: (value) {
validator: (value) { if (value.isEmpty) {
if (value.isEmpty) { setState(() {
setState(() { _userTokenError = 'Please enter the user token';
_userTokenError = 'Please enter the user token'; });
}); return _userTokenError;
return _userTokenError; }
} return null;
return null; },
}, style: TextStyle(
style: TextStyle( fontSize: 14,
color: StreamChatTheme.of(context).colorTheme.black,
),
textInputAction: TextInputAction.next,
decoration: InputDecoration(
errorStyle: TextStyle(height: 0, fontSize: 0),
labelStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14, fontSize: 14,
color: StreamChatTheme.of(context).colorTheme.black, color: _userTokenError != null
? StreamChatTheme.of(context).colorTheme.accentRed
: StreamChatTheme.of(context).colorTheme.grey,
), ),
textInputAction: TextInputAction.next, border: UnderlineInputBorder(
decoration: InputDecoration( borderRadius: BorderRadius.circular(8),
errorStyle: TextStyle(fontSize: 0), borderSide: BorderSide.none,
labelStyle: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
color: _userTokenError != null
? StreamChatTheme.of(context).colorTheme.accentRed
: StreamChatTheme.of(context)
.colorTheme
.black
.withOpacity(.5),
),
border: UnderlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide.none,
),
fillColor:
StreamChatTheme.of(context).colorTheme.whiteSmoke,
filled: true,
labelText:
'User Token ${_userTokenError != null ? ':$_userTokenError' : ''}',
), ),
fillColor:
StreamChatTheme.of(context).colorTheme.whiteSmoke,
filled: true,
labelText:
'User Token ${_userTokenError != null ? ': $_userTokenError' : ''}',
), ),
), ),
Padding( SizedBox(height: 8),
padding: const EdgeInsets.only(top: 8.0), TextFormField(
child: TextFormField( controller: _usernameController,
controller: _usernameController, textInputAction: TextInputAction.done,
textInputAction: TextInputAction.done, decoration: InputDecoration(
decoration: InputDecoration( labelStyle: TextStyle(
labelStyle: TextStyle( fontSize: 14,
fontSize: 14, fontWeight: FontWeight.bold,
fontWeight: FontWeight.bold, color: StreamChatTheme.of(context).colorTheme.grey,
color: StreamChatTheme.of(context)
.colorTheme
.black
.withOpacity(.5),
),
border: UnderlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide.none,
),
fillColor:
StreamChatTheme.of(context).colorTheme.whiteSmoke,
filled: true,
labelText: 'Username (optional)',
), ),
border: UnderlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide.none,
),
fillColor:
StreamChatTheme.of(context).colorTheme.whiteSmoke,
filled: true,
labelText: 'Username (optional)',
), ),
), ),
Expanded( Spacer(),
child: Align( RaisedButton(
alignment: Alignment.bottomCenter, elevation: 0,
child: FlatButton( child: Text('Login', style: TextStyle(fontSize: 16)),
color: onPressed: () async {
StreamChatTheme.of(context).colorTheme.accentBlue, if (loading) {
minWidth: double.infinity, return;
height: 48, }
child: Text( if (_formKey.currentState.validate()) {
'Login', final apiKey = _apiKeyController.text;
style: TextStyle( final userId = _userIdController.text;
color: StreamChatTheme.of(context).colorTheme.white, final userToken = _userTokenController.text;
fontSize: 16, final username = _usernameController.text;
),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(26),
),
onPressed: () async {
if (loading) {
return;
}
if (_formKey.currentState.validate()) {
final apiKey = _apiKeyController.text;
final userId = _userIdController.text;
final userToken = _userTokenController.text;
final username = _usernameController.text;
loading = true; loading = true;
showDialog( showDialog(
barrierDismissible: false, barrierDismissible: false,
context: context, context: context,
barrierColor: StreamChatTheme.of(context) barrierColor:
.colorTheme StreamChatTheme.of(context).colorTheme.overlay,
.overlay, builder: (context) => Center(
builder: (context) => Center( child: Container(
child: Container( decoration: BoxDecoration(
decoration: BoxDecoration( borderRadius: BorderRadius.circular(16),
borderRadius: BorderRadius.circular(16), color: StreamChatTheme.of(context)
color: StreamChatTheme.of(context) .colorTheme
.colorTheme .white,
.white,
),
height: 100,
width: 100,
child: Center(
child: CircularProgressIndicator(),
),
),
), ),
); height: 100,
width: 100,
child: Center(
child: CircularProgressIndicator(),
),
),
),
);
final client = Client( final client = Client(
apiKey, apiKey,
logLevel: Level.INFO, logLevel: Level.INFO,
showLocalNotification: showLocalNotification: (!kIsWeb && Platform.isAndroid)
(!kIsWeb && Platform.isAndroid) ? showLocalNotification
? showLocalNotification : null,
: null, persistenceEnabled: true,
persistenceEnabled: true, );
);
try { try {
await client.setUser( await client.setUser(
User(id: userId, extraData: { User(id: userId, extraData: {
'name': username, 'name': username,
}), }),
userToken, userToken,
); );
if (!kIsWeb) { if (!kIsWeb) {
initNotifications(client); initNotifications(client);
} }
final secureStorage = FlutterSecureStorage(); final secureStorage = FlutterSecureStorage();
secureStorage.write( secureStorage.write(
key: kStreamApiKey, key: kStreamApiKey,
value: apiKey, value: apiKey,
); );
secureStorage.write( secureStorage.write(
key: kStreamUserId, key: kStreamUserId,
value: userId, value: userId,
); );
secureStorage.write( secureStorage.write(
key: kStreamToken, key: kStreamToken,
value: userToken, value: userToken,
); );
} catch (e) { } catch (e) {
var errorText = 'Error connecting, retry'; var errorText = 'Error connecting, retry';
if (e is Map) { if (e is Map) {
errorText = e['message'] ?? errorText; errorText = e['message'] ?? errorText;
} }
Navigator.pop(context); Navigator.pop(context);
setState(() { setState(() {
_apiKeyError = errorText; _apiKeyError = errorText;
}); });
loading = false; loading = false;
await client.disconnect(); await client.disconnect();
return; return;
} }
if (!kIsWeb) { if (!kIsWeb) {
initNotifications(client); initNotifications(client);
} }
Navigator.pop(context); Navigator.pop(context);
Navigator.pop(context); Navigator.pop(context);
await Navigator.pushReplacement( await Navigator.pushReplacement(
context, context,
MaterialPageRoute( MaterialPageRoute(
builder: (context) { builder: (context) {
return MaterialApp( return MaterialApp(
theme: ThemeData.light(), theme: ThemeData.light(),
darkTheme: ThemeData.dark(), darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system, themeMode: ThemeMode.system,
builder: (context, widget) { builder: (context, widget) {
return StreamChat( return StreamChat(
child: widget, child: widget,
client: client, client: client,
);
},
home: ChannelListPage(),
); );
}, },
), home: ChannelListPage(),
); );
loading = false; },
} ),
}, );
), loading = false;
), }
},
), ),
StreamVersion(), StreamVersion(),
], ],
+6 -6
View File
@@ -72,6 +72,7 @@ class ChooseUserPage extends StatelessWidget {
child: SvgPicture.asset( child: SvgPicture.asset(
'assets/logo.svg', 'assets/logo.svg',
height: 40, height: 40,
color: StreamChatTheme.of(context).colorTheme.accentBlue,
), ),
), ),
), ),
@@ -92,9 +93,8 @@ class ChooseUserPage extends StatelessWidget {
child: ListView.separated( child: ListView.separated(
separatorBuilder: (context, i) { separatorBuilder: (context, i) {
return Container( return Container(
width: double.infinity,
color: Colors.black12,
height: 1, height: 1,
color: StreamChatTheme.of(context).colorTheme.greyWhisper,
); );
}, },
itemCount: users.length + 1, itemCount: users.length + 1,
@@ -180,10 +180,10 @@ class ChooseUserPage extends StatelessWidget {
.grey, .grey,
), ),
), ),
trailing: SvgPicture.asset( trailing: StreamSvgIcon.arrow_right(
'assets/icon_arrow_right.svg', color: StreamChatTheme.of(context)
height: 24, .colorTheme
width: 24, .accentBlue,
), ),
); );
}), }),
+2 -3
View File
@@ -28,9 +28,8 @@ class StreamVersion extends StatelessWidget {
return Text( return Text(
'Stream SDK v ${streamChatDep}', 'Stream SDK v ${streamChatDep}',
style: TextStyle( style: TextStyle(
fontSize: 14.5, fontSize: 14,
color: color: StreamChatTheme.of(context).colorTheme.greyGainsboro,
StreamChatTheme.of(context).colorTheme.black.withOpacity(.13),
), ),
); );
}, },
+1
View File
@@ -78,6 +78,7 @@ class StreamChatState extends State<StreamChat> with WidgetsBindingObserver {
primaryIconTheme: streamTheme.primaryIconTheme, primaryIconTheme: streamTheme.primaryIconTheme,
accentColor: streamTheme.colorTheme.accentBlue, accentColor: streamTheme.colorTheme.accentBlue,
scaffoldBackgroundColor: streamTheme.colorTheme.white, scaffoldBackgroundColor: streamTheme.colorTheme.white,
buttonTheme: streamTheme.buttonTheme,
), ),
child: widget.child, child: widget.child,
); );
+19 -1
View File
@@ -45,6 +45,9 @@ class StreamChatThemeData {
/// The text themes used in the widgets /// The text themes used in the widgets
final TextTheme textTheme; final TextTheme textTheme;
/// The button themes used in the widgets
final ButtonThemeData buttonTheme;
/// The text themes used in the widgets /// The text themes used in the widgets
final ColorTheme colorTheme; final ColorTheme colorTheme;
@@ -75,6 +78,7 @@ class StreamChatThemeData {
/// Create a theme from scratch /// Create a theme from scratch
const StreamChatThemeData({ const StreamChatThemeData({
this.textTheme, this.textTheme,
this.buttonTheme,
this.colorTheme, this.colorTheme,
this.channelPreviewTheme, this.channelPreviewTheme,
this.channelTheme, this.channelTheme,
@@ -106,6 +110,7 @@ class StreamChatThemeData {
/// Creates a copy of [StreamChatThemeData] with specified attributes overridden. /// Creates a copy of [StreamChatThemeData] with specified attributes overridden.
StreamChatThemeData copyWith({ StreamChatThemeData copyWith({
TextTheme textTheme, TextTheme textTheme,
ButtonThemeData buttonTheme,
ColorTheme colorTheme, ColorTheme colorTheme,
ChannelPreviewTheme channelPreviewTheme, ChannelPreviewTheme channelPreviewTheme,
ChannelTheme channelTheme, ChannelTheme channelTheme,
@@ -118,6 +123,7 @@ class StreamChatThemeData {
}) => }) =>
StreamChatThemeData( StreamChatThemeData(
textTheme: textTheme ?? this.textTheme, textTheme: textTheme ?? this.textTheme,
buttonTheme: buttonTheme ?? this.buttonTheme,
colorTheme: colorTheme ?? this.colorTheme, colorTheme: colorTheme ?? this.colorTheme,
primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme, primaryIconTheme: primaryIconTheme ?? this.primaryIconTheme,
defaultChannelImage: defaultChannelImage ?? this.defaultChannelImage, defaultChannelImage: defaultChannelImage ?? this.defaultChannelImage,
@@ -133,6 +139,7 @@ class StreamChatThemeData {
if (other == null) return this; if (other == null) return this;
return copyWith( return copyWith(
textTheme: textTheme?.merge(other.textTheme) ?? other.textTheme, textTheme: textTheme?.merge(other.textTheme) ?? other.textTheme,
buttonTheme: other.buttonTheme,
colorTheme: colorTheme?.merge(other.colorTheme) ?? other.colorTheme, colorTheme: colorTheme?.merge(other.colorTheme) ?? other.colorTheme,
primaryIconTheme: other.primaryIconTheme, primaryIconTheme: other.primaryIconTheme,
defaultChannelImage: other.defaultChannelImage, defaultChannelImage: other.defaultChannelImage,
@@ -159,6 +166,17 @@ class StreamChatThemeData {
return StreamChatThemeData( return StreamChatThemeData(
textTheme: textTheme, textTheme: textTheme,
colorTheme: colorTheme, colorTheme: colorTheme,
buttonTheme: ButtonThemeData(
height: 48.0,
buttonColor: isDark ? Color(0xffffffff) : Color(0xff006aff),
textTheme: ButtonTextTheme.accent,
colorScheme: theme.colorScheme.copyWith(
secondary: isDark ? Color(0xff005eff) : Color(0xffffffff),
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(26),
),
),
primaryIconTheme: IconThemeData(color: colorTheme.black.withOpacity(.5)), primaryIconTheme: IconThemeData(color: colorTheme.black.withOpacity(.5)),
defaultChannelImage: (context, channel) => SizedBox(), defaultChannelImage: (context, channel) => SizedBox(),
defaultUserImage: (context, user) => Center( defaultUserImage: (context, user) => Center(
@@ -475,7 +493,7 @@ class ColorTheme {
this.white = const Color(0xffffffff), this.white = const Color(0xffffffff),
this.blueAlice = const Color(0xffe9f2ff), this.blueAlice = const Color(0xffe9f2ff),
this.accentBlue = const Color(0xff005FFF), this.accentBlue = const Color(0xff005FFF),
this.accentRed = const Color(0xffFF3742), this.accentRed = const Color(0xffFF3842),
this.accentGreen = const Color(0xff20E070), this.accentGreen = const Color(0xff20E070),
this.highlight = const Color(0xfffbf4dd), this.highlight = const Color(0xfffbf4dd),
this.overlay = const Color.fromRGBO(0, 0, 0, 0.2), this.overlay = const Color.fromRGBO(0, 0, 0, 0.2),