upgrade null-safe

This commit is contained in:
csf 2022-02-17 15:22:14 +08:00
parent f5f496f1cf
commit b4ed72435c
9 changed files with 298 additions and 281 deletions

View File

@ -7,7 +7,7 @@ typedef F = String Function(String);
typedef FMethod = String Function(String, dynamic); typedef FMethod = String Function(String, dynamic);
class Translator { class Translator {
static F call; static late F call;
} }
class MyTheme { class MyTheme {
@ -32,8 +32,8 @@ final ButtonStyle flatButtonStyle = TextButton.styleFrom(
), ),
); );
void Function() loadingCancelCallback; void Function()? loadingCancelCallback;
void showLoading(String text, BuildContext context) { void showLoading(String text, BuildContext? context) {
if (_hasDialog && context != null) { if (_hasDialog && context != null) {
Navigator.pop(context); Navigator.pop(context);
_hasDialog = false; _hasDialog = false;
@ -43,34 +43,34 @@ void showLoading(String text, BuildContext context) {
EasyLoading.show(status: text, maskType: EasyLoadingMaskType.black); EasyLoading.show(status: text, maskType: EasyLoadingMaskType.black);
return; return;
} }
EasyLoading.showWidget( // EasyLoading.showWidget(
Container( // Container(
constraints: BoxConstraints(maxWidth: 300), // constraints: BoxConstraints(maxWidth: 300),
child: Column( // child: Column(
crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
children: [ // children: [
Center(child: CircularProgressIndicator()), // Center(child: CircularProgressIndicator()),
SizedBox(height: 20), // SizedBox(height: 20),
Center( // Center(
child: Text(Translator.call(text), // child: Text(Translator.call(text),
style: TextStyle(fontSize: 15))), // style: TextStyle(fontSize: 15))),
SizedBox(height: 20), // SizedBox(height: 20),
Center( // Center(
child: TextButton( // child: TextButton(
style: flatButtonStyle, // style: flatButtonStyle,
onPressed: () { // onPressed: () {
// with out loadingCancelCallback, we can see unexpected input password // // with out loadingCancelCallback, we can see unexpected input password
// dialog shown in home, no clue why, so use this as workaround // // dialog shown in home, no clue why, so use this as workaround
// why no such issue on android? // // why no such issue on android?
if (loadingCancelCallback != null) // if (loadingCancelCallback != null)
loadingCancelCallback(); // loadingCancelCallback();
Navigator.pop(context); // Navigator.pop(context);
}, // },
child: Text(Translator.call('Cancel'), // child: Text(Translator.call('Cancel'),
style: TextStyle(color: MyTheme.accent)))) // style: TextStyle(color: MyTheme.accent))))
], // ],
)), // )),
maskType: EasyLoadingMaskType.black); // maskType: EasyLoadingMaskType.black);
} }
void dismissLoading() { void dismissLoading() {
@ -82,8 +82,9 @@ bool _hasDialog = false;
typedef BuildAlertDailog = Tuple3<Widget, Widget, List<Widget>> Function( typedef BuildAlertDailog = Tuple3<Widget, Widget, List<Widget>> Function(
void Function(void Function())); void Function(void Function()));
Future<T> showAlertDialog<T>(BuildContext context, BuildAlertDailog build, // ??
[WillPopCallback onWillPop, Future<T?> showAlertDialog<T>(BuildContext context, BuildAlertDailog build,
[WillPopCallback? onWillPop,
bool barrierDismissible = false, bool barrierDismissible = false,
double contentPadding = 20]) async { double contentPadding = 20]) async {
dismissLoading(); dismissLoading();
@ -112,7 +113,7 @@ Future<T> showAlertDialog<T>(BuildContext context, BuildAlertDailog build,
} }
void msgbox(String type, String title, String text, BuildContext context, void msgbox(String type, String title, String text, BuildContext context,
[bool hasCancel]) { {bool? hasCancel}) {
var wrap = (String text, void Function() onPressed) => ButtonTheme( var wrap = (String text, void Function() onPressed) => ButtonTheme(
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
@ -148,26 +149,44 @@ void msgbox(String type, String title, String text, BuildContext context,
dismissLoading(); dismissLoading();
})); }));
} }
EasyLoading.showWidget( EasyLoading.show(
Container( status: "",
constraints: BoxConstraints(maxWidth: 300), maskType: EasyLoadingMaskType.black,
child: Column( indicator: Container(
crossAxisAlignment: CrossAxisAlignment.start, constraints: BoxConstraints(maxWidth: 300),
children: [ child: Column(
Text(Translator.call(title), style: TextStyle(fontSize: 21)), crossAxisAlignment: CrossAxisAlignment.start,
SizedBox(height: 20), children: [
Text(Translator.call(text), style: TextStyle(fontSize: 15)), Text(Translator.call(title), style: TextStyle(fontSize: 21)),
SizedBox(height: 20), SizedBox(height: 20),
Row( Text(Translator.call(text), style: TextStyle(fontSize: 15)),
children: buttons, SizedBox(height: 20),
) Row(
], children: buttons,
)), )
maskType: EasyLoadingMaskType.black); ],
))
);
// 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 { class PasswordWidget extends StatefulWidget {
PasswordWidget({Key key, this.controller}) : super(key: key); PasswordWidget({Key? key, required this.controller}) : super(key: key);
final TextEditingController controller; final TextEditingController controller;
@ -221,4 +240,4 @@ bool isAndroid = false;
bool isIOS = false; bool isIOS = false;
bool isWeb = false; bool isWeb = false;
bool isDesktop = false; bool isDesktop = false;
BuildContext nowCtx; BuildContext? currentCtx;

View File

@ -14,8 +14,8 @@ const kScaleSlop = kPrecisePointerPanSlop / 10;
class CustomTouchGestureRecognizer extends ScaleGestureRecognizer { class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
CustomTouchGestureRecognizer({ CustomTouchGestureRecognizer({
Object debugOwner, Object? debugOwner,
Set<PointerDeviceKind> supportedDevices, Set<PointerDeviceKind>? supportedDevices,
}) : super( }) : super(
debugOwner: debugOwner, debugOwner: debugOwner,
supportedDevices: supportedDevices, supportedDevices: supportedDevices,
@ -24,24 +24,24 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
} }
// oneFingerPan // oneFingerPan
GestureDragStartCallback onOneFingerPanStart; GestureDragStartCallback? onOneFingerPanStart;
GestureDragUpdateCallback onOneFingerPanUpdate; GestureDragUpdateCallback? onOneFingerPanUpdate;
GestureDragEndCallback onOneFingerPanEnd; GestureDragEndCallback? onOneFingerPanEnd;
// twoFingerScale // twoFingerScale
GestureScaleStartCallback onTwoFingerScaleStart; GestureScaleStartCallback? onTwoFingerScaleStart;
GestureScaleUpdateCallback onTwoFingerScaleUpdate; GestureScaleUpdateCallback? onTwoFingerScaleUpdate;
GestureScaleEndCallback onTwoFingerScaleEnd; GestureScaleEndCallback? onTwoFingerScaleEnd;
// twoFingerVerticalDrag // twoFingerVerticalDrag
GestureDragStartCallback onTwoFingerVerticalDragStart; GestureDragStartCallback? onTwoFingerVerticalDragStart;
GestureDragUpdateCallback onTwoFingerVerticalDragUpdate; GestureDragUpdateCallback? onTwoFingerVerticalDragUpdate;
GestureDragEndCallback onTwoFingerVerticalDragEnd; GestureDragEndCallback? onTwoFingerVerticalDragEnd;
// twoFingerHorizontalDrag // twoFingerHorizontalDrag
GestureDragStartCallback onTwoFingerHorizontalDragStart; GestureDragStartCallback? onTwoFingerHorizontalDragStart;
GestureDragUpdateCallback onTwoFingerHorizontalDragUpdate; GestureDragUpdateCallback? onTwoFingerHorizontalDragUpdate;
GestureDragEndCallback onTwoFingerHorizontalDragEnd; GestureDragEndCallback? onTwoFingerHorizontalDragEnd;
void _init() { void _init() {
debugPrint("CustomTouchGestureRecognizer init"); debugPrint("CustomTouchGestureRecognizer init");
@ -66,22 +66,22 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
switch (_currentState) { switch (_currentState) {
case CustomTouchGestureState.oneFingerPan: case CustomTouchGestureState.oneFingerPan:
if (onOneFingerPanUpdate != null) { if (onOneFingerPanUpdate != null) {
onOneFingerPanUpdate(_getDragUpdateDetails(d)); onOneFingerPanUpdate!(_getDragUpdateDetails(d));
} }
break; break;
case CustomTouchGestureState.twoFingerScale: case CustomTouchGestureState.twoFingerScale:
if (onTwoFingerScaleUpdate != null) { if (onTwoFingerScaleUpdate != null) {
onTwoFingerScaleUpdate(d); onTwoFingerScaleUpdate!(d);
} }
break; break;
case CustomTouchGestureState.twoFingerHorizontalDrag: case CustomTouchGestureState.twoFingerHorizontalDrag:
if (onTwoFingerHorizontalDragUpdate != null) { if (onTwoFingerHorizontalDragUpdate != null) {
onTwoFingerHorizontalDragUpdate(_getDragUpdateDetails(d)); onTwoFingerHorizontalDragUpdate!(_getDragUpdateDetails(d));
} }
break; break;
case CustomTouchGestureState.twoFingerVerticalDrag: case CustomTouchGestureState.twoFingerVerticalDrag:
if (onTwoFingerVerticalDragUpdate != null) { if (onTwoFingerVerticalDragUpdate != null) {
onTwoFingerVerticalDragUpdate(_getDragUpdateDetails(d)); onTwoFingerVerticalDragUpdate!(_getDragUpdateDetails(d));
} }
break; break;
default: default:
@ -97,25 +97,25 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
case CustomTouchGestureState.oneFingerPan: case CustomTouchGestureState.oneFingerPan:
debugPrint("TwoFingerState.pan onEnd"); debugPrint("TwoFingerState.pan onEnd");
if (onOneFingerPanEnd != null) { if (onOneFingerPanEnd != null) {
onOneFingerPanEnd(_getDragEndDetails(d)); onOneFingerPanEnd!(_getDragEndDetails(d));
} }
break; break;
case CustomTouchGestureState.twoFingerScale: case CustomTouchGestureState.twoFingerScale:
debugPrint("TwoFingerState.scale onEnd"); debugPrint("TwoFingerState.scale onEnd");
if (onTwoFingerScaleEnd != null) { if (onTwoFingerScaleEnd != null) {
onTwoFingerScaleEnd(d); onTwoFingerScaleEnd!(d);
} }
break; break;
case CustomTouchGestureState.twoFingerHorizontalDrag: case CustomTouchGestureState.twoFingerHorizontalDrag:
debugPrint("TwoFingerState.horizontal onEnd"); debugPrint("TwoFingerState.horizontal onEnd");
if (onTwoFingerHorizontalDragEnd != null) { if (onTwoFingerHorizontalDragEnd != null) {
onTwoFingerHorizontalDragEnd(_getDragEndDetails(d)); onTwoFingerHorizontalDragEnd!(_getDragEndDetails(d));
} }
break; break;
case CustomTouchGestureState.twoFingerVerticalDrag: case CustomTouchGestureState.twoFingerVerticalDrag:
debugPrint("TwoFingerState.vertical onEnd"); debugPrint("TwoFingerState.vertical onEnd");
if (onTwoFingerVerticalDragEnd != null) { if (onTwoFingerVerticalDragEnd != null) {
onTwoFingerVerticalDragEnd(_getDragEndDetails(d)); onTwoFingerVerticalDragEnd!(_getDragEndDetails(d));
} }
break; break;
default: default:
@ -129,7 +129,7 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
var _currentState = CustomTouchGestureState.none; var _currentState = CustomTouchGestureState.none;
var _isWatch = false; var _isWatch = false;
Timer _timer; Timer? _timer;
double _sumScale = 0; double _sumScale = 0;
double _sumVertical = 0; double _sumVertical = 0;
double _sumHorizontal = 0; double _sumHorizontal = 0;
@ -143,7 +143,7 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
void _reset() { void _reset() {
_isWatch = false; _isWatch = false;
_clearSum(); _clearSum();
if (_timer != null) _timer.cancel(); if (_timer != null) _timer!.cancel();
} }
void _updateCompute(ScaleUpdateDetails d) { void _updateCompute(ScaleUpdateDetails d) {
@ -155,14 +155,14 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
debugPrint("start Scale"); debugPrint("start Scale");
_currentState = CustomTouchGestureState.twoFingerScale; _currentState = CustomTouchGestureState.twoFingerScale;
if (onOneFingerPanStart != null) { if (onOneFingerPanStart != null) {
onOneFingerPanStart(_getDragStartDetails(d)); onOneFingerPanStart!(_getDragStartDetails(d));
} }
_reset(); _reset();
} else if (_sumHorizontal.abs() > kPrecisePointerPanSlop) { } else if (_sumHorizontal.abs() > kPrecisePointerPanSlop) {
debugPrint("start Horizontal"); debugPrint("start Horizontal");
_currentState = CustomTouchGestureState.twoFingerHorizontalDrag; _currentState = CustomTouchGestureState.twoFingerHorizontalDrag;
if (onTwoFingerHorizontalDragUpdate != null) { if (onTwoFingerHorizontalDragUpdate != null) {
onTwoFingerHorizontalDragUpdate(_getDragUpdateDetails(d)); onTwoFingerHorizontalDragUpdate!(_getDragUpdateDetails(d));
} }
_reset(); _reset();
} else if (_sumVertical.abs() > kPrecisePointerPanSlop) { } else if (_sumVertical.abs() > kPrecisePointerPanSlop) {
@ -179,7 +179,7 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
debugPrint("startWatchTimer"); debugPrint("startWatchTimer");
_isWatch = true; _isWatch = true;
_clearSum(); _clearSum();
if (_timer != null) _timer.cancel(); if (_timer != null) _timer!.cancel();
_timer = Timer(const Duration(milliseconds: 200), _reset); _timer = Timer(const Duration(milliseconds: 200), _reset);
} }
@ -201,24 +201,24 @@ class CustomTouchGestureRecognizer extends ScaleGestureRecognizer {
class HoldTapMoveGestureRecognizer extends GestureRecognizer { class HoldTapMoveGestureRecognizer extends GestureRecognizer {
HoldTapMoveGestureRecognizer({ HoldTapMoveGestureRecognizer({
Object debugOwner, Object? debugOwner,
Set<PointerDeviceKind> supportedDevices, Set<PointerDeviceKind>? supportedDevices,
}) : super( }) : super(
debugOwner: debugOwner, debugOwner: debugOwner,
supportedDevices: supportedDevices, supportedDevices: supportedDevices,
); );
GestureDragStartCallback onHoldDragStart; GestureDragStartCallback? onHoldDragStart;
GestureDragUpdateCallback onHoldDragUpdate; GestureDragUpdateCallback? onHoldDragUpdate;
GestureDragDownCallback onHoldDragDown; GestureDragDownCallback? onHoldDragDown;
GestureDragCancelCallback onHoldDragCancel; GestureDragCancelCallback? onHoldDragCancel;
bool _isStart = false; bool _isStart = false;
Timer _firstTapUpTimer; // reject Timer? _firstTapUpTimer; // reject
Timer _secondTapDownTimer; // reject drag update Timer? _secondTapDownTimer; // reject drag update
_TapTracker _firstTap; _TapTracker? _firstTap;
_TapTracker _secondTap; _TapTracker? _secondTap;
final Map<int, _TapTracker> _trackers = <int, _TapTracker>{}; final Map<int, _TapTracker> _trackers = <int, _TapTracker>{};
@ -244,11 +244,11 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
void addAllowedPointer(PointerDownEvent event) { void addAllowedPointer(PointerDownEvent event) {
// //
if (_firstTap != null) { if (_firstTap != null) {
if (!_firstTap.isWithinGlobalTolerance(event, kDoubleTapSlop)) { if (!_firstTap!.isWithinGlobalTolerance(event, kDoubleTapSlop)) {
// Ignore out-of-bounds second taps. // Ignore out-of-bounds second taps.
return; return;
} else if (!_firstTap.hasElapsedMinTime() || } else if (!_firstTap!.hasElapsedMinTime() ||
!_firstTap.hasSameButton(event)) { !_firstTap!.hasSameButton(event)) {
// Restart when the second tap is too close to the first (touch screens // Restart when the second tap is too close to the first (touch screens
// often detect touches intermittently), or when buttons mismatch. // often detect touches intermittently), or when buttons mismatch.
_reset(); _reset();
@ -256,7 +256,7 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
} else if (onHoldDragDown != null) { } else if (onHoldDragDown != null) {
invokeCallback<void>( invokeCallback<void>(
'onHoldDragDown', 'onHoldDragDown',
() => onHoldDragDown(DragDownDetails( () => onHoldDragDown!(DragDownDetails(
globalPosition: event.position, globalPosition: event.position,
localPosition: event.localPosition))); localPosition: event.localPosition)));
} }
@ -269,7 +269,7 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
_stopSecondTapDownTimer(); _stopSecondTapDownTimer();
final _TapTracker tracker = _TapTracker( final _TapTracker tracker = _TapTracker(
event: event, event: event,
entry: GestureBinding.instance.gestureArena.add(event.pointer, this), entry: GestureBinding.instance!.gestureArena.add(event.pointer, this),
doubleTapMinTime: kDoubleTapMinTime, doubleTapMinTime: kDoubleTapMinTime,
gestureSettings: gestureSettings, gestureSettings: gestureSettings,
); );
@ -279,7 +279,7 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
// down后一段时间没有抬起则表示start // down后一段时间没有抬起则表示start
void _handleEvent(PointerEvent event) { void _handleEvent(PointerEvent event) {
final _TapTracker tracker = _trackers[event.pointer]; final _TapTracker tracker = _trackers[event.pointer]!;
if (event is PointerUpEvent) { if (event is PointerUpEvent) {
if (_firstTap == null && _secondTap == null) { if (_firstTap == null && _secondTap == null) {
_registerFirstTap(tracker); _registerFirstTap(tracker);
@ -294,17 +294,17 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
} else if (event is PointerMoveEvent) { } else if (event is PointerMoveEvent) {
// first tap move second tap move且已经通过竞技场则update // first tap move second tap move且已经通过竞技场则update
if (!tracker.isWithinGlobalTolerance(event, kDoubleTapTouchSlop)) { if (!tracker.isWithinGlobalTolerance(event, kDoubleTapTouchSlop)) {
if (_firstTap != null && _firstTap.pointer == event.pointer) { if (_firstTap != null && _firstTap!.pointer == event.pointer) {
// first tap move // first tap move
_reject(tracker); _reject(tracker);
} else if (_secondTap != null && _secondTap.pointer == event.pointer) { } else if (_secondTap != null && _secondTap!.pointer == event.pointer) {
// debugPrint("_secondTap move"); // debugPrint("_secondTap move");
// second tap move // second tap move
if (!_isStart) { if (!_isStart) {
_resolve(); _resolve();
} }
if (onHoldDragUpdate != null) if (onHoldDragUpdate != null)
onHoldDragUpdate(DragUpdateDetails( onHoldDragUpdate!(DragUpdateDetails(
globalPosition: event.position, globalPosition: event.position,
localPosition: event.localPosition, localPosition: event.localPosition,
delta: event.delta)); delta: event.delta));
@ -320,9 +320,9 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
@override @override
void rejectGesture(int pointer) { 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 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; tracker = _firstTap;
} }
// If tracker is still null, we rejected ourselves already // If tracker is still null, we rejected ourselves already
@ -333,11 +333,11 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
void _resolve() { void _resolve() {
_stopSecondTapDownTimer(); _stopSecondTapDownTimer();
_firstTap?.entry?.resolve(GestureDisposition.accepted); _firstTap?.entry.resolve(GestureDisposition.accepted);
_secondTap?.entry?.resolve(GestureDisposition.accepted); _secondTap?.entry.resolve(GestureDisposition.accepted);
_isStart = true; _isStart = true;
// TODO start details // TODO start details
if (onHoldDragStart != null) onHoldDragStart(DragStartDetails()); if (onHoldDragStart != null) onHoldDragStart!(DragStartDetails());
} }
void _reject(_TapTracker tracker) { void _reject(_TapTracker tracker) {
@ -367,16 +367,16 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
} }
// Note, order is important below in order for the resolve -> reject logic // Note, order is important below in order for the resolve -> reject logic
// to work properly. // to work properly.
final _TapTracker tracker = _firstTap; final _TapTracker tracker = _firstTap!;
_firstTap = null; _firstTap = null;
_reject(tracker); _reject(tracker);
GestureBinding.instance.gestureArena.release(tracker.pointer); GestureBinding.instance!.gestureArena.release(tracker.pointer);
if (_secondTap != null) { if (_secondTap != null) {
final _TapTracker tracker = _secondTap; final _TapTracker tracker = _secondTap!;
_secondTap = null; _secondTap = null;
_reject(tracker); _reject(tracker);
GestureBinding.instance.gestureArena.release(tracker.pointer); GestureBinding.instance!.gestureArena.release(tracker.pointer);
} }
} }
// TODO // TODO
@ -387,7 +387,7 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
void _registerFirstTap(_TapTracker tracker) { void _registerFirstTap(_TapTracker tracker) {
_startFirstTapUpTimer(); _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 // Note, order is important below in order for the clear -> reject logic to
// work properly. // work properly.
_freezeTracker(tracker); _freezeTracker(tracker);
@ -399,12 +399,12 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
// first tap的状态 // first tap的状态
if (_firstTap != null) { if (_firstTap != null) {
_stopFirstTapUpTimer(); _stopFirstTapUpTimer();
_freezeTracker(_firstTap); _freezeTracker(_firstTap!);
_firstTap = null; _firstTap = null;
} }
_startSecondTapDownTimer(); _startSecondTapDownTimer();
GestureBinding.instance.gestureArena.hold(tracker.pointer); GestureBinding.instance!.gestureArena.hold(tracker.pointer);
_secondTap = tracker; _secondTap = tracker;
@ -430,21 +430,21 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
void _stopFirstTapUpTimer() { void _stopFirstTapUpTimer() {
if (_firstTapUpTimer != null) { if (_firstTapUpTimer != null) {
_firstTapUpTimer.cancel(); _firstTapUpTimer!.cancel();
_firstTapUpTimer = null; _firstTapUpTimer = null;
} }
} }
void _stopSecondTapDownTimer() { void _stopSecondTapDownTimer() {
if (_secondTapDownTimer != null) { if (_secondTapDownTimer != null) {
_secondTapDownTimer.cancel(); _secondTapDownTimer!.cancel();
_secondTapDownTimer = null; _secondTapDownTimer = null;
} }
} }
void _checkCancel() { void _checkCancel() {
if (onHoldDragCancel != null) { if (onHoldDragCancel != null) {
invokeCallback<void>('onHoldDragCancel', onHoldDragCancel); invokeCallback<void>('onHoldDragCancel', onHoldDragCancel!);
} }
} }
@ -454,19 +454,19 @@ class HoldTapMoveGestureRecognizer extends GestureRecognizer {
class DoubleFinerTapGestureRecognizer extends GestureRecognizer { class DoubleFinerTapGestureRecognizer extends GestureRecognizer {
DoubleFinerTapGestureRecognizer({ DoubleFinerTapGestureRecognizer({
Object debugOwner, Object? debugOwner,
Set<PointerDeviceKind> supportedDevices, Set<PointerDeviceKind>? supportedDevices,
}) : super( }) : super(
debugOwner: debugOwner, debugOwner: debugOwner,
supportedDevices: supportedDevices, supportedDevices: supportedDevices,
); );
GestureTapDownCallback onDoubleFinerTapDown; GestureTapDownCallback? onDoubleFinerTapDown;
GestureTapDownCallback onDoubleFinerTap; GestureTapDownCallback? onDoubleFinerTap;
GestureTapCancelCallback onDoubleFinerTapCancel; GestureTapCancelCallback? onDoubleFinerTapCancel;
Timer _firstTapTimer; // reject Timer? _firstTapTimer; // reject
_TapTracker _firstTap; _TapTracker? _firstTap;
var _isStart = false; var _isStart = false;
@ -505,7 +505,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer {
kind: getKindForPointer(event.pointer), kind: getKindForPointer(event.pointer),
); );
invokeCallback<void>( invokeCallback<void>(
'onDoubleFinerTapDown', () => onDoubleFinerTapDown(details)); 'onDoubleFinerTapDown', () => onDoubleFinerTapDown!(details));
} }
} else { } else {
// first tap // first tap
@ -518,7 +518,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer {
void _trackTap(PointerDownEvent event) { void _trackTap(PointerDownEvent event) {
final _TapTracker tracker = _TapTracker( final _TapTracker tracker = _TapTracker(
event: event, event: event,
entry: GestureBinding.instance.gestureArena.add(event.pointer, this), entry: GestureBinding.instance!.gestureArena.add(event.pointer, this),
doubleTapMinTime: kDoubleTapMinTime, doubleTapMinTime: kDoubleTapMinTime,
gestureSettings: gestureSettings, gestureSettings: gestureSettings,
); );
@ -531,7 +531,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer {
// down后一段时间没有抬起则表示start // down后一段时间没有抬起则表示start
void _handleEvent(PointerEvent event) { void _handleEvent(PointerEvent event) {
final _TapTracker tracker = _trackers[event.pointer]; final _TapTracker tracker = _trackers[event.pointer]!;
if (event is PointerUpEvent) { if (event is PointerUpEvent) {
debugPrint("PointerUpEvent"); debugPrint("PointerUpEvent");
_upTap.add(tracker.pointer); _upTap.add(tracker.pointer);
@ -548,9 +548,9 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer {
@override @override
void rejectGesture(int pointer) { 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 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; tracker = _firstTap;
} }
// If tracker is still null, we rejected ourselves already // If tracker is still null, we rejected ourselves already
@ -589,7 +589,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer {
} }
void _registerTap(_TapTracker tracker) { 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 // Note, order is important below in order for the clear -> reject logic to
// work properly. // work properly.
} }
@ -609,7 +609,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer {
void _stopFirstTapUpTimer() { void _stopFirstTapUpTimer() {
if (_firstTapTimer != null) { if (_firstTapTimer != null) {
_firstTapTimer.cancel(); _firstTapTimer!.cancel();
_firstTapTimer = null; _firstTapTimer = null;
} }
} }
@ -626,7 +626,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer {
void _resolve() { void _resolve() {
// TODO tap down details // TODO tap down details
if (onDoubleFinerTap != null) onDoubleFinerTap(TapDownDetails()); if (onDoubleFinerTap != null) onDoubleFinerTap!(TapDownDetails());
_trackers.forEach((key, value) { _trackers.forEach((key, value) {
value.entry.resolve(GestureDisposition.accepted); value.entry.resolve(GestureDisposition.accepted);
}); });
@ -635,7 +635,7 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer {
void _checkCancel() { void _checkCancel() {
if (onDoubleFinerTapCancel != null) { if (onDoubleFinerTapCancel != null) {
invokeCallback<void>('onHoldDragCancel', onDoubleFinerTapCancel); invokeCallback<void>('onHoldDragCancel', onDoubleFinerTapCancel!);
} }
} }
@ -647,10 +647,10 @@ class DoubleFinerTapGestureRecognizer extends GestureRecognizer {
/// larger gesture. /// larger gesture.
class _TapTracker { class _TapTracker {
_TapTracker({ _TapTracker({
PointerDownEvent event, required PointerDownEvent event,
this.entry, required this.entry,
Duration doubleTapMinTime, required Duration doubleTapMinTime,
this.gestureSettings, required this.gestureSettings,
}) : assert(doubleTapMinTime != null), }) : assert(doubleTapMinTime != null),
assert(event != null), assert(event != null),
assert(event.buttons != null), assert(event.buttons != null),
@ -660,7 +660,7 @@ class _TapTracker {
_doubleTapMinTimeCountdown = _doubleTapMinTimeCountdown =
_CountdownZoned(duration: doubleTapMinTime); _CountdownZoned(duration: doubleTapMinTime);
final DeviceGestureSettings gestureSettings; final DeviceGestureSettings? gestureSettings;
final int pointer; final int pointer;
final GestureArenaEntry entry; final GestureArenaEntry entry;
final Offset _initialGlobalPosition; final Offset _initialGlobalPosition;
@ -669,17 +669,17 @@ class _TapTracker {
bool _isTrackingPointer = false; bool _isTrackingPointer = false;
void startTrackingPointer(PointerRoute route, Matrix4 transform) { void startTrackingPointer(PointerRoute route, Matrix4? transform) {
if (!_isTrackingPointer) { if (!_isTrackingPointer) {
_isTrackingPointer = true; _isTrackingPointer = true;
GestureBinding.instance.pointerRouter.addRoute(pointer, route, transform); GestureBinding.instance!.pointerRouter.addRoute(pointer, route, transform);
} }
} }
void stopTrackingPointer(PointerRoute route) { void stopTrackingPointer(PointerRoute route) {
if (_isTrackingPointer) { if (_isTrackingPointer) {
_isTrackingPointer = false; _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 /// CountdownZoned tracks whether the specified duration has elapsed since
/// creation, honoring [Zone]. /// creation, honoring [Zone].
class _CountdownZoned { class _CountdownZoned {
_CountdownZoned({Duration duration}) : assert(duration != null) { _CountdownZoned({required Duration duration}) : assert(duration != null) {
Timer(duration, _onTimeout); Timer(duration, _onTimeout);
} }
@ -714,18 +714,19 @@ class _CountdownZoned {
} }
RawGestureDetector getMixinGestureDetector({ RawGestureDetector getMixinGestureDetector({
Widget child, Widget? child,
GestureTapUpCallback onTapUp, GestureTapUpCallback? onTapUp,
GestureDoubleTapCallback onDoubleTap, GestureDoubleTapCallback? onDoubleTap,
GestureDragStartCallback onHoldDragStart, GestureDragStartCallback? onHoldDragStart,
GestureDragUpdateCallback onHoldDragUpdate, GestureDragUpdateCallback? onHoldDragUpdate,
GestureDragCancelCallback onHoldDragCancel, GestureDragCancelCallback? onHoldDragCancel,
GestureTapDownCallback onDoubleFinerTap, GestureTapDownCallback? onDoubleFinerTap,
GestureDragStartCallback onOneFingerPanStart, GestureDragStartCallback? onOneFingerPanStart,
GestureDragUpdateCallback onOneFingerPanUpdate, GestureDragUpdateCallback? onOneFingerPanUpdate,
GestureScaleUpdateCallback onTwoFingerScaleUpdate, GestureScaleUpdateCallback? onTwoFingerScaleUpdate,
GestureDragUpdateCallback onTwoFingerHorizontalDragUpdate, GestureScaleEndCallback? onTwoFingerScaleEnd,
GestureDragUpdateCallback onTwoFingerVerticalDragUpdate, GestureDragUpdateCallback? onTwoFingerHorizontalDragUpdate,
GestureDragUpdateCallback? onTwoFingerVerticalDragUpdate,
}) { }) {
return RawGestureDetector( return RawGestureDetector(
child: child, child: child,
@ -763,6 +764,7 @@ RawGestureDetector getMixinGestureDetector({
..onOneFingerPanStart = onOneFingerPanStart ..onOneFingerPanStart = onOneFingerPanStart
..onOneFingerPanUpdate = onOneFingerPanUpdate ..onOneFingerPanUpdate = onOneFingerPanUpdate
..onTwoFingerScaleUpdate = onTwoFingerScaleUpdate ..onTwoFingerScaleUpdate = onTwoFingerScaleUpdate
..onTwoFingerScaleEnd = onTwoFingerScaleEnd
..onTwoFingerHorizontalDragUpdate = onTwoFingerHorizontalDragUpdate ..onTwoFingerHorizontalDragUpdate = onTwoFingerHorizontalDragUpdate
..onTwoFingerVerticalDragUpdate = onTwoFingerVerticalDragUpdate; ..onTwoFingerVerticalDragUpdate = onTwoFingerVerticalDragUpdate;
}) })

View File

@ -8,7 +8,7 @@ import 'model.dart';
import 'remote_page.dart'; import 'remote_page.dart';
class HomePage extends StatefulWidget { class HomePage extends StatefulWidget {
HomePage({Key key, this.title}) : super(key: key); HomePage({Key? key, required this.title}) : super(key: key);
final String title; final String title;
@ -55,18 +55,20 @@ class _HomePageState extends State<HomePage> {
}, },
onTap: () { onTap: () {
() async { () async {
var value = await showMenu( var value = await showMenu<dynamic>(
context: context, context: context,
position: this._menuPos, position: this._menuPos,
items: [ items: [
PopupMenuItem<String>( PopupMenuItem<String>(
child: Text(translate('ID Server')), child: Text(translate('ID Server')),
value: 'id_server'), value: 'id_server'),
// TODO test
isAndroid isAndroid
? PopupMenuItem<String>( ? PopupMenuItem<dynamic>(
child: Text(translate('Share My Screen')), child: Text(translate('Share My Screen')),
value: 'server') value: 'server')
: null, : PopupMenuItem<dynamic>(
child: SizedBox.shrink(), value: ''),
PopupMenuItem<String>( PopupMenuItem<String>(
child: Text(translate('About') + ' RustDesk'), child: Text(translate('About') + ' RustDesk'),
value: 'about'), value: 'about'),
@ -328,8 +330,8 @@ void showServer(BuildContext context) {
labelText: translate('ID Server'), labelText: translate('ID Server'),
), ),
validator: validate, validator: validate,
onSaved: (String value) { onSaved: (String? value) {
id = value.trim(); if (value != null) id = value.trim();
}, },
), ),
/* /*
@ -350,8 +352,8 @@ void showServer(BuildContext context) {
labelText: 'Key', labelText: 'Key',
), ),
validator: null, validator: null,
onSaved: (String value) { onSaved: (String? value) {
key = value.trim(); if (value != null) key = value.trim();
}, },
), ),
])), ])),
@ -366,8 +368,8 @@ void showServer(BuildContext context) {
TextButton( TextButton(
style: flatButtonStyle, style: flatButtonStyle,
onPressed: () { onPressed: () {
if (formKey.currentState.validate()) { if (formKey.currentState != null && formKey.currentState!.validate()) {
formKey.currentState.save(); formKey.currentState!.save();
if (id != id0) if (id != id0)
FFI.setByName('option', FFI.setByName('option',
'{"name": "custom-rendezvous-server", "value": "$id"}'); '{"name": "custom-rendezvous-server", "value": "$id"}');
@ -391,7 +393,7 @@ Future<Null> showAbout(BuildContext context) async {
showAlertDialog( showAlertDialog(
context, context,
(setState) => Tuple3( (setState) => Tuple3(
null, SizedBox.shrink(), // TODO test old:null
Wrap(direction: Axis.vertical, spacing: 12, children: [ Wrap(direction: Axis.vertical, spacing: 12, children: [
Text('Version: $version'), Text('Version: $version'),
InkWell( InkWell(
@ -409,12 +411,12 @@ Future<Null> showAbout(BuildContext context) async {
)), )),
)), )),
]), ]),
null), []),
() async => true, () async => true,
true); true);
} }
String validate(value) { String? validate(value) {
value = value.trim(); value = value.trim();
if (value.isEmpty) { if (value.isEmpty) {
return null; return null;

View File

@ -11,15 +11,15 @@ import 'common.dart';
import 'native_model.dart' if (dart.library.html) 'web_model.dart'; import 'native_model.dart' if (dart.library.html) 'web_model.dart';
class FfiModel with ChangeNotifier { class FfiModel with ChangeNotifier {
PeerInfo _pi; PeerInfo _pi = PeerInfo();
Display _display; Display _display = Display();
var _decoding = false; var _decoding = false;
bool _waitForImage; bool _waitForImage = false;
bool _initialized = false; bool _initialized = false;
var _inputBlocked = false; var _inputBlocked = false;
final _permissions = Map<String, bool>(); final _permissions = Map<String, bool>();
bool _secure; bool? _secure;
bool _direct; bool? _direct;
get permissions => _permissions; get permissions => _permissions;
@ -32,6 +32,7 @@ class FfiModel with ChangeNotifier {
get direct => _direct; get direct => _direct;
get pi => _pi; get pi => _pi;
get inputBlocked => _inputBlocked; get inputBlocked => _inputBlocked;
set inputBlocked(v) { set inputBlocked(v) {
@ -75,8 +76,8 @@ class FfiModel with ChangeNotifier {
_direct = direct; _direct = direct;
} }
Image getConnectionImage() { Image? getConnectionImage() {
String icon; String? icon;
if (secure == true && direct == true) { if (secure == true && direct == true) {
icon = 'secure'; icon = 'secure';
} else if (secure == false && direct == true) { } else if (secure == false && direct == true) {
@ -200,11 +201,11 @@ class FfiModel with ChangeNotifier {
} }
class ImageModel 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 (_image == null && image != null) {
if (isDesktop) { if (isDesktop) {
FFI.canvasModel.updateViewStyle(); FFI.canvasModel.updateViewStyle();
@ -223,28 +224,26 @@ class ImageModel with ChangeNotifier {
double get maxScale { double get maxScale {
if (_image == null) return 1.0; if (_image == null) return 1.0;
final size = MediaQueryData.fromWindow(ui.window).size; final size = MediaQueryData.fromWindow(ui.window).size;
final xscale = size.width / _image.width; final xscale = size.width / _image!.width;
final yscale = size.height / _image.height; final yscale = size.height / _image!.height;
return max(1.0, max(xscale, yscale)); return max(1.0, max(xscale, yscale));
} }
double get minScale { double get minScale {
if (_image == null) return 1.0; if (_image == null) return 1.0;
final size = MediaQueryData.fromWindow(ui.window).size; final size = MediaQueryData.fromWindow(ui.window).size;
final xscale = size.width / _image.width; final xscale = size.width / _image!.width;
final yscale = size.height / _image.height; final yscale = size.height / _image!.height;
return min(xscale, yscale); return min(xscale, yscale);
} }
} }
class CanvasModel with ChangeNotifier { class CanvasModel with ChangeNotifier {
double _x; double _x = 0;
double _y; double _y = 0;
double _scale; double _scale = 1.0;
CanvasModel() { CanvasModel();
clear();
}
double get x => _x; double get x => _x;
@ -355,7 +354,7 @@ class CanvasModel with ChangeNotifier {
} }
class CursorModel with ChangeNotifier { class CursorModel with ChangeNotifier {
ui.Image _image; ui.Image? _image;
final _images = Map<int, Tuple3<ui.Image, double, double>>(); final _images = Map<int, Tuple3<ui.Image, double, double>>();
double _x = -10000; double _x = -10000;
double _y = -10000; double _y = -10000;
@ -364,7 +363,7 @@ class CursorModel with ChangeNotifier {
double _displayOriginX = 0; double _displayOriginX = 0;
double _displayOriginY = 0; double _displayOriginY = 0;
ui.Image get image => _image; ui.Image? get image => _image;
double get x => _x - _displayOriginX; double get x => _x - _displayOriginX;
@ -445,7 +444,7 @@ class CursorModel with ChangeNotifier {
var tryMoveCanvasX = false; var tryMoveCanvasX = false;
if (dx > 0) { if (dx > 0) {
final maxCanvasCanMove = final maxCanvasCanMove =
_displayOriginX + FFI.imageModel.image.width - r.right; _displayOriginX + FFI.imageModel.image!.width - r.right;
tryMoveCanvasX = _x + dx > cx && maxCanvasCanMove > 0; tryMoveCanvasX = _x + dx > cx && maxCanvasCanMove > 0;
if (tryMoveCanvasX) { if (tryMoveCanvasX) {
dx = min(dx, maxCanvasCanMove); dx = min(dx, maxCanvasCanMove);
@ -466,7 +465,7 @@ class CursorModel with ChangeNotifier {
var tryMoveCanvasY = false; var tryMoveCanvasY = false;
if (dy > 0) { if (dy > 0) {
final mayCanvasCanMove = final mayCanvasCanMove =
_displayOriginY + FFI.imageModel.image.height - r.bottom; _displayOriginY + FFI.imageModel.image!.height - r.bottom;
tryMoveCanvasY = _y + dy > cy && mayCanvasCanMove > 0; tryMoveCanvasY = _y + dy > cy && mayCanvasCanMove > 0;
if (tryMoveCanvasY) { if (tryMoveCanvasY) {
dy = min(dy, mayCanvasCanMove); dy = min(dy, mayCanvasCanMove);
@ -567,12 +566,12 @@ class CursorModel with ChangeNotifier {
} }
class ClientState { class ClientState {
bool isStart; bool isStart = false;
bool isFileTransfer; bool isFileTransfer = false;
String name; String name = "";
String peerId; String peerId = "";
ClientState({this.isStart, this.isFileTransfer, this.name, this.peerId}); ClientState(this.isStart, this.isFileTransfer, this.name, this.peerId);
ClientState.fromJson(Map<String, dynamic> json) { ClientState.fromJson(Map<String, dynamic> json) {
isStart = json['is_start']; isStart = json['is_start'];
@ -592,20 +591,17 @@ class ClientState {
} }
class ServerModel with ChangeNotifier { class ServerModel with ChangeNotifier {
bool _mediaOk; bool _mediaOk = false;
bool _inputOk; bool _inputOk = false;
// bool _needServerOpen; bool _isPeerStart = false;
bool _isPeerStart; bool _isFileTransfer = false;
bool _isFileTransfer; String _peerName = "";
String _peerName; String _peerID = "";
String _peerID;
bool get mediaOk => _mediaOk; bool get mediaOk => _mediaOk;
bool get inputOk => _inputOk; bool get inputOk => _inputOk;
// bool get needServerOpen => _needServerOpen;
bool get isPeerStart => _isPeerStart; bool get isPeerStart => _isPeerStart;
bool get isFileTransfer => _isFileTransfer; bool get isFileTransfer => _isFileTransfer;
@ -614,18 +610,7 @@ class ServerModel with ChangeNotifier {
String get peerID => _peerID; String get peerID => _peerID;
ServerModel() { ServerModel();
_mediaOk = false;
_inputOk = false;
_isPeerStart = false;
_peerName = "";
_peerID = "";
}
// setNeedServerOpen(bool v){
// _needServerOpen = v;
// notifyListeners();
// }
changeStatue(String name, bool value) { changeStatue(String name, bool value) {
switch (name) { switch (name) {
@ -753,7 +738,7 @@ class FFI {
FFI.id = id; FFI.id = id;
} }
static Map<String, dynamic> popEvent() { static Map<String, dynamic>? popEvent() {
var s = getByName('event'); var s = getByName('event');
if (s == '') return null; if (s == '') return null;
try { try {
@ -892,13 +877,13 @@ class Display {
} }
class PeerInfo { class PeerInfo {
String version; String version = "";
String username; String username = "";
String hostname; String hostname = "";
String platform; String platform = "";
bool sasEnabled; bool sasEnabled = false;
int currentDisplay; int currentDisplay = 0;
List<Display> displays; List<Display> displays = [];
} }
void savePreference(String id, double xCursor, double yCursor, double xCanvas, 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)); prefs.setString('peer' + id, json.encode(p));
} }
Future<Map<String, dynamic>> getPreference(String id) async { Future<Map<String, dynamic>?> getPreference(String id) async {
if (!isDesktop) return null; if (!isDesktop) return null;
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
var p = prefs.getString('peer' + id); var p = prefs.getString('peer' + id);

View File

@ -11,8 +11,8 @@ import 'common.dart';
class RgbaFrame extends Struct { class RgbaFrame extends Struct {
@Uint32() @Uint32()
int len; external int len;
Pointer<Uint8> data; external Pointer<Uint8> data;
} }
typedef F2 = Pointer<Utf8> Function(Pointer<Utf8>, Pointer<Utf8>); typedef F2 = Pointer<Utf8> Function(Pointer<Utf8>, Pointer<Utf8>);
@ -21,24 +21,25 @@ typedef F4 = void Function(Pointer<RgbaFrame>);
typedef F5 = Pointer<RgbaFrame> Function(); typedef F5 = Pointer<RgbaFrame> Function();
class PlatformFFI { class PlatformFFI {
static Pointer<RgbaFrame> _lastRgbaFrame; static Pointer<RgbaFrame>? _lastRgbaFrame;
static String _dir = ''; static String _dir = '';
static String _homeDir = ''; static String _homeDir = '';
static F2 _getByName; static F2? _getByName;
static F3 _setByName; static F3? _setByName;
static F4 _freeRgba; static F4? _freeRgba;
static F5 _getRgba; static F5? _getRgba;
static void clearRgbaFrame() { static void clearRgbaFrame() {
if (_lastRgbaFrame != null && _lastRgbaFrame != nullptr) if (_lastRgbaFrame != null &&
_freeRgba(_lastRgbaFrame); _lastRgbaFrame != nullptr &&
_freeRgba != null) _freeRgba!(_lastRgbaFrame!);
} }
static Uint8List getRgba() { static Uint8List? getRgba() {
if (_getRgba == null) return null; if (_getRgba == null) return null;
_lastRgbaFrame = _getRgba(); _lastRgbaFrame = _getRgba!();
if (_lastRgbaFrame == null || _lastRgbaFrame == nullptr) return null; if (_lastRgbaFrame == null || _lastRgbaFrame == nullptr) return null;
final ref = _lastRgbaFrame.ref; final ref = _lastRgbaFrame!.ref;
return Uint8List.sublistView(ref.data.asTypedList(ref.len)); return Uint8List.sublistView(ref.data.asTypedList(ref.len));
} }
@ -51,7 +52,7 @@ class PlatformFFI {
if (_getByName == null) return ''; if (_getByName == null) return '';
var a = name.toNativeUtf8(); var a = name.toNativeUtf8();
var b = arg.toNativeUtf8(); var b = arg.toNativeUtf8();
var p = _getByName(a, b); var p = _getByName!(a, b);
assert(p != nullptr && p != null); assert(p != nullptr && p != null);
var res = p.toDartString(); var res = p.toDartString();
calloc.free(p); calloc.free(p);
@ -64,7 +65,7 @@ class PlatformFFI {
if (_setByName == null) return; if (_setByName == null) return;
var a = name.toNativeUtf8(); var a = name.toNativeUtf8();
var b = value.toNativeUtf8(); var b = value.toNativeUtf8();
_setByName(a, b); _setByName!(a, b);
calloc.free(a); calloc.free(a);
calloc.free(b); calloc.free(b);
} }
@ -110,6 +111,7 @@ class PlatformFFI {
static void startDesktopWebListener( static void startDesktopWebListener(
Function(Map<String, dynamic>) handleMouse) {} Function(Map<String, dynamic>) handleMouse) {}
static void stopDesktopWebListener() {} static void stopDesktopWebListener() {}
static void setMethodCallHandler(FMethod callback) { static void setMethodCallHandler(FMethod callback) {

View File

@ -14,7 +14,7 @@ import 'model.dart';
final initText = '\1' * 1024; final initText = '\1' * 1024;
class RemotePage extends StatefulWidget { class RemotePage extends StatefulWidget {
RemotePage({Key key, this.id}) : super(key: key); RemotePage({Key? key, required this.id}) : super(key: key);
final String id; final String id;
@ -23,8 +23,8 @@ class RemotePage extends StatefulWidget {
} }
class _RemotePageState extends State<RemotePage> { class _RemotePageState extends State<RemotePage> {
Timer _interval; Timer? _interval;
Timer _timer; Timer? _timer;
bool _showBar = !isDesktop; bool _showBar = !isDesktop;
double _bottom = 0; double _bottom = 0;
String _value = ''; String _value = '';
@ -47,14 +47,14 @@ class _RemotePageState extends State<RemotePage> {
void initState() { void initState() {
super.initState(); super.initState();
FFI.connect(widget.id); FFI.connect(widget.id);
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance!.addPostFrameCallback((_) {
SystemChrome.setEnabledSystemUIOverlays([]); SystemChrome.setEnabledSystemUIOverlays([]);
showLoading(translate('Connecting...'), context); showLoading(translate('Connecting...'), context);
_interval = _interval =
Timer.periodic(Duration(milliseconds: 30), (timer) => interval()); Timer.periodic(Duration(milliseconds: 30), (timer) => interval());
}); });
Wakelock.enable(); Wakelock.enable();
loadingCancelCallback = () => _interval.cancel(); loadingCancelCallback = () => _interval?.cancel();
_touchMode = FFI.getByName('peer_option', "touch-mode") != ''; _touchMode = FFI.getByName('peer_option', "touch-mode") != '';
} }
@ -63,7 +63,7 @@ class _RemotePageState extends State<RemotePage> {
_focusNode.dispose(); _focusNode.dispose();
FFI.close(); FFI.close();
loadingCancelCallback = null; loadingCancelCallback = null;
_interval.cancel(); _interval?.cancel();
_timer?.cancel(); _timer?.cancel();
dismissLoading(); dismissLoading();
SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values); SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
@ -354,8 +354,8 @@ class _RemotePageState extends State<RemotePage> {
onTapUp: (d) { onTapUp: (d) {
if (_drag || _scroll) return; if (_drag || _scroll) return;
if (_touchMode) { if (_touchMode) {
FFI.cursorModel.touch( FFI.cursorModel
d.localPosition.dx, d.localPosition.dy, _right); .touch(d.localPosition.dx, d.localPosition.dy, _right);
} else { } else {
FFI.tap(_right); FFI.tap(_right);
} }
@ -385,12 +385,12 @@ class _RemotePageState extends State<RemotePage> {
FFI.cursorModel.updatePan(d.delta.dx, d.delta.dy, _touchMode, _drag); FFI.cursorModel.updatePan(d.delta.dx, d.delta.dy, _touchMode, _drag);
}, },
onTwoFingerScaleUpdate: (d) { onTwoFingerScaleUpdate: (d) {
var scale = (d.scale -1) / 20 + 1; FFI.canvasModel.updateScale(d.scale/_scale);
FFI.canvasModel.updateScale(scale); _scale = d.scale;
_scale = scale;
}, },
onTwoFingerScaleEnd: (d)=>_scale = 1,
onTwoFingerVerticalDragUpdate: (d) { onTwoFingerVerticalDragUpdate: (d) {
FFI.scroll( - d.delta.dy / 20); FFI.scroll(d.delta.dy / 2);
}); });
return GestureDetector( return GestureDetector(
onLongPress: () { onLongPress: () {
@ -491,9 +491,8 @@ class _RemotePageState extends State<RemotePage> {
paints.add(CursorPaint()); paints.add(CursorPaint());
} }
return MouseRegion( return MouseRegion(
cursor: keyboard cursor: keyboard ? SystemMouseCursors.none : MouseCursor.defer,
? SystemMouseCursors.none // TODO old null // still laggy, set cursor directly for web is better
: null, // still laggy, set cursor directly for web is better
onEnter: (event) { onEnter: (event) {
print('enter'); print('enter');
FFI.listenToMouse(true); FFI.listenToMouse(true);
@ -586,8 +585,8 @@ class _RemotePageState extends State<RemotePage> {
FFI.setByName('refresh'); FFI.setByName('refresh');
} else if (value == 'paste') { } else if (value == 'paste') {
() async { () async {
ClipboardData data = await Clipboard.getData(Clipboard.kTextPlain); ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain);
if (data.text != null) { if (data != null && data.text != null) {
FFI.setByName('input_string', '${data.text}'); FFI.setByName('input_string', '${data.text}');
} }
}(); }();
@ -618,8 +617,8 @@ class _RemotePageState extends State<RemotePage> {
return SizedBox(); return SizedBox();
} }
final size = MediaQuery.of(context).size; final size = MediaQuery.of(context).size;
var wrap = var wrap = (String text, void Function() onPressed,
(String text, void Function() onPressed, [bool active, IconData icon]) { [bool? active, IconData? icon]) {
return TextButton( return TextButton(
style: TextButton.styleFrom( style: TextButton.styleFrom(
minimumSize: Size(0, 0), minimumSize: Size(0, 0),
@ -811,13 +810,13 @@ class CursorPaint extends StatelessWidget {
class ImagePainter extends CustomPainter { class ImagePainter extends CustomPainter {
ImagePainter({ ImagePainter({
this.image, required this.image,
this.x, required this.x,
this.y, required this.y,
this.scale, required this.scale,
}); });
ui.Image image; ui.Image? image;
double x; double x;
double y; double y;
double scale; double scale;
@ -826,7 +825,7 @@ class ImagePainter extends CustomPainter {
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
if (image == null) return; if (image == null) return;
canvas.scale(scale, scale); canvas.scale(scale, scale);
canvas.drawImage(image, new Offset(x, y), new Paint()); canvas.drawImage(image!, new Offset(x, y), new Paint());
} }
@override @override
@ -853,7 +852,9 @@ void enterPasswordDialog(String id, BuildContext context) {
), ),
value: remember, value: remember,
onChanged: (v) { onChanged: (v) {
setState(() => remember = v); if (v != null) {
setState(() => remember = v);
}
}, },
), ),
]), ]),
@ -918,7 +919,7 @@ CheckboxListTile getToggle(
} }
RadioListTile<String> getRadio(String name, String toValue, String curValue, RadioListTile<String> getRadio(String name, String toValue, String curValue,
void Function(String) onChange) { void Function(String?) onChange) {
return RadioListTile<String>( return RadioListTile<String>(
controlAffinity: ListTileControlAffinity.trailing, controlAffinity: ListTileControlAffinity.trailing,
title: Text(translate(name)), title: Text(translate(name)),
@ -985,13 +986,15 @@ void showOptions(BuildContext context) {
more.add(getToggle(setState, 'privacy-mode', 'Privacy mode')); more.add(getToggle(setState, 'privacy-mode', 'Privacy mode'));
} }
} }
var setQuality = (String value) { var setQuality = (String? value) {
if(value == null) return;
setState(() { setState(() {
quality = value; quality = value;
FFI.setByName('image_quality', value); FFI.setByName('image_quality', value);
}); });
}; };
var setViewStyle = (String value) { var setViewStyle = (String? value) {
if(value == null) return;
setState(() { setState(() {
viewStyle = value; viewStyle = value;
FFI.setByName( FFI.setByName(
@ -1000,7 +1003,7 @@ void showOptions(BuildContext context) {
}); });
}; };
return Tuple3( return Tuple3(
null, SizedBox.shrink(),
Column( Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: displays + children: displays +
@ -1012,7 +1015,7 @@ void showOptions(BuildContext context) {
getRadio('Stretch', 'stretch', viewStyle, setViewStyle), getRadio('Stretch', 'stretch', viewStyle, setViewStyle),
Divider(color: MyTheme.border), Divider(color: MyTheme.border),
] ]
: {}) + : []) +
<Widget>[ <Widget>[
getRadio('Good image quality', 'best', quality, setQuality), getRadio('Good image quality', 'best', quality, setQuality),
getRadio('Balanced', 'balanced', quality, setQuality), getRadio('Balanced', 'balanced', quality, setQuality),
@ -1023,7 +1026,7 @@ void showOptions(BuildContext context) {
setState, 'show-remote-cursor', 'Show remote cursor'), setState, 'show-remote-cursor', 'Show remote cursor'),
] + ] +
more), more),
null); []);
}, () async => true, true, 0); }, () async => true, true, 0);
} }
@ -1047,6 +1050,7 @@ void showSetOSPassword(BuildContext context, bool login) {
), ),
value: autoLogin, value: autoLogin,
onChanged: (v) { onChanged: (v) {
if(v==null) return;
setState(() => autoLogin = v); setState(() => autoLogin = v);
}, },
), ),

View File

@ -101,7 +101,7 @@ class _ServerInfoState extends State<ServerInfo> {
labelStyle: labelStyle:
TextStyle(fontWeight: FontWeight.bold, color: MyTheme.accent50), TextStyle(fontWeight: FontWeight.bold, color: MyTheme.accent50),
), ),
onSaved: (String value) {}, onSaved: (String? value) {},
), ),
TextFormField( TextFormField(
readOnly: true, readOnly: true,
@ -123,7 +123,7 @@ class _ServerInfoState extends State<ServerInfo> {
_passwdShow = !_passwdShow; _passwdShow = !_passwdShow;
}); });
})), })),
onSaved: (String value) {}, onSaved: (String? value) {},
), ),
], ],
)); ));
@ -187,7 +187,7 @@ class _PermissionCheckerState extends State<PermissionChecker> {
} }
} }
BuildContext loginReqAlertCtx; BuildContext? loginReqAlertCtx;
void showLoginReqAlert(BuildContext context, String peerID, String name) async { void showLoginReqAlert(BuildContext context, String peerID, String name) async {
await showDialog( await showDialog(
@ -238,7 +238,7 @@ void showLoginReqAlert(BuildContext context, String peerID, String name) async {
clearLoginReqAlert() { clearLoginReqAlert() {
if (loginReqAlertCtx != null) { if (loginReqAlertCtx != null) {
Navigator.of(loginReqAlertCtx).pop(); Navigator.of(loginReqAlertCtx!).pop();
FFI.serverModel.updateClientState(); FFI.serverModel.updateClientState();
} }
} }
@ -372,8 +372,10 @@ void toAndroidChannelInit() {
FFI.serverModel.updateClientState(); FFI.serverModel.updateClientState();
debugPrint( debugPrint(
"pre show loginAlert:${FFI.serverModel.isFileTransfer.toString()}"); "pre show loginAlert:${FFI.serverModel.isFileTransfer.toString()}");
showLoginReqAlert( if(currentCtx!=null){
currentCtx, FFI.serverModel.peerID, FFI.serverModel.peerName); showLoginReqAlert(
currentCtx!, FFI.serverModel.peerID, FFI.serverModel.peerName);
}
debugPrint("from jvm:try_start_without_auth done"); debugPrint("from jvm:try_start_without_auth done");
break; break;
} }

View File

@ -105,7 +105,7 @@ Map<String, dynamic> getEvent(MouseEvent evt) {
out['buttons'] = evt out['buttons'] = evt
.buttons; // left button: 1, right button: 2, middle button: 4, 1 | 2 = 3 (left + right) .buttons; // left button: 1, right button: 2, middle button: 4, 1 | 2 = 3 (left + right)
if (evt.buttons != 0) { if (evt.buttons != 0) {
lastMouseDownButtons = evt.buttons; lastMouseDownButtons = evt.buttons!;
} else { } else {
out['buttons'] = lastMouseDownButtons; out['buttons'] = lastMouseDownButtons;
} }
@ -125,7 +125,7 @@ void handleKey(KeyboardEvent evt, bool down) {
name = evt.code; name = evt.code;
} else { } else {
name = evt.key; name = evt.key;
if (name.toLowerCase() != name.toUpperCase() && if (name!=null && name.toLowerCase() != name.toUpperCase() &&
name == name.toUpperCase()) { name == name.toUpperCase()) {
if (!evt.shiftKey) out['shift'] = 'true'; if (!evt.shiftKey) out['shift'] = 'true';
} }

View File

@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.1.9+20 version: 1.1.9+20
environment: environment:
sdk: ">=2.7.0 <3.0.0" sdk: ">=2.12.0 <3.0.0"
dependencies: dependencies:
flutter: flutter:
@ -32,10 +32,11 @@ dependencies:
path_provider: ^2.0.2 path_provider: ^2.0.2
external_path: ^1.0.1 external_path: ^1.0.1
provider: ^5.0.0 provider: ^5.0.0
flutter_easyloading: # not Null safety 2.2.0 flutter_easyloading: ^3.0.3
git: # flutter_easyloading: # not Null safety 2.2.0
url: git://github.com/open-trade/flutter_easyloading # git:
#path: flutter_easyloading # url: git://github.com/open-trade/flutter_easyloading
# #path: flutter_easyloading
tuple: ^2.0.0 tuple: ^2.0.0
wakelock: ^0.5.2 wakelock: ^0.5.2
device_info: ^2.0.2 device_info: ^2.0.2