Skip to content

Commit d12d330

Browse files
committed
fix: stabilize draggable thumbnail by tracking offset state
1 parent 74adc67 commit d12d330

1 file changed

Lines changed: 31 additions & 14 deletions

File tree

lib/features/call/view/call_shell.dart

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -309,26 +309,39 @@ class _DraggableThumbnailState extends State<DraggableThumbnail> {
309309
child: GestureDetector(
310310
onTap: widget.onTap,
311311
onPanStart: (details) {
312+
// Sync state with actual render position before starting the drag
313+
final startRect = _findCallCardRect();
312314
setState(() {
315+
_offset = startRect.topLeft;
313316
_callCardPanning = true;
314317
});
315318
},
316319
onPanUpdate: (details) {
317-
final callCardRect = _findCallCardRect(details.delta);
318-
final translateX = _boundTranslateX(_activeRect, callCardRect);
319-
final translateY = _boundTranslateY(_activeRect, callCardRect);
320-
final offset = callCardRect.translate(translateX, translateY).topLeft;
320+
if (_offset == null) return;
321321

322-
widget.onOffsetUpdate?.call(offset);
322+
// Calculate new position based on state + delta (ignoring render lag)
323+
final currentSize = _callCardKey.currentContext?.size ?? Size.zero;
324+
final tentativeOffset = _offset! + details.delta;
325+
final tentativeRect = tentativeOffset & currentSize;
326+
327+
final translateX = _boundTranslateX(_activeRect, tentativeRect);
328+
final translateY = _boundTranslateY(_activeRect, tentativeRect);
329+
330+
final finalOffset = tentativeRect.translate(translateX, translateY).topLeft;
331+
332+
widget.onOffsetUpdate?.call(finalOffset);
323333
setState(() {
324-
_offset = offset;
334+
_offset = finalOffset;
325335
});
326336
},
327337
onPanEnd: (details) {
328-
final callCardRect = _findCallCardRect();
329-
final translateX = _stickTranslateX(_stickyRect, callCardRect);
330-
final translateY = _boundTranslateY(_stickyRect, callCardRect);
331-
final offset = callCardRect.translate(translateX, translateY).topLeft;
338+
// Calculate snapping based on the final dragged position
339+
final currentSize = _callCardKey.currentContext?.size ?? Size.zero;
340+
final currentRect = (_offset ?? Offset.zero) & currentSize;
341+
342+
final translateX = _stickTranslateX(_stickyRect, currentRect);
343+
final translateY = _boundTranslateY(_stickyRect, currentRect);
344+
final offset = currentRect.translate(translateX, translateY).topLeft;
332345

333346
widget.onOffsetUpdate?.call(offset);
334347
setState(() {
@@ -341,11 +354,15 @@ class _DraggableThumbnailState extends State<DraggableThumbnail> {
341354
);
342355
}
343356

344-
Rect _findCallCardRect([Offset delta = Offset.zero]) {
345-
final callCardRenderBox = _callCardKey.currentContext?.findRenderObject()! as RenderBox;
346-
final offset = callCardRenderBox.localToGlobal(Offset.zero) + delta;
357+
Rect _findCallCardRect() {
358+
final callCardContext = _callCardKey.currentContext;
359+
if (callCardContext == null) return Rect.zero;
360+
361+
final callCardRenderBox = callCardContext.findRenderObject() as RenderBox?;
362+
if (callCardRenderBox == null || !callCardRenderBox.hasSize) return Rect.zero;
363+
364+
final offset = callCardRenderBox.localToGlobal(Offset.zero);
347365
final size = callCardRenderBox.size;
348-
if (!callCardRenderBox.hasSize) return Rect.zero;
349366

350367
return Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height);
351368
}

0 commit comments

Comments
 (0)