Merge branch 'develop' into v4

This commit is contained in:
Salvatore Giordano
2022-04-13 14:31:44 +02:00
17 changed files with 427 additions and 46 deletions
+3 -1
View File
@@ -8,7 +8,7 @@
- Minor fixes and improvements.
## Upcoming
## 3.6.0
🐞 Fixed
@@ -19,10 +19,12 @@
channel update.
- [[#1054]](https://github.com/GetStream/stream-chat-flutter/issues/1054) Fix `Unsupported operation: Cannot remove from an unmodifiable list`.
- [[#1033]](https://github.com/GetStream/stream-chat-flutter/issues/1033) Hard delete from dashboard does not delete message from client.
- Send only `user_id` while reconnecting.
✅ Added
- Handle `event.message` in `channel.truncate` events
- Added additional parameters to `channel.truncate`
## 3.5.1
@@ -1055,10 +1055,23 @@ class Channel {
return _client.deleteChannel(id!, type);
}
/// Removes all messages from the channel.
Future<EmptyResponse> truncate() async {
/// Removes all messages from the channel up to [truncatedAt] or now if
/// [truncatedAt] is not provided.
/// If [skipPush] is true, no push notification will be sent.
/// [Message] is the system message that will be sent to the channel.
Future<EmptyResponse> truncate({
Message? message,
bool? skipPush,
DateTime? truncatedAt,
}) async {
_checkInitialized();
return _client.truncateChannel(id!, type);
return _client.truncateChannel(
id!,
type,
message: message,
skipPush: skipPush,
truncatedAt: truncatedAt,
);
}
/// Accept invitation to the channel.
@@ -328,7 +328,9 @@ class StreamChatClient {
_chatPersistenceClient = _originalChatPersistenceClient;
await _chatPersistenceClient!.connect(ownUser.id);
}
final connectedUser = await openConnection();
final connectedUser = await openConnection(
includeUserDetailsInConnectCall: true,
);
return state.currentUser = connectedUser;
} catch (e, stk) {
if (e is StreamWebSocketError && e.isRetriable) {
@@ -341,7 +343,11 @@ class StreamChatClient {
}
/// Creates a new WebSocket connection with the current user.
Future<OwnUser> openConnection() async {
/// If [includeUserDetailsInConnectCall] is true it will include the current
/// user details in the connect call.
Future<OwnUser> openConnection({
bool includeUserDetailsInConnectCall = false,
}) async {
assert(
state.currentUser != null,
'User is not set on client, '
@@ -371,7 +377,10 @@ class StreamChatClient {
_ws.connectionStatusStream.skip(1).listen(_connectionStatusHandler);
try {
final event = await _ws.connect(user);
final event = await _ws.connect(
user,
includeUserDetails: includeUserDetailsInConnectCall,
);
return user.merge(event.me);
} catch (e, stk) {
logger.severe('error connecting ws', e, stk);
@@ -940,14 +949,23 @@ class StreamChatClient {
channelType,
);
/// Removes all messages from the channel
/// Removes all messages from the channel up to [truncatedAt] or now if
/// [truncatedAt] is not provided.
/// If [skipPush] is true, no push notification will be sent.
/// [Message] is the system message that will be sent to the channel.
Future<EmptyResponse> truncateChannel(
String channelId,
String channelType,
) =>
String channelType, {
Message? message,
bool? skipPush,
DateTime? truncatedAt,
}) =>
_chatApi.channel.truncateChannel(
channelId,
channelType,
message: message,
skipPush: skipPush,
truncatedAt: truncatedAt,
);
/// Mutes the channel
@@ -265,11 +265,18 @@ class ChannelApi {
/// Removes all messages from the channel
Future<EmptyResponse> truncateChannel(
String channelId,
String channelType,
) async {
String channelType, {
Message? message,
bool? skipPush,
DateTime? truncatedAt,
}) async {
final response = await _client.post(
'${_getChannelUrl(channelId, channelType)}/truncate',
data: {},
data: {
if (message != null) 'message': message,
if (skipPush != null) 'skip_push': skipPush,
if (truncatedAt != null) 'truncated_at': truncatedAt,
},
);
return EmptyResponse.fromJson(response.data);
}
+16 -5
View File
@@ -147,12 +147,15 @@ class WebSocket with TimerHelper {
}
}
Future<Uri> _buildUri({bool refreshToken = false}) async {
Future<Uri> _buildUri({
bool refreshToken = false,
bool includeUserDetails = true,
}) async {
final user = _user!;
final token = await tokenManager.loadToken(refresh: refreshToken);
final params = {
'user_id': user.id,
'user_details': user,
if (includeUserDetails) 'user_details': user,
'user_token': token.rawValue,
'server_determines_connection_id': true,
};
@@ -176,7 +179,10 @@ class WebSocket with TimerHelper {
bool _connectRequestInProgress = false;
/// Connect the WS using the parameters passed in the constructor
Future<Event> connect(User user) async {
Future<Event> connect(
User user, {
bool includeUserDetails = false,
}) async {
if (_connectRequestInProgress) {
throw const StreamWebSocketError('''
You've called connect twice,
@@ -191,7 +197,9 @@ class WebSocket with TimerHelper {
connectionCompleter = Completer<Event>();
try {
final uri = await _buildUri();
final uri = await _buildUri(
includeUserDetails: includeUserDetails,
);
_initWebSocketChannel(uri);
} catch (e, stk) {
_onConnectionError(e, stk);
@@ -219,7 +227,10 @@ class WebSocket with TimerHelper {
setTimer(
Duration(milliseconds: delay),
() async {
final uri = await _buildUri(refreshToken: refreshToken);
final uri = await _buildUri(
refreshToken: refreshToken,
includeUserDetails: false,
);
try {
_initWebSocketChannel(uri);
} catch (e, stk) {
+8 -2
View File
@@ -124,7 +124,10 @@ class FakeWebSocket extends Fake implements WebSocket {
Completer<Event>? connectionCompleter;
@override
Future<Event> connect(User user) async {
Future<Event> connect(
User user, {
bool? includeUserDetails = true,
}) async {
connectionStatus = ConnectionStatus.connecting;
final event = Event(
type: EventType.healthCheck,
@@ -167,7 +170,10 @@ class FakeWebSocketWithConnectionError extends Fake implements WebSocket {
Completer<Event>? connectionCompleter;
@override
Future<Event> connect(User user) async {
Future<Event> connect(
User user, {
bool? includeUserDetails = true,
}) async {
connectionStatus = ConnectionStatus.connecting;
const error = StreamWebSocketError('Error Connecting');
connectionCompleter = Completer()..completeError(error);
@@ -14,10 +14,14 @@
- Added OpenGraph preview support for links in `StreamMessageInput`.
- Removed video compression.
## 3.6.0
🐞 Fixed
- Minor fixes and improvements
-[[#892]](https://github.com/GetStream/stream-chat-flutter/issues/892): Fix default `initialAlignment` in `MessageListView`.
- Fix `MessageInputTheme.inputBackgroundColor` color not being used in some widgets of `MessageInput`
- Removed dependency on `visibility_detector`
## 3.5.1
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
@@ -6,7 +6,6 @@ import 'dart:async';
import 'dart:math';
import 'package:collection/collection.dart' show IterableExtension;
import 'package:flutter/foundation.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
@@ -470,6 +470,7 @@ class MessageInputState extends State<MessageInput> {
if (widget.editMessage == null) {
child = Material(
elevation: 8,
color: _messageInputTheme.inputBackgroundColor,
child: child,
);
}
@@ -669,6 +670,7 @@ class MessageInputState extends State<MessageInput> {
gradient: _focusNode.hasFocus
? _messageInputTheme.activeBorderGradient
: _messageInputTheme.idleBorderGradient,
color: _messageInputTheme.inputBackgroundColor,
),
child: Padding(
padding: const EdgeInsets.all(1.5),
@@ -8,7 +8,6 @@ import 'package:stream_chat_flutter/scrollable_positioned_list/scrollable_positi
import 'package:stream_chat_flutter/src/extension.dart';
import 'package:stream_chat_flutter/src/swipeable.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
import 'package:visibility_detector/visibility_detector.dart';
/// Widget builder for message
/// [defaultMessageWidget] is the default [StreamMessageWidget] configuration
@@ -975,26 +974,7 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
int index,
) {
final messageWidget = buildMessage(message, messages, index);
return VisibilityDetector(
key: ValueKey('visibility: ${message.id}'),
onVisibilityChanged: (visibility) {
final isVisible = visibility.visibleBounds != Rect.zero;
if (isVisible) {
final channel = streamChannel.channel;
if (_upToDate &&
channel.config?.readEvents == true &&
channel.state!.unreadCount > 0) {
streamChannel.channel.markRead();
}
}
if (mounted) {
if (_showScrollToBottom.value == isVisible) {
_showScrollToBottom.value = !isVisible;
}
}
},
child: messageWidget,
);
return messageWidget;
}
Widget buildParentMessage(
@@ -1316,6 +1296,8 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
_scrollController = widget.scrollController ?? ItemScrollController();
_itemPositionListener =
widget.itemPositionListener ?? ItemPositionsListener.create();
_itemPositionListener.itemPositions
.addListener(_handleItemPositionsChanged);
_getOnThreadTap();
super.initState();
@@ -1365,6 +1347,34 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
super.didChangeDependencies();
}
void _handleItemPositionsChanged() {
final _itemPositions = _itemPositionListener.itemPositions.value.toList();
final _firstItemIndex =
_itemPositions.indexWhere((element) => element.index == 1);
var _isFirstItemVisible = false;
if (_firstItemIndex != -1) {
final _firstItem = _itemPositions[_firstItemIndex];
_isFirstItemVisible =
_firstItem.itemLeadingEdge > 0 && _firstItem.itemTrailingEdge < 1;
}
if (_isFirstItemVisible) {
// most recent message is visible
final channel = streamChannel?.channel;
if (channel != null) {
if (_upToDate &&
channel.config?.readEvents == true &&
channel.state!.unreadCount > 0) {
streamChannel!.channel.markRead();
}
}
}
if (mounted) {
if (_showScrollToBottom.value == _isFirstItemVisible) {
_showScrollToBottom.value = !_isFirstItemVisible;
}
}
}
void _getOnThreadTap() {
if (widget.onThreadTap != null) {
_onThreadTap = (Message message) {
@@ -1402,6 +1412,8 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
streamChannel!.reloadChannel();
}
_messageNewListener?.cancel();
_itemPositionListener.itemPositions
.removeListener(_handleItemPositionsChanged);
super.dispose();
}
}
+1 -2
View File
@@ -40,8 +40,7 @@ dependencies:
substring_highlight: ^1.0.26
url_launcher: ^6.0.3
video_player: ^2.1.0
video_thumbnail: ^0.4.3
visibility_detector: ^0.2.0
video_thumbnail: ^0.5.0
flutter:
assets:
@@ -9,6 +9,10 @@
- Updated `stream_chat` dependency to [`4.0.0-beta.0`](https://pub.dev/packages/stream_chat/changelog).
## 3.6.0
- Updated `stream_chat` dependency to [`3.6.0`](https://pub.dev/packages/stream_chat/changelog).
## 3.5.1
- Updated `stream_chat` dependency to [`3.5.1`](https://pub.dev/packages/stream_chat/changelog).