change file structure, replace rate_limit with the pub dependency
Signed-off-by: Sahil Kumar <[email protected]>
This commit is contained in:
+4
-5
@@ -4,13 +4,12 @@ import 'dart:math';
|
|||||||
import 'package:collection/collection.dart'
|
import 'package:collection/collection.dart'
|
||||||
show IterableExtension, ListEquality;
|
show IterableExtension, ListEquality;
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:logging/logging.dart';
|
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
import 'package:stream_chat/src/api/retry_queue.dart';
|
import 'package:stream_chat/src/client/retry_queue.dart';
|
||||||
import 'package:stream_chat/src/core/utils.dart';
|
import 'package:stream_chat/src/core/util/utils.dart';
|
||||||
import 'package:stream_chat/src/errors/stream_chat_error.dart';
|
import 'package:stream_chat/src/core/error/error.dart';
|
||||||
import 'package:stream_chat/src/event_type.dart';
|
import 'package:stream_chat/src/event_type.dart';
|
||||||
import 'package:stream_chat/src/extensions/rate_limit.dart';
|
import 'package:rate_limiter/rate_limiter.dart';
|
||||||
import 'package:stream_chat/src/core/models/attachment_file.dart';
|
import 'package:stream_chat/src/core/models/attachment_file.dart';
|
||||||
import 'package:stream_chat/src/core/models/channel_state.dart';
|
import 'package:stream_chat/src/core/models/channel_state.dart';
|
||||||
import 'package:stream_chat/src/core/models/user.dart';
|
import 'package:stream_chat/src/core/models/user.dart';
|
||||||
+4
-5
@@ -1,20 +1,19 @@
|
|||||||
// ignore_for_file: unnecessary_getters_setters
|
// ignore_for_file: unnecessary_getters_setters
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
import 'package:stream_chat/src/api/channel.dart';
|
import 'package:stream_chat/src/client/channel.dart';
|
||||||
import 'package:stream_chat/src/core/utils.dart';
|
import 'package:stream_chat/src/core/util/utils.dart';
|
||||||
import 'package:stream_chat/src/errors/stream_chat_error.dart';
|
import 'package:stream_chat/src/core/error/error.dart';
|
||||||
import 'package:stream_chat/src/location.dart';
|
import 'package:stream_chat/src/location.dart';
|
||||||
import 'package:stream_chat/src/ws/connection_status.dart';
|
import 'package:stream_chat/src/ws/connection_status.dart';
|
||||||
import 'package:stream_chat/src/core/api/attachment_file_uploader.dart';
|
import 'package:stream_chat/src/core/api/attachment_file_uploader.dart';
|
||||||
import 'package:stream_chat/src/core/api/requests.dart';
|
import 'package:stream_chat/src/core/api/requests.dart';
|
||||||
import 'package:stream_chat/src/core/api/responses.dart';
|
import 'package:stream_chat/src/core/api/responses.dart';
|
||||||
import 'package:stream_chat/src/api/retry_policy.dart';
|
import 'package:stream_chat/src/client/retry_policy.dart';
|
||||||
import 'package:stream_chat/src/ws/websocket.dart';
|
import 'package:stream_chat/src/ws/websocket.dart';
|
||||||
import 'package:stream_chat/src/core/api/stream_chat_api.dart';
|
import 'package:stream_chat/src/core/api/stream_chat_api.dart';
|
||||||
import 'package:stream_chat/src/core/http/connection_id_manager.dart';
|
import 'package:stream_chat/src/core/http/connection_id_manager.dart';
|
||||||
+2
-2
@@ -1,5 +1,5 @@
|
|||||||
import 'package:stream_chat/src/client.dart';
|
import 'package:stream_chat/src/client/client.dart';
|
||||||
import 'package:stream_chat/src/errors/stream_chat_error.dart';
|
import 'package:stream_chat/src/core/error/error.dart';
|
||||||
|
|
||||||
/// The retry options
|
/// The retry options
|
||||||
class RetryPolicy {
|
class RetryPolicy {
|
||||||
+3
-3
@@ -3,9 +3,9 @@ import 'dart:async';
|
|||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
import 'package:stream_chat/src/api/channel.dart';
|
import 'package:stream_chat/src/client/channel.dart';
|
||||||
import 'package:stream_chat/src/api/retry_policy.dart';
|
import 'package:stream_chat/src/client/retry_policy.dart';
|
||||||
import 'package:stream_chat/src/errors/stream_chat_error.dart';
|
import 'package:stream_chat/src/core/error/error.dart';
|
||||||
import 'package:stream_chat/src/event_type.dart';
|
import 'package:stream_chat/src/event_type.dart';
|
||||||
import 'package:stream_chat/src/core/models/message.dart';
|
import 'package:stream_chat/src/core/models/message.dart';
|
||||||
import 'package:stream_chat/stream_chat.dart';
|
import 'package:stream_chat/stream_chat.dart';
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:stream_chat/src/core/api/responses.dart';
|
import 'package:stream_chat/src/core/api/responses.dart';
|
||||||
import 'package:stream_chat/src/core/http/stream_http_client.dart';
|
import 'package:stream_chat/src/core/http/stream_http_client.dart';
|
||||||
import 'package:stream_chat/src/extensions/string_extension.dart';
|
import 'package:stream_chat/src/core/util/extension.dart';
|
||||||
import 'package:stream_chat/src/core/models/attachment_file.dart';
|
import 'package:stream_chat/src/core/models/attachment_file.dart';
|
||||||
|
|
||||||
/// Class responsible for uploading images and files to a given channel
|
/// Class responsible for uploading images and files to a given channel
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:stream_chat/src/client.dart';
|
import 'package:stream_chat/src/client/client.dart';
|
||||||
import 'package:stream_chat/src/core/models/channel_model.dart';
|
import 'package:stream_chat/src/core/models/channel_model.dart';
|
||||||
import 'package:stream_chat/src/core/models/channel_state.dart';
|
import 'package:stream_chat/src/core/models/channel_state.dart';
|
||||||
import 'package:stream_chat/src/core/models/device.dart';
|
import 'package:stream_chat/src/core/models/device.dart';
|
||||||
@@ -9,7 +9,7 @@ import 'package:stream_chat/src/core/models/message.dart';
|
|||||||
import 'package:stream_chat/src/core/models/reaction.dart';
|
import 'package:stream_chat/src/core/models/reaction.dart';
|
||||||
import 'package:stream_chat/src/core/models/read.dart';
|
import 'package:stream_chat/src/core/models/read.dart';
|
||||||
import 'package:stream_chat/src/core/models/user.dart';
|
import 'package:stream_chat/src/core/models/user.dart';
|
||||||
import 'package:stream_chat/src/errors/stream_chat_error.dart';
|
import 'package:stream_chat/src/core/error/error.dart';
|
||||||
|
|
||||||
part 'responses.g.dart';
|
part 'responses.g.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export 'chat_error_code.dart';
|
||||||
|
export 'stream_chat_error.dart';
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:stream_chat/src/errors/chat_error_code.dart';
|
import 'package:stream_chat/src/core/error/chat_error_code.dart';
|
||||||
import 'package:stream_chat/stream_chat.dart';
|
import 'package:stream_chat/stream_chat.dart';
|
||||||
|
|
||||||
///
|
///
|
||||||
@@ -5,8 +5,8 @@ import 'package:stream_chat/src/core/http/stream_http_client.dart';
|
|||||||
import 'package:stream_chat/src/core/http/token.dart';
|
import 'package:stream_chat/src/core/http/token.dart';
|
||||||
|
|
||||||
import 'package:stream_chat/src/core/http/token_manager.dart';
|
import 'package:stream_chat/src/core/http/token_manager.dart';
|
||||||
import 'package:stream_chat/src/errors/chat_error_code.dart';
|
import 'package:stream_chat/src/core/error/error.dart';
|
||||||
import 'package:stream_chat/src/errors/stream_chat_error.dart';
|
|
||||||
|
|
||||||
///
|
///
|
||||||
class AuthInterceptor extends Interceptor {
|
class AuthInterceptor extends Interceptor {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:stream_chat/src/errors/stream_chat_error.dart';
|
import 'package:stream_chat/src/core/error/error.dart';
|
||||||
|
|
||||||
///
|
///
|
||||||
class StreamChatDioError extends DioError {
|
class StreamChatDioError extends DioError {
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ import 'package:stream_chat/src/core/http/interceptor/connection_id_interceptor.
|
|||||||
import 'package:stream_chat/src/core/http/interceptor/logging_interceptor.dart';
|
import 'package:stream_chat/src/core/http/interceptor/logging_interceptor.dart';
|
||||||
import 'package:stream_chat/src/core/http/stream_chat_dio_error.dart';
|
import 'package:stream_chat/src/core/http/stream_chat_dio_error.dart';
|
||||||
import 'package:stream_chat/src/core/http/token_manager.dart';
|
import 'package:stream_chat/src/core/http/token_manager.dart';
|
||||||
import 'package:stream_chat/src/errors/stream_chat_error.dart';
|
import 'package:stream_chat/src/core/error/error.dart';
|
||||||
import 'package:stream_chat/src/location.dart';
|
import 'package:stream_chat/src/location.dart';
|
||||||
import 'package:stream_chat/src/platform_detector/platform_detector.dart';
|
import 'package:stream_chat/src/core/platform_detector/platform_detector.dart';
|
||||||
import 'package:stream_chat/version.dart';
|
import 'package:stream_chat/version.dart';
|
||||||
|
|
||||||
import 'package:stream_chat/src/core/http/connection_id_manager.dart';
|
import 'package:stream_chat/src/core/http/connection_id_manager.dart';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'dart:convert';
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:jose/jose.dart';
|
import 'package:jose/jose.dart';
|
||||||
import 'package:stream_chat/src/core/models/user.dart';
|
import 'package:stream_chat/src/core/models/user.dart';
|
||||||
import 'package:stream_chat/src/core/utils.dart';
|
import 'package:stream_chat/src/core/util/utils.dart';
|
||||||
|
|
||||||
///
|
///
|
||||||
typedef GuestTokenProvider = Future<String> Function(User user);
|
typedef GuestTokenProvider = Future<String> Function(User user);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import 'package:equatable/equatable.dart';
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:stream_chat/src/core/models/action.dart';
|
import 'package:stream_chat/src/core/models/action.dart';
|
||||||
import 'package:stream_chat/src/core/models/attachment_file.dart';
|
import 'package:stream_chat/src/core/models/attachment_file.dart';
|
||||||
import 'package:stream_chat/src/core/models/serialization.dart';
|
import 'package:stream_chat/src/core/util/serialization.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
part 'attachment.g.dart';
|
part 'attachment.g.dart';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:stream_chat/src/core/models/channel_config.dart';
|
import 'package:stream_chat/src/core/models/channel_config.dart';
|
||||||
import 'package:stream_chat/src/core/models/serialization.dart';
|
import 'package:stream_chat/src/core/util/serialization.dart';
|
||||||
import 'package:stream_chat/src/core/models/user.dart';
|
import 'package:stream_chat/src/core/models/user.dart';
|
||||||
|
|
||||||
part 'channel_model.g.dart';
|
part 'channel_model.g.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:stream_chat/src/core/models/channel_model.dart';
|
import 'package:stream_chat/src/core/models/channel_model.dart';
|
||||||
import 'package:stream_chat/src/core/models/message.dart';
|
import 'package:stream_chat/src/core/models/message.dart';
|
||||||
import 'package:stream_chat/src/core/models/serialization.dart';
|
import 'package:stream_chat/src/core/util/serialization.dart';
|
||||||
import 'package:stream_chat/stream_chat.dart';
|
import 'package:stream_chat/stream_chat.dart';
|
||||||
|
|
||||||
part 'event.g.dart';
|
part 'event.g.dart';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'package:equatable/equatable.dart';
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:stream_chat/src/core/models/attachment.dart';
|
import 'package:stream_chat/src/core/models/attachment.dart';
|
||||||
import 'package:stream_chat/src/core/models/reaction.dart';
|
import 'package:stream_chat/src/core/models/reaction.dart';
|
||||||
import 'package:stream_chat/src/core/models/serialization.dart';
|
import 'package:stream_chat/src/core/util/serialization.dart';
|
||||||
import 'package:stream_chat/src/core/models/user.dart';
|
import 'package:stream_chat/src/core/models/user.dart';
|
||||||
import 'package:uuid/uuid.dart';
|
import 'package:uuid/uuid.dart';
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ class Message extends Equatable {
|
|||||||
|
|
||||||
/// The list of user mentioned in the message
|
/// The list of user mentioned in the message
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
toJson: Serialization.userIds,
|
toJson: User.toIds,
|
||||||
defaultValue: [],
|
defaultValue: [],
|
||||||
)
|
)
|
||||||
final List<User> mentionedUsers;
|
final List<User> mentionedUsers;
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ Map<String, dynamic> _$MessageToJson(Message instance) {
|
|||||||
|
|
||||||
writeNotNull('type', readonly(instance.type));
|
writeNotNull('type', readonly(instance.type));
|
||||||
val['attachments'] = instance.attachments.map((e) => e.toJson()).toList();
|
val['attachments'] = instance.attachments.map((e) => e.toJson()).toList();
|
||||||
val['mentioned_users'] = Serialization.userIds(instance.mentionedUsers);
|
val['mentioned_users'] = User.toIds(instance.mentionedUsers);
|
||||||
writeNotNull('reaction_counts', readonly(instance.reactionCounts));
|
writeNotNull('reaction_counts', readonly(instance.reactionCounts));
|
||||||
writeNotNull('reaction_scores', readonly(instance.reactionScores));
|
writeNotNull('reaction_scores', readonly(instance.reactionScores));
|
||||||
writeNotNull('latest_reactions', readonly(instance.latestReactions));
|
writeNotNull('latest_reactions', readonly(instance.latestReactions));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:stream_chat/src/core/models/channel_model.dart';
|
import 'package:stream_chat/src/core/models/channel_model.dart';
|
||||||
import 'package:stream_chat/src/core/models/serialization.dart';
|
import 'package:stream_chat/src/core/util/serialization.dart';
|
||||||
import 'package:stream_chat/src/core/models/user.dart';
|
import 'package:stream_chat/src/core/models/user.dart';
|
||||||
|
|
||||||
part 'mute.g.dart';
|
part 'mute.g.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:stream_chat/src/core/models/device.dart';
|
import 'package:stream_chat/src/core/models/device.dart';
|
||||||
import 'package:stream_chat/src/core/models/mute.dart';
|
import 'package:stream_chat/src/core/models/mute.dart';
|
||||||
import 'package:stream_chat/src/core/models/serialization.dart';
|
import 'package:stream_chat/src/core/util/serialization.dart';
|
||||||
import 'package:stream_chat/src/core/models/user.dart';
|
import 'package:stream_chat/src/core/models/user.dart';
|
||||||
|
|
||||||
part 'own_user.g.dart';
|
part 'own_user.g.dart';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:stream_chat/src/core/models/serialization.dart';
|
import 'package:stream_chat/src/core/util/serialization.dart';
|
||||||
import 'package:stream_chat/src/core/models/user.dart';
|
import 'package:stream_chat/src/core/models/user.dart';
|
||||||
|
|
||||||
part 'reaction.g.dart';
|
part 'reaction.g.dart';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:stream_chat/src/core/models/serialization.dart';
|
import 'package:stream_chat/src/core/util/serialization.dart';
|
||||||
|
|
||||||
part 'user.g.dart';
|
part 'user.g.dart';
|
||||||
|
|
||||||
@@ -92,6 +92,10 @@ class User {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// List of users to list of userIds
|
||||||
|
static List<String>? toIds(List<User>? users) =>
|
||||||
|
users?.map((u) => u.id).toList();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import 'package:stream_chat/src/platform_detector/platform_detector_stub.dart'
|
import 'package:stream_chat/src/core/platform_detector/platform_detector_stub.dart'
|
||||||
if (dart.library.html) 'platform_detector_web.dart'
|
if (dart.library.html) 'platform_detector_web.dart'
|
||||||
if (dart.library.io) 'platform_detector_io.dart';
|
if (dart.library.io) 'platform_detector_io.dart';
|
||||||
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:stream_chat/src/platform_detector/platform_detector.dart';
|
import 'package:stream_chat/src/core/platform_detector/platform_detector.dart';
|
||||||
|
|
||||||
/// Version running on native systems
|
/// Version running on native systems
|
||||||
PlatformType get currentPlatform {
|
PlatformType get currentPlatform {
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import 'package:stream_chat/src/platform_detector/platform_detector.dart';
|
import 'package:stream_chat/src/core/platform_detector/platform_detector.dart';
|
||||||
|
|
||||||
/// Stub implementation
|
/// Stub implementation
|
||||||
PlatformType get currentPlatform {
|
PlatformType get currentPlatform {
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
import 'package:stream_chat/src/platform_detector/platform_detector.dart';
|
import 'package:stream_chat/src/core/platform_detector/platform_detector.dart';
|
||||||
|
|
||||||
/// Version running on web
|
/// Version running on web
|
||||||
PlatformType get currentPlatform => PlatformType.web;
|
PlatformType get currentPlatform => PlatformType.web;
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:http_parser/http_parser.dart';
|
||||||
|
import 'package:mime/mime.dart';
|
||||||
|
|
||||||
|
/// Useful extension functions for [Iterable]
|
||||||
|
extension IterableX<T> on Iterable<T?> {
|
||||||
|
/// Removes all the null values
|
||||||
|
/// and converts `Iterable<T?>` into `Iterable<T>`
|
||||||
|
Iterable<T> get withNullifyer => whereType();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Useful extension functions for [Map]
|
||||||
|
extension MapX<K, V> on Map<K, V> {
|
||||||
|
/// Returns a new map with null keys or values removed
|
||||||
|
Map<K, V> get nullProtected =>
|
||||||
|
Map.from(this)..removeWhere((key, value) => key == null || value == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Useful extension functions for [String]
|
||||||
|
extension StringX on String {
|
||||||
|
/// returns the mime type from the passed file name.
|
||||||
|
MediaType? get mimeType {
|
||||||
|
if (toLowerCase().endsWith('heic')) {
|
||||||
|
return MediaType.parse('image/heic');
|
||||||
|
} else {
|
||||||
|
final mimeType = lookupMimeType(this);
|
||||||
|
if (mimeType == null) return null;
|
||||||
|
return MediaType.parse(mimeType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
-6
@@ -1,5 +1,3 @@
|
|||||||
import 'package:stream_chat/src/core/models/user.dart';
|
|
||||||
|
|
||||||
/// Used to avoid to serialize properties to json
|
/// Used to avoid to serialize properties to json
|
||||||
// ignore: prefer_void_to_null
|
// ignore: prefer_void_to_null
|
||||||
Null readonly(_) => null;
|
Null readonly(_) => null;
|
||||||
@@ -9,10 +7,6 @@ class Serialization {
|
|||||||
/// Used to avoid to serialize properties to json
|
/// Used to avoid to serialize properties to json
|
||||||
static const Function readOnly = readonly;
|
static const Function readOnly = readonly;
|
||||||
|
|
||||||
/// List of users to list of userIds
|
|
||||||
static List<String>? userIds(List<User>? users) =>
|
|
||||||
users?.map((u) => u.id).toList();
|
|
||||||
|
|
||||||
/// Takes unknown json keys and puts them in the `extra_data` key
|
/// Takes unknown json keys and puts them in the `extra_data` key
|
||||||
static Map<String, dynamic> moveToExtraDataFromRoot(
|
static Map<String, dynamic> moveToExtraDataFromRoot(
|
||||||
Map<String, dynamic> json,
|
Map<String, dynamic> json,
|
||||||
+2
-2
@@ -4,14 +4,14 @@ import 'dart:math' as math;
|
|||||||
// This alphabet uses `A-Za-z0-9_-` symbols. The genetic algorithm helped
|
// This alphabet uses `A-Za-z0-9_-` symbols. The genetic algorithm helped
|
||||||
// optimize the gzip compression for this alphabet.
|
// optimize the gzip compression for this alphabet.
|
||||||
const _alphabet =
|
const _alphabet =
|
||||||
'ModuleSymbhasOwnPr0123456789ABCDEFGHNRVfgctiUvzKqYTJkLxpZXIjQW';
|
'ModuleSymbhasOwnPr-0123456789ABCDEFGHNRVfgctiUvz_KqYTJkLxpZXIjQW';
|
||||||
|
|
||||||
/// Generates a random String id
|
/// Generates a random String id
|
||||||
/// Adopted from: https://github.com/ai/nanoid/blob/main/non-secure/index.js
|
/// Adopted from: https://github.com/ai/nanoid/blob/main/non-secure/index.js
|
||||||
String randomId({int size = 21}) {
|
String randomId({int size = 21}) {
|
||||||
var id = '';
|
var id = '';
|
||||||
for (var i = 0; i < size; i++) {
|
for (var i = 0; i < size; i++) {
|
||||||
id += _alphabet[(math.Random().nextInt(32) * 64) | 0];
|
id += _alphabet[(math.Random().nextDouble() * 64).floor() | 0];
|
||||||
}
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ import 'package:stream_chat/src/core/models/message.dart';
|
|||||||
import 'package:stream_chat/src/core/models/reaction.dart';
|
import 'package:stream_chat/src/core/models/reaction.dart';
|
||||||
import 'package:stream_chat/src/core/models/read.dart';
|
import 'package:stream_chat/src/core/models/read.dart';
|
||||||
import 'package:stream_chat/src/core/models/user.dart';
|
import 'package:stream_chat/src/core/models/user.dart';
|
||||||
import 'package:stream_chat/src/extensions/iterable_extension.dart';
|
import 'package:stream_chat/src/core/util/extension.dart';
|
||||||
|
|
||||||
/// A simple client used for persisting chat data locally.
|
/// A simple client used for persisting chat data locally.
|
||||||
abstract class ChatPersistenceClient {
|
abstract class ChatPersistenceClient {
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
/// Useful extension functions for [Iterable]
|
|
||||||
extension IterableX<T> on Iterable<T?> {
|
|
||||||
/// Removes all the null values
|
|
||||||
/// and converts `Iterable<T?>` into `Iterable<T>`
|
|
||||||
Iterable<T> get withNullifyer => [
|
|
||||||
for (final item in this)
|
|
||||||
if (item != null) item
|
|
||||||
];
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
/// Useful extension functions for [Map]
|
|
||||||
extension MapX<K, V> on Map<K, V> {
|
|
||||||
/// Returns a new map with null keys or values removed
|
|
||||||
Map<K, V> get nullProtected =>
|
|
||||||
Map.from(this)..removeWhere((key, value) => key == null || value == null);
|
|
||||||
}
|
|
||||||
@@ -1,335 +0,0 @@
|
|||||||
// ignore_for_file: lines_longer_than_80_chars
|
|
||||||
|
|
||||||
import 'dart:async' show Timer;
|
|
||||||
import 'dart:math' as math;
|
|
||||||
|
|
||||||
/// Useful rate limiter extensions for [Function] class.
|
|
||||||
extension RateLimit on Function {
|
|
||||||
/// Converts this into a [Debounce] function.
|
|
||||||
Debounce debounced(
|
|
||||||
Duration wait, {
|
|
||||||
bool leading = false,
|
|
||||||
bool trailing = true,
|
|
||||||
Duration? maxWait,
|
|
||||||
}) =>
|
|
||||||
Debounce(
|
|
||||||
this,
|
|
||||||
wait,
|
|
||||||
leading: leading,
|
|
||||||
trailing: trailing,
|
|
||||||
maxWait: maxWait,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Converts this into a [Throttle] function.
|
|
||||||
Throttle throttled(
|
|
||||||
Duration wait, {
|
|
||||||
bool leading = true,
|
|
||||||
bool trailing = true,
|
|
||||||
}) =>
|
|
||||||
Throttle(
|
|
||||||
this,
|
|
||||||
wait,
|
|
||||||
leading: leading,
|
|
||||||
trailing: trailing,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// TopLevel lambda to create [Debounce] functions.
|
|
||||||
Debounce debounce(
|
|
||||||
Function func,
|
|
||||||
Duration wait, {
|
|
||||||
bool leading = false,
|
|
||||||
bool trailing = true,
|
|
||||||
Duration? maxWait,
|
|
||||||
}) =>
|
|
||||||
Debounce(
|
|
||||||
func,
|
|
||||||
wait,
|
|
||||||
leading: leading,
|
|
||||||
trailing: trailing,
|
|
||||||
maxWait: maxWait,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// TopLevel lambda to create [Throttle] functions.
|
|
||||||
Throttle throttle(
|
|
||||||
Function func,
|
|
||||||
Duration wait, {
|
|
||||||
bool leading = true,
|
|
||||||
bool trailing = true,
|
|
||||||
}) =>
|
|
||||||
Throttle(
|
|
||||||
func,
|
|
||||||
wait,
|
|
||||||
leading: leading,
|
|
||||||
trailing: trailing,
|
|
||||||
);
|
|
||||||
|
|
||||||
/// Creates a debounced function that delays invoking `func` until after `wait`
|
|
||||||
/// milliseconds have elapsed since the last time the debounced function was
|
|
||||||
/// invoked. The debounced function comes with a [Debounce.cancel] method to cancel
|
|
||||||
/// delayed `func` invocations and a [Debounce.flush] method to immediately invoke them.
|
|
||||||
/// Provide `leading` and/or `trailing` to indicate whether `func` should be
|
|
||||||
/// invoked on the `leading` and/or `trailing` edge of the `wait` interval.
|
|
||||||
/// The `func` is invoked with the last arguments provided to the [call]
|
|
||||||
/// function. Subsequent calls to the debounced function return the result of
|
|
||||||
/// the last `func` invocation.
|
|
||||||
///
|
|
||||||
/// **Note:** If `leading` and `trailing` options are `true`, `func` is
|
|
||||||
/// invoked on the trailing edge of the timeout only if the debounced function
|
|
||||||
/// is invoked more than once during the `wait` timeout.
|
|
||||||
///
|
|
||||||
/// If `wait` is [Duration.zero] and `leading` is `false`,
|
|
||||||
/// `func` invocation is deferred until the next tick.
|
|
||||||
///
|
|
||||||
/// See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
|
||||||
/// for details over the differences between [Debounce] and [Throttle].
|
|
||||||
///
|
|
||||||
/// Some examples:
|
|
||||||
///
|
|
||||||
/// Avoid calling costly network calls when user is typing something.
|
|
||||||
/// ```dart
|
|
||||||
/// void fetchData(String query) async {
|
|
||||||
/// final data = api.getData(query);
|
|
||||||
/// doSomethingWithTheData(data);
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// final debouncedFetchData = Debounce(
|
|
||||||
/// fetchData,
|
|
||||||
/// const Duration(milliseconds: 350),
|
|
||||||
/// );
|
|
||||||
///
|
|
||||||
/// void onSearchQueryChanged(query) {
|
|
||||||
/// debouncedFetchData(query);
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Cancel the trailing debounced invocation.
|
|
||||||
/// ```dart
|
|
||||||
/// void dispose() {
|
|
||||||
/// debounced.cancel();
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Check for pending invocations.
|
|
||||||
/// ```dart
|
|
||||||
/// final status = debounced.isPending ? "Pending..." : "Ready";
|
|
||||||
/// ```
|
|
||||||
class Debounce {
|
|
||||||
/// Creates a new instance of [Debounce].
|
|
||||||
Debounce(
|
|
||||||
this._func,
|
|
||||||
Duration wait, {
|
|
||||||
bool leading = false,
|
|
||||||
bool trailing = true,
|
|
||||||
Duration? maxWait,
|
|
||||||
}) : _leading = leading,
|
|
||||||
_trailing = trailing,
|
|
||||||
_wait = wait.inMilliseconds,
|
|
||||||
_maxing = maxWait != null {
|
|
||||||
if (_maxing) {
|
|
||||||
_maxWait = math.max(maxWait!.inMilliseconds, _wait);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final Function _func;
|
|
||||||
final bool _leading;
|
|
||||||
final bool _trailing;
|
|
||||||
final int _wait;
|
|
||||||
final bool _maxing;
|
|
||||||
|
|
||||||
late int _maxWait;
|
|
||||||
List<Object?>? _lastArgs;
|
|
||||||
Map<Symbol, Object>? _lastNamedArgs;
|
|
||||||
Timer? _timer;
|
|
||||||
int? _lastCallTime;
|
|
||||||
Object? _result;
|
|
||||||
int? _lastInvokeTime = 0;
|
|
||||||
|
|
||||||
Object? _invokeFunc(int? time) {
|
|
||||||
final args = _lastArgs;
|
|
||||||
final namedArgs = _lastNamedArgs;
|
|
||||||
_lastArgs = _lastNamedArgs = null;
|
|
||||||
_lastInvokeTime = time;
|
|
||||||
return _result = Function.apply(_func, args, namedArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer _startTimer(Function pendingFunc, int wait) =>
|
|
||||||
Timer(Duration(milliseconds: wait), pendingFunc as void Function());
|
|
||||||
|
|
||||||
bool _shouldInvoke(int time) {
|
|
||||||
final timeSinceLastCall = time - (_lastCallTime ?? double.nan);
|
|
||||||
final timeSinceLastInvoke = time - _lastInvokeTime!;
|
|
||||||
|
|
||||||
// Either this is the first call, activity has stopped and we're at the
|
|
||||||
// trailing edge, the system time has gone backwards and we're treating
|
|
||||||
// it as the trailing edge, or we've hit the `maxWait` limit.
|
|
||||||
return _lastCallTime == null ||
|
|
||||||
(timeSinceLastCall >= _wait) ||
|
|
||||||
(timeSinceLastCall < 0) ||
|
|
||||||
(_maxing && timeSinceLastInvoke >= _maxWait);
|
|
||||||
}
|
|
||||||
|
|
||||||
Object? _trailingEdge(int time) {
|
|
||||||
_timer = null;
|
|
||||||
|
|
||||||
// Only invoke if we have `lastArgs` which means `func` has been
|
|
||||||
// debounced at least once.
|
|
||||||
if (_trailing && _lastArgs != null) {
|
|
||||||
return _invokeFunc(time);
|
|
||||||
}
|
|
||||||
_lastArgs = _lastNamedArgs = null;
|
|
||||||
return _result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _remainingWait(int time) {
|
|
||||||
final timeSinceLastCall = time - _lastCallTime!;
|
|
||||||
final timeSinceLastInvoke = time - _lastInvokeTime!;
|
|
||||||
final timeWaiting = _wait - timeSinceLastCall;
|
|
||||||
|
|
||||||
return _maxing
|
|
||||||
? math.min(timeWaiting, _maxWait - timeSinceLastInvoke)
|
|
||||||
: timeWaiting;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _timerExpired() {
|
|
||||||
final time = DateTime.now().millisecondsSinceEpoch;
|
|
||||||
if (_shouldInvoke(time)) {
|
|
||||||
_trailingEdge(time);
|
|
||||||
} else {
|
|
||||||
// Restart the timer.
|
|
||||||
_timer = _startTimer(_timerExpired, _remainingWait(time));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Object? _leadingEdge(int? time) {
|
|
||||||
// Reset any `maxWait` timer.
|
|
||||||
_lastInvokeTime = time;
|
|
||||||
// Start the timer for the trailing edge.
|
|
||||||
_timer = _startTimer(_timerExpired, _wait);
|
|
||||||
// Invoke the leading edge.
|
|
||||||
return _leading ? _invokeFunc(time) : _result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Cancels all the remaining delayed functions.
|
|
||||||
void cancel() {
|
|
||||||
_timer?.cancel();
|
|
||||||
_lastInvokeTime = 0;
|
|
||||||
_lastArgs = _lastNamedArgs = _lastCallTime = _timer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Immediately invokes all the remaining delayed functions.
|
|
||||||
Object? flush() {
|
|
||||||
final now = DateTime.now().millisecondsSinceEpoch;
|
|
||||||
return _timer == null ? _result : _trailingEdge(now);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// True if there are functions remaining to get invoked.
|
|
||||||
bool get isPending => _timer != null;
|
|
||||||
|
|
||||||
/// Calls/invokes this class like a function.
|
|
||||||
/// Pass [args] and [namedArgs] to be used while invoking [_func].
|
|
||||||
Object? call(
|
|
||||||
List<dynamic> args, {
|
|
||||||
Map<Symbol, dynamic>? namedArgs,
|
|
||||||
}) {
|
|
||||||
final time = DateTime.now().millisecondsSinceEpoch;
|
|
||||||
final isInvoking = _shouldInvoke(time);
|
|
||||||
|
|
||||||
_lastArgs = args;
|
|
||||||
_lastNamedArgs = namedArgs as Map<Symbol, Object>?;
|
|
||||||
_lastCallTime = time;
|
|
||||||
|
|
||||||
if (isInvoking) {
|
|
||||||
if (_timer == null) {
|
|
||||||
return _leadingEdge(_lastCallTime);
|
|
||||||
}
|
|
||||||
if (_maxing) {
|
|
||||||
// Handle invocations in a tight loop.
|
|
||||||
_timer = _startTimer(_timerExpired, _wait);
|
|
||||||
return _invokeFunc(_lastCallTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_timer ??= _startTimer(_timerExpired, _wait);
|
|
||||||
return _result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a throttled function that only invokes `func` at most once per
|
|
||||||
/// every `wait` milliseconds. The throttled function comes with a [Throttle.cancel]
|
|
||||||
/// method to cancel delayed `func` invocations and a [Throttle.flush] method to
|
|
||||||
/// immediately invoke them. Provide `leading` and/or `trailing` to indicate
|
|
||||||
/// whether `func` should be invoked on the `leading` and/or `trailing` edge of the `wait` timeout.
|
|
||||||
/// The `func` is invoked with the last arguments provided to the
|
|
||||||
/// throttled function. Subsequent calls to the throttled function return the
|
|
||||||
/// result of the last `func` invocation.
|
|
||||||
///
|
|
||||||
/// **Note:** If `leading` and `trailing` options are `true`, `func` is
|
|
||||||
/// invoked on the trailing edge of the timeout only if the throttled function
|
|
||||||
/// is invoked more than once during the `wait` timeout.
|
|
||||||
///
|
|
||||||
/// If `wait` is [Duration.zero] and `leading` is `false`, `func` invocation is deferred
|
|
||||||
/// until the next tick.
|
|
||||||
///
|
|
||||||
/// See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
|
||||||
/// for details over the differences between [Throttle] and [Debounce].
|
|
||||||
///
|
|
||||||
/// Some examples:
|
|
||||||
///
|
|
||||||
/// Avoid excessively rebuilding UI progress while uploading data to server.
|
|
||||||
/// ```dart
|
|
||||||
/// void updateUI(Data data) {
|
|
||||||
/// updateProgress(data);
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// final throttledUpdateUI = Throttle(
|
|
||||||
/// updateUI,
|
|
||||||
/// const Duration(milliseconds: 350),
|
|
||||||
/// );
|
|
||||||
///
|
|
||||||
/// void onUploadProgressChanged(progress) {
|
|
||||||
/// throttledUpdateUI(progress);
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Cancel the trailing throttled invocation.
|
|
||||||
/// ```dart
|
|
||||||
/// void dispose() {
|
|
||||||
/// throttled.cancel();
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Check for pending invocations.
|
|
||||||
/// ```dart
|
|
||||||
/// final status = throttled.isPending ? "Pending..." : "Ready";
|
|
||||||
/// ```
|
|
||||||
class Throttle {
|
|
||||||
/// Creates a new instance of [Throttle]
|
|
||||||
Throttle(
|
|
||||||
Function func,
|
|
||||||
Duration wait, {
|
|
||||||
bool leading = true,
|
|
||||||
bool trailing = true,
|
|
||||||
}) : _debounce = Debounce(
|
|
||||||
func,
|
|
||||||
wait,
|
|
||||||
leading: leading,
|
|
||||||
trailing: trailing,
|
|
||||||
maxWait: wait,
|
|
||||||
);
|
|
||||||
|
|
||||||
final Debounce _debounce;
|
|
||||||
|
|
||||||
/// Cancels all the remaining delayed functions.
|
|
||||||
void cancel() => _debounce.cancel();
|
|
||||||
|
|
||||||
/// Immediately invokes all the remaining delayed functions.
|
|
||||||
Object? flush() => _debounce.flush();
|
|
||||||
|
|
||||||
/// True if there are functions remaining to get invoked.
|
|
||||||
bool get isPending => _debounce.isPending;
|
|
||||||
|
|
||||||
/// Calls/invokes this class like a function.
|
|
||||||
/// Pass [args] and [namedArgs] to be used while invoking `func`.
|
|
||||||
Object? call(List<dynamic> args, {Map<Symbol, dynamic>? namedArgs}) =>
|
|
||||||
_debounce.call(args, namedArgs: namedArgs);
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import 'package:http_parser/http_parser.dart' as http_parser;
|
|
||||||
import 'package:mime/mime.dart';
|
|
||||||
|
|
||||||
/// Useful extension functions for [String]
|
|
||||||
extension StringX on String {
|
|
||||||
/// Returns the mime type from the passed file name.
|
|
||||||
http_parser.MediaType? get mimeType {
|
|
||||||
if (toLowerCase().endsWith('heic')) {
|
|
||||||
return http_parser.MediaType.parse('image/heic');
|
|
||||||
} else {
|
|
||||||
final mimeType = lookupMimeType(this);
|
|
||||||
if (mimeType == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return http_parser.MediaType.parse(mimeType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,8 +5,7 @@ import 'dart:math' as math;
|
|||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
import 'package:stream_chat/src/errors/chat_error_code.dart';
|
import 'package:stream_chat/src/core/error/error.dart';
|
||||||
import 'package:stream_chat/src/errors/stream_chat_error.dart';
|
|
||||||
import 'package:stream_chat/src/ws/connection_status.dart';
|
import 'package:stream_chat/src/ws/connection_status.dart';
|
||||||
import 'package:stream_chat/src/core/http/token.dart';
|
import 'package:stream_chat/src/core/http/token.dart';
|
||||||
import 'package:stream_chat/src/core/http/token_manager.dart';
|
import 'package:stream_chat/src/core/http/token_manager.dart';
|
||||||
|
|||||||
@@ -6,14 +6,14 @@ export 'package:dio/src/multipart_file.dart';
|
|||||||
export 'package:dio/src/options.dart';
|
export 'package:dio/src/options.dart';
|
||||||
export 'package:dio/src/options.dart' show ProgressCallback;
|
export 'package:dio/src/options.dart' show ProgressCallback;
|
||||||
export 'package:logging/logging.dart' show Logger, Level;
|
export 'package:logging/logging.dart' show Logger, Level;
|
||||||
|
export 'package:rate_limiter/rate_limiter.dart';
|
||||||
|
|
||||||
export './src/api/channel.dart';
|
|
||||||
export './src/client.dart';
|
|
||||||
export './src/core/api/attachment_file_uploader.dart'
|
export './src/core/api/attachment_file_uploader.dart'
|
||||||
show AttachmentFileUploader;
|
show AttachmentFileUploader;
|
||||||
export './src/core/api/requests.dart';
|
export './src/core/api/requests.dart';
|
||||||
export './src/core/api/requests.dart';
|
export './src/core/api/requests.dart';
|
||||||
export './src/core/api/responses.dart';
|
export './src/core/api/responses.dart';
|
||||||
|
export './src/core/error/error.dart';
|
||||||
export './src/core/models/action.dart';
|
export './src/core/models/action.dart';
|
||||||
export './src/core/models/attachment.dart';
|
export './src/core/models/attachment.dart';
|
||||||
export './src/core/models/attachment_file.dart';
|
export './src/core/models/attachment_file.dart';
|
||||||
@@ -31,11 +31,10 @@ export './src/core/models/own_user.dart';
|
|||||||
export './src/core/models/reaction.dart';
|
export './src/core/models/reaction.dart';
|
||||||
export './src/core/models/read.dart';
|
export './src/core/models/read.dart';
|
||||||
export './src/core/models/user.dart';
|
export './src/core/models/user.dart';
|
||||||
|
export './src/core/util/extension.dart';
|
||||||
export './src/db/chat_persistence_client.dart';
|
export './src/db/chat_persistence_client.dart';
|
||||||
export './src/errors/chat_error_code.dart';
|
|
||||||
export './src/errors/stream_chat_error.dart';
|
|
||||||
export './src/event_type.dart';
|
export './src/event_type.dart';
|
||||||
export './src/extensions/rate_limit.dart';
|
|
||||||
export './src/extensions/string_extension.dart';
|
|
||||||
export './src/location.dart';
|
export './src/location.dart';
|
||||||
export './src/ws/connection_status.dart';
|
export './src/ws/connection_status.dart';
|
||||||
|
export 'src/client/channel.dart';
|
||||||
|
export 'src/client/client.dart';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import 'package:stream_chat/src/client.dart';
|
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
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ dependencies:
|
|||||||
logging: ^1.0.1
|
logging: ^1.0.1
|
||||||
meta: ^1.3.0
|
meta: ^1.3.0
|
||||||
mime: ^1.0.0
|
mime: ^1.0.0
|
||||||
|
rate_limiter: ^0.1.1
|
||||||
rxdart: ^0.27.0
|
rxdart: ^0.27.0
|
||||||
uuid: ^3.0.4
|
uuid: ^3.0.4
|
||||||
web_socket_channel: ^2.0.0
|
web_socket_channel: ^2.0.0
|
||||||
|
|||||||
@@ -4,6 +4,23 @@ import 'dart:io';
|
|||||||
import 'package:stream_chat/stream_chat.dart';
|
import 'package:stream_chat/stream_chat.dart';
|
||||||
import 'package:stream_chat/version.dart';
|
import 'package:stream_chat/version.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
// This alphabet uses `A-Za-z0-9_-` symbols. The genetic algorithm helped
|
||||||
|
// optimize the gzip compression for this alphabet.
|
||||||
|
const _alphabet =
|
||||||
|
'ModuleSymbhasOwnPr-0123456789ABCDEFGHNRVfgctiUvz_KqYTJkLxpZXIjQW';
|
||||||
|
|
||||||
|
/// Generates a random String id
|
||||||
|
/// Adopted from: https://github.com/ai/nanoid/blob/main/non-secure/index.js
|
||||||
|
String randomId({int size = 21}) {
|
||||||
|
var id = '';
|
||||||
|
for (var i = 0; i < size; i++) {
|
||||||
|
id += _alphabet[(math.Random().nextDouble() * 64).floor() | 0];
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void prepareTest() {
|
void prepareTest() {
|
||||||
// https://github.com/flutter/flutter/issues/20907
|
// https://github.com/flutter/flutter/issues/20907
|
||||||
@@ -15,30 +32,32 @@ void prepareTest() {
|
|||||||
void main() {
|
void main() {
|
||||||
prepareTest();
|
prepareTest();
|
||||||
test('stream chat version matches pubspec', () async {
|
test('stream chat version matches pubspec', () async {
|
||||||
/// Create a new instance of [StreamChatClient]
|
print(randomId());
|
||||||
/// by passing the apikey obtained from your project dashboard.
|
|
||||||
final client = StreamChatClient('b67pax5b2wdq', logLevel: Level.INFO);
|
|
||||||
|
|
||||||
/// Set the current user. In a production scenario, this should be done using
|
// /// Create a new instance of [StreamChatClient]
|
||||||
/// a backend to generate a user token using our server SDK.
|
// /// by passing the apikey obtained from your project dashboard.
|
||||||
/// Please see the following for more information:
|
// final client = StreamChatClient('b67pax5b2wdq', logLevel: Level.INFO);
|
||||||
/// https://getstream.io/chat/docs/ios_user_setup_and_tokens/
|
//
|
||||||
await client.connectUser(
|
// /// Set the current user. In a production scenario, this should be done using
|
||||||
User(
|
// /// a backend to generate a user token using our server SDK.
|
||||||
id: 'cool-shadow-7',
|
// /// Please see the following for more information:
|
||||||
extraData: {
|
// /// https://getstream.io/chat/docs/ios_user_setup_and_tokens/
|
||||||
'image':
|
// await client.connectUser(
|
||||||
'https://getstream.io/random_png/?id=cool-shadow-7&name=Cool+shadow',
|
// User(
|
||||||
},
|
// id: 'cool-shadow-7',
|
||||||
),
|
// extraData: {
|
||||||
'''eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiY29vbC1zaGFkb3ctNyJ9.gkOlCRb1qgy4joHPaxFwPOdXcGvSPvp6QY0S4mpRkVo''',
|
// 'image':
|
||||||
);
|
// 'https://getstream.io/random_png/?id=cool-shadow-7&name=Cool+shadow',
|
||||||
|
// },
|
||||||
try {
|
// ),
|
||||||
await client.banUser('asdasdas');
|
// '''eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiY29vbC1zaGFkb3ctNyJ9.gkOlCRb1qgy4joHPaxFwPOdXcGvSPvp6QY0S4mpRkVo''',
|
||||||
} catch (e) {
|
// );
|
||||||
print(e);
|
//
|
||||||
}
|
// try {
|
||||||
|
// await client.banUser('asdasdas');
|
||||||
|
// } catch (e) {
|
||||||
|
// print(e);
|
||||||
|
// }
|
||||||
|
|
||||||
// final pubspecPath = '${Directory.current.path}/pubspec.yaml';
|
// final pubspecPath = '${Directory.current.path}/pubspec.yaml';
|
||||||
// final pubspec = File(pubspecPath).readAsStringSync();
|
// final pubspec = File(pubspecPath).readAsStringSync();
|
||||||
|
|||||||
Reference in New Issue
Block a user