Skip to content

Commit

Permalink
feat: improving fetching chat room on chat room page
Browse files Browse the repository at this point in the history
  • Loading branch information
kosukesaigusa committed Aug 7, 2023
1 parent 08bdb67 commit 161fdc0
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 48 deletions.
19 changes: 17 additions & 2 deletions packages/mottai_flutter_app/lib/chat/chat_room.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,18 @@ final chatRoomStateNotifierProvider = StateNotifierProvider.family
.autoDispose<ChatRoomStateNotifier, ChatRoomState, String>(
(ref, chatRoomId) => ChatRoomStateNotifier(
chatRoomId: chatRoomId,
chatRoomRepository: ref.watch(chatRoomRepositoryProvider),
chatMessageRepository: ref.watch(chatMessageRepositoryProvider),
),
);

class ChatRoomStateNotifier extends StateNotifier<ChatRoomState> {
ChatRoomStateNotifier({
required String chatRoomId,
required ChatRoomRepository chatRoomRepository,
required ChatMessageRepository chatMessageRepository,
}) : _chatRoomId = chatRoomId,
_chatRoomRepository = chatRoomRepository,
_chatMessageRepository = chatMessageRepository,
super(const ChatRoomState()) {
_newReadChatMessagesSubscription = _chatMessageRepository
Expand All @@ -64,6 +67,7 @@ class ChatRoomStateNotifier extends StateNotifier<ChatRoomState> {
.listen(_updateNewReadChatMessages);
Future<void>(() async {
await Future.wait<void>([
_fetchChatRoom(),
loadMore(),
// ChatPage に遷移直後のメッセージアイコンを意図的に見せるために最低でも 500 ms 待つ。
Future<void>.delayed(const Duration(milliseconds: 500)),
Expand All @@ -78,10 +82,13 @@ class ChatRoomStateNotifier extends StateNotifier<ChatRoomState> {
super.dispose();
}

/// [ChatRoomRepository] のインスタンス。
final ChatRoomRepository _chatRoomRepository;

/// [ChatMessageRepository] のインスタンス。
late final ChatMessageRepository _chatMessageRepository;
final ChatMessageRepository _chatMessageRepository;

/// チャットルームの ID
/// チャットルームの ID.
final String _chatRoomId;

/// 無限スクロールで取得するメッセージ件数の limit 値。
Expand All @@ -95,6 +102,14 @@ class ChatRoomStateNotifier extends StateNotifier<ChatRoomState> {
late final StreamSubscription<List<ReadChatMessage>>
_newReadChatMessagesSubscription;

/// チャットルームを取得する。
Future<void> _fetchChatRoom() async {
final readChatRoom = await _chatRoomRepository.fetchChatRoom(
chatRoomId: _chatRoomId,
);
state = state.copyWith(readChatRoom: readChatRoom);
}

/// 過去のメッセージを、最後に取得した queryDocumentSnapshot 以降の _limit 件だけ取得する。
Future<void> loadMore() async {
if (!state.hasMore) {
Expand Down
3 changes: 3 additions & 0 deletions packages/mottai_flutter_app/lib/chat/chat_room_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ class ChatRoomState with _$ChatRoomState {
/// チャットページに入ったときの初回ローディング中かどうか。
@Default(true) bool loading,

/// チャットルーム。初回ローディングで取得することを期待する。
ReadChatRoom? readChatRoom,

/// メッセージを送信中かどうか。
@Default(false) bool sending,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ mixin _$ChatRoomState {
/// チャットページに入ったときの初回ローディング中かどうか。
bool get loading => throw _privateConstructorUsedError;

/// チャットルーム。初回ローディングで取得することを期待する。
ReadChatRoom? get readChatRoom => throw _privateConstructorUsedError;

/// メッセージを送信中かどうか。
bool get sending => throw _privateConstructorUsedError;

Expand Down Expand Up @@ -56,6 +59,7 @@ abstract class $ChatRoomStateCopyWith<$Res> {
@useResult
$Res call(
{bool loading,
ReadChatRoom? readChatRoom,
bool sending,
List<ReadChatMessage> readChatMessages,
List<ReadChatMessage> newReadChatMessages,
Expand All @@ -79,6 +83,7 @@ class _$ChatRoomStateCopyWithImpl<$Res, $Val extends ChatRoomState>
@override
$Res call({
Object? loading = null,
Object? readChatRoom = freezed,
Object? sending = null,
Object? readChatMessages = null,
Object? newReadChatMessages = null,
Expand All @@ -92,6 +97,10 @@ class _$ChatRoomStateCopyWithImpl<$Res, $Val extends ChatRoomState>
? _value.loading
: loading // ignore: cast_nullable_to_non_nullable
as bool,
readChatRoom: freezed == readChatRoom
? _value.readChatRoom
: readChatRoom // ignore: cast_nullable_to_non_nullable
as ReadChatRoom?,
sending: null == sending
? _value.sending
: sending // ignore: cast_nullable_to_non_nullable
Expand Down Expand Up @@ -134,6 +143,7 @@ abstract class _$$_ChatRoomStateCopyWith<$Res>
@useResult
$Res call(
{bool loading,
ReadChatRoom? readChatRoom,
bool sending,
List<ReadChatMessage> readChatMessages,
List<ReadChatMessage> newReadChatMessages,
Expand All @@ -155,6 +165,7 @@ class __$$_ChatRoomStateCopyWithImpl<$Res>
@override
$Res call({
Object? loading = null,
Object? readChatRoom = freezed,
Object? sending = null,
Object? readChatMessages = null,
Object? newReadChatMessages = null,
Expand All @@ -168,6 +179,10 @@ class __$$_ChatRoomStateCopyWithImpl<$Res>
? _value.loading
: loading // ignore: cast_nullable_to_non_nullable
as bool,
readChatRoom: freezed == readChatRoom
? _value.readChatRoom
: readChatRoom // ignore: cast_nullable_to_non_nullable
as ReadChatRoom?,
sending: null == sending
? _value.sending
: sending // ignore: cast_nullable_to_non_nullable
Expand Down Expand Up @@ -205,6 +220,7 @@ class __$$_ChatRoomStateCopyWithImpl<$Res>
class _$_ChatRoomState implements _ChatRoomState {
const _$_ChatRoomState(
{this.loading = true,
this.readChatRoom,
this.sending = false,
final List<ReadChatMessage> readChatMessages = const <ReadChatMessage>[],
final List<ReadChatMessage> newReadChatMessages =
Expand All @@ -223,6 +239,10 @@ class _$_ChatRoomState implements _ChatRoomState {
@JsonKey()
final bool loading;

/// チャットルーム。初回ローディングで取得することを期待する。
@override
final ReadChatRoom? readChatRoom;

/// メッセージを送信中かどうか。
@override
@JsonKey()
Expand Down Expand Up @@ -283,7 +303,7 @@ class _$_ChatRoomState implements _ChatRoomState {

@override
String toString() {
return 'ChatRoomState(loading: $loading, sending: $sending, readChatMessages: $readChatMessages, newReadChatMessages: $newReadChatMessages, pastReadChatMessages: $pastReadChatMessages, fetching: $fetching, hasMore: $hasMore, lastReadChatMessageId: $lastReadChatMessageId)';
return 'ChatRoomState(loading: $loading, readChatRoom: $readChatRoom, sending: $sending, readChatMessages: $readChatMessages, newReadChatMessages: $newReadChatMessages, pastReadChatMessages: $pastReadChatMessages, fetching: $fetching, hasMore: $hasMore, lastReadChatMessageId: $lastReadChatMessageId)';
}

@override
Expand All @@ -292,6 +312,8 @@ class _$_ChatRoomState implements _ChatRoomState {
(other.runtimeType == runtimeType &&
other is _$_ChatRoomState &&
(identical(other.loading, loading) || other.loading == loading) &&
(identical(other.readChatRoom, readChatRoom) ||
other.readChatRoom == readChatRoom) &&
(identical(other.sending, sending) || other.sending == sending) &&
const DeepCollectionEquality()
.equals(other._readChatMessages, _readChatMessages) &&
Expand All @@ -310,6 +332,7 @@ class _$_ChatRoomState implements _ChatRoomState {
int get hashCode => Object.hash(
runtimeType,
loading,
readChatRoom,
sending,
const DeepCollectionEquality().hash(_readChatMessages),
const DeepCollectionEquality().hash(_newReadChatMessages),
Expand All @@ -328,6 +351,7 @@ class _$_ChatRoomState implements _ChatRoomState {
abstract class _ChatRoomState implements ChatRoomState {
const factory _ChatRoomState(
{final bool loading,
final ReadChatRoom? readChatRoom,
final bool sending,
final List<ReadChatMessage> readChatMessages,
final List<ReadChatMessage> newReadChatMessages,
Expand All @@ -342,6 +366,10 @@ abstract class _ChatRoomState implements ChatRoomState {
bool get loading;
@override

/// チャットルーム。初回ローディングで取得することを期待する。
ReadChatRoom? get readChatRoom;
@override

/// メッセージを送信中かどうか。
bool get sending;
@override
Expand Down
91 changes: 46 additions & 45 deletions packages/mottai_flutter_app/lib/chat/ui/chat_room.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,9 @@ class _ChatRoomPageState extends ConsumerState<ChatRoomPage> {

@override
Widget build(BuildContext context) {
final readChatRoom =
ref.watch(chatRoomFutureProvider(widget.chatRoomId)).value;
if (readChatRoom == null) {
// TODO: この実装だと、loading 中に UnavailablePage がちらっと見えそうなので改善したい。
return const UnavailablePage('チャットルームの情報の取得に失敗しました。');
}
final state = ref.watch(chatRoomStateNotifierProvider(widget.chatRoomId));
final loading = state.loading;
final readChatRoom = state.readChatRoom;
return Scaffold(
appBar: AppBar(
// TODO: chatPartnerImageUrlProvider を真似して、chatPartnerNameProvider
Expand All @@ -88,50 +84,55 @@ class _ChatRoomPageState extends ConsumerState<ChatRoomPage> {
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: AuthDependentBuilder(
onAuthenticated: (userId) => state.loading
? const Center(
child: FaIcon(
FontAwesomeIcons.solidComment,
size: 72,
color: Colors.black12,
),
)
: Stack(
onAuthenticated: (userId) {
if (loading) {
return const Center(
child: FaIcon(
FontAwesomeIcons.solidComment,
size: 72,
color: Colors.black12,
),
);
}
if (readChatRoom == null) {
return const UnavailablePage('チャットルームの情報の取得に失敗しました。');
}
return Stack(
children: [
Column(
children: [
Column(
children: [
Expanded(
child: ListView.builder(
itemCount: state.readChatMessages.length,
reverse: true,
controller: _scrollController,
itemBuilder: (context, index) {
final readChatMessage =
state.readChatMessages[index];
return _ChatMessageItem(
readChatRoom: readChatRoom,
readChatMessage: readChatMessage,
isMyMessage: readChatMessage.senderId == userId,
chatRoomId: widget.chatRoomId,
);
},
),
),
_MessageTextField(
chatRoomId: widget.chatRoomId,
userId: userId,
),
const Gap(24),
],
),
Positioned(
child: Align(
alignment: Alignment.topCenter,
child: _DebugIndicator(chatRoomId: widget.chatRoomId),
Expanded(
child: ListView.builder(
itemCount: state.readChatMessages.length,
reverse: true,
controller: _scrollController,
itemBuilder: (context, index) {
final readChatMessage = state.readChatMessages[index];
return _ChatMessageItem(
readChatRoom: readChatRoom,
readChatMessage: readChatMessage,
isMyMessage: readChatMessage.senderId == userId,
chatRoomId: widget.chatRoomId,
);
},
),
),
_MessageTextField(
chatRoomId: widget.chatRoomId,
userId: userId,
),
const Gap(24),
],
),
Positioned(
child: Align(
alignment: Alignment.topCenter,
child: _DebugIndicator(chatRoomId: widget.chatRoomId),
),
),
],
);
},
),
),
);
Expand Down

0 comments on commit 161fdc0

Please sign in to comment.