Merge pull request #619 from GetStream/cds-405

refactor(ui): use channel `.nameStream` and `.imageStream` instead of `.extraDataStream`
This commit is contained in:
Salvatore Giordano
2021-08-23 11:26:20 +02:00
committed by GitHub
7 changed files with 127 additions and 147 deletions
@@ -90,57 +90,54 @@ class ChannelAvatar extends StatelessWidget {
final colorTheme = chatThemeData.colorTheme;
final previewTheme = chatThemeData.channelPreviewTheme.avatarTheme;
return BetterStreamBuilder<Map<String, dynamic>>(
stream: channel.extraDataStream,
initialData: channel.extraData,
builder: (context, extraData) {
final channelImage = extraData['image'];
if (channelImage != null) {
Widget child = ClipRRect(
borderRadius: borderRadius ?? previewTheme?.borderRadius,
child: Container(
constraints: constraints ?? previewTheme?.constraints,
decoration: BoxDecoration(color: colorTheme.accentPrimary),
child: InkWell(
onTap: onTap,
child: CachedNetworkImage(
imageUrl: channelImage,
errorWidget: (_, __, ___) => Center(
child: Text(
extraData['name']?[0] ?? '',
style: TextStyle(
color: colorTheme.barsBg,
fontWeight: FontWeight.bold,
),
return BetterStreamBuilder<String>(
stream: channel.imageStream,
initialData: channel.image,
builder: (context, channelImage) {
Widget child = ClipRRect(
borderRadius: borderRadius ?? previewTheme?.borderRadius,
child: Container(
constraints: constraints ?? previewTheme?.constraints,
decoration: BoxDecoration(color: colorTheme.accentPrimary),
child: InkWell(
onTap: onTap,
child: CachedNetworkImage(
imageUrl: channelImage,
errorWidget: (_, __, ___) => Center(
child: Text(
channel.name?[0] ?? '',
style: TextStyle(
color: colorTheme.barsBg,
fontWeight: FontWeight.bold,
),
),
fit: BoxFit.cover,
),
fit: BoxFit.cover,
),
),
),
);
if (selected) {
child = ClipRRect(
key: const Key('selectedImage'),
borderRadius: BorderRadius.circular(selectionThickness) +
(borderRadius ??
previewTheme?.borderRadius ??
BorderRadius.zero),
child: Container(
constraints: constraints ?? previewTheme?.constraints,
color: selectionColor ?? colorTheme.accentPrimary,
child: Padding(
padding: EdgeInsets.all(selectionThickness),
child: child,
),
),
);
if (selected) {
child = ClipRRect(
key: const Key('selectedImage'),
borderRadius: BorderRadius.circular(selectionThickness) +
(borderRadius ??
previewTheme?.borderRadius ??
BorderRadius.zero),
child: Container(
constraints: constraints ?? previewTheme?.constraints,
color: selectionColor ?? colorTheme.accentPrimary,
child: Padding(
padding: EdgeInsets.all(selectionThickness),
child: child,
),
),
);
}
return child;
}
return child;
},
noDataBuilder: (context) {
final currentUser = streamChat.currentUser!;
final otherMembers = channel.state!.members
.where((it) => it.userId != currentUser.id)
@@ -27,40 +27,46 @@ class ChannelName extends StatelessWidget {
final client = StreamChat.of(context);
final channel = StreamChannel.of(context).channel;
return BetterStreamBuilder<Map<String, Object?>>(
stream: channel.extraDataStream,
initialData: channel.extraData,
builder: (context, data) => _buildName(
data,
channel.state?.members,
client,
assert(channel.state != null, 'Channel ${channel.id} is not initialized');
return BetterStreamBuilder<String>(
stream: channel.nameStream,
initialData: channel.name,
builder: (context, channelName) => Text(
channelName,
style: textStyle,
overflow: textOverflow,
),
noDataBuilder: (context) => _generateName(
client.currentUser!,
channel.state!.members,
),
);
}
Widget _buildName(
Map<String, dynamic> extraData,
List<Member>? members,
StreamChatState client,
Widget _generateName(
User currentUser,
List<Member> members,
) =>
LayoutBuilder(
builder: (context, constraints) {
var title = context.translations.noTitleText;
if (extraData['name'] != null) {
title = extraData['name'];
} else {
final otherMembers = members
?.where((member) => member.userId != client.currentUser!.id);
if (otherMembers?.length == 1) {
if (otherMembers!.first.user != null) {
title = otherMembers.first.user!.name;
var channelName = context.translations.noTitleText;
final otherMembers = members.where(
(member) => member.userId != currentUser.id,
);
if (otherMembers.isNotEmpty) {
if (otherMembers.length == 1) {
final user = otherMembers.first.user;
if (user != null) {
channelName = user.name;
}
} else if (otherMembers?.isNotEmpty == true) {
} else {
final maxWidth = constraints.maxWidth;
final maxChars = maxWidth / (textStyle?.fontSize ?? 1);
var currentChars = 0;
final currentMembers = <Member>[];
otherMembers!.forEach((element) {
otherMembers.forEach((element) {
final newLength =
currentChars + (element.user?.name.length ?? 0);
if (newLength < maxChars) {
@@ -71,13 +77,14 @@ class ChannelName extends StatelessWidget {
final exceedingMembers =
otherMembers.length - currentMembers.length;
title = '${currentMembers.map((e) => e.user?.name).join(', ')} '
channelName =
'${currentMembers.map((e) => e.user?.name).join(', ')} '
'${exceedingMembers > 0 ? '+ $exceedingMembers' : ''}';
}
}
return Text(
title,
channelName,
style: textStyle,
overflow: textOverflow,
);
@@ -26,12 +26,11 @@ void main() {
when(() => channel.client).thenReturn(client);
when(() => channel.isMuted).thenReturn(false);
when(() => channel.isMutedStream).thenAnswer((i) => Stream.value(false));
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
'name': 'test',
}));
when(() => channel.extraData).thenReturn({
'name': 'test',
});
when(() => channel.nameStream).thenAnswer((_) => Stream.value('test'));
when(() => channel.name).thenReturn('test');
when(() => channel.imageStream)
.thenAnswer((i) => Stream.value('https://bit.ly/321RmWb'));
when(() => channel.image).thenReturn('https://bit.ly/321RmWb');
when(() => channelState.unreadCount).thenReturn(1);
when(() => client.wsConnectionStatusStream)
.thenAnswer((_) => Stream.value(ConnectionStatus.connected));
@@ -91,12 +90,11 @@ void main() {
when(() => channel.client).thenReturn(client);
when(() => channel.isMuted).thenReturn(false);
when(() => channel.isMutedStream).thenAnswer((i) => Stream.value(false));
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
'name': 'test',
}));
when(() => channel.extraData).thenReturn({
'name': 'test',
});
when(() => channel.nameStream).thenAnswer((_) => Stream.value('test'));
when(() => channel.name).thenReturn('test');
when(() => channel.imageStream)
.thenAnswer((i) => Stream.value('https://bit.ly/321RmWb'));
when(() => channel.image).thenReturn('https://bit.ly/321RmWb');
when(() => channelState.unreadCount).thenReturn(1);
when(() => channelState.unreadCountStream)
.thenAnswer((i) => Stream.value(1));
@@ -159,12 +157,11 @@ void main() {
when(() => channel.client).thenReturn(client);
when(() => channel.isMuted).thenReturn(false);
when(() => channel.isMutedStream).thenAnswer((i) => Stream.value(false));
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
'name': 'test',
}));
when(() => channel.extraData).thenReturn({
'name': 'test',
});
when(() => channel.nameStream).thenAnswer((_) => Stream.value('test'));
when(() => channel.name).thenReturn('test');
when(() => channel.imageStream)
.thenAnswer((i) => Stream.value('https://bit.ly/321RmWb'));
when(() => channel.image).thenReturn('https://bit.ly/321RmWb');
when(() => channelState.unreadCount).thenReturn(1);
when(() => channelState.unreadCountStream)
.thenAnswer((i) => Stream.value(1));
@@ -305,12 +302,11 @@ void main() {
when(() => channel.client).thenReturn(client);
when(() => channel.isMuted).thenReturn(false);
when(() => channel.isMutedStream).thenAnswer((i) => Stream.value(false));
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
'name': 'test',
}));
when(() => channel.extraData).thenReturn({
'name': 'test',
});
when(() => channel.nameStream).thenAnswer((_) => Stream.value('test'));
when(() => channel.name).thenReturn('test');
when(() => channel.imageStream)
.thenAnswer((i) => Stream.value('https://bit.ly/321RmWb'));
when(() => channel.image).thenReturn('https://bit.ly/321RmWb');
when(() => channelState.unreadCount).thenReturn(1);
when(() => channelState.unreadCountStream)
.thenAnswer((i) => Stream.value(1));
@@ -373,12 +369,11 @@ void main() {
when(() => channel.client).thenReturn(client);
when(() => channel.isMuted).thenReturn(false);
when(() => channel.isMutedStream).thenAnswer((i) => Stream.value(false));
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
'name': 'test',
}));
when(() => channel.extraData).thenReturn({
'name': 'test',
});
when(() => channel.nameStream).thenAnswer((_) => Stream.value('test'));
when(() => channel.name).thenReturn('test');
when(() => channel.imageStream)
.thenAnswer((i) => Stream.value('https://bit.ly/321RmWb'));
when(() => channel.image).thenReturn('https://bit.ly/321RmWb');
when(() => channelState.unreadCount).thenReturn(1);
when(() => channelState.unreadCountStream)
.thenAnswer((i) => Stream.value(1));
@@ -20,14 +20,11 @@ void main() {
when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client);
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
'name': 'test',
'image': 'imagetest',
}));
when(() => channel.extraData).thenReturn({
'name': 'test',
'image': 'imagetest',
});
when(() => channel.nameStream).thenAnswer((_) => Stream.value('test'));
when(() => channel.name).thenReturn('test');
when(() => channel.imageStream)
.thenAnswer((i) => Stream.value('https://bit.ly/321RmWb'));
when(() => channel.image).thenReturn('https://bit.ly/321RmWb');
await tester.pumpWidget(MaterialApp(
home: StreamChat(
@@ -43,7 +40,7 @@ void main() {
final image =
tester.widget<CachedNetworkImage>(find.byType(CachedNetworkImage));
expect(image.imageUrl, 'imagetest');
expect(image.imageUrl, 'https://bit.ly/321RmWb');
},
);
@@ -59,12 +56,10 @@ void main() {
when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client);
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
'name': 'test',
}));
when(() => channel.extraData).thenReturn({
'name': 'test',
});
when(() => channel.nameStream).thenAnswer((_) => Stream.value('test'));
when(() => channel.name).thenReturn('test');
when(() => channel.imageStream).thenAnswer((i) => Stream.value(null));
when(() => channel.image).thenReturn(null);
when(() => channelState.membersStream).thenAnswer((i) => Stream.value([
Member(
userId: 'user-id',
@@ -132,12 +127,9 @@ void main() {
when(() => clientState.currentUser).thenReturn(currentUser);
when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client);
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
'name': 'test',
}));
when(() => channel.extraData).thenReturn({
'name': 'test',
});
when(() => channel.nameStream).thenAnswer((_) => Stream.value('test'));
when(() => channel.name).thenReturn('test');
when(() => channel.imageStream).thenAnswer((i) => Stream.value(null));
final members = [
Member(
userId: 'user-id',
@@ -198,14 +190,11 @@ void main() {
when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client);
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
'name': 'test',
'image': 'imagetest',
}));
when(() => channel.extraData).thenReturn({
'name': 'test',
'image': 'imagetest',
});
when(() => channel.nameStream).thenAnswer((_) => Stream.value('test'));
when(() => channel.name).thenReturn('test');
when(() => channel.imageStream)
.thenAnswer((i) => Stream.value('https://bit.ly/321RmWb'));
when(() => channel.image).thenReturn('https://bit.ly/321RmWb');
await tester.pumpWidget(MaterialApp(
home: StreamChat(
@@ -21,17 +21,13 @@ void main() {
when(() => channel.state).thenReturn(channelState);
when(() => channel.client).thenReturn(client);
when(() => channel.isMuted).thenReturn(false);
when(() => channel.isMutedStream).thenAnswer((i) => Stream.value(false));
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
'name': 'test',
}));
when(() => channel.extraData).thenReturn({
'name': 'test',
});
when(() => channel.isMutedStream).thenAnswer((_) => Stream.value(false));
when(() => channel.nameStream).thenAnswer((_) => Stream.value('test'));
when(() => channel.name).thenReturn('test');
when(() => channelState.unreadCount).thenReturn(1);
when(() => channelState.unreadCountStream)
.thenAnswer((i) => Stream.value(1));
when(() => channelState.membersStream).thenAnswer((i) => Stream.value([
when(() => channelState.membersStream).thenAnswer((_) => Stream.value([
Member(
userId: 'user-id',
user: User(id: 'user-id'),
@@ -28,12 +28,12 @@ void main() {
when(() => channel.client).thenReturn(client);
when(() => channel.isMuted).thenReturn(false);
when(() => channel.isMutedStream).thenAnswer((i) => Stream.value(false));
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
'name': 'test name',
}));
when(() => channel.extraData).thenReturn({
'name': 'test name',
});
when(() => channel.nameStream)
.thenAnswer((i) => Stream.value('test name'));
when(() => channel.name).thenReturn('test name');
when(() => channel.imageStream)
.thenAnswer((i) => Stream.value('https://bit.ly/321RmWb'));
when(() => channel.image).thenReturn('https://bit.ly/321RmWb');
when(() => clientState.channels).thenReturn({
channel.cid!: channel,
});
@@ -22,12 +22,8 @@ void main() {
when(() => channel.client).thenReturn(client);
when(() => channel.isMuted).thenReturn(false);
when(() => channel.isMutedStream).thenAnswer((i) => Stream.value(false));
when(() => channel.extraDataStream).thenAnswer((i) => Stream.value({
'name': 'test',
}));
when(() => channel.extraData).thenReturn({
'name': 'test',
});
when(() => channel.name).thenReturn('test');
when(() => channel.nameStream).thenAnswer((i) => Stream.value('test'));
when(() => channelState.unreadCount).thenReturn(1);
when(() => channelState.unreadCountStream)
.thenAnswer((i) => Stream.value(1));