playWith/apps/app/lib/login_screen.dart

167 lines
5.5 KiB
Dart
Raw Normal View History

2025-11-25 16:34:13 +09:00
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:playwith_core/playwith_core.dart';
import 'lobby_screen.dart';
import 'screens/settings_screen.dart';
class LoginScreen extends StatefulWidget {
const LoginScreen({super.key});
@override
State<LoginScreen> createState() => _LoginScreenState();
}
class _LoginScreenState extends State<LoginScreen> {
final _nicknameController = TextEditingController();
final _settings = SettingsNotifier();
@override
void initState() {
super.initState();
// 저장된 닉네임 반영
Future.delayed(const Duration(milliseconds: 100), () {
if (mounted && _settings.nickname.isNotEmpty) {
setState(() {
_nicknameController.text = _settings.nickname;
});
}
});
_settings.addListener(_syncSettings);
}
@override
void dispose() {
_settings.removeListener(_syncSettings);
_nicknameController.dispose();
super.dispose();
}
void _syncSettings() {
if (_nicknameController.text != _settings.nickname) {
if (mounted) {
setState(() {
_nicknameController.text = _settings.nickname;
});
}
}
if (mounted) setState(() {});
}
Future<void> _enterLobby() async {
final inputNick = _nicknameController.text.trim();
if (inputNick.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("닉네임을 입력해주세요.")));
return;
}
// 안드로이드 권한 체크
if (Platform.isAndroid) {
Map<Permission, PermissionStatus> statuses = await [
Permission.location,
Permission.nearbyWifiDevices,
].request();
bool isNearby = statuses[Permission.nearbyWifiDevices]?.isGranted ?? false;
bool isLocation = statuses[Permission.location]?.isGranted ?? false;
if (!isNearby && !isLocation) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text("⚠️ 권한 허용이 필요합니다.")));
}
}
// 변경 사항 저장
if (inputNick != _settings.nickname) {
await _settings.setProfile(inputNick, _settings.avatarIndex);
}
// [수정] 초기화 시 닉네임과 이미지를 함께 전달
NetworkManager().initialize(
nickname: _settings.nickname,
profileImage: _settings.profileImageBase64, // [추가]
);
if (!mounted) return;
Navigator.push(context, MaterialPageRoute(builder: (_) => const LobbyScreen()));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.transparent,
elevation: 0,
actions: [
IconButton(
icon: const Icon(Icons.settings, color: Colors.grey),
tooltip: "설정",
onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (_) => const SettingsScreen())),
)
],
),
body: Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(32.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('PlayWith', style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold)),
const SizedBox(height: 40),
// [핵심] AvatarWidget 사용 (Core 컴포넌트)
ListenableBuilder(
listenable: _settings,
builder: (context, _) {
return GestureDetector(
onTap: () => _settings.pickProfileImage(),
child: Stack(
children: [
AvatarWidget(
base64Image: _settings.profileImageBase64,
colorValue: Colors.primaries[_settings.avatarIndex % Colors.primaries.length].value,
nickname: _nicknameController.text,
size: 120,
),
Positioned(
right: 0, bottom: 0,
child: Container(
padding: const EdgeInsets.all(8),
decoration: const BoxDecoration(color: Colors.blue, shape: BoxShape.circle),
child: const Icon(Icons.camera_alt, size: 20, color: Colors.white),
),
),
],
),
);
},
),
const SizedBox(height: 30),
TextField(
controller: _nicknameController,
textAlign: TextAlign.center,
decoration: const InputDecoration(
labelText: '닉네임',
border: OutlineInputBorder(),
floatingLabelBehavior: FloatingLabelBehavior.always,
),
),
const SizedBox(height: 30),
ElevatedButton(
onPressed: _enterLobby,
style: ElevatedButton.styleFrom(
minimumSize: const Size(double.infinity, 50),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
),
child: const Text('입장하기', style: TextStyle(fontSize: 18)),
),
],
),
),
),
);
}
}