Merge pull request #1712 from GetStream/release/v6.9.0
This commit is contained in:
@@ -3,7 +3,7 @@ name: legacy_version_analyze
|
|||||||
env:
|
env:
|
||||||
# Note: The versions below should be manually updated after a new stable
|
# Note: The versions below should be manually updated after a new stable
|
||||||
# version comes out.
|
# version comes out.
|
||||||
flutter_version: "3.7.12"
|
flutter_version: "3.10.6"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ name: stream_flutter_workflow
|
|||||||
|
|
||||||
env:
|
env:
|
||||||
ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'
|
ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'
|
||||||
flutter_version: "3.10.4"
|
flutter_channel: "stable"
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
@@ -37,7 +37,7 @@ jobs:
|
|||||||
uses: subosito/flutter-action@v2
|
uses: subosito/flutter-action@v2
|
||||||
with:
|
with:
|
||||||
cache: true
|
cache: true
|
||||||
flutter-version: ${{ env.flutter_version }}
|
channel: ${{ env.flutter_channel }}
|
||||||
- name: "Install Tools"
|
- name: "Install Tools"
|
||||||
run: |
|
run: |
|
||||||
flutter pub global activate melos
|
flutter pub global activate melos
|
||||||
|
|||||||
@@ -1,3 +1,18 @@
|
|||||||
|
## 6.8.0
|
||||||
|
|
||||||
|
🐞 Fixed
|
||||||
|
|
||||||
|
- Fixed `Channel.query` not initializing `ChannelState`.
|
||||||
|
|
||||||
|
✅ Added
|
||||||
|
|
||||||
|
- Added support for `channel.countUnreadMentions()` to get the count of unread messages mentioning the current user on a
|
||||||
|
channel. [#1692](https://github.com/GetStream/stream-chat-flutter/issues/1692)
|
||||||
|
|
||||||
|
🔄 Changed
|
||||||
|
|
||||||
|
- Updated minimum supported `SDK` version to Dart 3.0
|
||||||
|
|
||||||
## 6.7.0
|
## 6.7.0
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ publish_to: "none"
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.19.0 <4.0.0'
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.10.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
cupertino_icons: ^1.0.5
|
cupertino_icons: ^1.0.5
|
||||||
|
|||||||
@@ -1339,26 +1339,6 @@ class Channel {
|
|||||||
return _client.markChannelRead(id!, type, messageId: messageId);
|
return _client.markChannelRead(id!, type, messageId: messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Loads the initial channel state and watches for changes.
|
|
||||||
Future<ChannelState> watch({bool presence = false}) async {
|
|
||||||
ChannelState response;
|
|
||||||
|
|
||||||
try {
|
|
||||||
response = await query(watch: true, presence: presence);
|
|
||||||
} catch (error, stackTrace) {
|
|
||||||
if (!_initializedCompleter.isCompleted) {
|
|
||||||
_initializedCompleter.completeError(error, stackTrace);
|
|
||||||
}
|
|
||||||
rethrow;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == null) {
|
|
||||||
_initState(response);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _initState(ChannelState channelState) {
|
void _initState(ChannelState channelState) {
|
||||||
state = ChannelClientState(this, channelState);
|
state = ChannelClientState(this, channelState);
|
||||||
|
|
||||||
@@ -1370,6 +1350,22 @@ class Channel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Loads the initial channel state and watches for changes.
|
||||||
|
Future<ChannelState> watch({
|
||||||
|
bool presence = false,
|
||||||
|
PaginationParams? messagesPagination,
|
||||||
|
PaginationParams? membersPagination,
|
||||||
|
PaginationParams? watchersPagination,
|
||||||
|
}) {
|
||||||
|
return query(
|
||||||
|
watch: true,
|
||||||
|
presence: presence,
|
||||||
|
messagesPagination: messagesPagination,
|
||||||
|
membersPagination: membersPagination,
|
||||||
|
watchersPagination: watchersPagination,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Stop watching the channel.
|
/// Stop watching the channel.
|
||||||
Future<EmptyResponse> stopWatching() async {
|
Future<EmptyResponse> stopWatching() async {
|
||||||
_checkInitialized();
|
_checkInitialized();
|
||||||
@@ -1435,7 +1431,7 @@ class Channel {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/// Creates a new channel.
|
/// Creates a new channel.
|
||||||
Future<ChannelState> create() async => query(state: false);
|
Future<ChannelState> create() => query(state: false);
|
||||||
|
|
||||||
/// Query the API, get messages, members or other channel fields.
|
/// Query the API, get messages, members or other channel fields.
|
||||||
///
|
///
|
||||||
@@ -1450,23 +1446,28 @@ class Channel {
|
|||||||
PaginationParams? watchersPagination,
|
PaginationParams? watchersPagination,
|
||||||
bool preferOffline = false,
|
bool preferOffline = false,
|
||||||
}) async {
|
}) async {
|
||||||
if (preferOffline && cid != null) {
|
ChannelState? channelState;
|
||||||
final updatedState = await _client.chatPersistenceClient
|
|
||||||
?.getChannelStateByCid(cid!, messagePagination: messagesPagination);
|
|
||||||
if (updatedState != null &&
|
|
||||||
updatedState.messages != null &&
|
|
||||||
updatedState.messages!.isNotEmpty) {
|
|
||||||
if (this.state == null) {
|
|
||||||
_initState(updatedState);
|
|
||||||
} else {
|
|
||||||
this.state?.updateChannelState(updatedState);
|
|
||||||
}
|
|
||||||
return updatedState;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final updatedState = await _client.queryChannel(
|
// If we prefer offline, we first try to get the channel state from the
|
||||||
|
// offline storage.
|
||||||
|
if (preferOffline && !watch && cid != null) {
|
||||||
|
final persistenceClient = _client.chatPersistenceClient;
|
||||||
|
if (persistenceClient != null) {
|
||||||
|
final cachedState = await persistenceClient.getChannelStateByCid(
|
||||||
|
cid!,
|
||||||
|
messagePagination: messagesPagination,
|
||||||
|
);
|
||||||
|
|
||||||
|
// If the cached state contains messages, we can use it.
|
||||||
|
if (cachedState.messages?.isNotEmpty == true) {
|
||||||
|
channelState = cachedState;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we still don't have the channelState, we try to get it from the API.
|
||||||
|
channelState ??= await _client.queryChannel(
|
||||||
type,
|
type,
|
||||||
channelId: id,
|
channelId: id,
|
||||||
channelData: _extraData,
|
channelData: _extraData,
|
||||||
@@ -1479,18 +1480,35 @@ class Channel {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (_id == null) {
|
if (_id == null) {
|
||||||
_id = updatedState.channel!.id;
|
_id = channelState.channel!.id;
|
||||||
_cid = updatedState.channel!.cid;
|
_cid = channelState.channel!.cid;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.state?.updateChannelState(updatedState);
|
// Initialize the channel state if it's not initialized yet.
|
||||||
return updatedState;
|
if (this.state == null) {
|
||||||
} catch (e) {
|
_initState(channelState);
|
||||||
if (_client.persistenceEnabled) {
|
} else {
|
||||||
return _client.chatPersistenceClient!.getChannelStateByCid(
|
// Otherwise, update the channel state.
|
||||||
cid!,
|
this.state?.updateChannelState(channelState);
|
||||||
messagePagination: messagesPagination,
|
}
|
||||||
);
|
|
||||||
|
return channelState;
|
||||||
|
} catch (e, stk) {
|
||||||
|
// If we failed to get the channel state from the API and we were not
|
||||||
|
// supposed to watch the channel, we will try to get the channel state
|
||||||
|
// from the offline storage.
|
||||||
|
if (watch == false) {
|
||||||
|
if (_client.persistenceEnabled) {
|
||||||
|
return _client.chatPersistenceClient!.getChannelStateByCid(
|
||||||
|
cid!,
|
||||||
|
messagePagination: messagesPagination,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, we will just rethrow the error.
|
||||||
|
if (!_initializedCompleter.isCompleted) {
|
||||||
|
_initializedCompleter.completeError(e, stk);
|
||||||
}
|
}
|
||||||
|
|
||||||
rethrow;
|
rethrow;
|
||||||
@@ -2334,6 +2352,26 @@ class ChannelClientState {
|
|||||||
!isThreadMessage;
|
!isThreadMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Counts the number of unread messages mentioning the current user.
|
||||||
|
///
|
||||||
|
/// **NOTE**: The method relies on the [Channel.messages] list and doesn't do
|
||||||
|
/// any API call. Therefore, the count might be not reliable as it relies on
|
||||||
|
/// the local data.
|
||||||
|
int countUnreadMentions() {
|
||||||
|
final lastRead = currentUserRead?.lastRead;
|
||||||
|
final userId = _channel.client.state.currentUser?.id;
|
||||||
|
|
||||||
|
var count = 0;
|
||||||
|
for (final message in messages) {
|
||||||
|
if (_countMessageAsUnread(message) &&
|
||||||
|
(lastRead == null || message.createdAt.isAfter(lastRead)) &&
|
||||||
|
message.mentionedUsers.any((user) => user.id == userId) == true) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
/// Update threads with updated information about messages.
|
/// Update threads with updated information about messages.
|
||||||
void updateThreadInfo(String parentId, List<Message> messages) {
|
void updateThreadInfo(String parentId, List<Message> messages) {
|
||||||
final newThreads = Map<String, List<Message>>.from(threads);
|
final newThreads = Map<String, List<Message>>.from(threads);
|
||||||
|
|||||||
@@ -1696,7 +1696,7 @@ class ClientState {
|
|||||||
void updateUsers(List<User?> userList) {
|
void updateUsers(List<User?> userList) {
|
||||||
final newUsers = {
|
final newUsers = {
|
||||||
...users,
|
...users,
|
||||||
for (var user in userList)
|
for (final user in userList)
|
||||||
if (user != null) user.id: user,
|
if (user != null) user.id: user,
|
||||||
};
|
};
|
||||||
_usersController.add(newUsers);
|
_usersController.add(newUsers);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'dart:async';
|
|||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
///
|
///
|
||||||
class TimerHelper {
|
mixin class TimerHelper {
|
||||||
final _uuid = const Uuid();
|
final _uuid = const Uuid();
|
||||||
late final _timers = <String, Timer>{};
|
late final _timers = <String, Timer>{};
|
||||||
|
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ import 'package:stream_chat/src/client/client.dart';
|
|||||||
/// Current package version
|
/// Current package version
|
||||||
/// Used in [StreamChatClient] to build the `x-stream-client` header
|
/// Used in [StreamChatClient] to build the `x-stream-client` header
|
||||||
// ignore: constant_identifier_names
|
// ignore: constant_identifier_names
|
||||||
const PACKAGE_VERSION = '6.7.0';
|
const PACKAGE_VERSION = '6.8.0';
|
||||||
|
|||||||
@@ -1,24 +1,24 @@
|
|||||||
name: stream_chat
|
name: stream_chat
|
||||||
homepage: https://getstream.io/
|
homepage: https://getstream.io/
|
||||||
description: The official Dart client for Stream Chat, a service for building chat applications.
|
description: The official Dart client for Stream Chat, a service for building chat applications.
|
||||||
version: 6.7.0
|
version: 6.8.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.19.0 <4.0.0'
|
sdk: '>=3.0.0 <4.0.0'
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
async: ^2.10.0
|
async: ^2.11.0
|
||||||
collection: ^1.17.0
|
collection: ^1.17.1
|
||||||
dio: ^5.2.1+1
|
dio: ^5.3.2
|
||||||
equatable: ^2.0.5
|
equatable: ^2.0.5
|
||||||
freezed_annotation: ^2.2.0
|
freezed_annotation: ^2.4.1
|
||||||
http_parser: ^4.0.2
|
http_parser: ^4.0.2
|
||||||
jose: ^0.3.3
|
jose: ^0.3.4
|
||||||
json_annotation: ^4.8.1
|
json_annotation: ^4.8.1
|
||||||
logging: ^1.2.0
|
logging: ^1.2.0
|
||||||
meta: ^1.8.0
|
meta: ^1.9.1
|
||||||
mime: ^1.0.4
|
mime: ^1.0.4
|
||||||
rate_limiter: ^1.0.0
|
rate_limiter: ^1.0.0
|
||||||
rxdart: ^0.27.7
|
rxdart: ^0.27.7
|
||||||
@@ -27,8 +27,8 @@ dependencies:
|
|||||||
web_socket_channel: ^2.4.0
|
web_socket_channel: ^2.4.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.3.3
|
build_runner: ^2.4.6
|
||||||
freezed: ^2.4.0
|
freezed: ^2.4.2
|
||||||
json_serializable: ^6.6.2
|
json_serializable: ^6.7.1
|
||||||
mocktail: ^0.3.0
|
mocktail: ^1.0.0
|
||||||
test: ^1.24.3
|
test: ^1.24.6
|
||||||
|
|||||||
@@ -975,7 +975,7 @@ void main() {
|
|||||||
// skipping initial seed event -> {} users
|
// skipping initial seed event -> {} users
|
||||||
client.state.usersStream.skip(1),
|
client.state.usersStream.skip(1),
|
||||||
emitsInOrder([
|
emitsInOrder([
|
||||||
{for (var user in users) user.id: user},
|
{for (final user in users) user.id: user},
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
+2
@@ -1,3 +1,5 @@
|
|||||||
|
// ignore_for_file: invalid_use_of_protected_member
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:stream_chat/src/core/http/interceptor/additional_headers_interceptor.dart';
|
import 'package:stream_chat/src/core/http/interceptor/additional_headers_interceptor.dart';
|
||||||
import 'package:stream_chat/stream_chat.dart';
|
import 'package:stream_chat/stream_chat.dart';
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// ignore_for_file: invalid_use_of_protected_member
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:mocktail/mocktail.dart';
|
import 'package:mocktail/mocktail.dart';
|
||||||
import 'package:stream_chat/src/core/http/interceptor/auth_interceptor.dart';
|
import 'package:stream_chat/src/core/http/interceptor/auth_interceptor.dart';
|
||||||
|
|||||||
+2
@@ -1,3 +1,5 @@
|
|||||||
|
// ignore_for_file: invalid_use_of_protected_member
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:mocktail/mocktail.dart';
|
import 'package:mocktail/mocktail.dart';
|
||||||
import 'package:stream_chat/src/core/http/connection_id_manager.dart';
|
import 'package:stream_chat/src/core/http/connection_id_manager.dart';
|
||||||
|
|||||||
@@ -1,3 +1,38 @@
|
|||||||
|
## 6.9.0
|
||||||
|
|
||||||
|
🐞 Fixed
|
||||||
|
|
||||||
|
- [[#1702]](https://github.com/GetStream/stream-chat-flutter/issues/1702)
|
||||||
|
Fixed `Message.replaceMentions` not treating `@usernames` as mentions.
|
||||||
|
- [[#1694]](https://github.com/GetStream/stream-chat-flutter/issues/1694) Fixed Video player buttons
|
||||||
|
getting covered by bottom toolbar.
|
||||||
|
|
||||||
|
✅ Added
|
||||||
|
|
||||||
|
- Added support for listening error events in AttachmentPickerBottomSheet.
|
||||||
|
- Added support for overriding the `MessageWidget.onReactionTap` callback.
|
||||||
|
- Added support for `StreamMessageInput.contentInsertionConfiguration` to specify the content insertion configuration.
|
||||||
|
[#1613](https://github.com/GetStream/stream-chat-flutter/issues/1613)
|
||||||
|
|
||||||
|
```dart
|
||||||
|
StreamMessageInput(
|
||||||
|
...,
|
||||||
|
contentInsertionConfiguration: ContentInsertionConfiguration(
|
||||||
|
onContentInserted: (content) {
|
||||||
|
// Do something with the content.
|
||||||
|
controller.addAttachment(...);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
🔄 Changed
|
||||||
|
|
||||||
|
- Updated minimum supported `SDK` version to Flutter 3.10/Dart 3.0
|
||||||
|
- Updated `stream_chat_flutter_core` dependency
|
||||||
|
to [`6.8.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||||
|
- Updated jiffy dependency to ^6.2.1.
|
||||||
|
|
||||||
## 6.8.1
|
## 6.8.1
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
@@ -28,43 +63,57 @@
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#1620]](https://github.com/GetStream/stream-chat-flutter/issues/1620) Fixed messages Are Not Hard Deleting even
|
- [[#1620]](https://github.com/GetStream/stream-chat-flutter/issues/1620) Fixed messages Are Not
|
||||||
|
Hard Deleting even
|
||||||
after overriding the `onConfirmDeleteTap` callback.
|
after overriding the `onConfirmDeleteTap` callback.
|
||||||
- [[#1621]](https://github.com/GetStream/stream-chat-flutter/issues/1621) Fixed `createdAtStyle` null check error
|
- [[#1621]](https://github.com/GetStream/stream-chat-flutter/issues/1621) Fixed `createdAtStyle`
|
||||||
|
null check error
|
||||||
in `SendingIndicatorBuilder`.
|
in `SendingIndicatorBuilder`.
|
||||||
- [[#1069]](https://github.com/GetStream/stream-chat-flutter/issues/1069) Fixed message swipe to reply using same
|
- [[#1069]](https://github.com/GetStream/stream-chat-flutter/issues/1069) Fixed message swipe to
|
||||||
direction for both current user and other users. It now uses `SwipeDirection.startToEnd` for current user
|
reply using same
|
||||||
|
direction for both current user and other users. It now uses `SwipeDirection.startToEnd` for
|
||||||
|
current user
|
||||||
and `SwipeDirection.endToStart` for other users.
|
and `SwipeDirection.endToStart` for other users.
|
||||||
- [[#1590]](https://github.com/GetStream/stream-chat-flutter/issues/1590)
|
- [[#1590]](https://github.com/GetStream/stream-chat-flutter/issues/1590)
|
||||||
Fixed `StreamMessageWidget.showReactionPickerIndicator` not toggling the reaction picker indicator visibility.
|
Fixed `StreamMessageWidget.showReactionPickerIndicator` not toggling the reaction picker indicator
|
||||||
- [[#1639]](https://github.com/GetStream/stream-chat-flutter/issues/1639) Fixed attachments not showing in gallery view
|
visibility.
|
||||||
|
- [[#1639]](https://github.com/GetStream/stream-chat-flutter/issues/1639) Fixed attachments not
|
||||||
|
showing in gallery view
|
||||||
even after saving them to the device.
|
even after saving them to the device.
|
||||||
> **Note**
|
> **Note**
|
||||||
> This fix depends on the [image_gallery_saver](https://pub.dev/packages/image_gallery_saver) plugin. Make sure to add
|
> This fix depends on the [image_gallery_saver](https://pub.dev/packages/image_gallery_saver)
|
||||||
|
plugin. Make sure to add
|
||||||
necessary permissions in your App as per the plugin documentation.
|
necessary permissions in your App as per the plugin documentation.
|
||||||
- [[#1642]](https://github.com/GetStream/stream-chat-flutter/issues/1642) Fixed `StreamMessageWidget.widthFactor` not
|
- [[#1642]](https://github.com/GetStream/stream-chat-flutter/issues/1642)
|
||||||
|
Fixed `StreamMessageWidget.widthFactor` not
|
||||||
working on web and desktop platforms.
|
working on web and desktop platforms.
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- Added support for customizing attachments in `StreamMessageInput`. Use various properties mentioned
|
- Added support for customizing attachments in `StreamMessageInput`. Use various properties
|
||||||
|
mentioned
|
||||||
below. [#1511](https://github.com/GetStream/stream-chat-flutter/issues/1511)
|
below. [#1511](https://github.com/GetStream/stream-chat-flutter/issues/1511)
|
||||||
* `StreamMessageInput.attachmentListBuilder` to customize the attachment list.
|
* `StreamMessageInput.attachmentListBuilder` to customize the attachment list.
|
||||||
* `StreamMessageInput.fileAttachmentListBuilder` to customize the file attachment list.
|
* `StreamMessageInput.fileAttachmentListBuilder` to customize the file attachment list.
|
||||||
* `StreamMessageInput.mediaAttachmentListBuilder` to customize the media attachment list. Includes images, videos
|
* `StreamMessageInput.mediaAttachmentListBuilder` to customize the media attachment list.
|
||||||
|
Includes images, videos
|
||||||
and gifs.
|
and gifs.
|
||||||
* `StreamMessageInput.fileAttachmentBuilder` to customize the file attachment item shown in `FileAttachmentList`.
|
* `StreamMessageInput.fileAttachmentBuilder` to customize the file attachment item shown
|
||||||
|
in `FileAttachmentList`.
|
||||||
* `StreamMessageInput.mediaAttachmentBuilder` to customize the media attachment item shown in
|
* `StreamMessageInput.mediaAttachmentBuilder` to customize the media attachment item shown in
|
||||||
`MediaAttachmentList`.
|
`MediaAttachmentList`.
|
||||||
|
|
||||||
|
|
||||||
- Added `StreamMessageInput.quotedMessageAttachmentThumbnailBuilders` to customize the thumbnail builders for quoted
|
- Added `StreamMessageInput.quotedMessageAttachmentThumbnailBuilders` to customize the thumbnail
|
||||||
|
builders for quoted
|
||||||
message attachments.
|
message attachments.
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|
||||||
- Deprecated `StreamMessageInput.attachmentThumbnailBuilders` in favor of `StreamMessageInput.mediaAttachmentBuilder`.
|
- Deprecated `StreamMessageInput.attachmentThumbnailBuilders` in favor
|
||||||
- Deprecated `StreamMessageListView.onMessageSwiped`. Try wrapping the `MessageWidget` with a `Swipeable`, `Dismissible`
|
of `StreamMessageInput.mediaAttachmentBuilder`.
|
||||||
|
- Deprecated `StreamMessageListView.onMessageSwiped`. Try wrapping the `MessageWidget` with
|
||||||
|
a `Swipeable`, `Dismissible`
|
||||||
or a custom widget to achieve the swipe to reply behaviour.
|
or a custom widget to achieve the swipe to reply behaviour.
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
@@ -112,7 +161,8 @@
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
- Deprecated `StreamMessageWidget.showReactionPickerIndicator` in favor of `StreamMessageWidget.showReactionPicker`.
|
- Deprecated `StreamMessageWidget.showReactionPickerIndicator` in favor
|
||||||
|
of `StreamMessageWidget.showReactionPicker`.
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
StreamMessageWidget(
|
StreamMessageWidget(
|
||||||
@@ -129,16 +179,20 @@
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#1600]](https://github.com/GetStream/stream-chat-flutter/issues/1600) Fixed type `ImageDecoderCallback` not found
|
- [[#1600]](https://github.com/GetStream/stream-chat-flutter/issues/1600) Fixed
|
||||||
|
type `ImageDecoderCallback` not found
|
||||||
error on pre-Flutter 3.10.0 versions.
|
error on pre-Flutter 3.10.0 versions.
|
||||||
- [[#1605]](https://github.com/GetStream/stream-chat-flutter/issues/1605) Fixed Null exception is thrown on message list
|
- [[#1605]](https://github.com/GetStream/stream-chat-flutter/issues/1605) Fixed Null exception is
|
||||||
|
thrown on message list
|
||||||
for unread messages when `ScrollToBottomButton` is pressed.
|
for unread messages when `ScrollToBottomButton` is pressed.
|
||||||
- [[#1615]](https://github.com/GetStream/stream-chat-flutter/issues/1615) Fixed `StreamAttachmentPickerBottomSheet` not
|
- [[#1615]](https://github.com/GetStream/stream-chat-flutter/issues/1615)
|
||||||
|
Fixed `StreamAttachmentPickerBottomSheet` not
|
||||||
able to find the `StreamChatTheme` when used in nested MaterialApp.
|
able to find the `StreamChatTheme` when used in nested MaterialApp.
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- Added support for `StreamMessageInput.allowedAttachmentPickerTypes` to specify the allowed attachment picker types.
|
- Added support for `StreamMessageInput.allowedAttachmentPickerTypes` to specify the allowed
|
||||||
|
attachment picker types.
|
||||||
[#1601](https://github.com/GetStream/stream-chat-flutter/issues/1376)
|
[#1601](https://github.com/GetStream/stream-chat-flutter/issues/1376)
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
@@ -151,7 +205,8 @@
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
- Added support for `StreamMessageWidget.onConfirmDeleteTap` to override the default action on delete confirmation.
|
- Added support for `StreamMessageWidget.onConfirmDeleteTap` to override the default action on
|
||||||
|
delete confirmation.
|
||||||
[#1604](https://github.com/GetStream/stream-chat-flutter/issues/1604)
|
[#1604](https://github.com/GetStream/stream-chat-flutter/issues/1604)
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
@@ -164,8 +219,10 @@
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
- Added support for `StreamMessageWidget.quotedMessageBuilder` and `StreamMessageInput.quotedMessageBuilder` to override
|
- Added support for `StreamMessageWidget.quotedMessageBuilder`
|
||||||
the default quoted message widget. [#1547](https://github.com/GetStream/stream-chat-flutter/issues/1547)
|
and `StreamMessageInput.quotedMessageBuilder` to override
|
||||||
|
the default quoted message
|
||||||
|
widget. [#1547](https://github.com/GetStream/stream-chat-flutter/issues/1547)
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
StreamMessageWidget(
|
StreamMessageWidget(
|
||||||
@@ -179,7 +236,8 @@
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
- Added support for `StreamChannelAvatar.ownSpaceAvatarBuilder`, `StreamChannelAvatar.oneToOneAvatarBuilder` and
|
- Added support
|
||||||
|
for `StreamChannelAvatar.ownSpaceAvatarBuilder`, `StreamChannelAvatar.oneToOneAvatarBuilder` and
|
||||||
`StreamChannelAvatar.groupAvatarBuilder` to override the default avatar
|
`StreamChannelAvatar.groupAvatarBuilder` to override the default avatar
|
||||||
widget.[#1614](https://github.com/GetStream/stream-chat-flutter/issues/1614)
|
widget.[#1614](https://github.com/GetStream/stream-chat-flutter/issues/1614)
|
||||||
|
|
||||||
@@ -211,10 +269,13 @@
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#1592]](https://github.com/GetStream/stream-chat-flutter/issues/1592) Fixed broken attachment download on web.
|
- [[#1592]](https://github.com/GetStream/stream-chat-flutter/issues/1592) Fixed broken attachment
|
||||||
- [[#1591]](https://github.com/GetStream/stream-chat-flutter/issues/1591) Fixed `StreamChannelInfoBottomSheet` not
|
download on web.
|
||||||
|
- [[#1591]](https://github.com/GetStream/stream-chat-flutter/issues/1591)
|
||||||
|
Fixed `StreamChannelInfoBottomSheet` not
|
||||||
rendering member list properly.
|
rendering member list properly.
|
||||||
- [[#1427]](https://github.com/GetStream/stream-chat-flutter/issues/1427) Fixed unable to load asset error for
|
- [[#1427]](https://github.com/GetStream/stream-chat-flutter/issues/1427) Fixed unable to load asset
|
||||||
|
error for
|
||||||
`packages/stream_chat_flutter/lib/svgs/video_call_icon.svg`.
|
`packages/stream_chat_flutter/lib/svgs/video_call_icon.svg`.
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
@@ -227,30 +288,40 @@
|
|||||||
|
|
||||||
- [[#1546]](https://github.com/GetStream/stream-chat-flutter/issues/1546)
|
- [[#1546]](https://github.com/GetStream/stream-chat-flutter/issues/1546)
|
||||||
Fixed `StreamMessageInputTheme.linkHighlightColor` returning null for default theme.
|
Fixed `StreamMessageInputTheme.linkHighlightColor` returning null for default theme.
|
||||||
- [[#1548]](https://github.com/GetStream/stream-chat-flutter/issues/1548) Fixed `StreamMessageInput` urlRegex only
|
- [[#1548]](https://github.com/GetStream/stream-chat-flutter/issues/1548) Fixed `StreamMessageInput`
|
||||||
|
urlRegex only
|
||||||
matching the lowercase `http(s)|ftp`.
|
matching the lowercase `http(s)|ftp`.
|
||||||
- [[#1542]](https://github.com/GetStream/stream-chat-flutter/issues/1542) Handle error thrown in `StreamMessageInput`
|
- [[#1542]](https://github.com/GetStream/stream-chat-flutter/issues/1542) Handle error thrown
|
||||||
|
in `StreamMessageInput`
|
||||||
when unable to fetch a link preview.
|
when unable to fetch a link preview.
|
||||||
- [[#1540]](https://github.com/GetStream/stream-chat-flutter/issues/1540) Use `CircularProgressIndicator.adaptive`
|
- [[#1540]](https://github.com/GetStream/stream-chat-flutter/issues/1540)
|
||||||
|
Use `CircularProgressIndicator.adaptive`
|
||||||
instead of material indicator.
|
instead of material indicator.
|
||||||
- [[#1490]](https://github.com/GetStream/stream-chat-flutter/issues/1490) Fixed `editMessageInputBuilder` property not
|
- [[#1490]](https://github.com/GetStream/stream-chat-flutter/issues/1490)
|
||||||
|
Fixed `editMessageInputBuilder` property not
|
||||||
used in `MessageActionsModal.editMessage` option.
|
used in `MessageActionsModal.editMessage` option.
|
||||||
- [[#1544]](https://github.com/GetStream/stream-chat-flutter/issues/1544) Fixed error thrown when unable to fetch
|
- [[#1544]](https://github.com/GetStream/stream-chat-flutter/issues/1544) Fixed error thrown when
|
||||||
|
unable to fetch
|
||||||
image/data in Message link preview.
|
image/data in Message link preview.
|
||||||
- [[#1482]](https://github.com/GetStream/stream-chat-flutter/issues/1482) Fixed `StreaChannelListTile` not showing
|
- [[#1482]](https://github.com/GetStream/stream-chat-flutter/issues/1482)
|
||||||
|
Fixed `StreaChannelListTile` not showing
|
||||||
unread indicator when `currentUser` is not present in the initial member list.
|
unread indicator when `currentUser` is not present in the initial member list.
|
||||||
- [[#1487]](https://github.com/GetStream/stream-chat-flutter/issues/1487) Use localized title
|
- [[#1487]](https://github.com/GetStream/stream-chat-flutter/issues/1487) Use localized title
|
||||||
for `WebOrDesktopAttachmentPickerOption` in `StreamMessageInput`.
|
for `WebOrDesktopAttachmentPickerOption` in `StreamMessageInput`.
|
||||||
- [[#1250]](https://github.com/GetStream/stream-chat-flutter/issues/1250) Fixed bottomRow widgetSpans getting resized
|
- [[#1250]](https://github.com/GetStream/stream-chat-flutter/issues/1250) Fixed bottomRow
|
||||||
|
widgetSpans getting resized
|
||||||
twice when `textScaling` is enabled.
|
twice when `textScaling` is enabled.
|
||||||
- [[#1498]](https://github.com/GetStream/stream-chat-flutter/issues/1498) Fixed `MessageInput` autocomplete not working
|
- [[#1498]](https://github.com/GetStream/stream-chat-flutter/issues/1498) Fixed `MessageInput`
|
||||||
|
autocomplete not working
|
||||||
on non-mobile platforms.
|
on non-mobile platforms.
|
||||||
- [[#1576]](https://github.com/GetStream/stream-chat-flutter/issues/1576) Temporary fix for `StreamMessageListView`
|
- [[#1576]](https://github.com/GetStream/stream-chat-flutter/issues/1576) Temporary fix
|
||||||
|
for `StreamMessageListView`
|
||||||
getting broken when loaded at a particular message and a new message is added.
|
getting broken when loaded at a particular message and a new message is added.
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- Added support for `StreamMessageThemeData.urlAttachmentTextMaxLine` to specify the `.maxLines` for the url attachment
|
- Added support for `StreamMessageThemeData.urlAttachmentTextMaxLine` to specify the `.maxLines` for
|
||||||
|
the url attachment
|
||||||
text. [#1543](https://github.com/GetStream/stream-chat-flutter/issues/1543)
|
text. [#1543](https://github.com/GetStream/stream-chat-flutter/issues/1543)
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
@@ -265,24 +336,33 @@
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#1502]](https://github.com/GetStream/stream-chat-flutter/issues/1502) Fixed `isOnlyEmoji` method Detects Single
|
- [[#1502]](https://github.com/GetStream/stream-chat-flutter/issues/1502) Fixed `isOnlyEmoji` method
|
||||||
|
Detects Single
|
||||||
Hangul
|
Hangul
|
||||||
Consonants as Emoji.
|
Consonants as Emoji.
|
||||||
- [[#1505]](https://github.com/GetStream/stream-chat-flutter/issues/1505) Fixed Message bubble disappears for Hangul
|
- [[#1505]](https://github.com/GetStream/stream-chat-flutter/issues/1505) Fixed Message bubble
|
||||||
|
disappears for Hangul
|
||||||
Consonants.
|
Consonants.
|
||||||
- [[#1476]](https://github.com/GetStream/stream-chat-flutter/issues/1476) Fixed `UserAvatarTransform.userAvatarBuilder`
|
- [[#1476]](https://github.com/GetStream/stream-chat-flutter/issues/1476)
|
||||||
|
Fixed `UserAvatarTransform.userAvatarBuilder`
|
||||||
works only for otherUser.
|
works only for otherUser.
|
||||||
- [[#1490]](https://github.com/GetStream/stream-chat-flutter/issues/1490) Fixed `editMessageInputBuilder` property not
|
- [[#1490]](https://github.com/GetStream/stream-chat-flutter/issues/1490)
|
||||||
|
Fixed `editMessageInputBuilder` property not
|
||||||
used in message edit widget.
|
used in message edit widget.
|
||||||
- [[#1523]](https://github.com/GetStream/stream-chat-flutter/issues/1523) Fixed `StreamMessageThemeData` not being
|
- [[#1523]](https://github.com/GetStream/stream-chat-flutter/issues/1523)
|
||||||
|
Fixed `StreamMessageThemeData` not being
|
||||||
applied correctly.
|
applied correctly.
|
||||||
- [[#1525]](https://github.com/GetStream/stream-chat-flutter/issues/1525) Fixed `StreamQuotedMessageWidget` message for
|
- [[#1525]](https://github.com/GetStream/stream-chat-flutter/issues/1525)
|
||||||
|
Fixed `StreamQuotedMessageWidget` message for
|
||||||
deleted messages not being shown correctly.
|
deleted messages not being shown correctly.
|
||||||
- [[#1529]](https://github.com/GetStream/stream-chat-flutter/issues/1529) Fixed `ClipboardData` requires non-nullable
|
- [[#1529]](https://github.com/GetStream/stream-chat-flutter/issues/1529) Fixed `ClipboardData`
|
||||||
|
requires non-nullable
|
||||||
string as text on Flutter 3.10.
|
string as text on Flutter 3.10.
|
||||||
- [[#1533]](https://github.com/GetStream/stream-chat-flutter/issues/1533) Fixed `StreamMessageListView` messages grouped
|
- [[#1533]](https://github.com/GetStream/stream-chat-flutter/issues/1533)
|
||||||
|
Fixed `StreamMessageListView` messages grouped
|
||||||
incorrectly w.r.t. timestamp.
|
incorrectly w.r.t. timestamp.
|
||||||
- [[#1532]](https://github.com/GetStream/stream-chat-flutter/issues/1532) Fixed `StreamMessageWidget` actions dialog
|
- [[#1532]](https://github.com/GetStream/stream-chat-flutter/issues/1532)
|
||||||
|
Fixed `StreamMessageWidget` actions dialog
|
||||||
backdrop filter is cut off by safe area.
|
backdrop filter is cut off by safe area.
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
@@ -330,7 +410,8 @@
|
|||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|
||||||
- Updated `dart` sdk environment range to support `3.0.0`.
|
- Updated `dart` sdk environment range to support `3.0.0`.
|
||||||
- Deprecated `MessageTheme.linkBackgroundColor` in favor of `MessageTheme.urlAttachmentBackgroundColor`.
|
- Deprecated `MessageTheme.linkBackgroundColor` in favor
|
||||||
|
of `MessageTheme.urlAttachmentBackgroundColor`.
|
||||||
- Updated `stream_chat_flutter_core` dependency
|
- Updated `stream_chat_flutter_core` dependency
|
||||||
to [`6.1.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
to [`6.1.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||||
|
|
||||||
@@ -338,18 +419,23 @@
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#1456]](https://github.com/GetStream/stream-chat-flutter/issues/1456) Fixed logic for showing that a message was
|
- [[#1456]](https://github.com/GetStream/stream-chat-flutter/issues/1456) Fixed logic for showing
|
||||||
|
that a message was
|
||||||
read using sending indicator.
|
read using sending indicator.
|
||||||
- [[#1462]](https://github.com/GetStream/stream-chat-flutter/issues/1462) Fixed support for iPad in the share button for
|
- [[#1462]](https://github.com/GetStream/stream-chat-flutter/issues/1462) Fixed support for iPad in
|
||||||
|
the share button for
|
||||||
images.
|
images.
|
||||||
- [[#1475]](https://github.com/GetStream/stream-chat-flutter/issues/1475) Fixed typo to fix compilation.
|
- [[#1475]](https://github.com/GetStream/stream-chat-flutter/issues/1475) Fixed typo to fix
|
||||||
|
compilation.
|
||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- Now it is possible to customize the max lines of the title of a url attachment. Before it was always 1 line.
|
- Now it is possible to customize the max lines of the title of a url attachment. Before it was
|
||||||
|
always 1 line.
|
||||||
- Added `attachmentActionsModalBuilder` parameter to `StreamMessageWidget` that allows to
|
- Added `attachmentActionsModalBuilder` parameter to `StreamMessageWidget` that allows to
|
||||||
customize `AttachmentActionsModal`.
|
customize `AttachmentActionsModal`.
|
||||||
- Added `StreamMessageInput.sendMessageKeyPredicate` and `StreamMessageInput.clearQuotedMessageKeyPredicate` to
|
- Added `StreamMessageInput.sendMessageKeyPredicate`
|
||||||
|
and `StreamMessageInput.clearQuotedMessageKeyPredicate` to
|
||||||
customize the keys used to send and clear the quoted message.
|
customize the keys used to send and clear the quoted message.
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
@@ -358,7 +444,8 @@
|
|||||||
|
|
||||||
🚀 Improved
|
🚀 Improved
|
||||||
|
|
||||||
- Improved draw of reaction options. [#1455](https://github.com/GetStream/stream-chat-flutter/pull/1455)
|
- Improved draw of reaction
|
||||||
|
options. [#1455](https://github.com/GetStream/stream-chat-flutter/pull/1455)
|
||||||
|
|
||||||
## 5.3.0
|
## 5.3.0
|
||||||
|
|
||||||
@@ -368,7 +455,8 @@
|
|||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#1424]](https://github.com/GetStream/stream-chat-flutter/issues/1424) Fixed a render issue when showing messages
|
- [[#1424]](https://github.com/GetStream/stream-chat-flutter/issues/1424) Fixed a render issue when
|
||||||
|
showing messages
|
||||||
starting with 4 whitespaces.
|
starting with 4 whitespaces.
|
||||||
- Fixed a bug where the `AttachmentPickerBottomSheet` was not able to identify the mobile browser.
|
- Fixed a bug where the `AttachmentPickerBottomSheet` was not able to identify the mobile browser.
|
||||||
- Fixed uploading files on Windows - fixed temp file path.
|
- Fixed uploading files on Windows - fixed temp file path.
|
||||||
@@ -381,7 +469,8 @@
|
|||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- Added a new `bottomRowBuilderWithDefaultWidget` parameter to `StreamMessageWidget` which contains a third parameter (
|
- Added a new `bottomRowBuilderWithDefaultWidget` parameter to `StreamMessageWidget` which contains
|
||||||
|
a third parameter (
|
||||||
default `BottomRow` widget with `copyWith` method available) to allow easier customization.
|
default `BottomRow` widget with `copyWith` method available) to allow easier customization.
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
@@ -391,18 +480,23 @@
|
|||||||
- Updated `connectivity_plus` dependency to `^3.0.2`
|
- Updated `connectivity_plus` dependency to `^3.0.2`
|
||||||
- Updated `dart_vlc` dependency to `^0.4.0`
|
- Updated `dart_vlc` dependency to `^0.4.0`
|
||||||
- Updated `file_picker` dependency to `^5.2.4`
|
- Updated `file_picker` dependency to `^5.2.4`
|
||||||
- Deprecated `StreamMessageWidget.bottomRowBuilder` in favor of `StreamMessageWidget.bottomRowBuilderWithDefaultWidget`.
|
- Deprecated `StreamMessageWidget.bottomRowBuilder` in favor
|
||||||
|
of `StreamMessageWidget.bottomRowBuilderWithDefaultWidget`.
|
||||||
- Deprecated `StreamMessageWidget.deletedBottomRowBuilder` in favor
|
- Deprecated `StreamMessageWidget.deletedBottomRowBuilder` in favor
|
||||||
of `StreamMessageWidget.bottomRowBuilderWithDefaultWidget`.
|
of `StreamMessageWidget.bottomRowBuilderWithDefaultWidget`.
|
||||||
- Deprecated `StreamMessageWidget.usernameBuilder` in favor of `StreamMessageWidget.bottomRowBuilderWithDefaultWidget`.
|
- Deprecated `StreamMessageWidget.usernameBuilder` in favor
|
||||||
|
of `StreamMessageWidget.bottomRowBuilderWithDefaultWidget`.
|
||||||
|
|
||||||
🐞 Fixed
|
🐞 Fixed
|
||||||
|
|
||||||
- [[#1379]](https://github.com/GetStream/stream-chat-flutter/issues/1379) Fixed "Issues with photo attachments on web",
|
- [[#1379]](https://github.com/GetStream/stream-chat-flutter/issues/1379) Fixed "Issues with photo
|
||||||
|
attachments on web",
|
||||||
where the cached image attachment would not render while uploading.
|
where the cached image attachment would not render while uploading.
|
||||||
- Fix render overflow issue with `MessageSearchListTileTitle`. It now uses `Text.rich` instead of `Row`. Better default
|
- Fix render overflow issue with `MessageSearchListTileTitle`. It now uses `Text.rich` instead
|
||||||
|
of `Row`. Better default
|
||||||
behaviour and allows `TextOverflow`.
|
behaviour and allows `TextOverflow`.
|
||||||
- [[1346]](https://github.com/GetStream/stream-chat-flutter/issues/1346) Fixed a render issue while uploading video on
|
- [[1346]](https://github.com/GetStream/stream-chat-flutter/issues/1346) Fixed a render issue while
|
||||||
|
uploading video on
|
||||||
web.
|
web.
|
||||||
- [[#1347]](https://github.com/GetStream/stream-chat-flutter/issues/1347) `onReply` not working
|
- [[#1347]](https://github.com/GetStream/stream-chat-flutter/issues/1347) `onReply` not working
|
||||||
in `AttachmentActionsModal` which is used by `StreamImageAttachment` and `StreamImageGroup`.
|
in `AttachmentActionsModal` which is used by `StreamImageAttachment` and `StreamImageGroup`.
|
||||||
@@ -445,7 +539,8 @@
|
|||||||
* `textInputAction`
|
* `textInputAction`
|
||||||
* `keyboardType`
|
* `keyboardType`
|
||||||
* `textCapitalization`
|
* `textCapitalization`
|
||||||
- Added `showStreamAttachmentPickerModalBottomSheet` to show the attachment picker modal bottom sheet.
|
- Added `showStreamAttachmentPickerModalBottomSheet` to show the attachment picker modal bottom
|
||||||
|
sheet.
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ publish_to: 'none'
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.19.0 <4.0.0'
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.10.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
collection: ^1.15.0
|
collection: ^1.15.0
|
||||||
|
|||||||
@@ -66,7 +66,8 @@ class StreamGroupAvatar extends StatelessWidget {
|
|||||||
Widget avatar = GestureDetector(
|
Widget avatar = GestureDetector(
|
||||||
onTap: onTap,
|
onTap: onTap,
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: borderRadius ?? previewTheme?.borderRadius,
|
borderRadius:
|
||||||
|
borderRadius ?? previewTheme?.borderRadius ?? BorderRadius.zero,
|
||||||
child: Container(
|
child: Container(
|
||||||
constraints: constraints ?? previewTheme?.constraints,
|
constraints: constraints ?? previewTheme?.constraints,
|
||||||
decoration: BoxDecoration(color: colorTheme.accentPrimary),
|
decoration: BoxDecoration(color: colorTheme.accentPrimary),
|
||||||
|
|||||||
@@ -86,7 +86,8 @@ class StreamUserAvatar extends StatelessWidget {
|
|||||||
|
|
||||||
final backupGradientAvatar = ClipRRect(
|
final backupGradientAvatar = ClipRRect(
|
||||||
borderRadius: borderRadius ??
|
borderRadius: borderRadius ??
|
||||||
streamChatTheme.ownMessageTheme.avatarTheme?.borderRadius,
|
streamChatTheme.ownMessageTheme.avatarTheme?.borderRadius ??
|
||||||
|
BorderRadius.zero,
|
||||||
child: streamChatConfig.defaultUserImage(context, user),
|
child: streamChatConfig.defaultUserImage(context, user),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -106,9 +106,10 @@ class _ConnectedTitleState extends StatelessWidget {
|
|||||||
style: textStyle,
|
style: textStyle,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
final lastActive = otherMember.user?.lastActive ?? DateTime.now();
|
||||||
alternativeWidget = Text(
|
alternativeWidget = Text(
|
||||||
'${context.translations.userLastOnlineText} '
|
'${context.translations.userLastOnlineText} '
|
||||||
'${Jiffy(otherMember.user?.lastActive).fromNow()}',
|
'${Jiffy.parseFromDateTime(lastActive).fromNow()}',
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -349,16 +349,16 @@ class _Date extends StatelessWidget {
|
|||||||
|
|
||||||
if (lastMessageAt.millisecondsSinceEpoch >=
|
if (lastMessageAt.millisecondsSinceEpoch >=
|
||||||
startOfDay.millisecondsSinceEpoch) {
|
startOfDay.millisecondsSinceEpoch) {
|
||||||
stringDate = Jiffy(lastMessageAt.toLocal()).jm;
|
stringDate = Jiffy.parseFromDateTime(lastMessageAt.toLocal()).jm;
|
||||||
} else if (lastMessageAt.millisecondsSinceEpoch >=
|
} else if (lastMessageAt.millisecondsSinceEpoch >=
|
||||||
startOfDay
|
startOfDay
|
||||||
.subtract(const Duration(days: 1))
|
.subtract(const Duration(days: 1))
|
||||||
.millisecondsSinceEpoch) {
|
.millisecondsSinceEpoch) {
|
||||||
stringDate = context.translations.yesterdayLabel;
|
stringDate = context.translations.yesterdayLabel;
|
||||||
} else if (startOfDay.difference(lastMessageAt).inDays < 7) {
|
} else if (startOfDay.difference(lastMessageAt).inDays < 7) {
|
||||||
stringDate = Jiffy(lastMessageAt.toLocal()).EEEE;
|
stringDate = Jiffy.parseFromDateTime(lastMessageAt.toLocal()).EEEE;
|
||||||
} else {
|
} else {
|
||||||
stringDate = Jiffy(lastMessageAt.toLocal()).yMd;
|
stringDate = Jiffy.parseFromDateTime(lastMessageAt.toLocal()).yMd;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Text(
|
return Text(
|
||||||
|
|||||||
@@ -111,7 +111,8 @@ class StreamChannelAvatar extends StatelessWidget {
|
|||||||
initialData: channel.image,
|
initialData: channel.image,
|
||||||
builder: (context, channelImage) {
|
builder: (context, channelImage) {
|
||||||
Widget child = ClipRRect(
|
Widget child = ClipRRect(
|
||||||
borderRadius: borderRadius ?? previewTheme?.borderRadius,
|
borderRadius:
|
||||||
|
borderRadius ?? previewTheme?.borderRadius ?? BorderRadius.zero,
|
||||||
child: Container(
|
child: Container(
|
||||||
constraints: constraints ?? previewTheme?.constraints,
|
constraints: constraints ?? previewTheme?.constraints,
|
||||||
decoration: BoxDecoration(color: colorTheme.accentPrimary),
|
decoration: BoxDecoration(color: colorTheme.accentPrimary),
|
||||||
|
|||||||
@@ -3,13 +3,11 @@ import 'dart:io';
|
|||||||
|
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:chewie/chewie.dart';
|
import 'package:chewie/chewie.dart';
|
||||||
import 'package:contextmenu/contextmenu.dart';
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:photo_view/photo_view.dart';
|
import 'package:photo_view/photo_view.dart';
|
||||||
import 'package:shimmer/shimmer.dart';
|
import 'package:shimmer/shimmer.dart';
|
||||||
import 'package:stream_chat_flutter/platform_widget_builder/platform_widget_builder.dart';
|
import 'package:stream_chat_flutter/platform_widget_builder/platform_widget_builder.dart';
|
||||||
import 'package:stream_chat_flutter/src/context_menu_items/download_menu_item.dart';
|
|
||||||
import 'package:stream_chat_flutter/src/fullscreen_media/full_screen_media_widget.dart';
|
import 'package:stream_chat_flutter/src/fullscreen_media/full_screen_media_widget.dart';
|
||||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
import 'package:video_player/video_player.dart';
|
import 'package:video_player/video_player.dart';
|
||||||
@@ -281,84 +279,83 @@ class _FullScreenMediaState extends State<StreamFullScreenMedia> {
|
|||||||
final currentAttachmentPackage =
|
final currentAttachmentPackage =
|
||||||
widget.mediaAttachmentPackages[index];
|
widget.mediaAttachmentPackages[index];
|
||||||
final attachment = currentAttachmentPackage.attachment;
|
final attachment = currentAttachmentPackage.attachment;
|
||||||
if (attachment.type == 'image' || attachment.type == 'giphy') {
|
return ValueListenableBuilder(
|
||||||
final imageUrl = attachment.imageUrl ??
|
valueListenable: _isDisplayingDetail,
|
||||||
attachment.assetUrl ??
|
builder: (context, isDisplayingDetail, child) {
|
||||||
attachment.thumbUrl;
|
return AnimatedContainer(
|
||||||
return ValueListenableBuilder<bool>(
|
duration: kThemeChangeDuration,
|
||||||
valueListenable: _isDisplayingDetail,
|
|
||||||
builder: (context, isDisplayingDetail, _) =>
|
|
||||||
AnimatedContainer(
|
|
||||||
color: isDisplayingDetail
|
color: isDisplayingDetail
|
||||||
? StreamChannelHeaderTheme.of(context).color
|
? StreamChannelHeaderTheme.of(context).color
|
||||||
: Colors.black,
|
: Colors.black,
|
||||||
duration: kThemeAnimationDuration,
|
child: Builder(
|
||||||
child: ContextMenuArea(
|
builder: (context) {
|
||||||
verticalPadding: 0,
|
if (attachment.type == 'image' ||
|
||||||
builder: (_) => [
|
attachment.type == 'giphy') {
|
||||||
DownloadMenuItem(
|
final imageUrl = attachment.imageUrl ??
|
||||||
attachment: attachment,
|
attachment.assetUrl ??
|
||||||
),
|
attachment.thumbUrl;
|
||||||
],
|
|
||||||
child: PhotoView(
|
return PhotoView(
|
||||||
imageProvider: (imageUrl == null &&
|
imageProvider: (imageUrl == null &&
|
||||||
attachment.localUri != null &&
|
attachment.localUri != null &&
|
||||||
attachment.file?.bytes != null)
|
attachment.file?.bytes != null)
|
||||||
? Image.memory(attachment.file!.bytes!).image
|
? Image.memory(attachment.file!.bytes!).image
|
||||||
: CachedNetworkImageProvider(imageUrl!),
|
: CachedNetworkImageProvider(imageUrl!),
|
||||||
errorBuilder: (_, __, ___) => const AttachmentError(),
|
errorBuilder: (_, __, ___) =>
|
||||||
loadingBuilder: (context, _) {
|
const AttachmentError(),
|
||||||
final image = Image.asset(
|
loadingBuilder: (context, _) {
|
||||||
'images/placeholder.png',
|
final image = Image.asset(
|
||||||
fit: BoxFit.cover,
|
'images/placeholder.png',
|
||||||
package: 'stream_chat_flutter',
|
fit: BoxFit.cover,
|
||||||
|
package: 'stream_chat_flutter',
|
||||||
|
);
|
||||||
|
final colorTheme =
|
||||||
|
StreamChatTheme.of(context).colorTheme;
|
||||||
|
return Shimmer.fromColors(
|
||||||
|
baseColor: colorTheme.disabled,
|
||||||
|
highlightColor: colorTheme.inputBg,
|
||||||
|
child: image,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
maxScale: PhotoViewComputedScale.covered,
|
||||||
|
minScale: PhotoViewComputedScale.contained,
|
||||||
|
heroAttributes: PhotoViewHeroAttributes(
|
||||||
|
tag: widget.mediaAttachmentPackages,
|
||||||
|
),
|
||||||
|
backgroundDecoration: const BoxDecoration(
|
||||||
|
color: Colors.transparent,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
final colorTheme =
|
} else if (attachment.type == 'video') {
|
||||||
StreamChatTheme.of(context).colorTheme;
|
final controller = videoPackages[attachment.id]!;
|
||||||
return Shimmer.fromColors(
|
if (!controller.initialized) {
|
||||||
baseColor: colorTheme.disabled,
|
return const Center(
|
||||||
highlightColor: colorTheme.inputBg,
|
child: CircularProgressIndicator.adaptive(),
|
||||||
child: image,
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final mediaQuery = MediaQuery.of(context);
|
||||||
|
final bottomPadding = mediaQuery.padding.bottom;
|
||||||
|
|
||||||
|
return AnimatedPadding(
|
||||||
|
duration: kThemeChangeDuration,
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: isDisplayingDetail
|
||||||
|
? kToolbarHeight + bottomPadding
|
||||||
|
: 0,
|
||||||
|
),
|
||||||
|
child: Chewie(
|
||||||
|
controller: controller.chewieController!,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
maxScale: PhotoViewComputedScale.covered,
|
|
||||||
minScale: PhotoViewComputedScale.contained,
|
return const SizedBox();
|
||||||
heroAttributes: PhotoViewHeroAttributes(
|
},
|
||||||
tag: widget.mediaAttachmentPackages,
|
|
||||||
),
|
|
||||||
backgroundDecoration: const BoxDecoration(
|
|
||||||
color: Colors.transparent,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
|
||||||
} else if (attachment.type == 'video') {
|
|
||||||
final controller = videoPackages[attachment.id]!;
|
|
||||||
if (!controller.initialized) {
|
|
||||||
return const Center(
|
|
||||||
child: CircularProgressIndicator.adaptive(),
|
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
return InkWell(
|
);
|
||||||
onTap: switchDisplayingDetail,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 50),
|
|
||||||
child: ContextMenuArea(
|
|
||||||
verticalPadding: 0,
|
|
||||||
builder: (_) => [
|
|
||||||
DownloadMenuItem(
|
|
||||||
attachment: attachment,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
child: Chewie(
|
|
||||||
controller: controller.chewieController!,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return const SizedBox();
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -475,6 +472,7 @@ class VideoPackage {
|
|||||||
videoPlayerController: _videoPlayerController,
|
videoPlayerController: _videoPlayerController,
|
||||||
autoInitialize: _autoInitialize,
|
autoInitialize: _autoInitialize,
|
||||||
showControls: _showControls,
|
showControls: _showControls,
|
||||||
|
showOptions: false,
|
||||||
aspectRatio: _videoPlayerController.value.aspectRatio,
|
aspectRatio: _videoPlayerController.value.aspectRatio,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
+84
-77
@@ -307,88 +307,95 @@ class _FullScreenMediaDesktopState extends State<FullScreenMediaDesktop> {
|
|||||||
final currentAttachmentPackage =
|
final currentAttachmentPackage =
|
||||||
widget.mediaAttachmentPackages[index];
|
widget.mediaAttachmentPackages[index];
|
||||||
final attachment = currentAttachmentPackage.attachment;
|
final attachment = currentAttachmentPackage.attachment;
|
||||||
if (attachment.type == 'image' || attachment.type == 'giphy') {
|
|
||||||
final imageUrl = attachment.imageUrl ??
|
return ValueListenableBuilder(
|
||||||
attachment.assetUrl ??
|
valueListenable: _isDisplayingDetail,
|
||||||
attachment.thumbUrl;
|
builder: (context, isDisplayingDetail, child) {
|
||||||
return ValueListenableBuilder<bool>(
|
return AnimatedContainer(
|
||||||
valueListenable: _isDisplayingDetail,
|
duration: kThemeChangeDuration,
|
||||||
builder: (context, isDisplayingDetail, _) =>
|
|
||||||
AnimatedContainer(
|
|
||||||
color: isDisplayingDetail
|
color: isDisplayingDetail
|
||||||
? StreamChannelHeaderTheme.of(context).color
|
? StreamChannelHeaderTheme.of(context).color
|
||||||
: Colors.black,
|
: Colors.black,
|
||||||
duration: kThemeAnimationDuration,
|
child: Builder(
|
||||||
child: ContextMenuArea(
|
builder: (context) {
|
||||||
verticalPadding: 0,
|
if (attachment.type == 'image' ||
|
||||||
builder: (_) => [
|
attachment.type == 'giphy') {
|
||||||
DownloadMenuItem(
|
final imageUrl = attachment.imageUrl ??
|
||||||
attachment: attachment,
|
attachment.assetUrl ??
|
||||||
),
|
attachment.thumbUrl;
|
||||||
],
|
|
||||||
child: PhotoView(
|
|
||||||
imageProvider: (imageUrl == null &&
|
|
||||||
attachment.localUri != null &&
|
|
||||||
attachment.file?.bytes != null)
|
|
||||||
? Image.memory(attachment.file!.bytes!).image
|
|
||||||
: CachedNetworkImageProvider(imageUrl!),
|
|
||||||
errorBuilder: (_, __, ___) => const AttachmentError(),
|
|
||||||
loadingBuilder: (context, _) {
|
|
||||||
final image = Image.asset(
|
|
||||||
'images/placeholder.png',
|
|
||||||
fit: BoxFit.cover,
|
|
||||||
package: 'stream_chat_flutter',
|
|
||||||
);
|
|
||||||
final colorTheme =
|
|
||||||
StreamChatTheme.of(context).colorTheme;
|
|
||||||
return Shimmer.fromColors(
|
|
||||||
baseColor: colorTheme.disabled,
|
|
||||||
highlightColor: colorTheme.inputBg,
|
|
||||||
child: image,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
maxScale: PhotoViewComputedScale.covered,
|
|
||||||
minScale: PhotoViewComputedScale.contained,
|
|
||||||
heroAttributes: PhotoViewHeroAttributes(
|
|
||||||
tag: widget.mediaAttachmentPackages,
|
|
||||||
),
|
|
||||||
backgroundDecoration: const BoxDecoration(
|
|
||||||
color: Colors.transparent,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else if (attachment.type == 'video') {
|
|
||||||
final package = videoPackages[attachment.id]!;
|
|
||||||
package.player.open(
|
|
||||||
Playlist(
|
|
||||||
medias: [
|
|
||||||
Media.network(package.attachment.assetUrl),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
autoStart: widget.autoplayVideos,
|
|
||||||
);
|
|
||||||
|
|
||||||
return InkWell(
|
return PhotoView(
|
||||||
onTap: switchDisplayingDetail,
|
imageProvider: (imageUrl == null &&
|
||||||
child: Padding(
|
attachment.localUri != null &&
|
||||||
padding: const EdgeInsets.symmetric(vertical: 50),
|
attachment.file?.bytes != null)
|
||||||
child: ContextMenuArea(
|
? Image.memory(attachment.file!.bytes!).image
|
||||||
verticalPadding: 0,
|
: CachedNetworkImageProvider(imageUrl!),
|
||||||
builder: (_) => [
|
errorBuilder: (_, __, ___) =>
|
||||||
DownloadMenuItem(
|
const AttachmentError(),
|
||||||
attachment: attachment,
|
loadingBuilder: (context, _) {
|
||||||
),
|
final image = Image.asset(
|
||||||
],
|
'images/placeholder.png',
|
||||||
child: Video(
|
fit: BoxFit.cover,
|
||||||
player: package.player,
|
package: 'stream_chat_flutter',
|
||||||
),
|
);
|
||||||
|
final colorTheme =
|
||||||
|
StreamChatTheme.of(context).colorTheme;
|
||||||
|
return Shimmer.fromColors(
|
||||||
|
baseColor: colorTheme.disabled,
|
||||||
|
highlightColor: colorTheme.inputBg,
|
||||||
|
child: image,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
maxScale: PhotoViewComputedScale.covered,
|
||||||
|
minScale: PhotoViewComputedScale.contained,
|
||||||
|
heroAttributes: PhotoViewHeroAttributes(
|
||||||
|
tag: widget.mediaAttachmentPackages,
|
||||||
|
),
|
||||||
|
backgroundDecoration: const BoxDecoration(
|
||||||
|
color: Colors.transparent,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (attachment.type == 'video') {
|
||||||
|
final package = videoPackages[attachment.id]!;
|
||||||
|
package.player.open(
|
||||||
|
Playlist(
|
||||||
|
medias: [
|
||||||
|
Media.network(package.attachment.assetUrl),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
autoStart: widget.autoplayVideos,
|
||||||
|
);
|
||||||
|
|
||||||
|
final mediaQuery = MediaQuery.of(context);
|
||||||
|
final bottomPadding = mediaQuery.padding.bottom;
|
||||||
|
|
||||||
|
return AnimatedPadding(
|
||||||
|
duration: kThemeChangeDuration,
|
||||||
|
padding: EdgeInsets.symmetric(
|
||||||
|
vertical: isDisplayingDetail
|
||||||
|
? kToolbarHeight + bottomPadding
|
||||||
|
: 0,
|
||||||
|
),
|
||||||
|
child: ContextMenuArea(
|
||||||
|
verticalPadding: 0,
|
||||||
|
builder: (_) => [
|
||||||
|
DownloadMenuItem(
|
||||||
|
attachment: attachment,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
child: Video(
|
||||||
|
player: package.player,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return const SizedBox();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
}
|
);
|
||||||
return const SizedBox();
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -611,13 +611,15 @@ class DefaultTranslations implements Translations {
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return 'yesterday';
|
return 'yesterday';
|
||||||
} else {
|
} else {
|
||||||
return 'on ${Jiffy(date).MMMd}';
|
return 'on ${Jiffy.parseFromDateTime(date).MMMd}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
'Sent ${_getDay(date)} at ${Jiffy(time.toLocal()).format('HH:mm')}';
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return 'Sent ${_getDay(date)} at ${atTime.jm}';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => 'Today';
|
String get todayLabel => 'Today';
|
||||||
|
|||||||
+52
-17
@@ -698,6 +698,7 @@ Widget mobileAttachmentPickerBuilder({
|
|||||||
ThumbnailFormat attachmentThumbnailFormat = ThumbnailFormat.jpeg,
|
ThumbnailFormat attachmentThumbnailFormat = ThumbnailFormat.jpeg,
|
||||||
int attachmentThumbnailQuality = 100,
|
int attachmentThumbnailQuality = 100,
|
||||||
double attachmentThumbnailScale = 1,
|
double attachmentThumbnailScale = 1,
|
||||||
|
ErrorListener? onError,
|
||||||
}) {
|
}) {
|
||||||
return StreamMobileAttachmentPickerBottomSheet(
|
return StreamMobileAttachmentPickerBottomSheet(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
@@ -721,10 +722,15 @@ Widget mobileAttachmentPickerBuilder({
|
|||||||
mediaThumbnailQuality: attachmentThumbnailQuality,
|
mediaThumbnailQuality: attachmentThumbnailQuality,
|
||||||
mediaThumbnailScale: attachmentThumbnailScale,
|
mediaThumbnailScale: attachmentThumbnailScale,
|
||||||
onMediaItemSelected: (media) async {
|
onMediaItemSelected: (media) async {
|
||||||
if (selectedIds.contains(media.id)) {
|
try {
|
||||||
return controller.removeAssetAttachment(media);
|
if (selectedIds.contains(media.id)) {
|
||||||
|
return await controller.removeAssetAttachment(media);
|
||||||
|
}
|
||||||
|
return await controller.addAssetAttachment(media);
|
||||||
|
} catch (e, stk) {
|
||||||
|
if (onError != null) return onError.call(e, stk);
|
||||||
|
rethrow;
|
||||||
}
|
}
|
||||||
return controller.addAssetAttachment(media);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -736,8 +742,15 @@ Widget mobileAttachmentPickerBuilder({
|
|||||||
optionViewBuilder: (context, controller) {
|
optionViewBuilder: (context, controller) {
|
||||||
return StreamFilePicker(
|
return StreamFilePicker(
|
||||||
onFilePicked: (file) async {
|
onFilePicked: (file) async {
|
||||||
if (file != null) await controller.addAttachment(file);
|
try {
|
||||||
return Navigator.pop(context, controller.value);
|
if (file != null) await controller.addAttachment(file);
|
||||||
|
return Navigator.pop(context, controller.value);
|
||||||
|
} catch (e, stk) {
|
||||||
|
Navigator.pop(context, controller.value);
|
||||||
|
if (onError != null) return onError.call(e, stk);
|
||||||
|
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -749,10 +762,17 @@ Widget mobileAttachmentPickerBuilder({
|
|||||||
optionViewBuilder: (context, controller) {
|
optionViewBuilder: (context, controller) {
|
||||||
return StreamImagePicker(
|
return StreamImagePicker(
|
||||||
onImagePicked: (image) async {
|
onImagePicked: (image) async {
|
||||||
if (image != null) {
|
try {
|
||||||
await controller.addAttachment(image);
|
if (image != null) {
|
||||||
|
await controller.addAttachment(image);
|
||||||
|
}
|
||||||
|
return Navigator.pop(context, controller.value);
|
||||||
|
} catch (e, stk) {
|
||||||
|
Navigator.pop(context, controller.value);
|
||||||
|
if (onError != null) return onError.call(e, stk);
|
||||||
|
|
||||||
|
rethrow;
|
||||||
}
|
}
|
||||||
return Navigator.pop(context, controller.value);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -764,10 +784,17 @@ Widget mobileAttachmentPickerBuilder({
|
|||||||
optionViewBuilder: (context, controller) {
|
optionViewBuilder: (context, controller) {
|
||||||
return StreamVideoPicker(
|
return StreamVideoPicker(
|
||||||
onVideoPicked: (video) async {
|
onVideoPicked: (video) async {
|
||||||
if (video != null) {
|
try {
|
||||||
await controller.addAttachment(video);
|
if (video != null) {
|
||||||
|
await controller.addAttachment(video);
|
||||||
|
}
|
||||||
|
return Navigator.pop(context, controller.value);
|
||||||
|
} catch (e, stk) {
|
||||||
|
Navigator.pop(context, controller.value);
|
||||||
|
if (onError != null) return onError.call(e, stk);
|
||||||
|
|
||||||
|
rethrow;
|
||||||
}
|
}
|
||||||
return Navigator.pop(context, controller.value);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -787,6 +814,7 @@ Widget webOrDesktopAttachmentPickerBuilder({
|
|||||||
ThumbnailFormat attachmentThumbnailFormat = ThumbnailFormat.jpeg,
|
ThumbnailFormat attachmentThumbnailFormat = ThumbnailFormat.jpeg,
|
||||||
int attachmentThumbnailQuality = 100,
|
int attachmentThumbnailQuality = 100,
|
||||||
double attachmentThumbnailScale = 1,
|
double attachmentThumbnailScale = 1,
|
||||||
|
ErrorListener? onError,
|
||||||
}) {
|
}) {
|
||||||
return StreamWebOrDesktopAttachmentPickerBottomSheet(
|
return StreamWebOrDesktopAttachmentPickerBottomSheet(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
@@ -814,13 +842,20 @@ Widget webOrDesktopAttachmentPickerBuilder({
|
|||||||
}.where((option) => option.supportedTypes.every(allowedTypes.contains)),
|
}.where((option) => option.supportedTypes.every(allowedTypes.contains)),
|
||||||
},
|
},
|
||||||
onOptionTap: (context, controller, option) async {
|
onOptionTap: (context, controller, option) async {
|
||||||
final attachment = await StreamAttachmentHandler.instance.pickFile(
|
try {
|
||||||
type: option.type.fileType,
|
final attachment = await StreamAttachmentHandler.instance.pickFile(
|
||||||
);
|
type: option.type.fileType,
|
||||||
if (attachment != null) {
|
);
|
||||||
await controller.addAttachment(attachment);
|
if (attachment != null) {
|
||||||
|
await controller.addAttachment(attachment);
|
||||||
|
}
|
||||||
|
return Navigator.pop(context, controller.value);
|
||||||
|
} catch (e, stk) {
|
||||||
|
Navigator.pop(context, controller.value);
|
||||||
|
if (onError != null) return onError.call(e, stk);
|
||||||
|
|
||||||
|
rethrow;
|
||||||
}
|
}
|
||||||
return Navigator.pop(context, controller.value);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -69,6 +69,7 @@ Future<T?> showStreamAttachmentPickerModalBottomSheet<T>({
|
|||||||
List<AttachmentPickerType> allowedTypes = AttachmentPickerType.values,
|
List<AttachmentPickerType> allowedTypes = AttachmentPickerType.values,
|
||||||
List<Attachment>? initialAttachments,
|
List<Attachment>? initialAttachments,
|
||||||
StreamAttachmentPickerController? controller,
|
StreamAttachmentPickerController? controller,
|
||||||
|
ErrorListener? onError,
|
||||||
Color? backgroundColor,
|
Color? backgroundColor,
|
||||||
double? elevation,
|
double? elevation,
|
||||||
BoxConstraints? constraints,
|
BoxConstraints? constraints,
|
||||||
@@ -117,6 +118,7 @@ Future<T?> showStreamAttachmentPickerModalBottomSheet<T>({
|
|||||||
if (isWebOrDesktop) {
|
if (isWebOrDesktop) {
|
||||||
return webOrDesktopAttachmentPickerBuilder.call(
|
return webOrDesktopAttachmentPickerBuilder.call(
|
||||||
context: context,
|
context: context,
|
||||||
|
onError: onError,
|
||||||
controller: controller,
|
controller: controller,
|
||||||
allowedTypes: allowedTypes,
|
allowedTypes: allowedTypes,
|
||||||
customOptions: customOptions?.map(
|
customOptions: customOptions?.map(
|
||||||
@@ -131,6 +133,7 @@ Future<T?> showStreamAttachmentPickerModalBottomSheet<T>({
|
|||||||
|
|
||||||
return mobileAttachmentPickerBuilder.call(
|
return mobileAttachmentPickerBuilder.call(
|
||||||
context: context,
|
context: context,
|
||||||
|
onError: onError,
|
||||||
controller: controller,
|
controller: controller,
|
||||||
allowedTypes: allowedTypes,
|
allowedTypes: allowedTypes,
|
||||||
customOptions: customOptions,
|
customOptions: customOptions,
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ class StreamMessageInput extends StatefulWidget {
|
|||||||
_defaultClearQuotedMessageKeyPredicate,
|
_defaultClearQuotedMessageKeyPredicate,
|
||||||
this.ogPreviewFilter = _defaultOgPreviewFilter,
|
this.ogPreviewFilter = _defaultOgPreviewFilter,
|
||||||
this.hintGetter = _defaultHintGetter,
|
this.hintGetter = _defaultHintGetter,
|
||||||
|
this.contentInsertionConfiguration,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The predicate used to send a message on desktop/web
|
/// The predicate used to send a message on desktop/web
|
||||||
@@ -340,6 +341,9 @@ class StreamMessageInput extends StatefulWidget {
|
|||||||
/// Returns the hint text for the message input.
|
/// Returns the hint text for the message input.
|
||||||
final HintGetter hintGetter;
|
final HintGetter hintGetter;
|
||||||
|
|
||||||
|
/// {@macro flutter.widgets.editableText.contentInsertionConfiguration}
|
||||||
|
final ContentInsertionConfiguration? contentInsertionConfiguration;
|
||||||
|
|
||||||
static String? _defaultHintGetter(
|
static String? _defaultHintGetter(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
HintType type,
|
HintType type,
|
||||||
@@ -815,6 +819,7 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
Future<void> _onAttachmentButtonPressed() async {
|
Future<void> _onAttachmentButtonPressed() async {
|
||||||
final attachments = await showStreamAttachmentPickerModalBottomSheet(
|
final attachments = await showStreamAttachmentPickerModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
|
onError: widget.onError,
|
||||||
allowedTypes: widget.allowedAttachmentPickerTypes,
|
allowedTypes: widget.allowedAttachmentPickerTypes,
|
||||||
initialAttachments: _effectiveController.attachments,
|
initialAttachments: _effectiveController.attachments,
|
||||||
);
|
);
|
||||||
@@ -904,6 +909,8 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
decoration: _getInputDecoration(context),
|
decoration: _getInputDecoration(context),
|
||||||
textCapitalization: widget.textCapitalization,
|
textCapitalization: widget.textCapitalization,
|
||||||
autocorrect: widget.autoCorrect,
|
autocorrect: widget.autoCorrect,
|
||||||
|
contentInsertionConfiguration:
|
||||||
|
widget.contentInsertionConfiguration,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ class StreamMessageTextField extends StatefulWidget {
|
|||||||
this.restorationId,
|
this.restorationId,
|
||||||
this.scribbleEnabled = true,
|
this.scribbleEnabled = true,
|
||||||
this.enableIMEPersonalizedLearning = true,
|
this.enableIMEPersonalizedLearning = true,
|
||||||
|
this.contentInsertionConfiguration,
|
||||||
}) : assert(obscuringCharacter.length == 1, ''),
|
}) : assert(obscuringCharacter.length == 1, ''),
|
||||||
smartDashesType = smartDashesType ??
|
smartDashesType = smartDashesType ??
|
||||||
(obscureText ? SmartDashesType.disabled : SmartDashesType.enabled),
|
(obscureText ? SmartDashesType.disabled : SmartDashesType.enabled),
|
||||||
@@ -526,6 +527,9 @@ class StreamMessageTextField extends StatefulWidget {
|
|||||||
/// {@macro flutter.services.TextInputConfiguration.enableIMEPersonalizedLearning}
|
/// {@macro flutter.services.TextInputConfiguration.enableIMEPersonalizedLearning}
|
||||||
final bool enableIMEPersonalizedLearning;
|
final bool enableIMEPersonalizedLearning;
|
||||||
|
|
||||||
|
/// {@macro flutter.widgets.editableText.contentInsertionConfiguration}
|
||||||
|
final ContentInsertionConfiguration? contentInsertionConfiguration;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_StreamMessageTextFieldState createState() => _StreamMessageTextFieldState();
|
_StreamMessageTextFieldState createState() => _StreamMessageTextFieldState();
|
||||||
|
|
||||||
@@ -622,6 +626,9 @@ class StreamMessageTextField extends StatefulWidget {
|
|||||||
properties.add(DiagnosticsProperty<bool>(
|
properties.add(DiagnosticsProperty<bool>(
|
||||||
'enableIMEPersonalizedLearning', enableIMEPersonalizedLearning,
|
'enableIMEPersonalizedLearning', enableIMEPersonalizedLearning,
|
||||||
defaultValue: true));
|
defaultValue: true));
|
||||||
|
properties.add(DiagnosticsProperty<ContentInsertionConfiguration>(
|
||||||
|
'contentInsertionConfiguration', contentInsertionConfiguration,
|
||||||
|
defaultValue: null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -727,6 +734,7 @@ class _StreamMessageTextFieldState extends State<StreamMessageTextField>
|
|||||||
restorationId: widget.restorationId,
|
restorationId: widget.restorationId,
|
||||||
scribbleEnabled: widget.scribbleEnabled,
|
scribbleEnabled: widget.scribbleEnabled,
|
||||||
enableIMEPersonalizedLearning: widget.enableIMEPersonalizedLearning,
|
enableIMEPersonalizedLearning: widget.enableIMEPersonalizedLearning,
|
||||||
|
contentInsertionConfiguration: widget.contentInsertionConfiguration,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -669,14 +669,20 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
final isPartOfThread = message.replyCount! > 0 ||
|
final isPartOfThread = message.replyCount! > 0 ||
|
||||||
message.showInChannel == true;
|
message.showInChannel == true;
|
||||||
|
|
||||||
final createdAt = message.createdAt.toLocal();
|
final createdAt = Jiffy.parseFromDateTime(
|
||||||
final nextCreatedAt = nextMessage.createdAt.toLocal();
|
message.createdAt.toLocal(),
|
||||||
if (!Jiffy(createdAt).isSame(nextCreatedAt, Units.DAY)) {
|
);
|
||||||
|
|
||||||
|
final nextCreatedAt = Jiffy.parseFromDateTime(
|
||||||
|
nextMessage.createdAt.toLocal(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!createdAt.isSame(nextCreatedAt, unit: Unit.day)) {
|
||||||
separator = _buildDateDivider(nextMessage);
|
separator = _buildDateDivider(nextMessage);
|
||||||
} else {
|
} else {
|
||||||
final hasTimeDiff = !Jiffy(createdAt).isSame(
|
final hasTimeDiff = !createdAt.isSame(
|
||||||
nextCreatedAt,
|
nextCreatedAt,
|
||||||
Units.MINUTE,
|
unit: Unit.minute,
|
||||||
);
|
);
|
||||||
|
|
||||||
final isNextUserSame =
|
final isNextUserSame =
|
||||||
@@ -1071,10 +1077,12 @@ class _StreamMessageListViewState extends State<StreamMessageListView> {
|
|||||||
|
|
||||||
var hasTimeDiff = false;
|
var hasTimeDiff = false;
|
||||||
if (nextMessage != null) {
|
if (nextMessage != null) {
|
||||||
hasTimeDiff = !Jiffy(message.createdAt.toLocal()).isSame(
|
final createdAt = Jiffy.parseFromDateTime(message.createdAt.toLocal());
|
||||||
|
final nextCreatedAt = Jiffy.parseFromDateTime(
|
||||||
nextMessage.createdAt.toLocal(),
|
nextMessage.createdAt.toLocal(),
|
||||||
Units.MINUTE,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
hasTimeDiff = !createdAt.isSame(nextCreatedAt, unit: Unit.minute);
|
||||||
}
|
}
|
||||||
|
|
||||||
final hasFileAttachment =
|
final hasFileAttachment =
|
||||||
|
|||||||
@@ -162,8 +162,7 @@ class BottomRow extends StatelessWidget {
|
|||||||
msg = context.translations.threadReplyCountText(replyCount);
|
msg = context.translations.threadReplyCountText(replyCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore: prefer_function_declarations_over_variables
|
Future<void> _onThreadTap() async {
|
||||||
final _onThreadTap = () async {
|
|
||||||
try {
|
try {
|
||||||
var message = this.message;
|
var message = this.message;
|
||||||
if (showInChannel) {
|
if (showInChannel) {
|
||||||
@@ -172,12 +171,9 @@ class BottomRow extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
return onThreadTap!(message);
|
return onThreadTap!(message);
|
||||||
} catch (e, stk) {
|
} catch (e, stk) {
|
||||||
print(e);
|
debugPrint('Error while fetching message: $e, $stk');
|
||||||
print(stk);
|
|
||||||
// ignore: avoid_returning_null_for_void
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
const usernameKey = Key('username');
|
const usernameKey = Key('username');
|
||||||
|
|
||||||
@@ -191,7 +187,7 @@ class BottomRow extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
if (showTimeStamp)
|
if (showTimeStamp)
|
||||||
Text(
|
Text(
|
||||||
Jiffy(message.createdAt.toLocal()).jm,
|
Jiffy.parseFromDateTime(message.createdAt.toLocal()).jm,
|
||||||
style: messageTheme.createdAtStyle,
|
style: messageTheme.createdAtStyle,
|
||||||
),
|
),
|
||||||
if (showSendingIndicator)
|
if (showSendingIndicator)
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
this.attachmentBorderRadiusGeometry,
|
this.attachmentBorderRadiusGeometry,
|
||||||
this.onMentionTap,
|
this.onMentionTap,
|
||||||
this.onMessageTap,
|
this.onMessageTap,
|
||||||
|
this.onReactionsTap,
|
||||||
bool? showReactionPicker,
|
bool? showReactionPicker,
|
||||||
@Deprecated('Use `showReactionPicker` instead')
|
@Deprecated('Use `showReactionPicker` instead')
|
||||||
bool showReactionPickerIndicator = true,
|
bool showReactionPickerIndicator = true,
|
||||||
@@ -563,6 +564,9 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
/// {@macro onMessageTap}
|
/// {@macro onMessageTap}
|
||||||
final void Function(Message)? onMessageTap;
|
final void Function(Message)? onMessageTap;
|
||||||
|
|
||||||
|
/// {@macro onReactionsTap}
|
||||||
|
final OnReactionsTap? onReactionsTap;
|
||||||
|
|
||||||
/// {@template customActions}
|
/// {@template customActions}
|
||||||
/// List of custom actions shown on message long tap
|
/// List of custom actions shown on message long tap
|
||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
@@ -657,6 +661,7 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
bool? translateUserAvatar,
|
bool? translateUserAvatar,
|
||||||
OnQuotedMessageTap? onQuotedMessageTap,
|
OnQuotedMessageTap? onQuotedMessageTap,
|
||||||
void Function(Message)? onMessageTap,
|
void Function(Message)? onMessageTap,
|
||||||
|
OnReactionsTap? onReactionsTap,
|
||||||
List<StreamMessageAction>? customActions,
|
List<StreamMessageAction>? customActions,
|
||||||
void Function(Message message, Attachment attachment)? onAttachmentTap,
|
void Function(Message message, Attachment attachment)? onAttachmentTap,
|
||||||
Widget Function(BuildContext, User)? userAvatarBuilder,
|
Widget Function(BuildContext, User)? userAvatarBuilder,
|
||||||
@@ -746,6 +751,7 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
translateUserAvatar: translateUserAvatar ?? this.translateUserAvatar,
|
translateUserAvatar: translateUserAvatar ?? this.translateUserAvatar,
|
||||||
onQuotedMessageTap: onQuotedMessageTap ?? this.onQuotedMessageTap,
|
onQuotedMessageTap: onQuotedMessageTap ?? this.onQuotedMessageTap,
|
||||||
onMessageTap: onMessageTap ?? this.onMessageTap,
|
onMessageTap: onMessageTap ?? this.onMessageTap,
|
||||||
|
onReactionsTap: onReactionsTap ?? this.onReactionsTap,
|
||||||
customActions: customActions ?? this.customActions,
|
customActions: customActions ?? this.customActions,
|
||||||
onAttachmentTap: onAttachmentTap ?? this.onAttachmentTap,
|
onAttachmentTap: onAttachmentTap ?? this.onAttachmentTap,
|
||||||
userAvatarBuilder: userAvatarBuilder ?? this.userAvatarBuilder,
|
userAvatarBuilder: userAvatarBuilder ?? this.userAvatarBuilder,
|
||||||
@@ -986,7 +992,11 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
showPinHighlight: widget.showPinHighlight,
|
showPinHighlight: widget.showPinHighlight,
|
||||||
showReactionPickerTail: widget.showReactionPickerTail,
|
showReactionPickerTail: widget.showReactionPickerTail,
|
||||||
showReactions: showReactions,
|
showReactions: showReactions,
|
||||||
onReactionsTap: () => _showMessageReactionsModal(context),
|
onReactionsTap: () {
|
||||||
|
widget.onReactionsTap != null
|
||||||
|
? widget.onReactionsTap!(widget.message)
|
||||||
|
: _showMessageReactionsModal(context);
|
||||||
|
},
|
||||||
showUserAvatar: widget.showUserAvatar,
|
showUserAvatar: widget.showUserAvatar,
|
||||||
streamChat: _streamChat,
|
streamChat: _streamChat,
|
||||||
translateUserAvatar: widget.translateUserAvatar,
|
translateUserAvatar: widget.translateUserAvatar,
|
||||||
|
|||||||
@@ -20,17 +20,17 @@ class StreamDateDivider extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final createdAt = Jiffy(dateTime);
|
final createdAt = Jiffy.parseFromDateTime(dateTime);
|
||||||
final now = Jiffy(DateTime.now());
|
final now = Jiffy.parseFromDateTime(DateTime.now());
|
||||||
|
|
||||||
var dayInfo = createdAt.MMMd;
|
var dayInfo = createdAt.MMMd;
|
||||||
if (createdAt.isSame(now, Units.DAY)) {
|
if (createdAt.isSame(now, unit: Unit.day)) {
|
||||||
dayInfo = context.translations.todayLabel;
|
dayInfo = context.translations.todayLabel;
|
||||||
} else if (createdAt.isSame(now.subtract(days: 1), Units.DAY)) {
|
} else if (createdAt.isSame(now.subtract(days: 1), unit: Unit.day)) {
|
||||||
dayInfo = context.translations.yesterdayLabel;
|
dayInfo = context.translations.yesterdayLabel;
|
||||||
} else if (createdAt.isAfter(now.subtract(days: 7), Units.DAY)) {
|
} else if (createdAt.isAfter(now.subtract(days: 7), unit: Unit.day)) {
|
||||||
dayInfo = createdAt.EEEE;
|
dayInfo = createdAt.EEEE;
|
||||||
} else if (createdAt.isAfter(now.subtract(years: 1), Units.DAY)) {
|
} else if (createdAt.isAfter(now.subtract(years: 1), unit: Unit.day)) {
|
||||||
dayInfo = createdAt.MMMd;
|
dayInfo = createdAt.MMMd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -287,16 +287,16 @@ class ChannelLastMessageDate extends StatelessWidget {
|
|||||||
|
|
||||||
if (lastMessageAt.millisecondsSinceEpoch >=
|
if (lastMessageAt.millisecondsSinceEpoch >=
|
||||||
startOfDay.millisecondsSinceEpoch) {
|
startOfDay.millisecondsSinceEpoch) {
|
||||||
stringDate = Jiffy(lastMessageAt.toLocal()).jm;
|
stringDate = Jiffy.parseFromDateTime(lastMessageAt.toLocal()).jm;
|
||||||
} else if (lastMessageAt.millisecondsSinceEpoch >=
|
} else if (lastMessageAt.millisecondsSinceEpoch >=
|
||||||
startOfDay
|
startOfDay
|
||||||
.subtract(const Duration(days: 1))
|
.subtract(const Duration(days: 1))
|
||||||
.millisecondsSinceEpoch) {
|
.millisecondsSinceEpoch) {
|
||||||
stringDate = context.translations.yesterdayLabel;
|
stringDate = context.translations.yesterdayLabel;
|
||||||
} else if (startOfDay.difference(lastMessageAt).inDays < 7) {
|
} else if (startOfDay.difference(lastMessageAt).inDays < 7) {
|
||||||
stringDate = Jiffy(lastMessageAt.toLocal()).EEEE;
|
stringDate = Jiffy.parseFromDateTime(lastMessageAt.toLocal()).EEEE;
|
||||||
} else {
|
} else {
|
||||||
stringDate = Jiffy(lastMessageAt.toLocal()).yMd;
|
stringDate = Jiffy.parseFromDateTime(lastMessageAt.toLocal()).yMd;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Text(
|
return Text(
|
||||||
|
|||||||
+2
-2
@@ -227,9 +227,9 @@ class MessageSearchTileMessageDate extends StatelessWidget {
|
|||||||
if (now.year != createdAt.year ||
|
if (now.year != createdAt.year ||
|
||||||
now.month != createdAt.month ||
|
now.month != createdAt.month ||
|
||||||
now.day != createdAt.day) {
|
now.day != createdAt.day) {
|
||||||
stringDate = Jiffy(createdAt.toLocal()).yMd;
|
stringDate = Jiffy.parseFromDateTime(createdAt.toLocal()).yMd;
|
||||||
} else {
|
} else {
|
||||||
stringDate = Jiffy(createdAt.toLocal()).jm;
|
stringDate = Jiffy.parseFromDateTime(createdAt.toLocal()).jm;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Text(
|
return Text(
|
||||||
|
|||||||
+3
-5
@@ -202,10 +202,9 @@ class MediaThumbnailProvider extends ImageProvider<MediaThumbnailProvider> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@Deprecated('Will get replaced by loadImage in the next major version.')
|
ImageStreamCompleter loadImage(
|
||||||
ImageStreamCompleter loadBuffer(
|
|
||||||
MediaThumbnailProvider key,
|
MediaThumbnailProvider key,
|
||||||
DecoderBufferCallback decode,
|
ImageDecoderCallback decode,
|
||||||
) {
|
) {
|
||||||
return MultiFrameImageStreamCompleter(
|
return MultiFrameImageStreamCompleter(
|
||||||
codec: _loadAsync(key, decode),
|
codec: _loadAsync(key, decode),
|
||||||
@@ -220,10 +219,9 @@ class MediaThumbnailProvider extends ImageProvider<MediaThumbnailProvider> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated('Will get replaced by loadImage in the next major version.')
|
|
||||||
Future<ui.Codec> _loadAsync(
|
Future<ui.Codec> _loadAsync(
|
||||||
MediaThumbnailProvider key,
|
MediaThumbnailProvider key,
|
||||||
DecoderBufferCallback decode,
|
ImageDecoderCallback decode,
|
||||||
) async {
|
) async {
|
||||||
assert(key == this, '$key is not $this');
|
assert(key == this, '$key is not $this');
|
||||||
final bytes = await media.thumbnailDataWithSize(
|
final bytes = await media.thumbnailDataWithSize(
|
||||||
|
|||||||
+2
-1
@@ -176,11 +176,12 @@ class UserLastActive extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final chatTheme = StreamChatTheme.of(context);
|
final chatTheme = StreamChatTheme.of(context);
|
||||||
|
final lastActive = user.lastActive ?? DateTime.now();
|
||||||
return Text(
|
return Text(
|
||||||
user.online
|
user.online
|
||||||
? context.translations.userOnlineText
|
? context.translations.userOnlineText
|
||||||
: '${context.translations.userLastOnlineText} '
|
: '${context.translations.userLastOnlineText} '
|
||||||
'${Jiffy(user.lastActive).fromNow()}',
|
'${Jiffy.parseFromDateTime(lastActive).fromNow()}',
|
||||||
style: chatTheme.textTheme.footnote.copyWith(
|
style: chatTheme.textTheme.footnote.copyWith(
|
||||||
color: chatTheme.colorTheme.textHighEmphasis.withOpacity(0.5),
|
color: chatTheme.colorTheme.textHighEmphasis.withOpacity(0.5),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -165,9 +165,9 @@ class StreamChatState extends State<StreamChat> {
|
|||||||
@override
|
@override
|
||||||
void didChangeDependencies() {
|
void didChangeDependencies() {
|
||||||
final currentLocale = Localizations.localeOf(context).toString();
|
final currentLocale = Localizations.localeOf(context).toString();
|
||||||
final availableLocales = Jiffy.getAllAvailableLocales();
|
final availableLocales = Jiffy.getSupportedLocales();
|
||||||
if (availableLocales.contains(currentLocale)) {
|
if (availableLocales.contains(currentLocale)) {
|
||||||
Jiffy.locale(currentLocale);
|
Jiffy.setLocale(currentLocale);
|
||||||
}
|
}
|
||||||
super.didChangeDependencies();
|
super.didChangeDependencies();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,11 +74,12 @@ class StreamUserItem extends StatelessWidget {
|
|||||||
|
|
||||||
Widget _buildLastActive(BuildContext context) {
|
Widget _buildLastActive(BuildContext context) {
|
||||||
final chatTheme = StreamChatTheme.of(context);
|
final chatTheme = StreamChatTheme.of(context);
|
||||||
|
final lastActive = user.lastActive ?? DateTime.now();
|
||||||
return Text(
|
return Text(
|
||||||
user.online
|
user.online
|
||||||
? context.translations.userOnlineText
|
? context.translations.userOnlineText
|
||||||
: '${context.translations.userLastOnlineText} '
|
: '${context.translations.userLastOnlineText} '
|
||||||
'${Jiffy(user.lastActive).fromNow()}',
|
'${Jiffy.parseFromDateTime(lastActive).fromNow()}',
|
||||||
style: chatTheme.textTheme.footnote.copyWith(
|
style: chatTheme.textTheme.footnote.copyWith(
|
||||||
color: chatTheme.colorTheme.textHighEmphasis.withOpacity(0.5),
|
color: chatTheme.colorTheme.textHighEmphasis.withOpacity(0.5),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -352,12 +352,12 @@ extension MessageX on Message {
|
|||||||
final userName = user.name;
|
final userName = user.name;
|
||||||
if (linkify) {
|
if (linkify) {
|
||||||
messageTextToRender = messageTextToRender?.replaceAll(
|
messageTextToRender = messageTextToRender?.replaceAll(
|
||||||
'@$userId',
|
RegExp('@($userId|$userName)'),
|
||||||
'[@$userName](@${userName.replaceAll(' ', '')})',
|
'[@$userName]($userId)',
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
messageTextToRender = messageTextToRender?.replaceAll(
|
messageTextToRender = messageTextToRender?.replaceAll(
|
||||||
'@$userId',
|
RegExp('@($userId|$userName)'),
|
||||||
'@$userName',
|
'@$userName',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -230,6 +230,11 @@ typedef OnQuotedMessageTap = void Function(String?);
|
|||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
typedef OnMessageTap = void Function(Message);
|
typedef OnMessageTap = void Function(Message);
|
||||||
|
|
||||||
|
/// {@template onReactionsTap}
|
||||||
|
/// The action to perform when a message's reactions are tapped.
|
||||||
|
/// {@endtemplate}
|
||||||
|
typedef OnReactionsTap = void Function(Message);
|
||||||
|
|
||||||
/// {@template messageSearchItemTapCallback}
|
/// {@template messageSearchItemTapCallback}
|
||||||
/// The action to perform when tapping or clicking on a user in a
|
/// The action to perform when tapping or clicking on a user in a
|
||||||
// ignore: deprecated_member_use_from_same_package
|
// ignore: deprecated_member_use_from_same_package
|
||||||
|
|||||||
@@ -1,47 +1,47 @@
|
|||||||
name: stream_chat_flutter
|
name: stream_chat_flutter
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter.
|
description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter.
|
||||||
version: 6.8.1
|
version: 6.9.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.19.0 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.10.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
cached_network_image: ^3.2.3
|
cached_network_image: ^3.2.3
|
||||||
chewie: ^1.7.0
|
chewie: ^1.7.0
|
||||||
collection: ^1.17.0
|
collection: ^1.17.1
|
||||||
contextmenu: ^3.0.0
|
contextmenu: ^3.0.0
|
||||||
dart_vlc: ^0.4.0
|
dart_vlc: ^0.4.0
|
||||||
desktop_drop: ^0.4.1
|
desktop_drop: ^0.4.1
|
||||||
diacritic: ^0.1.4
|
diacritic: ^0.1.4
|
||||||
dio: ^5.2.1+1
|
dio: ^5.3.2
|
||||||
ezanimation: ^0.6.0
|
ezanimation: ^0.6.0
|
||||||
file_picker: ^5.3.1
|
file_picker: ^5.3.3
|
||||||
file_selector: ^1.0.0
|
file_selector: ^1.0.0
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_markdown: ^0.6.15
|
flutter_markdown: ^0.6.17+1
|
||||||
flutter_portal: ^1.1.4
|
flutter_portal: ^1.1.4
|
||||||
flutter_svg: ^2.0.5
|
flutter_svg: ^2.0.7
|
||||||
http_parser: ^4.0.2
|
http_parser: ^4.0.2
|
||||||
image_gallery_saver: ^2.0.3
|
image_gallery_saver: ^2.0.3
|
||||||
image_picker: ^1.0.0
|
image_picker: ^1.0.2
|
||||||
jiffy: ^5.0.0
|
jiffy: ^6.2.1
|
||||||
lottie: ^2.3.2
|
lottie: ^2.6.0
|
||||||
meta: ^1.8.0
|
meta: ^1.9.1
|
||||||
path_provider: ^2.0.15
|
path_provider: ^2.1.0
|
||||||
photo_manager: ^2.6.0
|
photo_manager: ^2.7.1
|
||||||
photo_view: ^0.14.0
|
photo_view: ^0.14.0
|
||||||
rxdart: ^0.27.7
|
rxdart: ^0.27.7
|
||||||
share_plus: ^7.0.2
|
share_plus: ^7.1.0
|
||||||
shimmer: ^3.0.0
|
shimmer: ^3.0.0
|
||||||
stream_chat_flutter_core: ^6.7.0
|
stream_chat_flutter_core: ^6.8.0
|
||||||
synchronized: ^3.1.0
|
synchronized: ^3.1.0
|
||||||
thumblr: ^0.0.4
|
thumblr: ^0.0.4
|
||||||
url_launcher: ^6.1.11
|
url_launcher: ^6.1.12
|
||||||
video_player: ^2.7.0
|
video_player: ^2.7.0
|
||||||
video_player_macos: ^2.0.1
|
video_player_macos: ^2.0.1
|
||||||
video_thumbnail: ^0.5.3
|
video_thumbnail: ^0.5.3
|
||||||
@@ -73,5 +73,5 @@ dev_dependencies:
|
|||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
golden_toolkit: ^0.15.0
|
golden_toolkit: ^0.15.0
|
||||||
mocktail: ^0.3.0
|
mocktail: ^1.0.0
|
||||||
path: ^1.8.2
|
path: ^1.8.3
|
||||||
@@ -148,4 +148,126 @@ void main() {
|
|||||||
expect('ㅎㅎㅎㅎ'.isOnlyEmoji, false);
|
expect('ㅎㅎㅎㅎ'.isOnlyEmoji, false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
group('Message Extension Tests', () {
|
||||||
|
test('replaceMentions should replace user mentions with names and IDs', () {
|
||||||
|
final user1 = User(id: 'user1', name: 'Alice');
|
||||||
|
final user2 = User(id: 'user2', name: 'Bob');
|
||||||
|
|
||||||
|
final message = Message(
|
||||||
|
text: 'Hello, @user1 and @user2!',
|
||||||
|
mentionedUsers: [user1, user2],
|
||||||
|
);
|
||||||
|
|
||||||
|
final modifiedMessage = message.replaceMentions();
|
||||||
|
|
||||||
|
expect(modifiedMessage.text, contains('[@Alice](user1)'));
|
||||||
|
expect(modifiedMessage.text, contains('[@Bob](user2)'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('replaceMentions without linkify should not add links', () {
|
||||||
|
final user = User(id: 'user1', name: 'Alice');
|
||||||
|
|
||||||
|
final message = Message(
|
||||||
|
text: 'Hello, @user1!',
|
||||||
|
mentionedUsers: [user],
|
||||||
|
);
|
||||||
|
|
||||||
|
final modifiedMessage = message.replaceMentions(linkify: false);
|
||||||
|
|
||||||
|
expect(modifiedMessage.text, contains('@Alice'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('replaceMentions should handle mentions with usernames', () {
|
||||||
|
final user = User(id: 'user1', name: 'Alice');
|
||||||
|
|
||||||
|
final message = Message(
|
||||||
|
text: 'Hello, @Alice!',
|
||||||
|
mentionedUsers: [user],
|
||||||
|
);
|
||||||
|
|
||||||
|
final modifiedMessage = message.replaceMentions();
|
||||||
|
|
||||||
|
expect(modifiedMessage.text, contains('[@Alice](user1)'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'''replaceMentions without linkify should not change mentions with usernames''',
|
||||||
|
() {
|
||||||
|
final user = User(id: 'user1', name: 'Alice');
|
||||||
|
|
||||||
|
final message = Message(
|
||||||
|
text: 'Hello, @Alice!',
|
||||||
|
mentionedUsers: [user],
|
||||||
|
);
|
||||||
|
|
||||||
|
final modifiedMessage = message.replaceMentions(linkify: false);
|
||||||
|
|
||||||
|
expect(modifiedMessage.text, contains('@Alice'));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'replaceMentions should replace mixed user mentions with names and IDs',
|
||||||
|
() {
|
||||||
|
final user1 = User(id: 'user1', name: 'Alice');
|
||||||
|
final user2 = User(id: 'user2', name: 'Bob');
|
||||||
|
|
||||||
|
final message = Message(
|
||||||
|
text: 'Hello, @user1 and @Bob!',
|
||||||
|
mentionedUsers: [user1, user2],
|
||||||
|
);
|
||||||
|
|
||||||
|
final modifiedMessage = message.replaceMentions();
|
||||||
|
|
||||||
|
expect(modifiedMessage.text, contains('[@Alice](user1)'));
|
||||||
|
expect(modifiedMessage.text, contains('[@Bob](user2)'));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test('replaceMentionsWithId should replace user names with IDs', () {
|
||||||
|
final user1 = User(id: 'user1', name: 'Alice');
|
||||||
|
final user2 = User(id: 'user2', name: 'Bob');
|
||||||
|
|
||||||
|
final message = Message(
|
||||||
|
text: 'Hello, @Alice and @Bob!',
|
||||||
|
mentionedUsers: [user1, user2],
|
||||||
|
);
|
||||||
|
|
||||||
|
final modifiedMessage = message.replaceMentionsWithId();
|
||||||
|
|
||||||
|
expect(modifiedMessage.text, contains('@user1'));
|
||||||
|
expect(modifiedMessage.text, contains('@user2'));
|
||||||
|
expect(modifiedMessage.text, isNot(contains('@Alice')));
|
||||||
|
expect(modifiedMessage.text, isNot(contains('@Bob')));
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'replaceMentionsWithId should not change message without mentions',
|
||||||
|
() {
|
||||||
|
final message = Message(
|
||||||
|
text: 'Hello, @Alice!',
|
||||||
|
);
|
||||||
|
|
||||||
|
final modifiedMessage = message.replaceMentionsWithId();
|
||||||
|
|
||||||
|
expect(modifiedMessage.text, equals('Hello, @Alice!'));
|
||||||
|
expect(modifiedMessage.text, isNot(contains('@user1')));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test('replaceMentionsWithId should handle message with only mention', () {
|
||||||
|
final user = User(id: 'user1', name: 'Alice');
|
||||||
|
|
||||||
|
final message = Message(
|
||||||
|
text: '@Alice',
|
||||||
|
mentionedUsers: [user],
|
||||||
|
);
|
||||||
|
|
||||||
|
final modifiedMessage = message.replaceMentionsWithId();
|
||||||
|
|
||||||
|
expect(modifiedMessage.text, contains('@user1'));
|
||||||
|
expect(modifiedMessage.text, isNot(contains('@Alice')));
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
## 6.8.0
|
||||||
|
|
||||||
|
- Updated minimum supported `SDK` version to Flutter 3.10/Dart 3.0
|
||||||
|
- Updated `stream_chat` dependency to [`6.8.0`](https://pub.dev/packages/stream_chat/changelog).
|
||||||
|
|
||||||
## 6.7.0
|
## 6.7.0
|
||||||
|
|
||||||
- Updated `stream_chat` dependency to [`6.7.0`](https://pub.dev/packages/stream_chat/changelog).
|
- Updated `stream_chat` dependency to [`6.7.0`](https://pub.dev/packages/stream_chat/changelog).
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ publish_to: 'none'
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.19.0 <4.0.0'
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.10.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
cupertino_icons: ^1.0.3
|
cupertino_icons: ^1.0.3
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
name: stream_chat_flutter_core
|
name: stream_chat_flutter_core
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter.
|
description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter.
|
||||||
version: 6.7.0
|
version: 6.8.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.19.0 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.10.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
collection: ^1.17.0
|
collection: ^1.17.1
|
||||||
connectivity_plus: ^4.0.1
|
connectivity_plus: ^4.0.2
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
freezed_annotation: ^2.2.0
|
freezed_annotation: ^2.4.1
|
||||||
meta: ^1.8.0
|
meta: ^1.9.1
|
||||||
rxdart: ^0.27.7
|
rxdart: ^0.27.7
|
||||||
stream_chat: ^6.7.0
|
stream_chat: ^6.8.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.3.3
|
build_runner: ^2.4.6
|
||||||
fake_async: ^1.3.1
|
fake_async: ^1.3.1
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
freezed: ^2.4.0
|
freezed: ^2.4.1
|
||||||
mocktail: ^0.3.0
|
mocktail: ^1.0.0
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
## 5.9.0
|
||||||
|
|
||||||
|
* Updated minimum supported `SDK` version to Flutter 3.10/Dart 3.0
|
||||||
|
* Updated `stream_chat_flutter` dependency to [`6.9.0`](https://pub.dev/packages/stream_chat_flutter/changelog).
|
||||||
|
|
||||||
## 5.8.0
|
## 5.8.0
|
||||||
|
|
||||||
* Updated `stream_chat_flutter` dependency to [`6.8.0`](https://pub.dev/packages/stream_chat_flutter/changelog).
|
* Updated `stream_chat_flutter` dependency to [`6.8.0`](https://pub.dev/packages/stream_chat_flutter/changelog).
|
||||||
|
|||||||
@@ -270,13 +270,15 @@ class NnStreamChatLocalizations extends GlobalStreamChatLocalizations {
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return 'yesterday';
|
return 'yesterday';
|
||||||
} else {
|
} else {
|
||||||
return 'on ${Jiffy(date).MMMd}';
|
return 'on ${Jiffy.parseFromDateTime(date).MMMd}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
'Sent ${_getDay(date)} at ${Jiffy(time.toLocal()).format('HH:mm')}';
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return 'Sent ${_getDay(date)} at ${atTime.jm}';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => 'Today';
|
String get todayLabel => 'Today';
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ publish_to: 'none'
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.19.0 <4.0.0'
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.10.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
cupertino_icons: ^1.0.3
|
cupertino_icons: ^1.0.3
|
||||||
|
|||||||
@@ -249,13 +249,15 @@ class StreamChatLocalizationsCa extends GlobalStreamChatLocalizations {
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return 'ahir';
|
return 'ahir';
|
||||||
} else {
|
} else {
|
||||||
return 'el ${Jiffy(date).MMMd}';
|
return 'el ${Jiffy.parseFromDateTime(date).MMMd}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
'''Enviat el ${_getDay(date)} a les ${Jiffy(time.toLocal()).format('HH:mm')}''';
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return 'Enviat el ${_getDay(date)} a les ${atTime.jm}';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => 'Avui';
|
String get todayLabel => 'Avui';
|
||||||
|
|||||||
@@ -239,13 +239,15 @@ class StreamChatLocalizationsDe extends GlobalStreamChatLocalizations {
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return 'Gestern';
|
return 'Gestern';
|
||||||
} else {
|
} else {
|
||||||
return 'am ${Jiffy(date).MMMd}';
|
return 'am ${Jiffy.parseFromDateTime(date).MMMd}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
'Gesendet ${_getDay(date)} am ${Jiffy(time.toLocal()).format('HH:mm')}';
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return 'Gesendet ${_getDay(date)} am ${atTime.jm}';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => 'Heute';
|
String get todayLabel => 'Heute';
|
||||||
|
|||||||
@@ -246,13 +246,15 @@ class StreamChatLocalizationsEn extends GlobalStreamChatLocalizations {
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return 'yesterday';
|
return 'yesterday';
|
||||||
} else {
|
} else {
|
||||||
return 'on ${Jiffy(date).MMMd}';
|
return 'on ${Jiffy.parseFromDateTime(date).MMMd}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
'Sent ${_getDay(date)} at ${Jiffy(time.toLocal()).format('HH:mm')}';
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return 'Sent ${_getDay(date)} at ${atTime.jm}';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => 'Today';
|
String get todayLabel => 'Today';
|
||||||
|
|||||||
@@ -250,13 +250,15 @@ class StreamChatLocalizationsEs extends GlobalStreamChatLocalizations {
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return 'ayer';
|
return 'ayer';
|
||||||
} else {
|
} else {
|
||||||
return 'el ${Jiffy(date).MMMd}';
|
return 'el ${Jiffy.parseFromDateTime(date).MMMd}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
'''Enviado el ${_getDay(date)} a las ${Jiffy(time.toLocal()).format('HH:mm')}''';
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return 'Enviado el ${_getDay(date)} a las ${atTime.jm}';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => 'Hoy';
|
String get todayLabel => 'Hoy';
|
||||||
|
|||||||
@@ -249,13 +249,15 @@ class StreamChatLocalizationsFr extends GlobalStreamChatLocalizations {
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return 'hier';
|
return 'hier';
|
||||||
} else {
|
} else {
|
||||||
return 'le ${Jiffy(date).MMMd}';
|
return 'le ${Jiffy.parseFromDateTime(date).MMMd}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
'Envoyé ${_getDay(date)} à ${Jiffy(time.toLocal()).format('HH:mm')}';
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return 'Envoyé ${_getDay(date)} à ${atTime.jm}';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => "Aujourd'hui";
|
String get todayLabel => "Aujourd'hui";
|
||||||
|
|||||||
@@ -243,13 +243,15 @@ class StreamChatLocalizationsHi extends GlobalStreamChatLocalizations {
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return 'कल';
|
return 'कल';
|
||||||
} else {
|
} else {
|
||||||
return '${Jiffy(date).MMMd} को';
|
return '${Jiffy.parseFromDateTime(date).MMMd} को';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
'${_getDay(date)} ${Jiffy(time.toLocal()).format('HH:mm')} बजे भेजा गया';
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return '${_getDay(date)} ${atTime.jm} बजे भेजा गया';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => 'आज';
|
String get todayLabel => 'आज';
|
||||||
|
|||||||
@@ -252,13 +252,15 @@ Il file è troppo grande per essere caricato. Il limite è di $limitInMB MB.''';
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return 'ieri';
|
return 'ieri';
|
||||||
} else {
|
} else {
|
||||||
return 'il ${Jiffy(date).MMMd}';
|
return 'il ${Jiffy.parseFromDateTime(date).MMMd}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
"Inviato ${_getDay(date)} alle ${Jiffy(time.toLocal()).format('HH:mm')}";
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return 'Inviato ${_getDay(date)} alle ${atTime.jm}';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => 'Oggi';
|
String get todayLabel => 'Oggi';
|
||||||
|
|||||||
@@ -236,13 +236,15 @@ class StreamChatLocalizationsJa extends GlobalStreamChatLocalizations {
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return '昨日';
|
return '昨日';
|
||||||
} else {
|
} else {
|
||||||
return '${Jiffy(date).MMMd}に';
|
return '${Jiffy.parseFromDateTime(date).MMMd}に';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
'${_getDay(date)}の${Jiffy(time.toLocal()).format('HH:mm')}に送信しました ';
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return '${_getDay(date)}の${atTime.jm}に送信しました ';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => '今日';
|
String get todayLabel => '今日';
|
||||||
|
|||||||
@@ -235,13 +235,15 @@ class StreamChatLocalizationsKo extends GlobalStreamChatLocalizations {
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return '어제';
|
return '어제';
|
||||||
} else {
|
} else {
|
||||||
return '${Jiffy(date).MMMd}에';
|
return '${Jiffy.parseFromDateTime(date).MMMd}에';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
'${_getDay(date)} ${Jiffy(time.toLocal()).format('HH:mm')}에 보냈습니다';
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return '${_getDay(date)} ${atTime.jm}에 보냈습니다';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => '오늘';
|
String get todayLabel => '오늘';
|
||||||
|
|||||||
@@ -242,13 +242,15 @@ class StreamChatLocalizationsNo extends GlobalStreamChatLocalizations {
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return 'i går';
|
return 'i går';
|
||||||
} else {
|
} else {
|
||||||
return 'på ${Jiffy(date).MMMd}';
|
return 'på ${Jiffy.parseFromDateTime(date).MMMd}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
'Sent ${_getDay(date)} kl. ${Jiffy(time.toLocal()).format('HH:mm')}';
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return 'Sent ${_getDay(date)} kl. ${atTime.jm}';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => 'I dag';
|
String get todayLabel => 'I dag';
|
||||||
|
|||||||
@@ -244,13 +244,15 @@ class StreamChatLocalizationsPt extends GlobalStreamChatLocalizations {
|
|||||||
} else if (date == yesterday) {
|
} else if (date == yesterday) {
|
||||||
return 'Ontem';
|
return 'Ontem';
|
||||||
} else {
|
} else {
|
||||||
return 'o ${Jiffy(date).MMMd}';
|
return 'o ${Jiffy.parseFromDateTime(date).MMMd}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String sentAtText({required DateTime date, required DateTime time}) =>
|
String sentAtText({required DateTime date, required DateTime time}) {
|
||||||
'''Enviado ${_getDay(date)} às ${Jiffy(time.toLocal()).format('HH:mm')}''';
|
final atTime = Jiffy.parseFromDateTime(time.toLocal());
|
||||||
|
return 'Enviado ${_getDay(date)} às ${atTime.jm}';
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get todayLabel => 'Hoje';
|
String get todayLabel => 'Hoje';
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
name: stream_chat_localizations
|
name: stream_chat_localizations
|
||||||
description: The Official localizations for Stream Chat Flutter, a service for building chat applications
|
description: The Official localizations for Stream Chat Flutter, a service for building chat applications
|
||||||
version: 5.8.0
|
version: 5.9.0
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.19.0 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.10.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
stream_chat_flutter: ^6.8.0
|
stream_chat_flutter: ^6.9.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
## 6.8.0
|
||||||
|
|
||||||
|
- Updated minimum supported `SDK` version to Flutter 3.10/Dart 3.0
|
||||||
|
- Updated `stream_chat` dependency to [`6.8.0`](https://pub.dev/packages/stream_chat/changelog).
|
||||||
|
|
||||||
## 6.7.0
|
## 6.7.0
|
||||||
|
|
||||||
- [[#1683]](https://github.com/GetStream/stream-chat-flutter/issues/1683) Fixed SqliteException no such
|
- [[#1683]](https://github.com/GetStream/stream-chat-flutter/issues/1683) Fixed SqliteException no such
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ publish_to: 'none'
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.19.0 <4.0.0'
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.10.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
cupertino_icons: ^1.0.3
|
cupertino_icons: ^1.0.3
|
||||||
|
|||||||
@@ -41,16 +41,13 @@ class $ChannelsTable extends Channels
|
|||||||
.withConverter<Map<String, dynamic>>($ChannelsTable.$converterconfig);
|
.withConverter<Map<String, dynamic>>($ChannelsTable.$converterconfig);
|
||||||
static const VerificationMeta _frozenMeta = const VerificationMeta('frozen');
|
static const VerificationMeta _frozenMeta = const VerificationMeta('frozen');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> frozen =
|
late final GeneratedColumn<bool> frozen = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('frozen', aliasedName, false,
|
'frozen', aliasedName, false,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints:
|
||||||
SqlDialect.sqlite: 'CHECK ("frozen" IN (0, 1))',
|
GeneratedColumn.constraintIsAlways('CHECK ("frozen" IN (0, 1))'),
|
||||||
SqlDialect.mysql: '',
|
defaultValue: const Constant(false));
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}),
|
|
||||||
defaultValue: const Constant(false));
|
|
||||||
static const VerificationMeta _lastMessageAtMeta =
|
static const VerificationMeta _lastMessageAtMeta =
|
||||||
const VerificationMeta('lastMessageAt');
|
const VerificationMeta('lastMessageAt');
|
||||||
@override
|
@override
|
||||||
@@ -726,28 +723,22 @@ class $MessagesTable extends Messages
|
|||||||
static const VerificationMeta _showInChannelMeta =
|
static const VerificationMeta _showInChannelMeta =
|
||||||
const VerificationMeta('showInChannel');
|
const VerificationMeta('showInChannel');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> showInChannel =
|
late final GeneratedColumn<bool> showInChannel = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('show_in_channel', aliasedName, true,
|
'show_in_channel', aliasedName, true,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
SqlDialect.sqlite: 'CHECK ("show_in_channel" IN (0, 1))',
|
'CHECK ("show_in_channel" IN (0, 1))'));
|
||||||
SqlDialect.mysql: '',
|
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}));
|
|
||||||
static const VerificationMeta _shadowedMeta =
|
static const VerificationMeta _shadowedMeta =
|
||||||
const VerificationMeta('shadowed');
|
const VerificationMeta('shadowed');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> shadowed =
|
late final GeneratedColumn<bool> shadowed = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('shadowed', aliasedName, false,
|
'shadowed', aliasedName, false,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints:
|
||||||
SqlDialect.sqlite: 'CHECK ("shadowed" IN (0, 1))',
|
GeneratedColumn.constraintIsAlways('CHECK ("shadowed" IN (0, 1))'),
|
||||||
SqlDialect.mysql: '',
|
defaultValue: const Constant(false));
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}),
|
|
||||||
defaultValue: const Constant(false));
|
|
||||||
static const VerificationMeta _commandMeta =
|
static const VerificationMeta _commandMeta =
|
||||||
const VerificationMeta('command');
|
const VerificationMeta('command');
|
||||||
@override
|
@override
|
||||||
@@ -797,16 +788,13 @@ class $MessagesTable extends Messages
|
|||||||
type: DriftSqlType.string, requiredDuringInsert: false);
|
type: DriftSqlType.string, requiredDuringInsert: false);
|
||||||
static const VerificationMeta _pinnedMeta = const VerificationMeta('pinned');
|
static const VerificationMeta _pinnedMeta = const VerificationMeta('pinned');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> pinned =
|
late final GeneratedColumn<bool> pinned = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('pinned', aliasedName, false,
|
'pinned', aliasedName, false,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints:
|
||||||
SqlDialect.sqlite: 'CHECK ("pinned" IN (0, 1))',
|
GeneratedColumn.constraintIsAlways('CHECK ("pinned" IN (0, 1))'),
|
||||||
SqlDialect.mysql: '',
|
defaultValue: const Constant(false));
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}),
|
|
||||||
defaultValue: const Constant(false));
|
|
||||||
static const VerificationMeta _pinnedAtMeta =
|
static const VerificationMeta _pinnedAtMeta =
|
||||||
const VerificationMeta('pinnedAt');
|
const VerificationMeta('pinnedAt');
|
||||||
@override
|
@override
|
||||||
@@ -2004,28 +1992,22 @@ class $PinnedMessagesTable extends PinnedMessages
|
|||||||
static const VerificationMeta _showInChannelMeta =
|
static const VerificationMeta _showInChannelMeta =
|
||||||
const VerificationMeta('showInChannel');
|
const VerificationMeta('showInChannel');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> showInChannel =
|
late final GeneratedColumn<bool> showInChannel = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('show_in_channel', aliasedName, true,
|
'show_in_channel', aliasedName, true,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
SqlDialect.sqlite: 'CHECK ("show_in_channel" IN (0, 1))',
|
'CHECK ("show_in_channel" IN (0, 1))'));
|
||||||
SqlDialect.mysql: '',
|
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}));
|
|
||||||
static const VerificationMeta _shadowedMeta =
|
static const VerificationMeta _shadowedMeta =
|
||||||
const VerificationMeta('shadowed');
|
const VerificationMeta('shadowed');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> shadowed =
|
late final GeneratedColumn<bool> shadowed = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('shadowed', aliasedName, false,
|
'shadowed', aliasedName, false,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints:
|
||||||
SqlDialect.sqlite: 'CHECK ("shadowed" IN (0, 1))',
|
GeneratedColumn.constraintIsAlways('CHECK ("shadowed" IN (0, 1))'),
|
||||||
SqlDialect.mysql: '',
|
defaultValue: const Constant(false));
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}),
|
|
||||||
defaultValue: const Constant(false));
|
|
||||||
static const VerificationMeta _commandMeta =
|
static const VerificationMeta _commandMeta =
|
||||||
const VerificationMeta('command');
|
const VerificationMeta('command');
|
||||||
@override
|
@override
|
||||||
@@ -2075,16 +2057,13 @@ class $PinnedMessagesTable extends PinnedMessages
|
|||||||
type: DriftSqlType.string, requiredDuringInsert: false);
|
type: DriftSqlType.string, requiredDuringInsert: false);
|
||||||
static const VerificationMeta _pinnedMeta = const VerificationMeta('pinned');
|
static const VerificationMeta _pinnedMeta = const VerificationMeta('pinned');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> pinned =
|
late final GeneratedColumn<bool> pinned = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('pinned', aliasedName, false,
|
'pinned', aliasedName, false,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints:
|
||||||
SqlDialect.sqlite: 'CHECK ("pinned" IN (0, 1))',
|
GeneratedColumn.constraintIsAlways('CHECK ("pinned" IN (0, 1))'),
|
||||||
SqlDialect.mysql: '',
|
defaultValue: const Constant(false));
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}),
|
|
||||||
defaultValue: const Constant(false));
|
|
||||||
static const VerificationMeta _pinnedAtMeta =
|
static const VerificationMeta _pinnedAtMeta =
|
||||||
const VerificationMeta('pinnedAt');
|
const VerificationMeta('pinnedAt');
|
||||||
@override
|
@override
|
||||||
@@ -3928,28 +3907,22 @@ class $UsersTable extends Users with TableInfo<$UsersTable, UserEntity> {
|
|||||||
type: DriftSqlType.dateTime, requiredDuringInsert: false);
|
type: DriftSqlType.dateTime, requiredDuringInsert: false);
|
||||||
static const VerificationMeta _onlineMeta = const VerificationMeta('online');
|
static const VerificationMeta _onlineMeta = const VerificationMeta('online');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> online =
|
late final GeneratedColumn<bool> online = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('online', aliasedName, false,
|
'online', aliasedName, false,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints:
|
||||||
SqlDialect.sqlite: 'CHECK ("online" IN (0, 1))',
|
GeneratedColumn.constraintIsAlways('CHECK ("online" IN (0, 1))'),
|
||||||
SqlDialect.mysql: '',
|
defaultValue: const Constant(false));
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}),
|
|
||||||
defaultValue: const Constant(false));
|
|
||||||
static const VerificationMeta _bannedMeta = const VerificationMeta('banned');
|
static const VerificationMeta _bannedMeta = const VerificationMeta('banned');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> banned =
|
late final GeneratedColumn<bool> banned = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('banned', aliasedName, false,
|
'banned', aliasedName, false,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints:
|
||||||
SqlDialect.sqlite: 'CHECK ("banned" IN (0, 1))',
|
GeneratedColumn.constraintIsAlways('CHECK ("banned" IN (0, 1))'),
|
||||||
SqlDialect.mysql: '',
|
defaultValue: const Constant(false));
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}),
|
|
||||||
defaultValue: const Constant(false));
|
|
||||||
static const VerificationMeta _extraDataMeta =
|
static const VerificationMeta _extraDataMeta =
|
||||||
const VerificationMeta('extraData');
|
const VerificationMeta('extraData');
|
||||||
@override
|
@override
|
||||||
@@ -4388,54 +4361,42 @@ class $MembersTable extends Members
|
|||||||
static const VerificationMeta _invitedMeta =
|
static const VerificationMeta _invitedMeta =
|
||||||
const VerificationMeta('invited');
|
const VerificationMeta('invited');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> invited =
|
late final GeneratedColumn<bool> invited = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('invited', aliasedName, false,
|
'invited', aliasedName, false,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints:
|
||||||
SqlDialect.sqlite: 'CHECK ("invited" IN (0, 1))',
|
GeneratedColumn.constraintIsAlways('CHECK ("invited" IN (0, 1))'),
|
||||||
SqlDialect.mysql: '',
|
defaultValue: const Constant(false));
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}),
|
|
||||||
defaultValue: const Constant(false));
|
|
||||||
static const VerificationMeta _bannedMeta = const VerificationMeta('banned');
|
static const VerificationMeta _bannedMeta = const VerificationMeta('banned');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> banned =
|
late final GeneratedColumn<bool> banned = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('banned', aliasedName, false,
|
'banned', aliasedName, false,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints:
|
||||||
SqlDialect.sqlite: 'CHECK ("banned" IN (0, 1))',
|
GeneratedColumn.constraintIsAlways('CHECK ("banned" IN (0, 1))'),
|
||||||
SqlDialect.mysql: '',
|
defaultValue: const Constant(false));
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}),
|
|
||||||
defaultValue: const Constant(false));
|
|
||||||
static const VerificationMeta _shadowBannedMeta =
|
static const VerificationMeta _shadowBannedMeta =
|
||||||
const VerificationMeta('shadowBanned');
|
const VerificationMeta('shadowBanned');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> shadowBanned =
|
late final GeneratedColumn<bool> shadowBanned = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('shadow_banned', aliasedName, false,
|
'shadow_banned', aliasedName, false,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
SqlDialect.sqlite: 'CHECK ("shadow_banned" IN (0, 1))',
|
'CHECK ("shadow_banned" IN (0, 1))'),
|
||||||
SqlDialect.mysql: '',
|
defaultValue: const Constant(false));
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}),
|
|
||||||
defaultValue: const Constant(false));
|
|
||||||
static const VerificationMeta _isModeratorMeta =
|
static const VerificationMeta _isModeratorMeta =
|
||||||
const VerificationMeta('isModerator');
|
const VerificationMeta('isModerator');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<bool> isModerator =
|
late final GeneratedColumn<bool> isModerator = GeneratedColumn<bool>(
|
||||||
GeneratedColumn<bool>('is_moderator', aliasedName, false,
|
'is_moderator', aliasedName, false,
|
||||||
type: DriftSqlType.bool,
|
type: DriftSqlType.bool,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultConstraints: GeneratedColumn.constraintsDependsOnDialect({
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
SqlDialect.sqlite: 'CHECK ("is_moderator" IN (0, 1))',
|
'CHECK ("is_moderator" IN (0, 1))'),
|
||||||
SqlDialect.mysql: '',
|
defaultValue: const Constant(false));
|
||||||
SqlDialect.postgres: '',
|
|
||||||
}),
|
|
||||||
defaultValue: const Constant(false));
|
|
||||||
static const VerificationMeta _createdAtMeta =
|
static const VerificationMeta _createdAtMeta =
|
||||||
const VerificationMeta('createdAt');
|
const VerificationMeta('createdAt');
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
name: stream_chat_persistence
|
name: stream_chat_persistence
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter.
|
description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter.
|
||||||
version: 6.7.0
|
version: 6.8.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.19.0 <4.0.0"
|
sdk: ">=3.0.0 <4.0.0"
|
||||||
flutter: ">=3.7.0"
|
flutter: ">=3.10.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
drift: ^2.8.0
|
drift: ^2.11.0
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
logging: ^1.2.0
|
logging: ^1.2.0
|
||||||
meta: ^1.8.0
|
meta: ^1.9.1
|
||||||
path: ^1.8.2
|
path: ^1.8.3
|
||||||
path_provider: ^2.0.15
|
path_provider: ^2.1.0
|
||||||
sqlite3_flutter_libs: ^0.5.15
|
sqlite3_flutter_libs: ^0.5.15
|
||||||
stream_chat: ^6.7.0
|
stream_chat: ^6.8.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.3.3
|
build_runner: ^2.4.6
|
||||||
drift_dev: ^2.8.3
|
drift_dev: ^2.11.0
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
mocktail: ^0.3.0
|
mocktail: ^1.0.0
|
||||||
|
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat_flutter_workspace
|
name: stream_chat_flutter_workspace
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=2.19.0 <4.0.0'
|
sdk: '>=3.0.0 <4.0.0'
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
melos: ^3.1.0
|
melos: ^3.1.0
|
||||||
|
|||||||
Reference in New Issue
Block a user