From b4ed72435c4c8ec70509d047342c910c0bc39ae6 Mon Sep 17 00:00:00 2001 From: csf Date: Thu, 17 Feb 2022 15:22:14 +0800 Subject: [PATCH] upgrade null-safe --- lib/common.dart | 123 +++++++++++++++----------- lib/gestures.dart | 198 +++++++++++++++++++++--------------------- lib/home_page.dart | 28 +++--- lib/model.dart | 103 ++++++++++------------ lib/native_model.dart | 30 ++++--- lib/remote_page.dart | 68 ++++++++------- lib/server_page.dart | 14 +-- lib/web_model.dart | 4 +- pubspec.yaml | 11 +-- 9 files changed, 298 insertions(+), 281 deletions(-) diff --git a/lib/common.dart b/lib/common.dart index 1da375e83..655c3a2ed 100644 --- a/lib/common.dart +++ b/lib/common.dart @@ -7,7 +7,7 @@ typedef F = String Function(String); typedef FMethod = String Function(String, dynamic); class Translator { - static F call; + static late F call; } class MyTheme { @@ -32,8 +32,8 @@ final ButtonStyle flatButtonStyle = TextButton.styleFrom( ), ); -void Function() loadingCancelCallback; -void showLoading(String text, BuildContext context) { +void Function()? loadingCancelCallback; +void showLoading(String text, BuildContext? context) { if (_hasDialog && context != null) { Navigator.pop(context); _hasDialog = false; @@ -43,34 +43,34 @@ void showLoading(String text, BuildContext context) { EasyLoading.show(status: text, maskType: EasyLoadingMaskType.black); return; } - EasyLoading.showWidget( - Container( - constraints: BoxConstraints(maxWidth: 300), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Center(child: CircularProgressIndicator()), - SizedBox(height: 20), - Center( - child: Text(Translator.call(text), - style: TextStyle(fontSize: 15))), - SizedBox(height: 20), - Center( - child: TextButton( - style: flatButtonStyle, - onPressed: () { - // with out loadingCancelCallback, we can see unexpected input password - // dialog shown in home, no clue why, so use this as workaround - // why no such issue on android? - if (loadingCancelCallback != null) - loadingCancelCallback(); - Navigator.pop(context); - }, - child: Text(Translator.call('Cancel'), - style: TextStyle(color: MyTheme.accent)))) - ], - )), - maskType: EasyLoadingMaskType.black); + // EasyLoading.showWidget( + // Container( + // constraints: BoxConstraints(maxWidth: 300), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Center(child: CircularProgressIndicator()), + // SizedBox(height: 20), + // Center( + // child: Text(Translator.call(text), + // style: TextStyle(fontSize: 15))), + // SizedBox(height: 20), + // Center( + // child: TextButton( + // style: flatButtonStyle, + // onPressed: () { + // // with out loadingCancelCallback, we can see unexpected input password + // // dialog shown in home, no clue why, so use this as workaround + // // why no such issue on android? + // if (loadingCancelCallback != null) + // loadingCancelCallback(); + // Navigator.pop(context); + // }, + // child: Text(Translator.call('Cancel'), + // style: TextStyle(color: MyTheme.accent)))) + // ], + // )), + // maskType: EasyLoadingMaskType.black); } void dismissLoading() { @@ -82,8 +82,9 @@ bool _hasDialog = false; typedef BuildAlertDailog = Tuple3> Function( void Function(void Function())); -Future showAlertDialog(BuildContext context, BuildAlertDailog build, - [WillPopCallback onWillPop, +// ?? +Future showAlertDialog(BuildContext context, BuildAlertDailog build, + [WillPopCallback? onWillPop, bool barrierDismissible = false, double contentPadding = 20]) async { dismissLoading(); @@ -112,7 +113,7 @@ Future showAlertDialog(BuildContext context, BuildAlertDailog build, } void msgbox(String type, String title, String text, BuildContext context, - [bool hasCancel]) { + {bool? hasCancel}) { var wrap = (String text, void Function() onPressed) => ButtonTheme( padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, @@ -148,26 +149,44 @@ void msgbox(String type, String title, String text, BuildContext context, dismissLoading(); })); } - EasyLoading.showWidget( - Container( - constraints: BoxConstraints(maxWidth: 300), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(Translator.call(title), style: TextStyle(fontSize: 21)), - SizedBox(height: 20), - Text(Translator.call(text), style: TextStyle(fontSize: 15)), - SizedBox(height: 20), - Row( - children: buttons, - ) - ], - )), - maskType: EasyLoadingMaskType.black); + EasyLoading.show( + status: "", + maskType: EasyLoadingMaskType.black, + indicator: Container( + constraints: BoxConstraints(maxWidth: 300), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(Translator.call(title), style: TextStyle(fontSize: 21)), + SizedBox(height: 20), + Text(Translator.call(text), style: TextStyle(fontSize: 15)), + SizedBox(height: 20), + Row( + children: buttons, + ) + ], + )) + ); + // EasyLoading.showWidget( + // Container( + // constraints: BoxConstraints(maxWidth: 300), + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text(Translator.call(title), style: TextStyle(fontSize: 21)), + // SizedBox(height: 20), + // Text(Translator.call(text), style: TextStyle(fontSize: 15)), + // SizedBox(height: 20), + // Row( + // children: buttons, + // ) + // ], + // )), + // maskType: EasyLoadingMaskType.black); } class PasswordWidget extends StatefulWidget { - PasswordWidget({Key key, this.controller}) : super(key: key); + PasswordWidget({Key? key, required this.controller}) : super(key: key); final TextEditingController controller; @@ -221,4 +240,4 @@ bool isAndroid = false; bool isIOS = false; bool isWeb = false; bool isDesktop = false; -BuildContext nowCtx; +BuildContext? currentCtx; diff --git a/lib/gestures.dart b/lib/gestures.dart index 57862bb93..c93042b7c 100644 --- a/lib/gestures.dart +++ b/lib/gestures.dart @@ -14,8 +14,8 @@ const kScaleSlop = kPrecisePointerPanSlop / 10; class CustomTouchGestureRecognizer extends ScaleGestureRecognizer { CustomTouchGestureRecognizer({ - Object debugOwner, - Set supportedDevices, + Object? debugOwner, + Set? supportedDevices, }) : super( debugOwner: debugOwner, supportedDevices: supportedDevices, @@ -24,24 +24,24 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer { } // oneFingerPan - GestureDragStartCallback onOneFingerPanStart; - GestureDragUpdateCallback onOneFingerPanUpdate; - GestureDragEndCallback onOneFingerPanEnd; + GestureDragStartCallback? onOneFingerPanStart; + GestureDragUpdateCallback? onOneFingerPanUpdate; + GestureDragEndCallback? onOneFingerPanEnd; // twoFingerScale - GestureScaleStartCallback onTwoFingerScaleStart; - GestureScaleUpdateCallback onTwoFingerScaleUpdate; - GestureScaleEndCallback onTwoFingerScaleEnd; + GestureScaleStartCallback? onTwoFingerScaleStart; + GestureScaleUpdateCallback? onTwoFingerScaleUpdate; + GestureScaleEndCallback? onTwoFingerScaleEnd; // twoFingerVerticalDrag - GestureDragStartCallback onTwoFingerVerticalDragStart; - GestureDragUpdateCallback onTwoFingerVerticalDragUpdate; - GestureDragEndCallback onTwoFingerVerticalDragEnd; + GestureDragStartCallback? onTwoFingerVerticalDragStart; + GestureDragUpdateCallback? onTwoFingerVerticalDragUpdate; + GestureDragEndCallback? onTwoFingerVerticalDragEnd; // twoFingerHorizontalDrag - GestureDragStartCallback onTwoFingerHorizontalDragStart; - GestureDragUpdateCallback onTwoFingerHorizontalDragUpdate; - GestureDragEndCallback onTwoFingerHorizontalDragEnd; + GestureDragStartCallback? onTwoFingerHorizontalDragStart; + GestureDragUpdateCallback? onTwoFingerHorizontalDragUpdate; + GestureDragEndCallback? onTwoFingerHorizontalDragEnd; void _init() { debugPrint("CustomTouchGestureRecognizer init"); @@ -66,22 +66,22 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer { switch (_currentState) { case CustomTouchGestureState.oneFingerPan: if (onOneFingerPanUpdate != null) { - onOneFingerPanUpdate(_getDragUpdateDetails(d)); + onOneFingerPanUpdate!(_getDragUpdateDetails(d)); } break; case CustomTouchGestureState.twoFingerScale: if (onTwoFingerScaleUpdate != null) { - onTwoFingerScaleUpdate(d); + onTwoFingerScaleUpdate!(d); } break; case CustomTouchGestureState.twoFingerHorizontalDrag: if (onTwoFingerHorizontalDragUpdate != null) { - onTwoFingerHorizontalDragUpdate(_getDragUpdateDetails(d)); + onTwoFingerHorizontalDragUpdate!(_getDragUpdateDetails(d)); } break; case CustomTouchGestureState.twoFingerVerticalDrag: if (onTwoFingerVerticalDragUpdate != null) { - onTwoFingerVerticalDragUpdate(_getDragUpdateDetails(d)); + onTwoFingerVerticalDragUpdate!(_getDragUpdateDetails(d)); } break; default: @@ -97,25 +97,25 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer { case CustomTouchGestureState.oneFingerPan: debugPrint("TwoFingerState.pan onEnd"); if (onOneFingerPanEnd != null) { - onOneFingerPanEnd(_getDragEndDetails(d)); + onOneFingerPanEnd!(_getDragEndDetails(d)); } break; case CustomTouchGestureState.twoFingerScale: debugPrint("TwoFingerState.scale onEnd"); if (onTwoFingerScaleEnd != null) { - onTwoFingerScaleEnd(d); + onTwoFingerScaleEnd!(d); } break; case CustomTouchGestureState.twoFingerHorizontalDrag: debugPrint("TwoFingerState.horizontal onEnd"); if (onTwoFingerHorizontalDragEnd != null) { - onTwoFingerHorizontalDragEnd(_getDragEndDetails(d)); + onTwoFingerHorizontalDragEnd!(_getDragEndDetails(d)); } break; case CustomTouchGestureState.twoFingerVerticalDrag: debugPrint("TwoFingerState.vertical onEnd"); if (onTwoFingerVerticalDragEnd != null) { - onTwoFingerVerticalDragEnd(_getDragEndDetails(d)); + onTwoFingerVerticalDragEnd!(_getDragEndDetails(d)); } break; default: @@ -129,7 +129,7 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer { var _currentState = CustomTouchGestureState.none; var _isWatch = false; - Timer _timer; + Timer? _timer; double _sumScale = 0; double _sumVertical = 0; double _sumHorizontal = 0; @@ -143,7 +143,7 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer { void _reset() { _isWatch = false; _clearSum(); - if (_timer != null) _timer.cancel(); + if (_timer != null) _timer!.cancel(); } void _updateCompute(ScaleUpdateDetails d) { @@ -155,14 +155,14 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer { debugPrint("start Scale"); _currentState = CustomTouchGestureState.twoFingerScale; if (onOneFingerPanStart != null) { - onOneFingerPanStart(_getDragStartDetails(d)); + onOneFingerPanStart!(_getDragStartDetails(d)); } _reset(); } else if (_sumHorizontal.abs() > kPrecisePointerPanSlop) { debugPrint("start Horizontal"); _currentState = CustomTouchGestureState.twoFingerHorizontalDrag; if (onTwoFingerHorizontalDragUpdate != null) { - onTwoFingerHorizontalDragUpdate(_getDragUpdateDetails(d)); + onTwoFingerHorizontalDragUpdate!(_getDragUpdateDetails(d)); } _reset(); } else if (_sumVertical.abs() > kPrecisePointerPanSlop) { @@ -179,7 +179,7 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer { debugPrint("startWatchTimer"); _isWatch = true; _clearSum(); - if (_timer != null) _timer.cancel(); + if (_timer != null) _timer!.cancel(); _timer = Timer(const Duration(milliseconds: 200), _reset); } @@ -201,24 +201,24 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer { class HoldTapMoveGestureRecognizer extends GestureRecognizer { HoldTapMoveGestureRecognizer({ - Object debugOwner, - Set supportedDevices, + Object? debugOwner, + Set? supportedDevices, }) : super( debugOwner: debugOwner, supportedDevices: supportedDevices, ); - GestureDragStartCallback onHoldDragStart; - GestureDragUpdateCallback onHoldDragUpdate; - GestureDragDownCallback onHoldDragDown; - GestureDragCancelCallback onHoldDragCancel; + GestureDragStartCallback? onHoldDragStart; + GestureDragUpdateCallback? onHoldDragUpdate; + GestureDragDownCallback? onHoldDragDown; + GestureDragCancelCallback? onHoldDragCancel; bool _isStart = false; - Timer _firstTapUpTimer; // 第一次点击后的计时 超时未等到第二次操作则reject - Timer _secondTapDownTimer; // 第二次点击后的计时 期间内有其他的操作则reject 超时则判定成功 drag update - _TapTracker _firstTap; - _TapTracker _secondTap; + Timer? _firstTapUpTimer; // 第一次点击后的计时 超时未等到第二次操作则reject + Timer? _secondTapDownTimer; // 第二次点击后的计时 期间内有其他的操作则reject 超时则判定成功 drag update + _TapTracker? _firstTap; + _TapTracker? _secondTap; final Map _trackers = {}; @@ -244,11 +244,11 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { void addAllowedPointer(PointerDownEvent event) { // 检测按下事件 if (_firstTap != null) { - if (!_firstTap.isWithinGlobalTolerance(event, kDoubleTapSlop)) { + if (!_firstTap!.isWithinGlobalTolerance(event, kDoubleTapSlop)) { // Ignore out-of-bounds second taps. return; - } else if (!_firstTap.hasElapsedMinTime() || - !_firstTap.hasSameButton(event)) { + } else if (!_firstTap!.hasElapsedMinTime() || + !_firstTap!.hasSameButton(event)) { // Restart when the second tap is too close to the first (touch screens // often detect touches intermittently), or when buttons mismatch. _reset(); @@ -256,7 +256,7 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { } else if (onHoldDragDown != null) { invokeCallback( 'onHoldDragDown', - () => onHoldDragDown(DragDownDetails( + () => onHoldDragDown!(DragDownDetails( globalPosition: event.position, localPosition: event.localPosition))); } @@ -269,7 +269,7 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { _stopSecondTapDownTimer(); final _TapTracker tracker = _TapTracker( event: event, - entry: GestureBinding.instance.gestureArena.add(event.pointer, this), + entry: GestureBinding.instance!.gestureArena.add(event.pointer, this), doubleTapMinTime: kDoubleTapMinTime, gestureSettings: gestureSettings, ); @@ -279,7 +279,7 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { // 实际的逻辑应该是第二次down后一段时间没有抬起则表示start 刚好是双击取反 void _handleEvent(PointerEvent event) { - final _TapTracker tracker = _trackers[event.pointer]; + final _TapTracker tracker = _trackers[event.pointer]!; if (event is PointerUpEvent) { if (_firstTap == null && _secondTap == null) { _registerFirstTap(tracker); @@ -294,17 +294,17 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { } else if (event is PointerMoveEvent) { // 检测到first tap move 则取消,检测到second tap move且已经通过竞技场则update if (!tracker.isWithinGlobalTolerance(event, kDoubleTapTouchSlop)) { - if (_firstTap != null && _firstTap.pointer == event.pointer) { + if (_firstTap != null && _firstTap!.pointer == event.pointer) { // first tap move _reject(tracker); - } else if (_secondTap != null && _secondTap.pointer == event.pointer) { + } else if (_secondTap != null && _secondTap!.pointer == event.pointer) { // debugPrint("_secondTap move"); // second tap move if (!_isStart) { _resolve(); } if (onHoldDragUpdate != null) - onHoldDragUpdate(DragUpdateDetails( + onHoldDragUpdate!(DragUpdateDetails( globalPosition: event.position, localPosition: event.localPosition, delta: event.delta)); @@ -320,9 +320,9 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { @override void rejectGesture(int pointer) { - _TapTracker tracker = _trackers[pointer]; + _TapTracker? tracker = _trackers[pointer]; // If tracker isn't in the list, check if this is the first tap tracker - if (tracker == null && _firstTap != null && _firstTap.pointer == pointer) { + if (tracker == null && _firstTap != null && _firstTap!.pointer == pointer) { tracker = _firstTap; } // If tracker is still null, we rejected ourselves already @@ -333,11 +333,11 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { void _resolve() { _stopSecondTapDownTimer(); - _firstTap?.entry?.resolve(GestureDisposition.accepted); - _secondTap?.entry?.resolve(GestureDisposition.accepted); + _firstTap?.entry.resolve(GestureDisposition.accepted); + _secondTap?.entry.resolve(GestureDisposition.accepted); _isStart = true; // TODO start details - if (onHoldDragStart != null) onHoldDragStart(DragStartDetails()); + if (onHoldDragStart != null) onHoldDragStart!(DragStartDetails()); } void _reject(_TapTracker tracker) { @@ -367,16 +367,16 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { } // Note, order is important below in order for the resolve -> reject logic // to work properly. - final _TapTracker tracker = _firstTap; + final _TapTracker tracker = _firstTap!; _firstTap = null; _reject(tracker); - GestureBinding.instance.gestureArena.release(tracker.pointer); + GestureBinding.instance!.gestureArena.release(tracker.pointer); if (_secondTap != null) { - final _TapTracker tracker = _secondTap; + final _TapTracker tracker = _secondTap!; _secondTap = null; _reject(tracker); - GestureBinding.instance.gestureArena.release(tracker.pointer); + GestureBinding.instance!.gestureArena.release(tracker.pointer); } } // TODO 正确的释放资源 @@ -387,7 +387,7 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { void _registerFirstTap(_TapTracker tracker) { _startFirstTapUpTimer(); - GestureBinding.instance.gestureArena.hold(tracker.pointer); + GestureBinding.instance!.gestureArena.hold(tracker.pointer); // Note, order is important below in order for the clear -> reject logic to // work properly. _freezeTracker(tracker); @@ -399,12 +399,12 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { // 清除first tap的状态 if (_firstTap != null) { _stopFirstTapUpTimer(); - _freezeTracker(_firstTap); + _freezeTracker(_firstTap!); _firstTap = null; } _startSecondTapDownTimer(); - GestureBinding.instance.gestureArena.hold(tracker.pointer); + GestureBinding.instance!.gestureArena.hold(tracker.pointer); _secondTap = tracker; @@ -430,21 +430,21 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { void _stopFirstTapUpTimer() { if (_firstTapUpTimer != null) { - _firstTapUpTimer.cancel(); + _firstTapUpTimer!.cancel(); _firstTapUpTimer = null; } } void _stopSecondTapDownTimer() { if (_secondTapDownTimer != null) { - _secondTapDownTimer.cancel(); + _secondTapDownTimer!.cancel(); _secondTapDownTimer = null; } } void _checkCancel() { if (onHoldDragCancel != null) { - invokeCallback('onHoldDragCancel', onHoldDragCancel); + invokeCallback('onHoldDragCancel', onHoldDragCancel!); } } @@ -454,19 +454,19 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer { class DoubleFinerTapGestureRecognizer extends GestureRecognizer { DoubleFinerTapGestureRecognizer({ - Object debugOwner, - Set supportedDevices, + Object? debugOwner, + Set? supportedDevices, }) : super( debugOwner: debugOwner, supportedDevices: supportedDevices, ); - GestureTapDownCallback onDoubleFinerTapDown; - GestureTapDownCallback onDoubleFinerTap; - GestureTapCancelCallback onDoubleFinerTapCancel; + GestureTapDownCallback? onDoubleFinerTapDown; + GestureTapDownCallback? onDoubleFinerTap; + GestureTapCancelCallback? onDoubleFinerTapCancel; - Timer _firstTapTimer; // 第一次点击后的计时 超时未等到第二次操作则reject - _TapTracker _firstTap; + Timer? _firstTapTimer; // 第一次点击后的计时 超时未等到第二次操作则reject + _TapTracker? _firstTap; var _isStart = false; @@ -505,7 +505,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer { kind: getKindForPointer(event.pointer), ); invokeCallback( - 'onDoubleFinerTapDown', () => onDoubleFinerTapDown(details)); + 'onDoubleFinerTapDown', () => onDoubleFinerTapDown!(details)); } } else { // first tap @@ -518,7 +518,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer { void _trackTap(PointerDownEvent event) { final _TapTracker tracker = _TapTracker( event: event, - entry: GestureBinding.instance.gestureArena.add(event.pointer, this), + entry: GestureBinding.instance!.gestureArena.add(event.pointer, this), doubleTapMinTime: kDoubleTapMinTime, gestureSettings: gestureSettings, ); @@ -531,7 +531,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer { // 实际的逻辑应该是第二次down后一段时间没有抬起则表示start 刚好是双击取反 void _handleEvent(PointerEvent event) { - final _TapTracker tracker = _trackers[event.pointer]; + final _TapTracker tracker = _trackers[event.pointer]!; if (event is PointerUpEvent) { debugPrint("PointerUpEvent"); _upTap.add(tracker.pointer); @@ -548,9 +548,9 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer { @override void rejectGesture(int pointer) { - _TapTracker tracker = _trackers[pointer]; + _TapTracker? tracker = _trackers[pointer]; // If tracker isn't in the list, check if this is the first tap tracker - if (tracker == null && _firstTap != null && _firstTap.pointer == pointer) { + if (tracker == null && _firstTap != null && _firstTap!.pointer == pointer) { tracker = _firstTap; } // If tracker is still null, we rejected ourselves already @@ -589,7 +589,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer { } void _registerTap(_TapTracker tracker) { - GestureBinding.instance.gestureArena.hold(tracker.pointer); + GestureBinding.instance!.gestureArena.hold(tracker.pointer); // Note, order is important below in order for the clear -> reject logic to // work properly. } @@ -609,7 +609,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer { void _stopFirstTapUpTimer() { if (_firstTapTimer != null) { - _firstTapTimer.cancel(); + _firstTapTimer!.cancel(); _firstTapTimer = null; } } @@ -626,7 +626,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer { void _resolve() { // TODO tap down details - if (onDoubleFinerTap != null) onDoubleFinerTap(TapDownDetails()); + if (onDoubleFinerTap != null) onDoubleFinerTap!(TapDownDetails()); _trackers.forEach((key, value) { value.entry.resolve(GestureDisposition.accepted); }); @@ -635,7 +635,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer { void _checkCancel() { if (onDoubleFinerTapCancel != null) { - invokeCallback('onHoldDragCancel', onDoubleFinerTapCancel); + invokeCallback('onHoldDragCancel', onDoubleFinerTapCancel!); } } @@ -647,10 +647,10 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer { /// larger gesture. class _TapTracker { _TapTracker({ - PointerDownEvent event, - this.entry, - Duration doubleTapMinTime, - this.gestureSettings, + required PointerDownEvent event, + required this.entry, + required Duration doubleTapMinTime, + required this.gestureSettings, }) : assert(doubleTapMinTime != null), assert(event != null), assert(event.buttons != null), @@ -660,7 +660,7 @@ class _TapTracker { _doubleTapMinTimeCountdown = _CountdownZoned(duration: doubleTapMinTime); - final DeviceGestureSettings gestureSettings; + final DeviceGestureSettings? gestureSettings; final int pointer; final GestureArenaEntry entry; final Offset _initialGlobalPosition; @@ -669,17 +669,17 @@ class _TapTracker { bool _isTrackingPointer = false; - void startTrackingPointer(PointerRoute route, Matrix4 transform) { + void startTrackingPointer(PointerRoute route, Matrix4? transform) { if (!_isTrackingPointer) { _isTrackingPointer = true; - GestureBinding.instance.pointerRouter.addRoute(pointer, route, transform); + GestureBinding.instance!.pointerRouter.addRoute(pointer, route, transform); } } void stopTrackingPointer(PointerRoute route) { if (_isTrackingPointer) { _isTrackingPointer = false; - GestureBinding.instance.pointerRouter.removeRoute(pointer, route); + GestureBinding.instance!.pointerRouter.removeRoute(pointer, route); } } @@ -700,7 +700,7 @@ class _TapTracker { /// CountdownZoned tracks whether the specified duration has elapsed since /// creation, honoring [Zone]. class _CountdownZoned { - _CountdownZoned({Duration duration}) : assert(duration != null) { + _CountdownZoned({required Duration duration}) : assert(duration != null) { Timer(duration, _onTimeout); } @@ -714,18 +714,19 @@ class _CountdownZoned { } RawGestureDetector getMixinGestureDetector({ - Widget child, - GestureTapUpCallback onTapUp, - GestureDoubleTapCallback onDoubleTap, - GestureDragStartCallback onHoldDragStart, - GestureDragUpdateCallback onHoldDragUpdate, - GestureDragCancelCallback onHoldDragCancel, - GestureTapDownCallback onDoubleFinerTap, - GestureDragStartCallback onOneFingerPanStart, - GestureDragUpdateCallback onOneFingerPanUpdate, - GestureScaleUpdateCallback onTwoFingerScaleUpdate, - GestureDragUpdateCallback onTwoFingerHorizontalDragUpdate, - GestureDragUpdateCallback onTwoFingerVerticalDragUpdate, + Widget? child, + GestureTapUpCallback? onTapUp, + GestureDoubleTapCallback? onDoubleTap, + GestureDragStartCallback? onHoldDragStart, + GestureDragUpdateCallback? onHoldDragUpdate, + GestureDragCancelCallback? onHoldDragCancel, + GestureTapDownCallback? onDoubleFinerTap, + GestureDragStartCallback? onOneFingerPanStart, + GestureDragUpdateCallback? onOneFingerPanUpdate, + GestureScaleUpdateCallback? onTwoFingerScaleUpdate, + GestureScaleEndCallback? onTwoFingerScaleEnd, + GestureDragUpdateCallback? onTwoFingerHorizontalDragUpdate, + GestureDragUpdateCallback? onTwoFingerVerticalDragUpdate, }) { return RawGestureDetector( child: child, @@ -763,6 +764,7 @@ RawGestureDetector getMixinGestureDetector({ ..onOneFingerPanStart = onOneFingerPanStart ..onOneFingerPanUpdate = onOneFingerPanUpdate ..onTwoFingerScaleUpdate = onTwoFingerScaleUpdate + ..onTwoFingerScaleEnd = onTwoFingerScaleEnd ..onTwoFingerHorizontalDragUpdate = onTwoFingerHorizontalDragUpdate ..onTwoFingerVerticalDragUpdate = onTwoFingerVerticalDragUpdate; }) diff --git a/lib/home_page.dart b/lib/home_page.dart index 577812c98..988859087 100644 --- a/lib/home_page.dart +++ b/lib/home_page.dart @@ -8,7 +8,7 @@ import 'model.dart'; import 'remote_page.dart'; class HomePage extends StatefulWidget { - HomePage({Key key, this.title}) : super(key: key); + HomePage({Key? key, required this.title}) : super(key: key); final String title; @@ -55,18 +55,20 @@ class _HomePageState extends State { }, onTap: () { () async { - var value = await showMenu( + var value = await showMenu( context: context, position: this._menuPos, items: [ PopupMenuItem( child: Text(translate('ID Server')), value: 'id_server'), + // TODO test isAndroid - ? PopupMenuItem( + ? PopupMenuItem( child: Text(translate('Share My Screen')), value: 'server') - : null, + : PopupMenuItem( + child: SizedBox.shrink(), value: ''), PopupMenuItem( child: Text(translate('About') + ' RustDesk'), value: 'about'), @@ -328,8 +330,8 @@ void showServer(BuildContext context) { labelText: translate('ID Server'), ), validator: validate, - onSaved: (String value) { - id = value.trim(); + onSaved: (String? value) { + if (value != null) id = value.trim(); }, ), /* @@ -350,8 +352,8 @@ void showServer(BuildContext context) { labelText: 'Key', ), validator: null, - onSaved: (String value) { - key = value.trim(); + onSaved: (String? value) { + if (value != null) key = value.trim(); }, ), ])), @@ -366,8 +368,8 @@ void showServer(BuildContext context) { TextButton( style: flatButtonStyle, onPressed: () { - if (formKey.currentState.validate()) { - formKey.currentState.save(); + if (formKey.currentState != null && formKey.currentState!.validate()) { + formKey.currentState!.save(); if (id != id0) FFI.setByName('option', '{"name": "custom-rendezvous-server", "value": "$id"}'); @@ -391,7 +393,7 @@ Future showAbout(BuildContext context) async { showAlertDialog( context, (setState) => Tuple3( - null, + SizedBox.shrink(), // TODO test old:null Wrap(direction: Axis.vertical, spacing: 12, children: [ Text('Version: $version'), InkWell( @@ -409,12 +411,12 @@ Future showAbout(BuildContext context) async { )), )), ]), - null), + []), () async => true, true); } -String validate(value) { +String? validate(value) { value = value.trim(); if (value.isEmpty) { return null; diff --git a/lib/model.dart b/lib/model.dart index 52d4506e6..a341f0b54 100644 --- a/lib/model.dart +++ b/lib/model.dart @@ -11,15 +11,15 @@ import 'common.dart'; import 'native_model.dart' if (dart.library.html) 'web_model.dart'; class FfiModel with ChangeNotifier { - PeerInfo _pi; - Display _display; + PeerInfo _pi = PeerInfo(); + Display _display = Display(); var _decoding = false; - bool _waitForImage; + bool _waitForImage = false; bool _initialized = false; var _inputBlocked = false; final _permissions = Map(); - bool _secure; - bool _direct; + bool? _secure; + bool? _direct; get permissions => _permissions; @@ -32,6 +32,7 @@ class FfiModel with ChangeNotifier { get direct => _direct; get pi => _pi; + get inputBlocked => _inputBlocked; set inputBlocked(v) { @@ -75,8 +76,8 @@ class FfiModel with ChangeNotifier { _direct = direct; } - Image getConnectionImage() { - String icon; + Image? getConnectionImage() { + String? icon; if (secure == true && direct == true) { icon = 'secure'; } else if (secure == false && direct == true) { @@ -200,11 +201,11 @@ class FfiModel with ChangeNotifier { } class ImageModel with ChangeNotifier { - ui.Image _image; + ui.Image? _image; - ui.Image get image => _image; + ui.Image? get image => _image; - void update(ui.Image image) { + void update(ui.Image? image) { if (_image == null && image != null) { if (isDesktop) { FFI.canvasModel.updateViewStyle(); @@ -223,28 +224,26 @@ class ImageModel with ChangeNotifier { double get maxScale { if (_image == null) return 1.0; final size = MediaQueryData.fromWindow(ui.window).size; - final xscale = size.width / _image.width; - final yscale = size.height / _image.height; + final xscale = size.width / _image!.width; + final yscale = size.height / _image!.height; return max(1.0, max(xscale, yscale)); } double get minScale { if (_image == null) return 1.0; final size = MediaQueryData.fromWindow(ui.window).size; - final xscale = size.width / _image.width; - final yscale = size.height / _image.height; + final xscale = size.width / _image!.width; + final yscale = size.height / _image!.height; return min(xscale, yscale); } } class CanvasModel with ChangeNotifier { - double _x; - double _y; - double _scale; + double _x = 0; + double _y = 0; + double _scale = 1.0; - CanvasModel() { - clear(); - } + CanvasModel(); double get x => _x; @@ -355,7 +354,7 @@ class CanvasModel with ChangeNotifier { } class CursorModel with ChangeNotifier { - ui.Image _image; + ui.Image? _image; final _images = Map>(); double _x = -10000; double _y = -10000; @@ -364,7 +363,7 @@ class CursorModel with ChangeNotifier { double _displayOriginX = 0; double _displayOriginY = 0; - ui.Image get image => _image; + ui.Image? get image => _image; double get x => _x - _displayOriginX; @@ -445,7 +444,7 @@ class CursorModel with ChangeNotifier { var tryMoveCanvasX = false; if (dx > 0) { final maxCanvasCanMove = - _displayOriginX + FFI.imageModel.image.width - r.right; + _displayOriginX + FFI.imageModel.image!.width - r.right; tryMoveCanvasX = _x + dx > cx && maxCanvasCanMove > 0; if (tryMoveCanvasX) { dx = min(dx, maxCanvasCanMove); @@ -466,7 +465,7 @@ class CursorModel with ChangeNotifier { var tryMoveCanvasY = false; if (dy > 0) { final mayCanvasCanMove = - _displayOriginY + FFI.imageModel.image.height - r.bottom; + _displayOriginY + FFI.imageModel.image!.height - r.bottom; tryMoveCanvasY = _y + dy > cy && mayCanvasCanMove > 0; if (tryMoveCanvasY) { dy = min(dy, mayCanvasCanMove); @@ -567,12 +566,12 @@ class CursorModel with ChangeNotifier { } class ClientState { - bool isStart; - bool isFileTransfer; - String name; - String peerId; + bool isStart = false; + bool isFileTransfer = false; + String name = ""; + String peerId = ""; - ClientState({this.isStart, this.isFileTransfer, this.name, this.peerId}); + ClientState(this.isStart, this.isFileTransfer, this.name, this.peerId); ClientState.fromJson(Map json) { isStart = json['is_start']; @@ -592,20 +591,17 @@ class ClientState { } class ServerModel with ChangeNotifier { - bool _mediaOk; - bool _inputOk; - // bool _needServerOpen; - bool _isPeerStart; - bool _isFileTransfer; - String _peerName; - String _peerID; + bool _mediaOk = false; + bool _inputOk = false; + bool _isPeerStart = false; + bool _isFileTransfer = false; + String _peerName = ""; + String _peerID = ""; bool get mediaOk => _mediaOk; bool get inputOk => _inputOk; - // bool get needServerOpen => _needServerOpen; - bool get isPeerStart => _isPeerStart; bool get isFileTransfer => _isFileTransfer; @@ -614,18 +610,7 @@ class ServerModel with ChangeNotifier { String get peerID => _peerID; - ServerModel() { - _mediaOk = false; - _inputOk = false; - _isPeerStart = false; - _peerName = ""; - _peerID = ""; - } - - // setNeedServerOpen(bool v){ - // _needServerOpen = v; - // notifyListeners(); - // } + ServerModel(); changeStatue(String name, bool value) { switch (name) { @@ -753,7 +738,7 @@ class FFI { FFI.id = id; } - static Map popEvent() { + static Map? popEvent() { var s = getByName('event'); if (s == '') return null; try { @@ -892,13 +877,13 @@ class Display { } class PeerInfo { - String version; - String username; - String hostname; - String platform; - bool sasEnabled; - int currentDisplay; - List displays; + String version = ""; + String username = ""; + String hostname = ""; + String platform = ""; + bool sasEnabled = false; + int currentDisplay = 0; + List displays = []; } void savePreference(String id, double xCursor, double yCursor, double xCanvas, @@ -914,7 +899,7 @@ void savePreference(String id, double xCursor, double yCursor, double xCanvas, prefs.setString('peer' + id, json.encode(p)); } -Future> getPreference(String id) async { +Future?> getPreference(String id) async { if (!isDesktop) return null; SharedPreferences prefs = await SharedPreferences.getInstance(); var p = prefs.getString('peer' + id); diff --git a/lib/native_model.dart b/lib/native_model.dart index b26df8470..c8fb81c58 100644 --- a/lib/native_model.dart +++ b/lib/native_model.dart @@ -11,8 +11,8 @@ import 'common.dart'; class RgbaFrame extends Struct { @Uint32() - int len; - Pointer data; + external int len; + external Pointer data; } typedef F2 = Pointer Function(Pointer, Pointer); @@ -21,24 +21,25 @@ typedef F4 = void Function(Pointer); typedef F5 = Pointer Function(); class PlatformFFI { - static Pointer _lastRgbaFrame; + static Pointer? _lastRgbaFrame; static String _dir = ''; static String _homeDir = ''; - static F2 _getByName; - static F3 _setByName; - static F4 _freeRgba; - static F5 _getRgba; + static F2? _getByName; + static F3? _setByName; + static F4? _freeRgba; + static F5? _getRgba; static void clearRgbaFrame() { - if (_lastRgbaFrame != null && _lastRgbaFrame != nullptr) - _freeRgba(_lastRgbaFrame); + if (_lastRgbaFrame != null && + _lastRgbaFrame != nullptr && + _freeRgba != null) _freeRgba!(_lastRgbaFrame!); } - static Uint8List getRgba() { + static Uint8List? getRgba() { if (_getRgba == null) return null; - _lastRgbaFrame = _getRgba(); + _lastRgbaFrame = _getRgba!(); if (_lastRgbaFrame == null || _lastRgbaFrame == nullptr) return null; - final ref = _lastRgbaFrame.ref; + final ref = _lastRgbaFrame!.ref; return Uint8List.sublistView(ref.data.asTypedList(ref.len)); } @@ -51,7 +52,7 @@ class PlatformFFI { if (_getByName == null) return ''; var a = name.toNativeUtf8(); var b = arg.toNativeUtf8(); - var p = _getByName(a, b); + var p = _getByName!(a, b); assert(p != nullptr && p != null); var res = p.toDartString(); calloc.free(p); @@ -64,7 +65,7 @@ class PlatformFFI { if (_setByName == null) return; var a = name.toNativeUtf8(); var b = value.toNativeUtf8(); - _setByName(a, b); + _setByName!(a, b); calloc.free(a); calloc.free(b); } @@ -110,6 +111,7 @@ class PlatformFFI { static void startDesktopWebListener( Function(Map) handleMouse) {} + static void stopDesktopWebListener() {} static void setMethodCallHandler(FMethod callback) { diff --git a/lib/remote_page.dart b/lib/remote_page.dart index 397f89ac0..1ed6b47b8 100644 --- a/lib/remote_page.dart +++ b/lib/remote_page.dart @@ -14,7 +14,7 @@ import 'model.dart'; final initText = '\1' * 1024; class RemotePage extends StatefulWidget { - RemotePage({Key key, this.id}) : super(key: key); + RemotePage({Key? key, required this.id}) : super(key: key); final String id; @@ -23,8 +23,8 @@ class RemotePage extends StatefulWidget { } class _RemotePageState extends State { - Timer _interval; - Timer _timer; + Timer? _interval; + Timer? _timer; bool _showBar = !isDesktop; double _bottom = 0; String _value = ''; @@ -47,14 +47,14 @@ class _RemotePageState extends State { void initState() { super.initState(); FFI.connect(widget.id); - WidgetsBinding.instance.addPostFrameCallback((_) { + WidgetsBinding.instance!.addPostFrameCallback((_) { SystemChrome.setEnabledSystemUIOverlays([]); showLoading(translate('Connecting...'), context); _interval = Timer.periodic(Duration(milliseconds: 30), (timer) => interval()); }); Wakelock.enable(); - loadingCancelCallback = () => _interval.cancel(); + loadingCancelCallback = () => _interval?.cancel(); _touchMode = FFI.getByName('peer_option', "touch-mode") != ''; } @@ -63,7 +63,7 @@ class _RemotePageState extends State { _focusNode.dispose(); FFI.close(); loadingCancelCallback = null; - _interval.cancel(); + _interval?.cancel(); _timer?.cancel(); dismissLoading(); SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values); @@ -354,8 +354,8 @@ class _RemotePageState extends State { onTapUp: (d) { if (_drag || _scroll) return; if (_touchMode) { - FFI.cursorModel.touch( - d.localPosition.dx, d.localPosition.dy, _right); + FFI.cursorModel + .touch(d.localPosition.dx, d.localPosition.dy, _right); } else { FFI.tap(_right); } @@ -385,12 +385,12 @@ class _RemotePageState extends State { FFI.cursorModel.updatePan(d.delta.dx, d.delta.dy, _touchMode, _drag); }, onTwoFingerScaleUpdate: (d) { - var scale = (d.scale -1) / 20 + 1; - FFI.canvasModel.updateScale(scale); - _scale = scale; + FFI.canvasModel.updateScale(d.scale/_scale); + _scale = d.scale; }, + onTwoFingerScaleEnd: (d)=>_scale = 1, onTwoFingerVerticalDragUpdate: (d) { - FFI.scroll( - d.delta.dy / 20); + FFI.scroll(d.delta.dy / 2); }); return GestureDetector( onLongPress: () { @@ -491,9 +491,8 @@ class _RemotePageState extends State { paints.add(CursorPaint()); } return MouseRegion( - cursor: keyboard - ? SystemMouseCursors.none - : null, // still laggy, set cursor directly for web is better + cursor: keyboard ? SystemMouseCursors.none : MouseCursor.defer, + // TODO old null // still laggy, set cursor directly for web is better onEnter: (event) { print('enter'); FFI.listenToMouse(true); @@ -586,8 +585,8 @@ class _RemotePageState extends State { FFI.setByName('refresh'); } else if (value == 'paste') { () async { - ClipboardData data = await Clipboard.getData(Clipboard.kTextPlain); - if (data.text != null) { + ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain); + if (data != null && data.text != null) { FFI.setByName('input_string', '${data.text}'); } }(); @@ -618,8 +617,8 @@ class _RemotePageState extends State { return SizedBox(); } final size = MediaQuery.of(context).size; - var wrap = - (String text, void Function() onPressed, [bool active, IconData icon]) { + var wrap = (String text, void Function() onPressed, + [bool? active, IconData? icon]) { return TextButton( style: TextButton.styleFrom( minimumSize: Size(0, 0), @@ -811,13 +810,13 @@ class CursorPaint extends StatelessWidget { class ImagePainter extends CustomPainter { ImagePainter({ - this.image, - this.x, - this.y, - this.scale, + required this.image, + required this.x, + required this.y, + required this.scale, }); - ui.Image image; + ui.Image? image; double x; double y; double scale; @@ -826,7 +825,7 @@ class ImagePainter extends CustomPainter { void paint(Canvas canvas, Size size) { if (image == null) return; canvas.scale(scale, scale); - canvas.drawImage(image, new Offset(x, y), new Paint()); + canvas.drawImage(image!, new Offset(x, y), new Paint()); } @override @@ -853,7 +852,9 @@ void enterPasswordDialog(String id, BuildContext context) { ), value: remember, onChanged: (v) { - setState(() => remember = v); + if (v != null) { + setState(() => remember = v); + } }, ), ]), @@ -918,7 +919,7 @@ CheckboxListTile getToggle( } RadioListTile getRadio(String name, String toValue, String curValue, - void Function(String) onChange) { + void Function(String?) onChange) { return RadioListTile( controlAffinity: ListTileControlAffinity.trailing, title: Text(translate(name)), @@ -985,13 +986,15 @@ void showOptions(BuildContext context) { more.add(getToggle(setState, 'privacy-mode', 'Privacy mode')); } } - var setQuality = (String value) { + var setQuality = (String? value) { + if(value == null) return; setState(() { quality = value; FFI.setByName('image_quality', value); }); }; - var setViewStyle = (String value) { + var setViewStyle = (String? value) { + if(value == null) return; setState(() { viewStyle = value; FFI.setByName( @@ -1000,7 +1003,7 @@ void showOptions(BuildContext context) { }); }; return Tuple3( - null, + SizedBox.shrink(), Column( mainAxisSize: MainAxisSize.min, children: displays + @@ -1012,7 +1015,7 @@ void showOptions(BuildContext context) { getRadio('Stretch', 'stretch', viewStyle, setViewStyle), Divider(color: MyTheme.border), ] - : {}) + + : []) + [ getRadio('Good image quality', 'best', quality, setQuality), getRadio('Balanced', 'balanced', quality, setQuality), @@ -1023,7 +1026,7 @@ void showOptions(BuildContext context) { setState, 'show-remote-cursor', 'Show remote cursor'), ] + more), - null); + []); }, () async => true, true, 0); } @@ -1047,6 +1050,7 @@ void showSetOSPassword(BuildContext context, bool login) { ), value: autoLogin, onChanged: (v) { + if(v==null) return; setState(() => autoLogin = v); }, ), diff --git a/lib/server_page.dart b/lib/server_page.dart index 9081b59ed..6eb8e00de 100644 --- a/lib/server_page.dart +++ b/lib/server_page.dart @@ -101,7 +101,7 @@ class _ServerInfoState extends State { labelStyle: TextStyle(fontWeight: FontWeight.bold, color: MyTheme.accent50), ), - onSaved: (String value) {}, + onSaved: (String? value) {}, ), TextFormField( readOnly: true, @@ -123,7 +123,7 @@ class _ServerInfoState extends State { _passwdShow = !_passwdShow; }); })), - onSaved: (String value) {}, + onSaved: (String? value) {}, ), ], )); @@ -187,7 +187,7 @@ class _PermissionCheckerState extends State { } } -BuildContext loginReqAlertCtx; +BuildContext? loginReqAlertCtx; void showLoginReqAlert(BuildContext context, String peerID, String name) async { await showDialog( @@ -238,7 +238,7 @@ void showLoginReqAlert(BuildContext context, String peerID, String name) async { clearLoginReqAlert() { if (loginReqAlertCtx != null) { - Navigator.of(loginReqAlertCtx).pop(); + Navigator.of(loginReqAlertCtx!).pop(); FFI.serverModel.updateClientState(); } } @@ -372,8 +372,10 @@ void toAndroidChannelInit() { FFI.serverModel.updateClientState(); debugPrint( "pre show loginAlert:${FFI.serverModel.isFileTransfer.toString()}"); - showLoginReqAlert( - currentCtx, FFI.serverModel.peerID, FFI.serverModel.peerName); + if(currentCtx!=null){ + showLoginReqAlert( + currentCtx!, FFI.serverModel.peerID, FFI.serverModel.peerName); + } debugPrint("from jvm:try_start_without_auth done"); break; } diff --git a/lib/web_model.dart b/lib/web_model.dart index 9deff35f5..7c1eadd4b 100644 --- a/lib/web_model.dart +++ b/lib/web_model.dart @@ -105,7 +105,7 @@ Map getEvent(MouseEvent evt) { out['buttons'] = evt .buttons; // left button: 1, right button: 2, middle button: 4, 1 | 2 = 3 (left + right) if (evt.buttons != 0) { - lastMouseDownButtons = evt.buttons; + lastMouseDownButtons = evt.buttons!; } else { out['buttons'] = lastMouseDownButtons; } @@ -125,7 +125,7 @@ void handleKey(KeyboardEvent evt, bool down) { name = evt.code; } else { name = evt.key; - if (name.toLowerCase() != name.toUpperCase() && + if (name!=null && name.toLowerCase() != name.toUpperCase() && name == name.toUpperCase()) { if (!evt.shiftKey) out['shift'] = 'true'; } diff --git a/pubspec.yaml b/pubspec.yaml index 9e0366015..eca19df92 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.1.9+20 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.0 <3.0.0" dependencies: flutter: @@ -32,10 +32,11 @@ dependencies: path_provider: ^2.0.2 external_path: ^1.0.1 provider: ^5.0.0 - flutter_easyloading: # not Null safety 2.2.0 - git: - url: git://github.com/open-trade/flutter_easyloading - #path: flutter_easyloading + flutter_easyloading: ^3.0.3 +# flutter_easyloading: # not Null safety 2.2.0 +# git: +# url: git://github.com/open-trade/flutter_easyloading +# #path: flutter_easyloading tuple: ^2.0.0 wakelock: ^0.5.2 device_info: ^2.0.2