...
This commit is contained in:
@@ -0,0 +1,167 @@
|
||||
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)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user