fix light theme on ios

This commit is contained in:
Salvatore Giordano
2020-12-31 17:18:30 +01:00
parent 35adbde641
commit 0afae55f2e
5 changed files with 233 additions and 245 deletions
+1 -1
View File
@@ -842,4 +842,4 @@
/* End XCConfigurationList section */ /* End XCConfigurationList section */
}; };
rootObject = 97C146E61CF9000F007C117D /* Project object */; rootObject = 97C146E61CF9000F007C117D /* Project object */;
} }
-2
View File
@@ -58,8 +58,6 @@
<array> <array>
<string>remote-notification</string> <string>remote-notification</string>
</array> </array>
<key>UIUserInterfaceStyle</key>
<string>Light</string>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<true/> <true/>
</dict> </dict>
+4 -1
View File
@@ -59,7 +59,10 @@ class MyApp extends StatelessWidget {
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
theme: ThemeData.light(), theme: ThemeData.light(),
darkTheme: ThemeData.dark(), darkTheme: ThemeData.dark(),
themeMode: ThemeMode.system, themeMode:
WidgetsBinding.instance.window.platformBrightness == Brightness.light
? ThemeMode.light
: ThemeMode.dark,
onGenerateRoute: AppRoutes.generateRoute, onGenerateRoute: AppRoutes.generateRoute,
initialRoute: initialRoute:
client.state.user == null ? Routes.CHOOSE_USER : Routes.HOME, client.state.user == null ? Routes.CHOOSE_USER : Routes.HOME,
+1 -1
View File
@@ -1,6 +1,6 @@
name: example name: example
description: A new Flutter project. description: A new Flutter project.
version: 1.0.105+108 version: 1.0.106+109
environment: environment:
sdk: ">=2.2.2 <3.0.0" sdk: ">=2.2.2 <3.0.0"
+227 -240
View File
@@ -173,10 +173,10 @@ class _MessageListViewState extends State<MessageListView> {
bool _showScrollToBottom = false; bool _showScrollToBottom = false;
ItemPositionsListener _itemPositionListener; ItemPositionsListener _itemPositionListener;
int _messageListLength; int _messageListLength;
StreamChannelState streamChannel;
int get _initialIndex { int get _initialIndex {
if (widget.initialScrollIndex != null) return widget.initialScrollIndex; if (widget.initialScrollIndex != null) return widget.initialScrollIndex;
final streamChannel = StreamChannel.of(context);
if (streamChannel.initialMessageId != null) { if (streamChannel.initialMessageId != null) {
final messages = streamChannel.channel.state.messages; final messages = streamChannel.channel.state.messages;
final totalMessages = messages.length; final totalMessages = messages.length;
@@ -196,11 +196,10 @@ class _MessageListViewState extends State<MessageListView> {
} }
bool _isInitialMessage(String id) { bool _isInitialMessage(String id) {
final streamChannel = StreamChannel.of(context);
return streamChannel.initialMessageId == id; return streamChannel.initialMessageId == id;
} }
bool get _upToDate => StreamChannel.of(context).channel.state.isUpToDate; bool get _upToDate => streamChannel.channel.state.isUpToDate;
bool _topPaginationActive = false; bool _topPaginationActive = false;
bool _bottomPaginationActive = false; bool _bottomPaginationActive = false;
@@ -216,270 +215,259 @@ class _MessageListViewState extends State<MessageListView> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final streamChannel = StreamChannel.of(context);
final messagesStream = widget.parentMessage != null final messagesStream = widget.parentMessage != null
? streamChannel.channel.state.threadsStream ? streamChannel.channel.state.threadsStream
.where((threads) => threads.containsKey(widget.parentMessage.id)) .where((threads) => threads.containsKey(widget.parentMessage.id))
.map((threads) => threads[widget.parentMessage.id]) .map((threads) => threads[widget.parentMessage.id])
: streamChannel.channel.state?.messagesStream; : streamChannel.channel.state?.messagesStream;
return WillPopScope( return StreamBuilder<List<Message>>(
onWillPop: () async { stream: messagesStream?.map((messages) => messages
if (!_upToDate) { ?.where((e) =>
await streamChannel.reloadChannel(); !e.isDeleted ||
} (e.isDeleted &&
return true; e.user.id == streamChannel.channel.client.state.user.id))
}, ?.toList()),
child: StreamBuilder<List<Message>>( builder: (context, snapshot) {
stream: messagesStream?.map((messages) => messages if (!snapshot.hasData) {
?.where((e) => return Center(
!e.isDeleted || child: const CircularProgressIndicator(),
(e.isDeleted && );
e.user.id == streamChannel.channel.client.state.user.id)) }
?.toList()),
builder: (context, snapshot) { final messageList = snapshot.data?.reversed?.toList() ?? [];
if (!snapshot.hasData) { if (messageList.isEmpty) {
if (_upToDate) {
return Center( return Center(
child: const CircularProgressIndicator(), child: Text(
'No chats here yet...',
style: StreamChatTheme.of(context)
.textTheme
.footnote
.copyWith(
color: StreamChatTheme.of(context)
.colorTheme
.black
.withOpacity(.5)),
),
); );
} }
} else {
messages = messageList;
}
final messageList = snapshot.data?.reversed?.toList() ?? []; final newMessagesListLength = messages.length;
if (messageList.isEmpty) {
if (_upToDate) {
return Center(
child: Text(
'No chats here yet...',
style: StreamChatTheme.of(context)
.textTheme
.footnote
.copyWith(
color: StreamChatTheme.of(context)
.colorTheme
.black
.withOpacity(.5)),
),
);
}
} else {
messages = messageList;
}
final newMessagesListLength = messages.length; if (_messageListLength != null) {
if (_bottomPaginationActive || (_inBetweenList && _upToDate)) {
if (_messageListLength != null) { if (_itemPositionListener.itemPositions.value?.isNotEmpty ==
if (_bottomPaginationActive || (_inBetweenList && _upToDate)) { true) {
if (_itemPositionListener.itemPositions.value?.isNotEmpty == final first = _itemPositionListener.itemPositions.value.first;
true) { final diff = newMessagesListLength - _messageListLength;
final first = _itemPositionListener.itemPositions.value.first; if (diff > 0) {
final diff = newMessagesListLength - _messageListLength; initialIndex = first.index + diff;
if (diff > 0) { initialAlignment = first.itemLeadingEdge;
initialIndex = first.index + diff;
initialAlignment = first.itemLeadingEdge;
}
} }
} else if (!_topPaginationActive && _upToDate) {
// Reset the index in-case we send any new message
initialIndex = 0;
initialAlignment = 0;
} }
} else if (!_topPaginationActive && _upToDate) {
// Reset the index in-case we send any new message
initialIndex = 0;
initialAlignment = 0;
} }
}
_messageListLength = newMessagesListLength; _messageListLength = newMessagesListLength;
return Stack( return Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
LazyLoadScrollView( LazyLoadScrollView(
onStartOfPage: () async { onStartOfPage: () async {
_inBetweenList = false; _inBetweenList = false;
if (!_upToDate) { if (!_upToDate) {
_topPaginationActive = false; _topPaginationActive = false;
_bottomPaginationActive = true; _bottomPaginationActive = true;
return _paginateData(
streamChannel,
QueryDirection.bottom,
);
}
},
onEndOfPage: () async {
_inBetweenList = false;
_topPaginationActive = true;
_bottomPaginationActive = false;
return _paginateData( return _paginateData(
streamChannel, streamChannel,
QueryDirection.top, QueryDirection.bottom,
); );
}, }
onInBetweenOfPage: () { },
_inBetweenList = true; onEndOfPage: () async {
}, _inBetweenList = false;
child: ScrollablePositionedList.builder( _topPaginationActive = true;
key: ValueKey(initialIndex + initialAlignment), _bottomPaginationActive = false;
itemPositionsListener: _itemPositionListener, return _paginateData(
addAutomaticKeepAlives: true, streamChannel,
initialScrollIndex: initialIndex ?? 0, QueryDirection.top,
initialAlignment: initialAlignment ?? 0, );
physics: widget.scrollPhysics, },
itemScrollController: _scrollController, onInBetweenOfPage: () {
reverse: true, _inBetweenList = true;
itemCount: messages.length + },
2 + child: ScrollablePositionedList.builder(
(widget.parentMessage != null ? 1 : 0), key: ValueKey(initialIndex + initialAlignment),
itemBuilder: (context, i) { itemPositionsListener: _itemPositionListener,
if (i == messages.length + 2) { addAutomaticKeepAlives: true,
if (widget.parentMessageBuilder != null) { initialScrollIndex: initialIndex ?? 0,
return widget.parentMessageBuilder( initialAlignment: initialAlignment ?? 0,
context, physics: widget.scrollPhysics,
widget.parentMessage, itemScrollController: _scrollController,
); reverse: true,
} else { itemCount: messages.length +
return Column( 2 +
crossAxisAlignment: CrossAxisAlignment.stretch, (widget.parentMessage != null ? 1 : 0),
children: <Widget>[ itemBuilder: (context, i) {
buildParentMessage(widget.parentMessage), if (i == messages.length + 2) {
Container( if (widget.parentMessageBuilder != null) {
decoration: BoxDecoration( return widget.parentMessageBuilder(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
StreamChatTheme.of(context)
.colorTheme
.whiteSmoke,
StreamChatTheme.of(context)
.colorTheme
.whiteSnow,
],
),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'${widget.parentMessage.replyCount} ${widget.parentMessage.replyCount == 1 ? 'Reply' : 'Replies'}',
textAlign: TextAlign.center,
style: StreamChatTheme.of(context)
.channelTheme
.channelHeaderTheme
.lastMessageAt,
),
),
),
],
);
}
}
if (i == messages.length + 1) {
return _buildLoadingIndicator(
streamChannel,
QueryDirection.top,
);
}
if (i == 0) {
return _buildLoadingIndicator(
streamChannel,
QueryDirection.bottom,
);
}
final message = messages[i - 1];
final nextMessage = (i - 1) > 0 ? messages[i - 2] : null;
Widget messageWidget;
if (i == 1) {
messageWidget = _buildBottomMessage(
context, context,
message, widget.parentMessage,
messages,
streamChannel,
);
} else if (i == messages.length - 1) {
messageWidget = _buildTopMessage(
context,
message,
messages,
streamChannel,
); );
} else { } else {
if (widget.messageBuilder != null) {
messageWidget = Builder(
key: ValueKey<String>('MESSAGE-${message.id}'),
builder: (_) => widget.messageBuilder(
context,
MessageDetails(
context,
message,
messages,
i,
),
messages),
);
} else {
messageWidget = buildMessage(message, messages, i);
}
}
if (nextMessage != null &&
!Jiffy(message.createdAt.toLocal()).isSame(
nextMessage.createdAt.toLocal(), Units.DAY)) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[ children: <Widget>[
messageWidget, buildParentMessage(widget.parentMessage),
Padding( Container(
padding: decoration: BoxDecoration(
const EdgeInsets.symmetric(vertical: 12.0), gradient: LinearGradient(
child: widget.dateDividerBuilder != null begin: Alignment.topCenter,
? widget.dateDividerBuilder( end: Alignment.bottomCenter,
nextMessage.createdAt.toLocal()) colors: [
: DateDivider( StreamChatTheme.of(context)
dateTime: nextMessage.createdAt.toLocal(), .colorTheme
), .whiteSmoke,
StreamChatTheme.of(context)
.colorTheme
.whiteSnow,
],
),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'${widget.parentMessage.replyCount} ${widget.parentMessage.replyCount == 1 ? 'Reply' : 'Replies'}',
textAlign: TextAlign.center,
style: StreamChatTheme.of(context)
.channelTheme
.channelHeaderTheme
.lastMessageAt,
),
),
), ),
], ],
); );
} }
}
if (i == messages.length + 1) {
return _buildLoadingIndicator(
streamChannel,
QueryDirection.top,
);
}
if (i == 0) {
return _buildLoadingIndicator(
streamChannel,
QueryDirection.bottom,
);
}
final message = messages[i - 1];
final nextMessage = (i - 1) > 0 ? messages[i - 2] : null;
return messageWidget; Widget messageWidget;
},
), if (i == 1) {
messageWidget = _buildBottomMessage(
context,
message,
messages,
streamChannel,
);
} else if (i == messages.length - 1) {
messageWidget = _buildTopMessage(
context,
message,
messages,
streamChannel,
);
} else {
if (widget.messageBuilder != null) {
messageWidget = Builder(
key: ValueKey<String>('MESSAGE-${message.id}'),
builder: (_) => widget.messageBuilder(
context,
MessageDetails(
context,
message,
messages,
i,
),
messages),
);
} else {
messageWidget = buildMessage(message, messages, i);
}
}
if (nextMessage != null &&
!Jiffy(message.createdAt.toLocal()).isSame(
nextMessage.createdAt.toLocal(), Units.DAY)) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
messageWidget,
Padding(
padding: const EdgeInsets.symmetric(vertical: 12.0),
child: widget.dateDividerBuilder != null
? widget.dateDividerBuilder(
nextMessage.createdAt.toLocal())
: DateDivider(
dateTime: nextMessage.createdAt.toLocal(),
),
),
],
);
}
return messageWidget;
},
), ),
if (widget.showScrollToBottom) _buildScrollToBottom(), ),
Positioned( if (widget.showScrollToBottom) _buildScrollToBottom(),
top: 20.0, Positioned(
child: ValueListenableBuilder<Iterable<ItemPosition>>( top: 20.0,
valueListenable: _itemPositionListener.itemPositions, child: ValueListenableBuilder<Iterable<ItemPosition>>(
builder: (context, values, _) { valueListenable: _itemPositionListener.itemPositions,
final items = _itemPositionListener.itemPositions?.value; builder: (context, values, _) {
if (items.isEmpty || messages.isEmpty) { final items = _itemPositionListener.itemPositions?.value;
return SizedBox(); if (items.isEmpty || messages.isEmpty) {
} return SizedBox();
}
var index = _getTopElement(values).index; var index = _getTopElement(values).index;
if (index > messages.length) { if (index > messages.length) {
return SizedBox(); return SizedBox();
} }
if (index == messages.length) { if (index == messages.length) {
index = max(index - 1, 0); index = max(index - 1, 0);
} }
return widget.dateDividerBuilder != null return widget.dateDividerBuilder != null
? widget.dateDividerBuilder( ? widget.dateDividerBuilder(
messages[index].createdAt.toLocal(), messages[index].createdAt.toLocal(),
) )
: DateDivider( : DateDivider(
dateTime: messages[index].createdAt.toLocal(), dateTime: messages[index].createdAt.toLocal(),
); );
}, },
),
), ),
], ),
); ],
}), );
); });
} }
Future<void> _paginateData( Future<void> _paginateData(
@@ -499,7 +487,6 @@ class _MessageListViewState extends State<MessageListView> {
} }
Widget _buildScrollToBottom() { Widget _buildScrollToBottom() {
final streamChannel = StreamChannel.of(context);
return StreamBuilder<Tuple2<bool, int>>( return StreamBuilder<Tuple2<bool, int>>(
stream: Rx.combineLatest2( stream: Rx.combineLatest2(
streamChannel.channel.state.isUpToDateStream, streamChannel.channel.state.isUpToDateStream,
@@ -744,7 +731,7 @@ class _MessageListViewState extends State<MessageListView> {
final isNextUser = final isNextUser =
index - 2 >= 0 && message.user.id == messages[index - 2]?.user?.id; index - 2 >= 0 && message.user.id == messages[index - 2]?.user?.id;
final channel = StreamChannel.of(context).channel; final channel = streamChannel.channel;
final readList = channel.state?.read final readList = channel.state?.read
?.where((element) => element.user.id != userId) ?.where((element) => element.user.id != userId)
?.where((read) => ?.where((read) =>
@@ -836,7 +823,7 @@ class _MessageListViewState extends State<MessageListView> {
_itemPositionListener = _itemPositionListener =
widget.itemPositionListener ?? ItemPositionsListener.create(); widget.itemPositionListener ?? ItemPositionsListener.create();
final streamChannel = StreamChannel.of(context); streamChannel = StreamChannel.of(context);
initialIndex = _initialIndex; initialIndex = _initialIndex;
initialAlignment = _initialAlignment; initialAlignment = _initialAlignment;
@@ -879,16 +866,13 @@ class _MessageListViewState extends State<MessageListView> {
context, context,
MaterialPageRoute(builder: (_) { MaterialPageRoute(builder: (_) {
return StreamBuilder<Message>( return StreamBuilder<Message>(
stream: StreamChannel.of(context) stream: streamChannel.channel.state.messagesStream.map(
.channel (messages) =>
.state
.messagesStream
.map((messages) =>
messages.firstWhere((m) => m.id == message.id)), messages.firstWhere((m) => m.id == message.id)),
initialData: message, initialData: message,
builder: (_, snapshot) { builder: (_, snapshot) {
return StreamChannel( return StreamChannel(
channel: StreamChannel.of(context).channel, channel: streamChannel.channel,
child: widget.threadBuilder(context, snapshot.data), child: widget.threadBuilder(context, snapshot.data),
); );
}); });
@@ -900,6 +884,9 @@ class _MessageListViewState extends State<MessageListView> {
@override @override
void dispose() { void dispose() {
if (!_upToDate) {
streamChannel.reloadChannel();
}
_messageNewListener?.cancel(); _messageNewListener?.cancel();
super.dispose(); super.dispose();
} }