diff --git a/lib/src/features/new_character/new_character_screen.dart b/lib/src/features/new_character/new_character_screen.dart index a1de027..6a8f5ef 100644 --- a/lib/src/features/new_character/new_character_screen.dart +++ b/lib/src/features/new_character/new_character_screen.dart @@ -61,6 +61,9 @@ class _NewCharacterScreenState extends State { // 테스트 모드 (웹에서 모바일 캐로셀 레이아웃 활성화) bool _testModeEnabled = false; + // 굴리기 버튼 연속 클릭 방지 + bool _isRolling = false; + @override void initState() { super.initState(); @@ -96,23 +99,22 @@ class _NewCharacterScreenState extends State { const itemHeight = 48.0; WidgetsBinding.instance.addPostFrameCallback((_) { + if (!mounted) return; + + // 스크롤 애니메이션 대신 즉시 점프 (WASM 모드 안정성) if (_raceScrollController.hasClients) { final raceOffset = _selectedRaceIndex * itemHeight; - _raceScrollController.animateTo( + _raceScrollController.jumpTo( raceOffset.clamp(0.0, _raceScrollController.position.maxScrollExtent), - duration: const Duration(milliseconds: 300), - curve: Curves.easeOut, ); } if (_klassScrollController.hasClients) { final klassOffset = _selectedKlassIndex * itemHeight; - _klassScrollController.animateTo( + _klassScrollController.jumpTo( klassOffset.clamp( 0.0, _klassScrollController.position.maxScrollExtent, ), - duration: const Duration(milliseconds: 300), - curve: Curves.easeOut, ); } }); @@ -134,6 +136,10 @@ class _NewCharacterScreenState extends State { /// Re-Roll 버튼 클릭 /// 원본 NewGuy.pas RerollClick: 스탯, 종족, 클래스 모두 랜덤화 void _onReroll() { + // 연속 클릭 방지 + if (_isRolling) return; + _isRolling = true; + // 현재 시드를 이력에 저장 _rollHistory.insert(0, _currentSeed); @@ -156,6 +162,11 @@ class _NewCharacterScreenState extends State { // 선택된 종족/직업으로 스크롤 _scrollToSelectedItems(); + + // 짧은 딜레이 후 다시 클릭 가능 + Future.delayed(const Duration(milliseconds: 100), () { + if (mounted) _isRolling = false; + }); } /// Unroll 버튼 클릭 (이전 롤로 복원) @@ -401,8 +412,10 @@ class _NewCharacterScreenState extends State { const SizedBox(height: 12), // Roll 버튼들 - Row( - mainAxisAlignment: MainAxisAlignment.center, + Wrap( + alignment: WrapAlignment.center, + spacing: 16, + runSpacing: 8, children: [ OutlinedButton.icon( onPressed: _onUnroll, @@ -412,7 +425,6 @@ class _NewCharacterScreenState extends State { foregroundColor: _rollHistory.isEmpty ? Colors.grey : null, ), ), - const SizedBox(width: 16), FilledButton.icon( onPressed: _onReroll, icon: const Icon(Icons.casino),