Merge pull request #1506 from GetStream/fix/pana
This commit is contained in:
@@ -27,7 +27,7 @@ dependencies:
|
|||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.3.3
|
build_runner: ^2.3.3
|
||||||
dart_code_metrics: ^5.7.0
|
dart_code_metrics: ^5.7.2
|
||||||
freezed: ^2.3.2
|
freezed: ^2.3.2
|
||||||
json_serializable: ^6.6.1
|
json_serializable: ^6.6.1
|
||||||
mocktail: ^0.3.0
|
mocktail: ^0.3.0
|
||||||
|
|||||||
+5
-8
@@ -7,8 +7,7 @@ import 'package:flutter/widgets.dart';
|
|||||||
/// A registry to track some [Element]s in the tree.
|
/// A registry to track some [Element]s in the tree.
|
||||||
class RegistryWidget extends StatefulWidget {
|
class RegistryWidget extends StatefulWidget {
|
||||||
/// Creates a [RegistryWidget].
|
/// Creates a [RegistryWidget].
|
||||||
const RegistryWidget({Key? key, this.elementNotifier, required this.child})
|
const RegistryWidget({super.key, this.elementNotifier, required this.child});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
/// The widget below this widget in the tree.
|
/// The widget below this widget in the tree.
|
||||||
final Widget child;
|
final Widget child;
|
||||||
@@ -28,8 +27,7 @@ class RegistryWidget extends StatefulWidget {
|
|||||||
/// [RegistryWidget].
|
/// [RegistryWidget].
|
||||||
class RegisteredElementWidget extends ProxyWidget {
|
class RegisteredElementWidget extends ProxyWidget {
|
||||||
/// Creates a [RegisteredElementWidget].
|
/// Creates a [RegisteredElementWidget].
|
||||||
const RegisteredElementWidget({Key? key, required Widget child})
|
const RegisteredElementWidget({super.key, required super.child});
|
||||||
: super(key: key, child: child);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Element createElement() => _RegisteredElement(this);
|
Element createElement() => _RegisteredElement(this);
|
||||||
@@ -47,10 +45,9 @@ class _RegistryWidgetState extends State<RegistryWidget> {
|
|||||||
|
|
||||||
class _InheritedRegistryWidget extends InheritedWidget {
|
class _InheritedRegistryWidget extends InheritedWidget {
|
||||||
const _InheritedRegistryWidget({
|
const _InheritedRegistryWidget({
|
||||||
Key? key,
|
|
||||||
required this.state,
|
required this.state,
|
||||||
required Widget child,
|
required super.child,
|
||||||
}) : super(key: key, child: child);
|
});
|
||||||
|
|
||||||
final _RegistryWidgetState state;
|
final _RegistryWidgetState state;
|
||||||
|
|
||||||
@@ -59,7 +56,7 @@ class _InheritedRegistryWidget extends InheritedWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _RegisteredElement extends ProxyElement {
|
class _RegisteredElement extends ProxyElement {
|
||||||
_RegisteredElement(ProxyWidget widget) : super(widget);
|
_RegisteredElement(super.widget);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void notifyClients(ProxyWidget oldWidget) {}
|
void notifyClients(ProxyWidget oldWidget) {}
|
||||||
|
|||||||
+12
-13
@@ -25,7 +25,7 @@ import 'package:stream_chat_flutter/scrollable_positioned_list/src/scroll_view.d
|
|||||||
class PositionedList extends StatefulWidget {
|
class PositionedList extends StatefulWidget {
|
||||||
/// Create a [PositionedList].
|
/// Create a [PositionedList].
|
||||||
const PositionedList({
|
const PositionedList({
|
||||||
Key? key,
|
super.key,
|
||||||
required this.itemCount,
|
required this.itemCount,
|
||||||
required this.itemBuilder,
|
required this.itemBuilder,
|
||||||
this.separatorBuilder,
|
this.separatorBuilder,
|
||||||
@@ -44,9 +44,8 @@ class PositionedList extends StatefulWidget {
|
|||||||
this.addRepaintBoundaries = true,
|
this.addRepaintBoundaries = true,
|
||||||
this.addAutomaticKeepAlives = true,
|
this.addAutomaticKeepAlives = true,
|
||||||
this.keyboardDismissBehavior,
|
this.keyboardDismissBehavior,
|
||||||
}) : assert((positionedIndex == 0) || (positionedIndex < itemCount),
|
}) : assert((positionedIndex == 0) || (positionedIndex < itemCount),
|
||||||
'positionedIndex cannot be 0 and must be smaller than itemCount'),
|
'positionedIndex cannot be 0 and must be smaller than itemCount');
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
/// Called to find the new index of a child based on its key in case of
|
/// Called to find the new index of a child based on its key in case of
|
||||||
/// reordering.
|
/// reordering.
|
||||||
@@ -272,7 +271,7 @@ class _PositionedListState extends State<PositionedList> {
|
|||||||
: widget.reverse
|
: widget.reverse
|
||||||
? widget.padding?.copyWith(left: 0)
|
? widget.padding?.copyWith(left: 0)
|
||||||
: widget.padding?.copyWith(right: 0)) ??
|
: widget.padding?.copyWith(right: 0)) ??
|
||||||
const EdgeInsets.all(0);
|
EdgeInsets.zero;
|
||||||
|
|
||||||
EdgeInsets get _centerSliverPadding => widget.scrollDirection == Axis.vertical
|
EdgeInsets get _centerSliverPadding => widget.scrollDirection == Axis.vertical
|
||||||
? widget.reverse
|
? widget.reverse
|
||||||
@@ -283,14 +282,14 @@ class _PositionedListState extends State<PositionedList> {
|
|||||||
bottom:
|
bottom:
|
||||||
widget.positionedIndex == 0 ? widget.padding!.bottom : 0,
|
widget.positionedIndex == 0 ? widget.padding!.bottom : 0,
|
||||||
) ??
|
) ??
|
||||||
const EdgeInsets.all(0)
|
EdgeInsets.zero
|
||||||
: widget.padding?.copyWith(
|
: widget.padding?.copyWith(
|
||||||
top: widget.positionedIndex == 0 ? widget.padding!.top : 0,
|
top: widget.positionedIndex == 0 ? widget.padding!.top : 0,
|
||||||
bottom: widget.positionedIndex == widget.itemCount - 1
|
bottom: widget.positionedIndex == widget.itemCount - 1
|
||||||
? widget.padding!.bottom
|
? widget.padding!.bottom
|
||||||
: 0,
|
: 0,
|
||||||
) ??
|
) ??
|
||||||
const EdgeInsets.all(0)
|
EdgeInsets.zero
|
||||||
: widget.reverse
|
: widget.reverse
|
||||||
? widget.padding?.copyWith(
|
? widget.padding?.copyWith(
|
||||||
left: widget.positionedIndex == widget.itemCount - 1
|
left: widget.positionedIndex == widget.itemCount - 1
|
||||||
@@ -298,23 +297,23 @@ class _PositionedListState extends State<PositionedList> {
|
|||||||
: 0,
|
: 0,
|
||||||
right: widget.positionedIndex == 0 ? widget.padding!.right : 0,
|
right: widget.positionedIndex == 0 ? widget.padding!.right : 0,
|
||||||
) ??
|
) ??
|
||||||
const EdgeInsets.all(0)
|
EdgeInsets.zero
|
||||||
: widget.padding?.copyWith(
|
: widget.padding?.copyWith(
|
||||||
left: widget.positionedIndex == 0 ? widget.padding!.left : 0,
|
left: widget.positionedIndex == 0 ? widget.padding!.left : 0,
|
||||||
right: widget.positionedIndex == widget.itemCount - 1
|
right: widget.positionedIndex == widget.itemCount - 1
|
||||||
? widget.padding!.right
|
? widget.padding!.right
|
||||||
: 0,
|
: 0,
|
||||||
) ??
|
) ??
|
||||||
const EdgeInsets.all(0);
|
EdgeInsets.zero;
|
||||||
|
|
||||||
EdgeInsets get _trailingSliverPadding =>
|
EdgeInsets get _trailingSliverPadding =>
|
||||||
widget.scrollDirection == Axis.vertical
|
widget.scrollDirection == Axis.vertical
|
||||||
? widget.reverse
|
? widget.reverse
|
||||||
? widget.padding?.copyWith(bottom: 0) ?? const EdgeInsets.all(0)
|
? widget.padding?.copyWith(bottom: 0) ?? EdgeInsets.zero
|
||||||
: widget.padding?.copyWith(top: 0) ?? const EdgeInsets.all(0)
|
: widget.padding?.copyWith(top: 0) ?? EdgeInsets.zero
|
||||||
: widget.reverse
|
: widget.reverse
|
||||||
? widget.padding?.copyWith(right: 0) ?? const EdgeInsets.all(0)
|
? widget.padding?.copyWith(right: 0) ?? EdgeInsets.zero
|
||||||
: widget.padding?.copyWith(left: 0) ?? const EdgeInsets.all(0);
|
: widget.padding?.copyWith(left: 0) ?? EdgeInsets.zero;
|
||||||
|
|
||||||
void _schedulePositionNotificationUpdate() {
|
void _schedulePositionNotificationUpdate() {
|
||||||
if (!updateScheduled) {
|
if (!updateScheduled) {
|
||||||
|
|||||||
+2
-3
@@ -7,8 +7,7 @@ import 'package:flutter/widgets.dart';
|
|||||||
/// Widget whose [Element] calls a callback when the element is mounted.
|
/// Widget whose [Element] calls a callback when the element is mounted.
|
||||||
class PostMountCallback extends StatelessWidget {
|
class PostMountCallback extends StatelessWidget {
|
||||||
/// Creates a [PostMountCallback] widget.
|
/// Creates a [PostMountCallback] widget.
|
||||||
const PostMountCallback({required this.child, this.callback, Key? key})
|
const PostMountCallback({required this.child, this.callback, super.key});
|
||||||
: super(key: key);
|
|
||||||
|
|
||||||
/// The widget below this widget in the tree.
|
/// The widget below this widget in the tree.
|
||||||
final Widget child;
|
final Widget child;
|
||||||
@@ -24,7 +23,7 @@ class PostMountCallback extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _PostMountCallbackElement extends StatelessElement {
|
class _PostMountCallbackElement extends StatelessElement {
|
||||||
_PostMountCallbackElement(PostMountCallback widget) : super(widget);
|
_PostMountCallbackElement(PostMountCallback super.widget);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void mount(Element? parent, dynamic newSlot) {
|
void mount(Element? parent, dynamic newSlot) {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:flutter/gestures.dart';
|
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:stream_chat_flutter/scrollable_positioned_list/src/viewport.dart';
|
import 'package:stream_chat_flutter/scrollable_positioned_list/src/viewport.dart';
|
||||||
@@ -14,36 +13,24 @@ import 'package:stream_chat_flutter/scrollable_positioned_list/src/viewport.dart
|
|||||||
class UnboundedCustomScrollView extends CustomScrollView {
|
class UnboundedCustomScrollView extends CustomScrollView {
|
||||||
/// {@macro custom_scroll_view}
|
/// {@macro custom_scroll_view}
|
||||||
const UnboundedCustomScrollView({
|
const UnboundedCustomScrollView({
|
||||||
Key? key,
|
super.key,
|
||||||
Axis scrollDirection = Axis.vertical,
|
super.scrollDirection,
|
||||||
bool reverse = false,
|
super.reverse,
|
||||||
ScrollController? controller,
|
super.controller,
|
||||||
bool? primary,
|
super.primary,
|
||||||
ScrollPhysics? physics,
|
super.physics,
|
||||||
bool shrinkWrap = false,
|
super.shrinkWrap,
|
||||||
Key? center,
|
super.center,
|
||||||
double anchor = 0.0,
|
double anchor = 0.0,
|
||||||
double? cacheExtent,
|
super.cacheExtent,
|
||||||
List<Widget> slivers = const <Widget>[],
|
super.slivers,
|
||||||
int? semanticChildCount,
|
super.semanticChildCount,
|
||||||
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
|
super.dragStartBehavior,
|
||||||
ScrollViewKeyboardDismissBehavior? keyboardDismissBehavior,
|
ScrollViewKeyboardDismissBehavior? keyboardDismissBehavior,
|
||||||
}) : _anchor = anchor,
|
}) : _anchor = anchor,
|
||||||
super(
|
super(
|
||||||
key: key,
|
|
||||||
keyboardDismissBehavior: keyboardDismissBehavior ??
|
keyboardDismissBehavior: keyboardDismissBehavior ??
|
||||||
ScrollViewKeyboardDismissBehavior.manual,
|
ScrollViewKeyboardDismissBehavior.manual,
|
||||||
scrollDirection: scrollDirection,
|
|
||||||
reverse: reverse,
|
|
||||||
controller: controller,
|
|
||||||
primary: primary,
|
|
||||||
physics: physics,
|
|
||||||
shrinkWrap: shrinkWrap,
|
|
||||||
center: center,
|
|
||||||
cacheExtent: cacheExtent,
|
|
||||||
semanticChildCount: semanticChildCount,
|
|
||||||
dragStartBehavior: dragStartBehavior,
|
|
||||||
slivers: slivers,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// [CustomScrollView] enforces constraints on [CustomScrollView.anchor], so
|
// [CustomScrollView] enforces constraints on [CustomScrollView.anchor], so
|
||||||
|
|||||||
+7
-10
@@ -35,7 +35,7 @@ class ScrollablePositionedList extends StatefulWidget {
|
|||||||
const ScrollablePositionedList.builder({
|
const ScrollablePositionedList.builder({
|
||||||
required this.itemCount,
|
required this.itemCount,
|
||||||
required this.itemBuilder,
|
required this.itemBuilder,
|
||||||
Key? key,
|
super.key,
|
||||||
this.itemScrollController,
|
this.itemScrollController,
|
||||||
ItemPositionsListener? itemPositionsListener,
|
ItemPositionsListener? itemPositionsListener,
|
||||||
this.initialScrollIndex = 0,
|
this.initialScrollIndex = 0,
|
||||||
@@ -52,16 +52,15 @@ class ScrollablePositionedList extends StatefulWidget {
|
|||||||
this.findChildIndexCallback,
|
this.findChildIndexCallback,
|
||||||
this.keyboardDismissBehavior,
|
this.keyboardDismissBehavior,
|
||||||
}) : itemPositionsNotifier = itemPositionsListener as ItemPositionsNotifier?,
|
}) : itemPositionsNotifier = itemPositionsListener as ItemPositionsNotifier?,
|
||||||
separatorBuilder = null,
|
separatorBuilder = null;
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
/// Create a [ScrollablePositionedList] whose items are provided by
|
/// Create a [ScrollablePositionedList] whose items are provided by
|
||||||
/// [itemBuilder] and separators provided by [separatorBuilder].
|
/// [itemBuilder] and separators provided by [separatorBuilder].
|
||||||
const ScrollablePositionedList.separated({
|
const ScrollablePositionedList.separated({
|
||||||
required this.itemCount,
|
required this.itemCount,
|
||||||
required this.itemBuilder,
|
required this.itemBuilder,
|
||||||
required this.separatorBuilder,
|
required IndexedWidgetBuilder this.separatorBuilder,
|
||||||
Key? key,
|
super.key,
|
||||||
this.itemScrollController,
|
this.itemScrollController,
|
||||||
ItemPositionsListener? itemPositionsListener,
|
ItemPositionsListener? itemPositionsListener,
|
||||||
this.initialScrollIndex = 0,
|
this.initialScrollIndex = 0,
|
||||||
@@ -77,9 +76,7 @@ class ScrollablePositionedList extends StatefulWidget {
|
|||||||
this.minCacheExtent,
|
this.minCacheExtent,
|
||||||
this.findChildIndexCallback,
|
this.findChildIndexCallback,
|
||||||
this.keyboardDismissBehavior,
|
this.keyboardDismissBehavior,
|
||||||
}) : assert(separatorBuilder != null, 'seperatorBuilder cannot be null'),
|
}) : itemPositionsNotifier = itemPositionsListener as ItemPositionsNotifier?;
|
||||||
itemPositionsNotifier = itemPositionsListener as ItemPositionsNotifier?,
|
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
/// Called to find the new index of a child based on its key in case of
|
/// Called to find the new index of a child based on its key in case of
|
||||||
/// reordering.
|
/// reordering.
|
||||||
@@ -280,7 +277,7 @@ class _ScrollablePositionedListState extends State<ScrollablePositionedList>
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
final ItemPosition? initialPosition =
|
final ItemPosition? initialPosition =
|
||||||
PageStorage.of(context)!.readState(context);
|
PageStorage.of(context).readState(context);
|
||||||
primary
|
primary
|
||||||
..target = initialPosition?.index ?? widget.initialScrollIndex
|
..target = initialPosition?.index ?? widget.initialScrollIndex
|
||||||
..alignment = initialPosition?.itemLeadingEdge ?? widget.initialAlignment;
|
..alignment = initialPosition?.itemLeadingEdge ?? widget.initialAlignment;
|
||||||
@@ -572,7 +569,7 @@ class _ScrollablePositionedListState extends State<ScrollablePositionedList>
|
|||||||
.where((ItemPosition position) =>
|
.where((ItemPosition position) =>
|
||||||
position.itemLeadingEdge < 1 && position.itemTrailingEdge > 0);
|
position.itemLeadingEdge < 1 && position.itemTrailingEdge > 0);
|
||||||
if (itemPositions.isNotEmpty) {
|
if (itemPositions.isNotEmpty) {
|
||||||
PageStorage.of(context)!.writeState(
|
PageStorage.of(context).writeState(
|
||||||
context,
|
context,
|
||||||
itemPositions.reduce((value, element) =>
|
itemPositions.reduce((value, element) =>
|
||||||
value.itemLeadingEdge < element.itemLeadingEdge ? value : element),
|
value.itemLeadingEdge < element.itemLeadingEdge ? value : element),
|
||||||
|
|||||||
@@ -19,24 +19,15 @@ import 'package:flutter/widgets.dart';
|
|||||||
class UnboundedViewport extends Viewport {
|
class UnboundedViewport extends Viewport {
|
||||||
/// {@macro unbounded_viewport}
|
/// {@macro unbounded_viewport}
|
||||||
UnboundedViewport({
|
UnboundedViewport({
|
||||||
Key? key,
|
super.key,
|
||||||
AxisDirection axisDirection = AxisDirection.down,
|
super.axisDirection,
|
||||||
AxisDirection? crossAxisDirection,
|
super.crossAxisDirection,
|
||||||
double anchor = 0.0,
|
double anchor = 0.0,
|
||||||
required ViewportOffset offset,
|
required super.offset,
|
||||||
Key? center,
|
super.center,
|
||||||
double? cacheExtent,
|
super.cacheExtent,
|
||||||
List<Widget> slivers = const <Widget>[],
|
super.slivers,
|
||||||
}) : _anchor = anchor,
|
}) : _anchor = anchor;
|
||||||
super(
|
|
||||||
key: key,
|
|
||||||
axisDirection: axisDirection,
|
|
||||||
crossAxisDirection: crossAxisDirection,
|
|
||||||
offset: offset,
|
|
||||||
center: center,
|
|
||||||
cacheExtent: cacheExtent,
|
|
||||||
slivers: slivers,
|
|
||||||
);
|
|
||||||
|
|
||||||
// [Viewport] enforces constraints on [Viewport.anchor], so we need our own
|
// [Viewport] enforces constraints on [Viewport.anchor], so we need our own
|
||||||
// version.
|
// version.
|
||||||
@@ -68,22 +59,14 @@ class UnboundedViewport extends Viewport {
|
|||||||
class UnboundedRenderViewport extends RenderViewport {
|
class UnboundedRenderViewport extends RenderViewport {
|
||||||
/// Creates a viewport for [RenderSliver] objects.
|
/// Creates a viewport for [RenderSliver] objects.
|
||||||
UnboundedRenderViewport({
|
UnboundedRenderViewport({
|
||||||
AxisDirection axisDirection = AxisDirection.down,
|
super.axisDirection,
|
||||||
required AxisDirection crossAxisDirection,
|
required super.crossAxisDirection,
|
||||||
required ViewportOffset offset,
|
required super.offset,
|
||||||
double anchor = 0.0,
|
double anchor = 0.0,
|
||||||
List<RenderSliver>? children,
|
super.children,
|
||||||
RenderSliver? center,
|
super.center,
|
||||||
double? cacheExtent,
|
super.cacheExtent,
|
||||||
}) : _anchor = anchor,
|
}) : _anchor = anchor;
|
||||||
super(
|
|
||||||
axisDirection: axisDirection,
|
|
||||||
crossAxisDirection: crossAxisDirection,
|
|
||||||
offset: offset,
|
|
||||||
center: center,
|
|
||||||
cacheExtent: cacheExtent,
|
|
||||||
children: children,
|
|
||||||
);
|
|
||||||
|
|
||||||
static const int _maxLayoutCycles = 10;
|
static const int _maxLayoutCycles = 10;
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,21 @@ dependencies:
|
|||||||
video_thumbnail: ^0.5.0
|
video_thumbnail: ^0.5.0
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
|
plugin:
|
||||||
|
platforms:
|
||||||
|
android:
|
||||||
|
default_package: stream_chat_flutter
|
||||||
|
ios:
|
||||||
|
default_package: stream_chat_flutter
|
||||||
|
windows:
|
||||||
|
default_package: stream_chat_flutter
|
||||||
|
linux:
|
||||||
|
default_package: stream_chat_flutter
|
||||||
|
macos:
|
||||||
|
default_package: stream_chat_flutter
|
||||||
|
web:
|
||||||
|
default_package: stream_chat_flutter
|
||||||
|
|
||||||
assets:
|
assets:
|
||||||
- images/
|
- images/
|
||||||
- svgs/
|
- svgs/
|
||||||
@@ -54,7 +69,7 @@ flutter:
|
|||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
dart_code_metrics: ^5.7.0
|
dart_code_metrics: ^5.7.2
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
golden_toolkit: ^0.15.0
|
golden_toolkit: ^0.15.0
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'package:stream_chat/stream_chat.dart' hide Success;
|
import 'package:stream_chat/stream_chat.dart' hide Success;
|
||||||
import 'package:stream_chat_flutter_core/src/paged_value_notifier.dart';
|
import 'package:stream_chat_flutter_core/src/paged_value_notifier.dart';
|
||||||
|
|
||||||
import 'package:stream_chat_flutter_core/src/stream_channel_list_event_handler.dart';
|
import 'package:stream_chat_flutter_core/src/stream_channel_list_event_handler.dart';
|
||||||
|
|
||||||
/// The default channel page limit to load.
|
/// The default channel page limit to load.
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ dependencies:
|
|||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.3.3
|
build_runner: ^2.3.3
|
||||||
dart_code_metrics: ^5.7.0
|
dart_code_metrics: ^5.7.2
|
||||||
fake_async: ^1.2.0
|
fake_async: ^1.2.0
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|||||||
@@ -17,6 +17,22 @@ dependencies:
|
|||||||
stream_chat_flutter: ^5.3.0
|
stream_chat_flutter: ^5.3.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
dart_code_metrics: ^4.16.0
|
dart_code_metrics: ^5.7.2
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
|
flutter:
|
||||||
|
plugin:
|
||||||
|
platforms:
|
||||||
|
android:
|
||||||
|
default_package: stream_chat_localizations
|
||||||
|
ios:
|
||||||
|
default_package: stream_chat_localizations
|
||||||
|
windows:
|
||||||
|
default_package: stream_chat_localizations
|
||||||
|
linux:
|
||||||
|
default_package: stream_chat_localizations
|
||||||
|
macos:
|
||||||
|
default_package: stream_chat_localizations
|
||||||
|
web:
|
||||||
|
default_package: stream_chat_localizations
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
## Upcoming
|
## Upcoming
|
||||||
|
|
||||||
|
- Updated `drift` to `^2.7.0`.
|
||||||
- Updated dependencies to resolvable versions.
|
- Updated dependencies to resolvable versions.
|
||||||
|
|
||||||
## 5.1.0
|
## 5.1.0
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ targets:
|
|||||||
builders:
|
builders:
|
||||||
drift_dev:
|
drift_dev:
|
||||||
options:
|
options:
|
||||||
generate_connect_constructor: true
|
|
||||||
data_class_to_companions: false
|
data_class_to_companions: false
|
||||||
apply_converters_on_variables: true
|
apply_converters_on_variables: true
|
||||||
generate_values_in_copy_with: true
|
generate_values_in_copy_with: true
|
||||||
|
|||||||
@@ -6,7 +6,21 @@ import 'package:drift/drift.dart';
|
|||||||
/// by the sqlite backend.
|
/// by the sqlite backend.
|
||||||
class ListConverter<T> extends TypeConverter<List<T>, String> {
|
class ListConverter<T> extends TypeConverter<List<T>, String> {
|
||||||
@override
|
@override
|
||||||
List<T>? mapToDart(String? fromDb) {
|
List<T> fromSql(String fromDb) {
|
||||||
|
return List<T>.from(jsonDecode(fromDb) ?? []);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toSql(List<T> value) {
|
||||||
|
return jsonEncode(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maps a nullable [List] of type [T] into a nullable [String] understood
|
||||||
|
/// by the sqlite backend.
|
||||||
|
class NullableListConverter<T> extends TypeConverter<List<T>?, String?> {
|
||||||
|
@override
|
||||||
|
List<T>? fromSql(String? fromDb) {
|
||||||
if (fromDb == null) {
|
if (fromDb == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -14,7 +28,7 @@ class ListConverter<T> extends TypeConverter<List<T>, String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String? mapToSql(List<T>? value) {
|
String? toSql(List<T>? value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,21 @@ import 'package:drift/drift.dart';
|
|||||||
/// by the sqlite backend.
|
/// by the sqlite backend.
|
||||||
class MapConverter<T> extends TypeConverter<Map<String, T>, String> {
|
class MapConverter<T> extends TypeConverter<Map<String, T>, String> {
|
||||||
@override
|
@override
|
||||||
Map<String, T>? mapToDart(String? fromDb) {
|
Map<String, T> fromSql(String fromDb) {
|
||||||
|
return Map<String, T>.from(jsonDecode(fromDb) ?? {});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toSql(Map<String, T> value) {
|
||||||
|
return jsonEncode(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Maps a nullable [Map] of type [String], [T] into a nullable [String]
|
||||||
|
/// understood by the sqlite backend.
|
||||||
|
class NullableMapConverter<T> extends TypeConverter<Map<String, T>?, String?> {
|
||||||
|
@override
|
||||||
|
Map<String, T>? fromSql(String? fromDb) {
|
||||||
if (fromDb == null) {
|
if (fromDb == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -14,7 +28,7 @@ class MapConverter<T> extends TypeConverter<Map<String, T>, String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String? mapToSql(Map<String, T>? value) {
|
String? toSql(Map<String, T>? value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-6
@@ -6,7 +6,7 @@ import 'package:stream_chat/stream_chat.dart';
|
|||||||
class MessageSendingStatusConverter
|
class MessageSendingStatusConverter
|
||||||
extends TypeConverter<MessageSendingStatus, int> {
|
extends TypeConverter<MessageSendingStatus, int> {
|
||||||
@override
|
@override
|
||||||
MessageSendingStatus? mapToDart(int? fromDb) {
|
MessageSendingStatus fromSql(int fromDb) {
|
||||||
switch (fromDb) {
|
switch (fromDb) {
|
||||||
case 0:
|
case 0:
|
||||||
return MessageSendingStatus.sending;
|
return MessageSendingStatus.sending;
|
||||||
@@ -22,13 +22,12 @@ class MessageSendingStatusConverter
|
|||||||
return MessageSendingStatus.deleting;
|
return MessageSendingStatus.deleting;
|
||||||
case 6:
|
case 6:
|
||||||
return MessageSendingStatus.failed_delete;
|
return MessageSendingStatus.failed_delete;
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return MessageSendingStatus.sending;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int? mapToSql(MessageSendingStatus? value) {
|
int toSql(MessageSendingStatus value) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case MessageSendingStatus.sending:
|
case MessageSendingStatus.sending:
|
||||||
return 0;
|
return 0;
|
||||||
@@ -44,8 +43,6 @@ class MessageSendingStatusConverter
|
|||||||
return 5;
|
return 5;
|
||||||
case MessageSendingStatus.failed_delete:
|
case MessageSendingStatus.failed_delete:
|
||||||
return 6;
|
return 6;
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,7 @@
|
|||||||
|
|
||||||
part of 'channel_dao.dart';
|
part of 'channel_dao.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// ignore_for_file: type=lint
|
||||||
// DaoGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
mixin _$ChannelDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
mixin _$ChannelDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
||||||
$ChannelsTable get channels => attachedDatabase.channels;
|
$ChannelsTable get channels => attachedDatabase.channels;
|
||||||
$UsersTable get users => attachedDatabase.users;
|
$UsersTable get users => attachedDatabase.users;
|
||||||
|
|||||||
@@ -2,10 +2,7 @@
|
|||||||
|
|
||||||
part of 'channel_query_dao.dart';
|
part of 'channel_query_dao.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// ignore_for_file: type=lint
|
||||||
// DaoGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
mixin _$ChannelQueryDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
mixin _$ChannelQueryDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
||||||
$ChannelQueriesTable get channelQueries => attachedDatabase.channelQueries;
|
$ChannelQueriesTable get channelQueries => attachedDatabase.channelQueries;
|
||||||
$ChannelsTable get channels => attachedDatabase.channels;
|
$ChannelsTable get channels => attachedDatabase.channels;
|
||||||
|
|||||||
@@ -2,10 +2,7 @@
|
|||||||
|
|
||||||
part of 'connection_event_dao.dart';
|
part of 'connection_event_dao.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// ignore_for_file: type=lint
|
||||||
// DaoGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
mixin _$ConnectionEventDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
mixin _$ConnectionEventDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
||||||
$ConnectionEventsTable get connectionEvents =>
|
$ConnectionEventsTable get connectionEvents =>
|
||||||
attachedDatabase.connectionEvents;
|
attachedDatabase.connectionEvents;
|
||||||
|
|||||||
@@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
part of 'member_dao.dart';
|
part of 'member_dao.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// ignore_for_file: type=lint
|
||||||
// DaoGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
mixin _$MemberDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
mixin _$MemberDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
||||||
|
$ChannelsTable get channels => attachedDatabase.channels;
|
||||||
$MembersTable get members => attachedDatabase.members;
|
$MembersTable get members => attachedDatabase.members;
|
||||||
$UsersTable get users => attachedDatabase.users;
|
$UsersTable get users => attachedDatabase.users;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
part of 'message_dao.dart';
|
part of 'message_dao.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// ignore_for_file: type=lint
|
||||||
// DaoGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
mixin _$MessageDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
mixin _$MessageDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
||||||
|
$ChannelsTable get channels => attachedDatabase.channels;
|
||||||
$MessagesTable get messages => attachedDatabase.messages;
|
$MessagesTable get messages => attachedDatabase.messages;
|
||||||
$UsersTable get users => attachedDatabase.users;
|
$UsersTable get users => attachedDatabase.users;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
part of 'pinned_message_dao.dart';
|
part of 'pinned_message_dao.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// ignore_for_file: type=lint
|
||||||
// DaoGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
mixin _$PinnedMessageDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
mixin _$PinnedMessageDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
||||||
|
$ChannelsTable get channels => attachedDatabase.channels;
|
||||||
$PinnedMessagesTable get pinnedMessages => attachedDatabase.pinnedMessages;
|
$PinnedMessagesTable get pinnedMessages => attachedDatabase.pinnedMessages;
|
||||||
$UsersTable get users => attachedDatabase.users;
|
$UsersTable get users => attachedDatabase.users;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,10 @@
|
|||||||
|
|
||||||
part of 'pinned_message_reaction_dao.dart';
|
part of 'pinned_message_reaction_dao.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// ignore_for_file: type=lint
|
||||||
// DaoGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
mixin _$PinnedMessageReactionDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
mixin _$PinnedMessageReactionDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
||||||
|
$ChannelsTable get channels => attachedDatabase.channels;
|
||||||
|
$PinnedMessagesTable get pinnedMessages => attachedDatabase.pinnedMessages;
|
||||||
$PinnedMessageReactionsTable get pinnedMessageReactions =>
|
$PinnedMessageReactionsTable get pinnedMessageReactions =>
|
||||||
attachedDatabase.pinnedMessageReactions;
|
attachedDatabase.pinnedMessageReactions;
|
||||||
$UsersTable get users => attachedDatabase.users;
|
$UsersTable get users => attachedDatabase.users;
|
||||||
|
|||||||
@@ -2,11 +2,10 @@
|
|||||||
|
|
||||||
part of 'reaction_dao.dart';
|
part of 'reaction_dao.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// ignore_for_file: type=lint
|
||||||
// DaoGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
mixin _$ReactionDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
mixin _$ReactionDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
||||||
|
$ChannelsTable get channels => attachedDatabase.channels;
|
||||||
|
$MessagesTable get messages => attachedDatabase.messages;
|
||||||
$ReactionsTable get reactions => attachedDatabase.reactions;
|
$ReactionsTable get reactions => attachedDatabase.reactions;
|
||||||
$UsersTable get users => attachedDatabase.users;
|
$UsersTable get users => attachedDatabase.users;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,9 @@
|
|||||||
|
|
||||||
part of 'read_dao.dart';
|
part of 'read_dao.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// ignore_for_file: type=lint
|
||||||
// DaoGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
mixin _$ReadDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
mixin _$ReadDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
||||||
|
$ChannelsTable get channels => attachedDatabase.channels;
|
||||||
$ReadsTable get reads => attachedDatabase.reads;
|
$ReadsTable get reads => attachedDatabase.reads;
|
||||||
$UsersTable get users => attachedDatabase.users;
|
$UsersTable get users => attachedDatabase.users;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,7 @@
|
|||||||
|
|
||||||
part of 'user_dao.dart';
|
part of 'user_dao.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// ignore_for_file: type=lint
|
||||||
// DaoGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
mixin _$UserDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
mixin _$UserDaoMixin on DatabaseAccessor<DriftChatDatabase> {
|
||||||
$UsersTable get users => attachedDatabase.users;
|
$UsersTable get users => attachedDatabase.users;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:stream_chat/stream_chat.dart';
|
import 'package:stream_chat/stream_chat.dart';
|
||||||
|
|
||||||
import 'package:stream_chat_persistence/src/converter/converter.dart';
|
import 'package:stream_chat_persistence/src/converter/converter.dart';
|
||||||
import 'package:stream_chat_persistence/src/dao/dao.dart';
|
import 'package:stream_chat_persistence/src/dao/dao.dart';
|
||||||
import 'package:stream_chat_persistence/src/entity/entity.dart';
|
import 'package:stream_chat_persistence/src/entity/entity.dart';
|
||||||
@@ -37,18 +36,12 @@ part 'drift_chat_database.g.dart';
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
class DriftChatDatabase extends _$DriftChatDatabase {
|
class DriftChatDatabase extends _$DriftChatDatabase {
|
||||||
/// Creates a new moor chat database instance
|
/// Creates a new drift chat database instance
|
||||||
DriftChatDatabase(
|
DriftChatDatabase(
|
||||||
this._userId,
|
this._userId,
|
||||||
QueryExecutor executor,
|
QueryExecutor executor,
|
||||||
) : super(executor);
|
) : super(executor);
|
||||||
|
|
||||||
/// Instantiate a new database instance
|
|
||||||
DriftChatDatabase.connect(
|
|
||||||
this._userId,
|
|
||||||
DatabaseConnection connection,
|
|
||||||
) : super.connect(connection);
|
|
||||||
|
|
||||||
final String _userId;
|
final String _userId;
|
||||||
|
|
||||||
/// User id to which the database is connected
|
/// User id to which the database is connected
|
||||||
@@ -56,7 +49,7 @@ class DriftChatDatabase extends _$DriftChatDatabase {
|
|||||||
|
|
||||||
// you should bump this number whenever you change or add a table definition.
|
// you should bump this number whenever you change or add a table definition.
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 9;
|
int get schemaVersion => 10;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration => MigrationStrategy(
|
MigrationStrategy get migration => MigrationStrategy(
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@ class SharedDB {
|
|||||||
}) async {
|
}) async {
|
||||||
final dbName = 'db_$userId';
|
final dbName = 'db_$userId';
|
||||||
if (connectionMode == ConnectionMode.background) {
|
if (connectionMode == ConnectionMode.background) {
|
||||||
return DriftChatDatabase.connect(
|
return DriftChatDatabase(
|
||||||
userId,
|
userId,
|
||||||
DatabaseConnection.delayed(Future(() async {
|
DatabaseConnection.delayed(Future(() async {
|
||||||
final isolate = await _createMoorIsolate(
|
final isolate = await _createMoorIsolate(
|
||||||
@@ -34,6 +34,7 @@ class SharedDB {
|
|||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return DriftChatDatabase(
|
return DriftChatDatabase(
|
||||||
userId,
|
userId,
|
||||||
LazyDatabase(
|
LazyDatabase(
|
||||||
@@ -68,7 +69,7 @@ class SharedDB {
|
|||||||
logStatements: request.logStatements,
|
logStatements: request.logStatements,
|
||||||
));
|
));
|
||||||
final moorIsolate = DriftIsolate.inCurrent(
|
final moorIsolate = DriftIsolate.inCurrent(
|
||||||
() => DatabaseConnection.fromExecutor(executor),
|
() => DatabaseConnection(executor),
|
||||||
);
|
);
|
||||||
request.sendMoorIsolate.send(moorIsolate);
|
request.sendMoorIsolate.send(moorIsolate);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:stream_chat_persistence/src/entity/channels.dart';
|
||||||
|
|
||||||
/// Represents a [Members] table in [MoorChatDatabase].
|
/// Represents a [Members] table in [MoorChatDatabase].
|
||||||
@DataClassName('MemberEntity')
|
@DataClassName('MemberEntity')
|
||||||
@@ -9,7 +10,7 @@ class Members extends Table {
|
|||||||
|
|
||||||
/// The channel cid of which this user is part of
|
/// The channel cid of which this user is part of
|
||||||
TextColumn get channelCid =>
|
TextColumn get channelCid =>
|
||||||
text().customConstraint('REFERENCES channels(cid) ON DELETE CASCADE')();
|
text().references(Channels, #cid, onDelete: KeyAction.cascade)();
|
||||||
|
|
||||||
/// The role of the user in the channel
|
/// The role of the user in the channel
|
||||||
TextColumn get channelRole => text().nullable()();
|
TextColumn get channelRole => text().nullable()();
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:drift/drift.dart';
|
|||||||
import 'package:stream_chat_persistence/src/converter/list_converter.dart';
|
import 'package:stream_chat_persistence/src/converter/list_converter.dart';
|
||||||
import 'package:stream_chat_persistence/src/converter/map_converter.dart';
|
import 'package:stream_chat_persistence/src/converter/map_converter.dart';
|
||||||
import 'package:stream_chat_persistence/src/converter/message_sending_status_converter.dart';
|
import 'package:stream_chat_persistence/src/converter/message_sending_status_converter.dart';
|
||||||
|
import 'package:stream_chat_persistence/src/entity/channels.dart';
|
||||||
|
|
||||||
/// Represents a [Messages] table in [MoorChatDatabase].
|
/// Represents a [Messages] table in [MoorChatDatabase].
|
||||||
@DataClassName('MessageEntity')
|
@DataClassName('MessageEntity')
|
||||||
@@ -78,10 +79,11 @@ class Messages extends Table {
|
|||||||
|
|
||||||
/// The channel cid of which this message is part of
|
/// The channel cid of which this message is part of
|
||||||
TextColumn get channelCid =>
|
TextColumn get channelCid =>
|
||||||
text().customConstraint('REFERENCES channels(cid) ON DELETE CASCADE')();
|
text().references(Channels, #cid, onDelete: KeyAction.cascade)();
|
||||||
|
|
||||||
/// A Map of [messageText] translations.
|
/// A Map of [messageText] translations.
|
||||||
TextColumn get i18n => text().nullable().map(MapConverter<String>())();
|
TextColumn get i18n =>
|
||||||
|
text().nullable().map(NullableMapConverter<String>())();
|
||||||
|
|
||||||
/// Message custom extraData
|
/// Message custom extraData
|
||||||
TextColumn get extraData => text().nullable().map(MapConverter<Object?>())();
|
TextColumn get extraData => text().nullable().map(MapConverter<Object?>())();
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:stream_chat_persistence/src/entity/pinned_messages.dart';
|
||||||
import 'package:stream_chat_persistence/src/entity/reactions.dart';
|
import 'package:stream_chat_persistence/src/entity/reactions.dart';
|
||||||
|
|
||||||
/// Represents a [PinnedMessageReactions] table in [MoorChatDatabase].
|
/// Represents a [PinnedMessageReactions] table in [MoorChatDatabase].
|
||||||
@@ -8,6 +8,6 @@ import 'package:stream_chat_persistence/src/entity/reactions.dart';
|
|||||||
class PinnedMessageReactions extends Reactions {
|
class PinnedMessageReactions extends Reactions {
|
||||||
/// The messageId to which the reaction belongs
|
/// The messageId to which the reaction belongs
|
||||||
@override
|
@override
|
||||||
TextColumn get messageId => text()
|
TextColumn get messageId =>
|
||||||
.customConstraint('REFERENCES pinned_messages(id) ON DELETE CASCADE')();
|
text().references(PinnedMessages, #id, onDelete: KeyAction.cascade)();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
|
|
||||||
import 'package:stream_chat_persistence/src/entity/messages.dart';
|
import 'package:stream_chat_persistence/src/entity/messages.dart';
|
||||||
|
|
||||||
/// Represents a [PinnedMessages] table in [MoorChatDatabase].
|
/// Represents a [PinnedMessages] table in [MoorChatDatabase].
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:stream_chat_persistence/src/converter/map_converter.dart';
|
import 'package:stream_chat_persistence/src/converter/map_converter.dart';
|
||||||
|
import 'package:stream_chat_persistence/src/entity/messages.dart';
|
||||||
|
|
||||||
/// Represents a [Reactions] table in [MoorChatDatabase].
|
/// Represents a [Reactions] table in [MoorChatDatabase].
|
||||||
@DataClassName('ReactionEntity')
|
@DataClassName('ReactionEntity')
|
||||||
@@ -10,7 +11,7 @@ class Reactions extends Table {
|
|||||||
|
|
||||||
/// The messageId to which the reaction belongs
|
/// The messageId to which the reaction belongs
|
||||||
TextColumn get messageId =>
|
TextColumn get messageId =>
|
||||||
text().customConstraint('REFERENCES messages(id) ON DELETE CASCADE')();
|
text().references(Messages, #id, onDelete: KeyAction.cascade)();
|
||||||
|
|
||||||
/// The type of the reaction
|
/// The type of the reaction
|
||||||
TextColumn get type => text()();
|
TextColumn get type => text()();
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// coverage:ignore-file
|
// coverage:ignore-file
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
|
import 'package:stream_chat_persistence/src/entity/channels.dart';
|
||||||
|
|
||||||
/// Represents a [Reads] table in [MoorChatDatabase].
|
/// Represents a [Reads] table in [MoorChatDatabase].
|
||||||
@DataClassName('ReadEntity')
|
@DataClassName('ReadEntity')
|
||||||
@@ -12,7 +13,7 @@ class Reads extends Table {
|
|||||||
|
|
||||||
/// The channel cid of which this read belongs
|
/// The channel cid of which this read belongs
|
||||||
TextColumn get channelCid =>
|
TextColumn get channelCid =>
|
||||||
text().customConstraint('REFERENCES channels(cid) ON DELETE CASCADE')();
|
text().references(Channels, #cid, onDelete: KeyAction.cascade)();
|
||||||
|
|
||||||
/// Number of unread messages
|
/// Number of unread messages
|
||||||
IntColumn get unreadMessages => integer().withDefault(const Constant(0))();
|
IntColumn get unreadMessages => integer().withDefault(const Constant(0))();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ environment:
|
|||||||
flutter: ">=1.17.0"
|
flutter: ">=1.17.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
drift: ^1.7.1
|
drift: ^2.7.0
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
logging: ^1.0.1
|
logging: ^1.0.1
|
||||||
@@ -23,8 +23,8 @@ dependencies:
|
|||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.3.3
|
build_runner: ^2.3.3
|
||||||
dart_code_metrics: ^4.18.0
|
dart_code_metrics: ^5.7.2
|
||||||
drift_dev: ^1.7.1
|
drift_dev: ^2.7.0
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
mocktail: ^0.3.0
|
mocktail: ^0.3.0
|
||||||
|
|||||||
@@ -4,50 +4,91 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
import 'package:stream_chat_persistence/src/converter/list_converter.dart';
|
import 'package:stream_chat_persistence/src/converter/list_converter.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('mapToDart', () {
|
group('ListConverter', () {
|
||||||
final listConverter = ListConverter<String>();
|
final listConverter = ListConverter<String>();
|
||||||
|
|
||||||
test('should return null if nothing is provided', () {
|
group('fromSql', () {
|
||||||
final res = listConverter.mapToDart(null);
|
test('should throw type error if the provided json is not a list', () {
|
||||||
expect(res, isNull);
|
final json = {'test_key': 'testData'};
|
||||||
});
|
expect(
|
||||||
|
() => listConverter.fromSql(jsonEncode(json)),
|
||||||
|
throwsA(isA<TypeError>()),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
test('should throw type error if the provided json is not a list', () {
|
test(
|
||||||
final json = {'test_key': 'testData'};
|
'should throw type error if the provided json is not a list of String',
|
||||||
expect(
|
|
||||||
() => listConverter.mapToDart(jsonEncode(json)),
|
|
||||||
throwsA(isA<TypeError>()),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should throw type error if the provided json is not a list of String',
|
|
||||||
() {
|
() {
|
||||||
final json = [22, 33, 44];
|
final json = [22, 33, 44];
|
||||||
expect(
|
expect(
|
||||||
() => listConverter.mapToDart(jsonEncode(json)),
|
() => listConverter.fromSql(jsonEncode(json)),
|
||||||
throwsA(isA<TypeError>()),
|
throwsA(isA<TypeError>()),
|
||||||
|
);
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test('should return list of String if json data list is provided', () {
|
||||||
|
final data = ['data1', 'data2', 'data3'];
|
||||||
|
final res = listConverter.fromSql(jsonEncode(data));
|
||||||
|
expect(res.length, data.length);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return list of String if json data list is provided', () {
|
group('toSql', () {
|
||||||
final data = ['data1', 'data2', 'data3'];
|
test('should return json string if data list is provided', () {
|
||||||
final res = listConverter.mapToDart(jsonEncode(data));
|
final data = ['data1', 'data2', 'data3'];
|
||||||
expect(res!.length, data.length);
|
final res = listConverter.toSql(data);
|
||||||
|
expect(res, jsonEncode(data));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('mapToSql', () {
|
group('NullableListConverter', () {
|
||||||
final listConverter = ListConverter<String>();
|
final listConverter = NullableListConverter<String>();
|
||||||
|
|
||||||
test('should return null if nothing is provided', () {
|
group('fromSql', () {
|
||||||
final res = listConverter.mapToSql(null);
|
test('should return null if nothing is provided', () {
|
||||||
expect(res, isNull);
|
final res = listConverter.fromSql(null);
|
||||||
|
expect(res, isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should throw type error if the provided json is not a list', () {
|
||||||
|
final json = {'test_key': 'testData'};
|
||||||
|
expect(
|
||||||
|
() => listConverter.fromSql(jsonEncode(json)),
|
||||||
|
throwsA(isA<TypeError>()),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should throw type error if the provided json is not a list of String',
|
||||||
|
() {
|
||||||
|
final json = [22, 33, 44];
|
||||||
|
expect(
|
||||||
|
() => listConverter.fromSql(jsonEncode(json)),
|
||||||
|
throwsA(isA<TypeError>()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test('should return list of String if json data list is provided', () {
|
||||||
|
final data = ['data1', 'data2', 'data3'];
|
||||||
|
final res = listConverter.fromSql(jsonEncode(data));
|
||||||
|
expect(res!.length, data.length);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return json string if data list is provided', () {
|
group('toSql', () {
|
||||||
final data = ['data1', 'data2', 'data3'];
|
test('should return null if nothing is provided', () {
|
||||||
final res = listConverter.mapToSql(data);
|
final res = listConverter.toSql(null);
|
||||||
expect(res, jsonEncode(data));
|
expect(res, isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return json string if data list is provided', () {
|
||||||
|
final data = ['data1', 'data2', 'data3'];
|
||||||
|
final res = listConverter.toSql(data);
|
||||||
|
expect(res, jsonEncode(data));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,61 +4,109 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
import 'package:stream_chat_persistence/src/converter/map_converter.dart';
|
import 'package:stream_chat_persistence/src/converter/map_converter.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('mapToDart', () {
|
group('MapConverter', () {
|
||||||
final mapConverter = MapConverter<String>();
|
final mapConverter = MapConverter<String>();
|
||||||
|
|
||||||
test('should return null if nothing is provided', () {
|
group('fromSql', () {
|
||||||
final res = mapConverter.mapToDart(null);
|
test('should throw type error if the provided json is not a map', () {
|
||||||
expect(res, isNull);
|
const json = ['testData1', 'testData2', 'testData3'];
|
||||||
});
|
|
||||||
|
|
||||||
test('should throw type error if the provided json is not a map', () {
|
|
||||||
const json = ['testData1', 'testData2', 'testData3'];
|
|
||||||
expect(
|
|
||||||
() => mapConverter.mapToDart(jsonEncode(json)),
|
|
||||||
throwsA(isA<TypeError>()),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test(
|
|
||||||
'should throw type error if the provided json is not a '
|
|
||||||
'map of String, String',
|
|
||||||
() {
|
|
||||||
const json = {'test_key': 22, 'test_key2': 33, 'test_key3': 44};
|
|
||||||
expect(
|
expect(
|
||||||
() => mapConverter.mapToDart(jsonEncode(json)),
|
() => mapConverter.fromSql(jsonEncode(json)),
|
||||||
throwsA(isA<TypeError>()),
|
throwsA(isA<TypeError>()),
|
||||||
);
|
);
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
test('should return map of String, String if json data is provided', () {
|
test(
|
||||||
const data = {
|
'should throw type error if the provided json is not a '
|
||||||
'test_key': 'testValue',
|
'map of String, String',
|
||||||
'test_key2': 'testValue2',
|
() {
|
||||||
'test_key3': 'testValue3',
|
const json = {'test_key': 22, 'test_key2': 33, 'test_key3': 44};
|
||||||
};
|
expect(
|
||||||
final res = mapConverter.mapToDart(jsonEncode(data));
|
() => mapConverter.fromSql(jsonEncode(json)),
|
||||||
expect(res, data);
|
throwsA(isA<TypeError>()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test('should return map of String, String if json data is provided', () {
|
||||||
|
const data = {
|
||||||
|
'test_key': 'testValue',
|
||||||
|
'test_key2': 'testValue2',
|
||||||
|
'test_key3': 'testValue3',
|
||||||
|
};
|
||||||
|
final res = mapConverter.fromSql(jsonEncode(data));
|
||||||
|
expect(res, data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('toSql', () {
|
||||||
|
test('should return json string if data map is provided', () {
|
||||||
|
const data = {
|
||||||
|
'test_key': 'testValue',
|
||||||
|
'test_key2': 'testValue2',
|
||||||
|
'test_key3': 'testValue3',
|
||||||
|
};
|
||||||
|
final res = mapConverter.toSql(data);
|
||||||
|
expect(res, jsonEncode(data));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('mapToSql', () {
|
group('NullableMapConverter', () {
|
||||||
final mapConverter = MapConverter<String>();
|
final mapConverter = NullableMapConverter<String>();
|
||||||
|
|
||||||
test('should return null if nothing is provided', () {
|
group('fromSql', () {
|
||||||
final res = mapConverter.mapToSql(null);
|
test('should return null if nothing is provided', () {
|
||||||
expect(res, isNull);
|
final res = mapConverter.fromSql(null);
|
||||||
|
expect(res, isNull);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should throw type error if the provided json is not a map', () {
|
||||||
|
const json = ['testData1', 'testData2', 'testData3'];
|
||||||
|
expect(
|
||||||
|
() => mapConverter.fromSql(jsonEncode(json)),
|
||||||
|
throwsA(isA<TypeError>()),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'should throw type error if the provided json is not a '
|
||||||
|
'map of String, String',
|
||||||
|
() {
|
||||||
|
const json = {'test_key': 22, 'test_key2': 33, 'test_key3': 44};
|
||||||
|
expect(
|
||||||
|
() => mapConverter.fromSql(jsonEncode(json)),
|
||||||
|
throwsA(isA<TypeError>()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test('should return map of String, String if json data is provided', () {
|
||||||
|
const data = {
|
||||||
|
'test_key': 'testValue',
|
||||||
|
'test_key2': 'testValue2',
|
||||||
|
'test_key3': 'testValue3',
|
||||||
|
};
|
||||||
|
final res = mapConverter.fromSql(jsonEncode(data));
|
||||||
|
expect(res, data);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should return json string if data map is provided', () {
|
group('toSql', () {
|
||||||
const data = {
|
test('should return null if nothing is provided', () {
|
||||||
'test_key': 'testValue',
|
final res = mapConverter.toSql(null);
|
||||||
'test_key2': 'testValue2',
|
expect(res, isNull);
|
||||||
'test_key3': 'testValue3',
|
});
|
||||||
};
|
|
||||||
final res = mapConverter.mapToSql(data);
|
test('should return json string if data map is provided', () {
|
||||||
expect(res, jsonEncode(data));
|
const data = {
|
||||||
|
'test_key': 'testValue',
|
||||||
|
'test_key2': 'testValue2',
|
||||||
|
'test_key3': 'testValue3',
|
||||||
|
};
|
||||||
|
final res = mapConverter.toSql(data);
|
||||||
|
expect(res, jsonEncode(data));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-16
@@ -3,31 +3,21 @@ import 'package:stream_chat/stream_chat.dart';
|
|||||||
import 'package:stream_chat_persistence/src/converter/message_sending_status_converter.dart';
|
import 'package:stream_chat_persistence/src/converter/message_sending_status_converter.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('mapToDart', () {
|
group('fromSql', () {
|
||||||
final statusConverter = MessageSendingStatusConverter();
|
final statusConverter = MessageSendingStatusConverter();
|
||||||
|
|
||||||
test('should return null if nothing is provided', () {
|
|
||||||
final res = statusConverter.mapToDart(null);
|
|
||||||
expect(res, isNull);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should return expected status if status code is provided', () {
|
test('should return expected status if status code is provided', () {
|
||||||
final res = statusConverter.mapToDart(3);
|
final res = statusConverter.fromSql(6);
|
||||||
expect(res, MessageSendingStatus.updating);
|
expect(res, MessageSendingStatus.failed_delete);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('mapToSql', () {
|
group('toSql', () {
|
||||||
final statusConverter = MessageSendingStatusConverter();
|
final statusConverter = MessageSendingStatusConverter();
|
||||||
|
|
||||||
test('should return null if nothing is provided', () {
|
|
||||||
final res = statusConverter.mapToSql(null);
|
|
||||||
expect(res, isNull);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('should return expected code if the status is provided', () {
|
test('should return expected code if the status is provided', () {
|
||||||
final res = statusConverter.mapToSql(MessageSendingStatus.updating);
|
final res = statusConverter.toSql(MessageSendingStatus.failed_delete);
|
||||||
expect(res, 3);
|
expect(res, 6);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
import 'package:stream_chat_persistence/src/db/drift_chat_database.dart';
|
import 'package:stream_chat_persistence/src/db/drift_chat_database.dart';
|
||||||
|
|
||||||
DatabaseConnection _backgroundConnection() =>
|
DatabaseConnection _backgroundConnection() =>
|
||||||
DatabaseConnection.fromExecutor(NativeDatabase.memory());
|
DatabaseConnection(NativeDatabase.memory());
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
test(
|
test(
|
||||||
@@ -30,7 +30,7 @@ void main() {
|
|||||||
final isolate = await DriftIsolate.spawn(_backgroundConnection);
|
final isolate = await DriftIsolate.spawn(_backgroundConnection);
|
||||||
final connection = DatabaseConnection.delayed(isolate.connect());
|
final connection = DatabaseConnection.delayed(isolate.connect());
|
||||||
|
|
||||||
final database = DriftChatDatabase.connect(userId, connection);
|
final database = DriftChatDatabase(userId, connection);
|
||||||
expect(database, isNotNull);
|
expect(database, isNotNull);
|
||||||
expect(database.userId, userId);
|
expect(database.userId, userId);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user