Files
2026-09-04 15:22:20 +08:00

73 lines
1.9 KiB
Dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:talker_flutter/talker_flutter.dart';
import 'package:new_learn/core/router/router_keys.dart';
final Talker talker = Talker();
class DebugTalkerBubble extends StatefulWidget {
const DebugTalkerBubble({
super.key,
required this.child,
});
final Widget child;
@override
State<DebugTalkerBubble> createState() => _DebugTalkerBubbleState();
}
class _DebugTalkerBubbleState extends State<DebugTalkerBubble> {
Offset _offset = const Offset(16, 120);
@override
Widget build(BuildContext context) {
if (kReleaseMode) return widget.child;
return LayoutBuilder(
builder: (context, constraints) {
final maxX = constraints.maxWidth - 56;
final maxY = constraints.maxHeight - 56;
final clamped = Offset(
_offset.dx.clamp(0.0, maxX.isFinite ? maxX : 0.0),
_offset.dy.clamp(0.0, maxY.isFinite ? maxY : 0.0),
);
if (clamped != _offset) {
_offset = clamped;
}
return Stack(
children: [
widget.child,
Positioned(
left: _offset.dx,
top: _offset.dy,
child: GestureDetector(
onPanUpdate: (details) {
setState(() {
_offset += details.delta;
});
},
child: FloatingActionButton(
onPressed: () {
final nav = rootNavigatorKey.currentState;
if (nav == null) return;
nav.push(
MaterialPageRoute<void>(
builder: (_) => TalkerScreen(talker: talker),
),
);
},
child: const Icon(Icons.bug_report),
),
),
),
],
);
},
);
}
}