Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion melos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ command:
stream_core_flutter:
git:
url: https://github.com/GetStream/stream-core-flutter.git
ref: 8057a775c2ed764dbd5cbabd2dd60d3cd68d2f08
ref: 226389ad533276d8daf2e03b90ed4cb3bfeecde3
path: packages/stream_core_flutter
synchronized: ^3.1.0+1
thumblr: ^0.0.4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'package:stream_chat_flutter/scrollable_positioned_list/scrollable_positi
import 'package:stream_chat_flutter/src/message_list_view/floating_date_divider.dart';
import 'package:stream_chat_flutter/src/message_list_view/loading_indicator.dart';
import 'package:stream_chat_flutter/src/message_list_view/mlv_utils.dart';
import 'package:stream_chat_flutter/src/message_list_view/stream_message_list_skeleton_loading.dart';
import 'package:stream_chat_flutter/src/message_list_view/thread_separator.dart';
import 'package:stream_chat_flutter/src/message_list_view/unread_messages_separator.dart';
import 'package:stream_chat_flutter/src/message_widget/ephemeral_message.dart';
Expand Down Expand Up @@ -563,11 +564,7 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
child: MessageListCore(
paginationLimit: widget.paginationLimit,
messageFilter: widget.messageFilter,
loadingBuilder:
widget.loadingBuilder ??
(context) => const Center(
child: CircularProgressIndicator.adaptive(),
),
loadingBuilder: widget.loadingBuilder ?? (context) => const StreamMessageListSkeletonLoading(),
emptyBuilder:
widget.emptyBuilder ??
(context) => Center(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import 'package:flutter/material.dart';
import 'package:stream_core_flutter/stream_core_flutter.dart';

/// A shimmer loading placeholder for the message list view.
///
/// Displays a skeleton UI with shimmer animation that mimics a chat
/// conversation with incoming (left-aligned) and outgoing (right-aligned)
/// message bubbles using [StreamSkeletonLoading] and [StreamSkeletonBox].
class StreamMessageListSkeletonLoading extends StatelessWidget {
/// Creates a new instance of [StreamMessageListSkeletonLoading].
const StreamMessageListSkeletonLoading({super.key});

@override
Widget build(BuildContext context) {
final spacing = context.streamSpacing;

return StreamSkeletonLoading(
child: LayoutBuilder(
builder: (context, constraints) {
return Padding(
padding: EdgeInsets.all(spacing.md),
child: Column(
children: [
_IncomingBubble(),
SizedBox(height: spacing.lg),
_OutgoingBubble(),
SizedBox(height: spacing.lg),
_IncomingBubble(),
SizedBox(height: spacing.lg),
_OutgoingBubble(),
SizedBox(height: spacing.lg),
_IncomingBubble(),
SizedBox(height: spacing.md),
],
),
);
},
),
);
}
}

class _IncomingBubble extends StatelessWidget {
@override
Widget build(BuildContext context) {
final spacing = context.streamSpacing;

return Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
const StreamSkeletonBox.circular(radius: 16),
SizedBox(width: spacing.xs),
Expanded(
flex: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
StreamSkeletonBox(
height: 56,
borderRadius: BorderRadius.only(
topRight: context.streamRadius.xl,
bottomRight: context.streamRadius.xl,
topLeft: context.streamRadius.xl,
),
),
SizedBox(height: spacing.xs),
StreamSkeletonBox(
width: 56,
height: 12,
borderRadius: BorderRadius.all(context.streamRadius.max),
),
SizedBox(height: spacing.xs),
],
),
),
const Spacer(
flex: 1,
),
],
);
}
}

class _OutgoingBubble extends StatelessWidget {
@override
Widget build(BuildContext context) {
final spacing = context.streamSpacing;

return Row(
children: [
const Spacer(
flex: 1,
),
Expanded(
flex: 2,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
StreamSkeletonBox(
height: 56,
borderRadius: BorderRadius.all(
context.streamRadius.xl,
),
),
SizedBox(height: spacing.xs),
StreamSkeletonBox(
width: 56,
height: 12,
borderRadius: BorderRadius.all(context.streamRadius.max),
),
],
),
),
],
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import 'package:flutter/material.dart';
import 'package:stream_core_flutter/stream_core_flutter.dart';

/// A shimmer loading placeholder for the channel list view.
///
/// Displays a skeleton UI with shimmer animation using
/// [StreamSkeletonLoading] and [StreamSkeletonBox] from the core package.
class StreamChannelListSkeletonLoading extends StatelessWidget {
/// Creates a new instance of [StreamChannelListSkeletonLoading].
const StreamChannelListSkeletonLoading({
super.key,
this.itemCount = 7,
});

/// The number of skeleton items to display.
final int itemCount;

@override
Widget build(BuildContext context) {
return StreamSkeletonLoading(
child: ListView.separated(
physics: const NeverScrollableScrollPhysics(),
itemCount: itemCount,
separatorBuilder: (context, index) => const SizedBox(height: 1),
itemBuilder: (context, index) => const _StreamChannelListItemSkeleton(),
),
);
}
}

class _StreamChannelListItemSkeleton extends StatelessWidget {
const _StreamChannelListItemSkeleton();

@override
Widget build(BuildContext context) {
final spacing = context.streamSpacing;

return Padding(
padding: EdgeInsets.all(spacing.md),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
spacing: spacing.md,
children: [
const StreamSkeletonBox.circular(radius: 24),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
spacing: spacing.xs,
children: [
Row(
children: [
Expanded(
child: StreamSkeletonBox(
width: double.infinity,
height: 16,
borderRadius: BorderRadius.all(context.streamRadius.max),
),
),
SizedBox(width: spacing.md),
StreamSkeletonBox(
width: 48,
height: 16,
borderRadius: BorderRadius.all(context.streamRadius.max),
),
],
),
Row(
children: [
Expanded(
flex: 3,
child: StreamSkeletonBox(
width: double.infinity,
height: 16,
borderRadius: BorderRadius.all(context.streamRadius.max),
),
),
const Spacer(
flex: 2,
),
],
),
],
),
),
],
),
);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/src/scroll_view/channel_scroll_view/stream_channel_list_skeleton_loading.dart';
import 'package:stream_chat_flutter/src/scroll_view/stream_scroll_view_error_widget.dart';
import 'package:stream_chat_flutter/src/scroll_view/stream_scroll_view_load_more_error.dart';
import 'package:stream_chat_flutter/src/scroll_view/stream_scroll_view_load_more_indicator.dart';
import 'package:stream_chat_flutter/src/scroll_view/stream_scroll_view_loading_widget.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';

/// Default separator builder for [StreamChannelListView].
Expand Down Expand Up @@ -347,11 +347,7 @@ class StreamChannelListView extends StatelessWidget {
child: StreamScrollViewLoadMoreIndicator(),
),
),
loadingBuilder: (context) =>
loadingBuilder?.call(context) ??
const Center(
child: StreamScrollViewLoadingWidget(),
),
loadingBuilder: (context) => loadingBuilder?.call(context) ?? const StreamChannelListSkeletonLoading(),
errorBuilder: (context, error) =>
errorBuilder?.call(context, error) ??
Center(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import 'package:flutter/material.dart';
import 'package:stream_core_flutter/stream_core_flutter.dart';

/// A shimmer loading placeholder for the thread list view.
///
/// Displays a skeleton UI with shimmer animation using
/// [StreamSkeletonLoading] and [StreamSkeletonBox] from the core package.
class StreamThreadListSkeletonLoading extends StatelessWidget {
/// Creates a new instance of [StreamThreadListSkeletonLoading].
const StreamThreadListSkeletonLoading({
super.key,
this.itemCount = 6,
});

/// The number of skeleton items to display.
final int itemCount;

@override
Widget build(BuildContext context) {
return StreamSkeletonLoading(
child: ListView.separated(
physics: const NeverScrollableScrollPhysics(),
itemCount: itemCount,
separatorBuilder: (context, index) => const SizedBox(height: 1),
itemBuilder: (context, index) => const _StreamThreadListItemSkeleton(),
),
);
}
}

class _StreamThreadListItemSkeleton extends StatelessWidget {
const _StreamThreadListItemSkeleton();

@override
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.all(context.streamSpacing.sm),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const StreamSkeletonBox.circular(radius: 24),
SizedBox(width: context.streamSpacing.sm),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
flex: 2,
child: StreamSkeletonBox(
width: double.infinity,
height: 12,
borderRadius: BorderRadius.all(context.streamRadius.max),
),
),
SizedBox(width: context.streamSpacing.sm),
const Spacer(
flex: 2,
),
StreamSkeletonBox(
width: 48,
height: 16,
borderRadius: BorderRadius.all(context.streamRadius.max),
),
],
),
SizedBox(height: context.streamSpacing.xs),
Row(
children: [
Expanded(
child: StreamSkeletonBox(
width: double.infinity,
height: 20,
borderRadius: BorderRadius.all(context.streamRadius.max),
),
),
SizedBox(width: context.streamSpacing.sm),
const SizedBox(width: 48),
],
),
SizedBox(height: context.streamSpacing.xs),
Row(
children: [
const StreamSkeletonBox.circular(radius: 12),
SizedBox(width: context.streamSpacing.xs),
StreamSkeletonBox(
width: 64,
height: 12,
borderRadius: BorderRadius.all(context.streamRadius.max),
),
SizedBox(width: context.streamSpacing.xs),
StreamSkeletonBox(
width: 64,
height: 12,
borderRadius: BorderRadius.all(context.streamRadius.max),
),
],
),
],
),
),
],
),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/src/scroll_view/stream_scroll_view_error_widget.dart';
import 'package:stream_chat_flutter/src/scroll_view/stream_scroll_view_load_more_error.dart';
import 'package:stream_chat_flutter/src/scroll_view/stream_scroll_view_load_more_indicator.dart';
import 'package:stream_chat_flutter/src/scroll_view/stream_scroll_view_loading_widget.dart';
import 'package:stream_chat_flutter/src/scroll_view/thread_scroll_view/stream_thread_list_skeleton_loading.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';

/// Default separator builder for [StreamThreadListView].
Expand Down Expand Up @@ -342,7 +342,7 @@ class StreamThreadListView extends StatelessWidget {
loadingBuilder: (context) =>
loadingBuilder?.call(context) ??
const Center(
child: StreamScrollViewLoadingWidget(),
child: StreamThreadListSkeletonLoading(),
),
errorBuilder: (context, error) =>
errorBuilder?.call(context, error) ??
Expand Down
2 changes: 1 addition & 1 deletion packages/stream_chat_flutter/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ dependencies:
stream_core_flutter:
git:
url: https://github.com/GetStream/stream-core-flutter.git
ref: 8057a775c2ed764dbd5cbabd2dd60d3cd68d2f08
ref: 226389ad533276d8daf2e03b90ed4cb3bfeecde3
path: packages/stream_core_flutter
svg_icon_widget: ^0.0.1
synchronized: ^3.1.0+1
Expand Down
Loading