1차 최종

This commit is contained in:
eld_master 2025-01-22 19:51:36 +09:00
parent b34802b894
commit 7278c6e06e
24 changed files with 1143 additions and 1060 deletions

View File

@ -20,8 +20,8 @@ android {
applicationId "com.allscore_app"
minSdkVersion 23
targetSdkVersion 34
versionCode 1
versionName "1.0"
versionCode 4
versionName "1.0.3"
}
// ...

View File

@ -5,6 +5,7 @@ class Config {
static const String realAdUnitId = 'ca-app-pub-6461991944599918~9492697896';
// ID
static const String adUnitId = 'ca-app-pub-6461991944599918~9492697896';
// static const String adUnitId = 'ca-app-pub-3940256099942544/6300978111';
//
static const String baseUrl = 'https://eldsoft.com:8097';
//

View File

@ -64,8 +64,9 @@ class _ScoreEditDialogState extends State<ScoreEditDialog> {
void _onDelta(int delta) {
setState(() {
newScore += delta;
if (newScore < 0) newScore = 0; // 0
// if (newScore < 0) newScore = 0; // 0
if (newScore > 999999) newScore = 999999; //
if (newScore < -999999) newScore = -999999; //
});
}
@ -122,17 +123,24 @@ class _ScoreEditDialogState extends State<ScoreEditDialog> {
],
),
const SizedBox(height: 8),
Wrap(
spacing: 4,
runSpacing: 4,
children: [
_buildDeltaButton(-100),
_buildDeltaButton(-10),
_buildDeltaButton(-1),
_buildDeltaButton(1),
_buildDeltaButton(10),
_buildDeltaButton(100),
],
SizedBox(
// height: 120, //
child: GridView.count(
crossAxisCount: 2, // 3
mainAxisSpacing: 8,
crossAxisSpacing: 8,
childAspectRatio: 2.0, // :
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
children: [
_buildDeltaButton(-100),
_buildDeltaButton(100),
_buildDeltaButton(-10),
_buildDeltaButton(10),
_buildDeltaButton(-1),
_buildDeltaButton(1),
],
),
),
const SizedBox(height: 12),

View File

@ -121,7 +121,7 @@ class _TeamNameEditModalState extends State<TeamNameEditModal> {
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SizedBox(
width: 100,
width: 80,
child: ElevatedButton(
onPressed: _onUpdateTeamName,
style: ElevatedButton.styleFrom(backgroundColor: Colors.black),
@ -130,7 +130,7 @@ class _TeamNameEditModalState extends State<TeamNameEditModal> {
),
),
SizedBox(
width: 100,
width: 80,
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
style: ElevatedButton.styleFrom(backgroundColor: Colors.black),

View File

@ -23,7 +23,7 @@ class UserInfoBasicDialog extends StatelessWidget {
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text('유저 정보 (진행중-개인전)',
const Text('유저 정보',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 12),

View File

@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'response_dialog.dart';
import '../../plugins/api.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:auto_size_text/auto_size_text.dart';
class UserInfoPrivateDialog extends StatefulWidget {
final Map<String, dynamic> userData;
@ -24,6 +26,10 @@ class _UserInfoPrivateDialogState extends State<UserInfoPrivateDialog> {
late String participantType; // 'ADMIN' or 'PLAYER'
late String introduceMyself;
//
double scaleFactor = 1.0;
double buttonScaleFactor = 1.0;
@override
void initState() {
super.initState();
@ -32,6 +38,22 @@ class _UserInfoPrivateDialogState extends State<UserInfoPrivateDialog> {
introduceMyself = widget.userData['introduce_myself'] ?? '';
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
_updateScaleFactor();
}
//
void _updateScaleFactor() {
final screenWidth = MediaQuery.of(context).size.width;
const baseWidth = 450.0;
setState(() {
scaleFactor = (screenWidth / baseWidth).clamp(0.8, 1.2);
buttonScaleFactor = (screenWidth / baseWidth).clamp(0.6, 1.2);
});
}
/// API ( )
Future<void> _onUpdateUserInfo() async {
//
@ -71,6 +93,13 @@ class _UserInfoPrivateDialogState extends State<UserInfoPrivateDialog> {
Future<void> _onKickParticipant() async {
// -> return
if (!widget.isRoomMaster) return;
//
final prefs = await SharedPreferences.getInstance();
final mySeq = prefs.getInt('my_user_seq')?.toString() ?? '0';
if (widget.userData['user_seq'] == mySeq) {
await showResponseDialog(context, '오류', '방장은 추방할 수 없습니다.');
return;
}
final reqBody = {
"room_seq": "${widget.roomSeq}",
@ -116,7 +145,7 @@ class _UserInfoPrivateDialogState extends State<UserInfoPrivateDialog> {
mainAxisSize: MainAxisSize.min,
children: [
const Text(
'유저 정보 (개인전)',
'유저 정보',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
@ -224,34 +253,40 @@ class _UserInfoPrivateDialogState extends State<UserInfoPrivateDialog> {
children: [
// (D-1)
SizedBox(
width: 90,
width: scaleFactor==0.8 ? 50 : 90,
child: ElevatedButton(
onPressed: _onUpdateUserInfo,
style: ElevatedButton.styleFrom(backgroundColor: Colors.black),
child: FittedBox(
child: Text('수정하기', style: TextStyle(color: Colors.white)),
child: AutoSizeText(
scaleFactor==0.8 ? '수정' : '수정하기',
maxLines: 1,
style: TextStyle(color: Colors.white),
),
),
),
// (D-2)
SizedBox(
width: 90,
width: scaleFactor==0.8 ? 50 : 90,
child: ElevatedButton(
onPressed: _onKickParticipant,
style: ElevatedButton.styleFrom(backgroundColor: Colors.black),
child: FittedBox(
child: Text('추방하기', style: TextStyle(color: Colors.white)),
child: AutoSizeText(
scaleFactor==0.8 ? '추방' : '추방하기',
maxLines: 1,
style: TextStyle(color: Colors.white),
),
),
),
// (D-3)
SizedBox(
width: 90,
width: scaleFactor==0.8 ? 50 : 90,
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
style: ElevatedButton.styleFrom(backgroundColor: Colors.black),
child: FittedBox(
child: Text('확인', style: TextStyle(color: Colors.white)),
child: AutoSizeText(
'확인',
maxLines: 1,
style: TextStyle(color: Colors.white),
),
),
),
@ -261,7 +296,11 @@ class _UserInfoPrivateDialogState extends State<UserInfoPrivateDialog> {
ElevatedButton(
onPressed: () => Navigator.pop(context),
style: ElevatedButton.styleFrom(backgroundColor: Colors.black),
child: const Text('확인', style: TextStyle(color: Colors.white)),
child: AutoSizeText(
'확인',
maxLines: 1,
style: TextStyle(color: Colors.white),
),
),
],
],

View File

@ -1,6 +1,8 @@
import 'package:flutter/material.dart';
import 'response_dialog.dart';
import '../../plugins/api.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:auto_size_text/auto_size_text.dart';
class UserInfoTeamDialog extends StatefulWidget {
final Map<String, dynamic> userData;
@ -27,6 +29,10 @@ class _UserInfoTeamDialogState extends State<UserInfoTeamDialog> {
late String teamName; // 'A'/'B'/'WAIT'
late String introduceMyself; //
//
double scaleFactor = 1.0;
double buttonScaleFactor = 1.0;
@override
void initState() {
super.initState();
@ -45,6 +51,22 @@ class _UserInfoTeamDialogState extends State<UserInfoTeamDialog> {
}
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
_updateScaleFactor();
}
//
void _updateScaleFactor() {
final screenWidth = MediaQuery.of(context).size.width;
const baseWidth = 450.0;
setState(() {
scaleFactor = (screenWidth / baseWidth).clamp(0.8, 1.2);
buttonScaleFactor = (screenWidth / baseWidth).clamp(0.6, 1.2);
});
}
// (1) / API ( )
Future<void> _onUpdateUserInfo() async {
// -> return
@ -85,6 +107,13 @@ class _UserInfoTeamDialogState extends State<UserInfoTeamDialog> {
Future<void> _onKickParticipant() async {
//
if (!widget.isRoomMaster) return;
//
final prefs = await SharedPreferences.getInstance();
final mySeq = prefs.getInt('my_user_seq')?.toString() ?? '0';
if (widget.userData['user_seq'] == mySeq) {
await showResponseDialog(context, '오류', '방장은 추방할 수 없습니다.');
return;
}
final reqBody = {
"room_seq": "${widget.roomSeq}",
@ -124,12 +153,13 @@ class _UserInfoTeamDialogState extends State<UserInfoTeamDialog> {
return Dialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
insetPadding: const EdgeInsets.symmetric(horizontal: 20),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text('유저 정보 (팀전)', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const Text('유저 정보', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 12),
// (A)
@ -257,44 +287,41 @@ class _UserInfoTeamDialogState extends State<UserInfoTeamDialog> {
children: [
//
SizedBox(
width: 90,
width: scaleFactor==0.8 ? 75 : 90,
child: ElevatedButton(
onPressed: _onUpdateUserInfo,
style: ElevatedButton.styleFrom(backgroundColor: Colors.black),
// () FittedBox
child: FittedBox(
child: Text(
'수정하기',
style: TextStyle(color: Colors.white),
),
child: AutoSizeText(
scaleFactor==0.8 ? '수정' : '수정하기',
maxLines: 1,
style: TextStyle(color: Colors.white),
),
),
),
//
SizedBox(
width: 90,
width: scaleFactor==0.8 ? 75 : 90,
child: ElevatedButton(
onPressed: _onKickParticipant,
style: ElevatedButton.styleFrom(backgroundColor: Colors.black),
child: FittedBox(
child: Text(
'추방하기',
style: TextStyle(color: Colors.white),
),
child: AutoSizeText(
scaleFactor==0.8 ? '추방' : '추방하기',
maxLines: 1,
style: TextStyle(color: Colors.white),
),
),
),
//
SizedBox(
width: 90,
width: scaleFactor==0.8 ? 75 : 90,
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
style: ElevatedButton.styleFrom(backgroundColor: Colors.black),
child: FittedBox(
child: Text(
'확인',
style: TextStyle(color: Colors.white),
),
child: AutoSizeText(
'확인',
maxLines: 1,
style: TextStyle(color: Colors.white),
),
),
),
@ -305,7 +332,11 @@ class _UserInfoTeamDialogState extends State<UserInfoTeamDialog> {
ElevatedButton(
onPressed: () => Navigator.pop(context),
style: ElevatedButton.styleFrom(backgroundColor: Colors.black),
child: const Text('확인', style: TextStyle(color: Colors.white)),
child: AutoSizeText(
'확인',
maxLines: 1,
style: TextStyle(color: Colors.white),
),
),
],
],

85
lib/plugins/admob.dart Normal file
View File

@ -0,0 +1,85 @@
import 'package:flutter/material.dart';
// import 'package:google_mobile_ads/google_mobile_ads.dart';
// import '../config/config.dart';
/*
// ================== ( ) ==================
// class AdBannerWidget extends StatefulWidget {
// const AdBannerWidget({Key? key}) : super(key: key);
// @override
// State<AdBannerWidget> createState() => _AdBannerWidgetState();
// }
// class _AdBannerWidgetState extends State<AdBannerWidget> {
// BannerAd? _bannerAd; //
// @override
// void initState() {
// super.initState();
// _initBannerAd();
// }
// @override
// void dispose() {
// _bannerAd?.dispose();
// super.dispose();
// }
// /// &
// void _initBannerAd() {
// _bannerAd = BannerAd(
// size: AdSize.banner, // ()
// adUnitId: Config.adUnitId, // ID (Config에서 )
// listener: BannerAdListener(
// onAdLoaded: (Ad ad) {
// // : _bannerAd를 .
// setState(() {/* 굳이 아무 것도 안 해도 됨 */});
// },
// onAdFailedToLoad: (Ad ad, LoadAdError error) {
// // : & null
// ad.dispose();
// setState(() {
// _bannerAd = null;
// });
// },
// ),
// request: const AdRequest(),
// );
// //
// _bannerAd!.load();
// }
// @override
// Widget build(BuildContext context) {
// // / _bannerAd가 null
// if (_bannerAd == null) {
// return const SizedBox.shrink();
// }
// // Container에 AdWidget으로
// return Container(
// color: Colors.white, //
// width: _bannerAd!.size.width.toDouble(),
// height: _bannerAd!.size.height.toDouble(),
// child: AdWidget(ad: _bannerAd!),
// );
// }
// }
*/
// ================== / ==================
class AdBannerWidget extends StatelessWidget {
const AdBannerWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// () 50dp
// or return SizedBox.shrink()
return const SizedBox(
height: 50, //
child: ColoredBox(color: Colors.white), //
);
}
}

View File

@ -130,7 +130,7 @@ class _SurveyPageState extends State<SurveyPage> {
}
final requestBody = {
"QNA": qnaList.toString(),
"QNA": qnaList,
};
try {

View File

@ -7,7 +7,7 @@ import 'pw_finding_page.dart';
import 'signup_page.dart';
//
import 'package:google_mobile_ads/google_mobile_ads.dart';
import '../../plugins/admob.dart';
//
import '../../config/config.dart';
@ -27,11 +27,6 @@ class _IdFindingPageState extends State<IdFindingPage> {
String foundIdMessage = '';
String authId = '';
/// (1)
BannerAd? _bannerAd;
bool _isBannerReady = false; //
String adUnitId = Config.adUnitId;
Future<void> _findId(String nickname, String email) async {
@ -100,30 +95,10 @@ class _IdFindingPageState extends State<IdFindingPage> {
@override
void initState() {
super.initState();
_initBannerAd();
}
void _initBannerAd() {
_bannerAd = BannerAd(
// / ID
adUnitId: adUnitId,
size: AdSize.banner,
request: const AdRequest(),
listener: BannerAdListener(
onAdLoaded: (ad) {
setState(() => _isBannerReady = true);
},
onAdFailedToLoad: (ad, error) {
ad.dispose();
},
),
);
_bannerAd?.load();
}
@override
void dispose() {
_bannerAd?.dispose();
super.dispose();
}
@ -349,14 +324,7 @@ class _IdFindingPageState extends State<IdFindingPage> {
),
// (3)
bottomNavigationBar: _isBannerReady && _bannerAd != null
? Container(
color: Colors.white,
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
)
: SizedBox.shrink(), // or
bottomNavigationBar: AdBannerWidget(),
);
}
}

View File

@ -369,7 +369,7 @@ class _LoginPageState extends State<LoginPage> {
.
7.
: eld_yeojh@naver.com
: eldyeojh@gmail.com
8.
, .

View File

@ -7,7 +7,7 @@ import 'signup_page.dart'; // 회원가입 페이지 임포트 추가
import 'id_finding_page.dart'; // ID
//
import 'package:google_mobile_ads/google_mobile_ads.dart';
import '../../plugins/admob.dart';
//
import '../../config/config.dart';
@ -25,11 +25,6 @@ class _PwFindingPageState extends State<PwFindingPage> {
String emailErrorMessage = ''; //
String idErrorMessage = ''; // ID
/// (1)
BannerAd? _bannerAd;
bool _isBannerReady = false; //
String adUnitId = Config.adUnitId;
Future<void> _findPassword(String id, String email) async {
// PW
@ -125,30 +120,10 @@ class _PwFindingPageState extends State<PwFindingPage> {
@override
void initState() {
super.initState();
_initBannerAd();
}
void _initBannerAd() {
_bannerAd = BannerAd(
// / ID
adUnitId: adUnitId,
size: AdSize.banner,
request: const AdRequest(),
listener: BannerAdListener(
onAdLoaded: (ad) {
setState(() => _isBannerReady = true);
},
onAdFailedToLoad: (ad, error) {
ad.dispose();
},
),
);
_bannerAd?.load();
}
@override
void dispose() {
_bannerAd?.dispose();
super.dispose();
}
@ -254,14 +229,7 @@ class _PwFindingPageState extends State<PwFindingPage> {
),
// (3)
bottomNavigationBar: _isBannerReady && _bannerAd != null
? Container(
color: Colors.white,
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
)
: SizedBox.shrink(), // or
bottomNavigationBar: AdBannerWidget(),
);
}
}

View File

@ -253,8 +253,7 @@ class _SignUpPageState extends State<SignUpPage> {
'이용자는 개인정보 수집 및 이용에 대한 동의를 거부할 권리가 있습니다.\n'
'그러나 필수 항목에 대한 동의를 거부하실 경우 서비스 이용이 제한될 수 있습니다.\n\n'
'7. 개인정보 보호책임자\n'
'이름: 여정훈\n'
'연락처: eld_yeojh@naver.com\n\n'
'연락처: eldyeojh@gmail.com\n\n'
'8. 개인정보의 안전성 확보 조치\n'
'회사는 개인정보의 안전한 처리를 위하여 기술적, 관리적 보호조치를 시행하고 있습니다.\n'
'개인정보의 암호화\n'

View File

@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart'; // AdMob
// import...
import '../../dialogs/settings_dialog.dart';
@ -25,6 +24,9 @@ import '../../config/config.dart';
//
import '../../dialogs/survey_dialog.dart';
//
import '../../plugins/admob.dart';
class MainPage extends StatefulWidget {
const MainPage({Key? key}) : super(key: key);
@ -33,11 +35,6 @@ class MainPage extends StatefulWidget {
}
class _MainPageState extends State<MainPage> {
/// (1)
BannerAd? _bannerAd;
bool _isBannerReady = false; //
String adUnitId = Config.adUnitId;
//
DateTime? _lastPressedTime;
@ -55,38 +52,13 @@ class _MainPageState extends State<MainPage> {
WidgetsBinding.instance.addPostFrameCallback((_) {
_checkLandingMainPageInfo();
});
// (C)
_initBannerAd();
}
@override
void dispose() {
_bannerAd?.dispose();
super.dispose();
}
///
void _initBannerAd() {
_bannerAd = BannerAd(
size: AdSize.banner, //
// adUnitId: 'ca-app-pub-3940256099942544/6300978111' ()
adUnitId: adUnitId, // / ID
listener: BannerAdListener(
onAdLoaded: (Ad ad) {
setState(() => _isBannerReady = true);
},
onAdFailedToLoad: (Ad ad, LoadAdError err) {
ad.dispose();
},
),
request: const AdRequest(),
);
// load()
_bannerAd?.load();
}
Future<bool> _onWillPop() async {
final now = DateTime.now();
if (_lastPressedTime == null ||
@ -202,14 +174,7 @@ class _MainPageState extends State<MainPage> {
],
),
bottomNavigationBar: _isBannerReady && _bannerAd != null
? Container(
color: Colors.white,
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
)
: SizedBox.shrink(), // or
bottomNavigationBar: AdBannerWidget(),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,

View File

@ -9,8 +9,8 @@ import '../../plugins/api.dart';
import '../../dialogs/response_dialog.dart';
import '../../dialogs/score_edit_dialog.dart'; //
import '../../dialogs/user_info_basic_dialog.dart'; //
import '../../plugins/admob.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import '../../config/config.dart';
class PlayingPrivatePage extends StatefulWidget {
@ -58,14 +58,12 @@ class _PlayingPrivatePageState extends State<PlayingPrivatePage> {
String mySeq = '0';
//
String myParticipantType = 'PLAYER';
// userListMap: { userSeq: true/false }
Map<String, bool> _userListMap = {};
/// (1)
BannerAd? _bannerAd;
bool _isBannerReady = false; //
String adUnitId = Config.adUnitId;
@override
void initState() {
super.initState();
@ -73,8 +71,6 @@ class _PlayingPrivatePageState extends State<PlayingPrivatePage> {
FirebaseDatabase.instance.goOnline();
roomTitle = widget.roomTitle;
// (C)
_initBannerAd();
// (D)
_initFirebase();
}
@ -86,27 +82,6 @@ class _PlayingPrivatePageState extends State<PlayingPrivatePage> {
super.dispose();
}
///
void _initBannerAd() {
_bannerAd = BannerAd(
size: AdSize.banner, //
// adUnitId: 'ca-app-pub-3940256099942544/6300978111' ()
adUnitId: adUnitId, // / ID
listener: BannerAdListener(
onAdLoaded: (Ad ad) {
setState(() => _isBannerReady = true);
},
onAdFailedToLoad: (Ad ad, LoadAdError err) {
ad.dispose();
},
),
request: const AdRequest(),
);
// load()
_bannerAd?.load();
}
Future<void> _initFirebase() async {
final prefs = await SharedPreferences.getInstance();
mySeq = prefs.getInt('my_user_seq')?.toString() ?? '0';
@ -192,6 +167,10 @@ class _PlayingPrivatePageState extends State<PlayingPrivatePage> {
'introduce_myself': uData['introduce_myself'] ?? '',
'is_my_score': (uSeq.toString() == mySeq) ? 'Y' : 'N',
});
if (uSeq.toString() == mySeq) {
myParticipantType = (uData['participant_type'] ?? '').toString().toUpperCase();
}
});
//
@ -386,11 +365,13 @@ class _PlayingPrivatePageState extends State<PlayingPrivatePage> {
},
);
if (confirm != true) return false;
if (confirm != true) {
return false;
}
}
// userList => false
final userRef = _roomRef.child('userList').child(mySeq);
final userRef = _roomRef.child('userList').child('_$mySeq');
await userRef.set(false);
if (!mounted) return false;
@ -449,8 +430,7 @@ class _PlayingPrivatePageState extends State<PlayingPrivatePage> {
}
Future<void> _onTapUser(Map<String, dynamic> userData) async {
final pType = (userData['participant_type'] ?? '').toString().toUpperCase();
if (pType == 'ADMIN') {
if (myParticipantType == 'ADMIN') {
//
await showDialog(
context: context,
@ -460,16 +440,6 @@ class _PlayingPrivatePageState extends State<PlayingPrivatePage> {
userData: userData,
),
);
} else if (roomMasterYn == 'Y') {
// (PLAYER)
await showDialog(
context: context,
builder: (_) => ScoreEditDialog(
roomSeq: widget.roomSeq,
roomType: 'PRIVATE',
userData: userData,
),
);
} else {
//
await showDialog(
@ -552,14 +522,7 @@ class _PlayingPrivatePageState extends State<PlayingPrivatePage> {
),
],
),
bottomNavigationBar: _isBannerReady && _bannerAd != null
? Container(
color: Colors.white,
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
)
: SizedBox.shrink(), // or
bottomNavigationBar: AdBannerWidget(),
),
);
}

View File

@ -9,8 +9,7 @@ import '../../plugins/api.dart';
import '../../dialogs/response_dialog.dart';
import '../../dialogs/score_edit_dialog.dart';
import '../../dialogs/user_info_basic_dialog.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import '../../plugins/admob.dart';
import '../../config/config.dart';
class PlayingTeamPage extends StatefulWidget {
@ -60,14 +59,12 @@ class _PlayingTeamPageState extends State<PlayingTeamPage> {
// userListMap: { seq: true/false }
Map<String, bool> _userListMap = {};
//
String myParticipantType = 'PLAYER';
//
String scoreOpenRange = 'ALL';
/// (1)
BannerAd? _bannerAd;
bool _isBannerReady = false; //
String adUnitId = Config.adUnitId;
@override
void initState() {
super.initState();
@ -75,8 +72,6 @@ class _PlayingTeamPageState extends State<PlayingTeamPage> {
FirebaseDatabase.instance.goOnline();
roomTitle = widget.roomTitle;
// (C)
_initBannerAd();
// (D)
_initFirebase();
}
@ -88,27 +83,6 @@ class _PlayingTeamPageState extends State<PlayingTeamPage> {
super.dispose();
}
///
void _initBannerAd() {
_bannerAd = BannerAd(
size: AdSize.banner, //
// adUnitId: 'ca-app-pub-3940256099942544/6300978111' ()
adUnitId: adUnitId, // / ID
listener: BannerAdListener(
onAdLoaded: (Ad ad) {
setState(() => _isBannerReady = true);
},
onAdFailedToLoad: (Ad ad, LoadAdError err) {
ad.dispose();
},
),
request: const AdRequest(),
);
// load()
_bannerAd?.load();
}
Future<void> _initFirebase() async {
final prefs = await SharedPreferences.getInstance();
mySeq = prefs.getInt('my_user_seq')?.toString() ?? '0';
@ -191,6 +165,9 @@ class _PlayingTeamPageState extends State<PlayingTeamPage> {
'team_name': (uData['team_name'] ?? '').toString().toUpperCase(),
'score': uData['score'] ?? 0,
});
if (uSeq.toString() == mySeq) {
myParticipantType = (uData['participant_type'] ?? '').toString().toUpperCase();
}
});
// &
@ -415,7 +392,7 @@ class _PlayingTeamPageState extends State<PlayingTeamPage> {
}
// userList => false
final userRef = _roomRef.child('userList').child(mySeq);
final userRef = _roomRef.child('userList').child('_$mySeq');
await userRef.set(false);
if (!mounted) return false;
@ -510,14 +487,7 @@ class _PlayingTeamPageState extends State<PlayingTeamPage> {
),
],
),
bottomNavigationBar: _isBannerReady && _bannerAd != null
? Container(
color: Colors.white,
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
)
: SizedBox.shrink(), // or
bottomNavigationBar: AdBannerWidget(),
),
);
}
@ -616,17 +586,7 @@ class _PlayingTeamPageState extends State<PlayingTeamPage> {
}
Future<void> _onTapUser(Map<String, dynamic> userData) async {
final pType = (userData['participant_type'] ?? '').toString().toUpperCase();
if (pType == 'ADMIN') {
await showDialog(
context: context,
builder: (_) => ScoreEditDialog(
roomSeq: widget.roomSeq,
roomType: 'TEAM',
userData: userData,
),
);
} else if (roomMasterYn == 'Y') {
if (myParticipantType == 'ADMIN') {
await showDialog(
context: context,
builder: (_) => ScoreEditDialog(

View File

@ -5,7 +5,7 @@ import 'room_search_list_page.dart';
import '../../config/config.dart';
//
import 'package:google_mobile_ads/google_mobile_ads.dart'; // AdMob
import '../../plugins/admob.dart';
class RoomSearchHomePage extends StatefulWidget {
const RoomSearchHomePage({Key? key}) : super(key: key);
@ -15,43 +15,32 @@ class RoomSearchHomePage extends StatefulWidget {
}
class _RoomSearchHomePageState extends State<RoomSearchHomePage> {
BannerAd? _bannerAd;
bool _isBannerReady = false; //
String adUnitId = Config.adUnitId;
//
double scaleFactor = 1.0;
@override
void initState() {
super.initState();
// (C)
_initBannerAd();
}
@override
void dispose() {
_bannerAd?.dispose();
super.dispose();
}
///
void _initBannerAd() {
_bannerAd = BannerAd(
size: AdSize.banner, //
// adUnitId: 'ca-app-pub-3940256099942544/6300978111' ()
adUnitId: adUnitId, // / ID
listener: BannerAdListener(
onAdLoaded: (Ad ad) {
setState(() => _isBannerReady = true);
},
onAdFailedToLoad: (Ad ad, LoadAdError err) {
//
},
),
request: const AdRequest(),
);
@override
void didChangeDependencies() {
super.didChangeDependencies();
_updateScaleFactor();
}
// load()
_bannerAd?.load();
//
void _updateScaleFactor() {
final screenWidth = MediaQuery.of(context).size.width;
const baseWidth = 450.0;
setState(() {
scaleFactor = (screenWidth / baseWidth).clamp(0.8, 1.2);
});
}
@override
@ -70,14 +59,7 @@ class _RoomSearchHomePageState extends State<RoomSearchHomePage> {
),
//
bottomNavigationBar: _isBannerReady && _bannerAd != null
? Container(
color: Colors.white,
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
)
: SizedBox.shrink(), // or
bottomNavigationBar: AdBannerWidget(),
// : 3 ( / / )
body: Center(
@ -102,8 +84,8 @@ class _RoomSearchHomePageState extends State<RoomSearchHomePage> {
required String status,
}) {
return SizedBox(
width: 100,
height: 100,
width: 100 * scaleFactor,
height: 100 * scaleFactor,
child: ElevatedButton(
onPressed: () {
// RoomSearchListPage로 , roomStatus

View File

@ -14,7 +14,7 @@ import '../room/finish_team_page.dart';
import '../../config/config.dart';
//
import 'package:google_mobile_ads/google_mobile_ads.dart'; // AdMob
import '../../plugins/admob.dart';
class RoomSearchListPage extends StatefulWidget {
final String roomStatus; // WAIT / RUNNING / FINISH
@ -37,20 +37,12 @@ class _RoomSearchListPageState extends State<RoomSearchListPage> {
late ScrollController _scrollController;
//
BannerAd? _bannerAd;
bool _isBannerReady = false; //
String adUnitId = Config.adUnitId;
@override
void initState() {
super.initState();
_scrollController = ScrollController()..addListener(_onScroll);
_fetchRoomList(isRefresh: true);
// (C)
_initBannerAd();
}
@override
@ -58,31 +50,9 @@ class _RoomSearchListPageState extends State<RoomSearchListPage> {
_scrollController.removeListener(_onScroll);
_scrollController.dispose();
_searchController.dispose();
_bannerAd?.dispose();
super.dispose();
}
///
void _initBannerAd() {
_bannerAd = BannerAd(
size: AdSize.banner, //
// adUnitId: 'ca-app-pub-3940256099942544/6300978111' ()
adUnitId: adUnitId, // / ID
listener: BannerAdListener(
onAdLoaded: (Ad ad) {
setState(() => _isBannerReady = true);
},
onAdFailedToLoad: (Ad ad, LoadAdError err) {
ad.dispose();
},
),
request: const AdRequest(),
);
// load()
_bannerAd?.load();
}
void _onScroll() {
if (!_scrollController.hasClients) return;
final thresholdPixels = 200;
@ -236,14 +206,8 @@ class _RoomSearchListPageState extends State<RoomSearchListPage> {
),
),
//
bottomNavigationBar: _isBannerReady && _bannerAd != null
? Container(
color: Colors.white,
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
)
: SizedBox.shrink(), // or
bottomNavigationBar: AdBannerWidget(),
body: Column(
children: [
//

View File

@ -12,10 +12,12 @@ import '../../dialogs/user_info_private_dialog.dart';
import 'playing_private_page.dart';
//
import 'package:google_mobile_ads/google_mobile_ads.dart';
import '../../plugins/admob.dart';
//
import '../../config/config.dart';
//
import 'package:auto_size_text/auto_size_text.dart';
class WaitingRoomPrivatePage extends StatefulWidget {
final int roomSeq;
@ -74,14 +76,13 @@ class _WaitingRoomPrivatePageState extends State<WaitingRoomPrivatePage> {
bool _roomTimeOut = false;
String _roomExitYn = 'N';
/// (1)
BannerAd? _bannerAd;
bool _isBannerReady = false; //
String adUnitId = Config.adUnitId;
// SEQ
String _masterSeqString = '0';
//
double scaleFactor = 1.0;
double buttonScaleFactor = 1.0;
@override
void initState() {
super.initState();
@ -89,8 +90,6 @@ class _WaitingRoomPrivatePageState extends State<WaitingRoomPrivatePage> {
FirebaseDatabase.instance.goOnline();
// (B)
_initRoomRef();
// (C)
_initBannerAd();
}
@override
@ -100,25 +99,20 @@ class _WaitingRoomPrivatePageState extends State<WaitingRoomPrivatePage> {
super.dispose();
}
///
void _initBannerAd() {
_bannerAd = BannerAd(
size: AdSize.banner, //
// adUnitId: 'ca-app-pub-3940256099942544/6300978111' ()
adUnitId: adUnitId, // / ID
listener: BannerAdListener(
onAdLoaded: (Ad ad) {
setState(() => _isBannerReady = true);
},
onAdFailedToLoad: (Ad ad, LoadAdError err) {
ad.dispose();
},
),
request: const AdRequest(),
);
@override
void didChangeDependencies() {
super.didChangeDependencies();
_updateScaleFactor();
}
// load()
_bannerAd?.load();
//
void _updateScaleFactor() {
final screenWidth = MediaQuery.of(context).size.width;
const baseWidth = 450.0;
setState(() {
scaleFactor = (screenWidth / baseWidth).clamp(0.8, 1.2);
buttonScaleFactor = (screenWidth / baseWidth).clamp(0.6, 1.2);
});
}
Future<void> _initRoomRef() async {
@ -328,7 +322,7 @@ class _WaitingRoomPrivatePageState extends State<WaitingRoomPrivatePage> {
final response = await Api.serverRequest(uri: '/room/score/game/leave', body: reqBody);
// result ok ->
} catch (e) {
//
await showResponseDialog(context, '오류', '방 나가기 처리 실패');
}
if (mounted) {
Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (_) => const MainPage()), (route) => false);
@ -410,7 +404,7 @@ class _WaitingRoomPrivatePageState extends State<WaitingRoomPrivatePage> {
final me = _userList.firstWhere((u) => (u['user_seq'].toString() ?? '0') == mySeq, orElse: () => {});
final myReadyYn = (me['ready_yn'] ?? 'N').toString().toUpperCase();
final bool isReady = (myReadyYn == 'Y');
final readyLabel = isReady ? '준비완료' : '준비';
final readyLabel = '준비';
final btnStyle = ElevatedButton.styleFrom(
backgroundColor: Colors.white,
@ -428,7 +422,11 @@ class _WaitingRoomPrivatePageState extends State<WaitingRoomPrivatePage> {
child: ElevatedButton(
style: btnStyle,
onPressed: _onOpenRoomSetting,
child: const Text('방 설정'),
child: AutoSizeText(
'방 설정',
maxLines: 1,
style: TextStyle(fontSize: 14 * scaleFactor),
),
),
),
),
@ -438,7 +436,11 @@ class _WaitingRoomPrivatePageState extends State<WaitingRoomPrivatePage> {
child: ElevatedButton(
style: btnStyle,
onPressed: _readyButtonEnabled ? _onToggleReady : null,
child: Text(readyLabel),
child: AutoSizeText(
readyLabel,
maxLines: 1,
style: TextStyle(fontSize: 14 * scaleFactor, color: isReady ? Colors.red : Colors.black),
),
),
),
),
@ -448,7 +450,11 @@ class _WaitingRoomPrivatePageState extends State<WaitingRoomPrivatePage> {
child: ElevatedButton(
style: btnStyle,
onPressed: _onGameStart,
child: const Text('게임 시작'),
child: AutoSizeText(
scaleFactor==0.8 ? '시작' : '게임 시작',
maxLines: 1,
style: TextStyle(fontSize: 14 * scaleFactor),
),
),
),
),
@ -464,7 +470,11 @@ class _WaitingRoomPrivatePageState extends State<WaitingRoomPrivatePage> {
child: ElevatedButton(
style: btnStyle,
onPressed: _onOpenRoomSetting,
child: const Text('방 설정'),
child: AutoSizeText(
'방 설정',
maxLines: 1,
style: TextStyle(fontSize: 14 * scaleFactor),
),
),
),
),
@ -474,7 +484,11 @@ class _WaitingRoomPrivatePageState extends State<WaitingRoomPrivatePage> {
child: ElevatedButton(
style: btnStyle,
onPressed: _readyButtonEnabled ? _onToggleReady : null,
child: Text(readyLabel),
child: AutoSizeText(
readyLabel,
maxLines: 1,
style: TextStyle(fontSize: 14 * scaleFactor, color: isReady ? Colors.red : Colors.black),
),
),
),
),
@ -619,14 +633,8 @@ class _WaitingRoomPrivatePageState extends State<WaitingRoomPrivatePage> {
onPressed: () => _onLeaveRoom(),
),
),
bottomNavigationBar: _isBannerReady && _bannerAd != null
? Container(
color: Colors.white,
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
)
: SizedBox.shrink(), // or
bottomNavigationBar: AdBannerWidget(),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(

View File

@ -18,10 +18,12 @@ import '../../dialogs/team_name_edit_dialog.dart';
import 'playing_team_page.dart';
//
import 'package:google_mobile_ads/google_mobile_ads.dart';
import '../../plugins/admob.dart';
//
import '../../config/config.dart';
//
import 'package:auto_size_text/auto_size_text.dart';
class WaitingRoomTeamPage extends StatefulWidget {
final int roomSeq;
@ -76,24 +78,37 @@ class _WaitingRoomTeamPageState extends State<WaitingRoomTeamPage> {
bool _roomTimeOut = false;
String _roomExitYn = 'N';
/// (1)
BannerAd? _bannerAd;
bool _isBannerReady = false; //
String adUnitId = Config.adUnitId;
// SEQ
String _masterSeqString = '0';
//
double scaleFactor = 1.0;
double buttonScaleFactor = 1.0;
@override
void initState() {
super.initState();
FirebaseDatabase.instance.goOnline();
// (C)
_initBannerAd();
// (D)
_initRoomRef();
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
_updateScaleFactor();
}
//
void _updateScaleFactor() {
final screenWidth = MediaQuery.of(context).size.width;
const baseWidth = 450.0;
setState(() {
scaleFactor = (screenWidth / baseWidth).clamp(0.8, 1.2);
buttonScaleFactor = (screenWidth / baseWidth).clamp(0.6, 1.2);
});
}
Future<void> _initRoomRef() async {
final prefs = await SharedPreferences.getInstance();
mySeq = prefs.getInt('my_user_seq')?.toString() ?? '0';
@ -118,27 +133,6 @@ class _WaitingRoomTeamPageState extends State<WaitingRoomTeamPage> {
super.dispose();
}
///
void _initBannerAd() {
_bannerAd = BannerAd(
size: AdSize.banner, //
// adUnitId: 'ca-app-pub-3940256099942544/6300978111' ()
adUnitId: adUnitId, // / ID
listener: BannerAdListener(
onAdLoaded: (Ad ad) {
setState(() => _isBannerReady = true);
},
onAdFailedToLoad: (Ad ad, LoadAdError err) {
ad.dispose();
},
),
request: const AdRequest(),
);
// load()
_bannerAd?.load();
}
void _listenRoomData() {
_roomStream = _roomRef.onValue;
_roomStreamSubscription = _roomStream?.listen((event) {
@ -416,7 +410,7 @@ class _WaitingRoomTeamPageState extends State<WaitingRoomTeamPage> {
final me = _userList.firstWhere((u) => (u['user_seq'].toString() ?? '0') == mySeq, orElse: () => {});
final myReadyYn = (me['ready_yn'] ?? 'N').toString().toUpperCase();
final bool isReady = (myReadyYn == 'Y');
final readyLabel = isReady ? '준비완료' : '준비';
final readyLabel = '준비';
final btnStyle = ElevatedButton.styleFrom(
backgroundColor: Colors.white,
@ -433,7 +427,11 @@ class _WaitingRoomTeamPageState extends State<WaitingRoomTeamPage> {
child: ElevatedButton(
style: btnStyle,
onPressed: _onOpenRoomSetting,
child: const Text('방 설정'),
child: AutoSizeText(
'방 설정',
maxLines: 1,
style: TextStyle(fontSize: 14 * scaleFactor),
),
),
),
),
@ -443,7 +441,11 @@ class _WaitingRoomTeamPageState extends State<WaitingRoomTeamPage> {
child: ElevatedButton(
style: btnStyle,
onPressed: _readyButtonEnabled ? _onToggleReady : null,
child: Text(readyLabel),
child: AutoSizeText(
readyLabel,
maxLines: 1,
style: TextStyle(fontSize: 14 * scaleFactor, color: isReady ? Colors.red : Colors.black),
),
),
),
),
@ -455,7 +457,11 @@ class _WaitingRoomTeamPageState extends State<WaitingRoomTeamPage> {
onPressed: _isServerRequestLoading ? null : _onGameStart,
child: _isServerRequestLoading
? const CircularProgressIndicator()
: const Text('게임 시작'),
: AutoSizeText(
scaleFactor==0.8 ? '시작' : '게임 시작',
maxLines: 1,
style: TextStyle(fontSize: 14 * scaleFactor),
),
),
),
),
@ -470,7 +476,11 @@ class _WaitingRoomTeamPageState extends State<WaitingRoomTeamPage> {
child: ElevatedButton(
style: btnStyle,
onPressed: _onOpenRoomSetting,
child: const Text('방 설정'),
child: AutoSizeText(
'방 설정',
maxLines: 1,
style: TextStyle(fontSize: 14 * scaleFactor),
),
),
),
),
@ -480,7 +490,11 @@ class _WaitingRoomTeamPageState extends State<WaitingRoomTeamPage> {
child: ElevatedButton(
style: btnStyle,
onPressed: _readyButtonEnabled ? _onToggleReady : null,
child: Text(readyLabel),
child: AutoSizeText(
readyLabel,
maxLines: 1,
style: TextStyle(fontSize: 14 * scaleFactor, color: isReady ? Colors.red : Colors.black),
),
),
),
),
@ -637,14 +651,8 @@ class _WaitingRoomTeamPageState extends State<WaitingRoomTeamPage> {
onPressed: () => _onLeaveRoom(),
),
),
bottomNavigationBar: _isBannerReady && _bannerAd != null
? Container(
color: Colors.white,
width: _bannerAd!.size.width.toDouble(),
height: _bannerAd!.size.height.toDouble(),
child: AdWidget(ad: _bannerAd!),
)
: SizedBox.shrink(), // or
bottomNavigationBar: AdBannerWidget(),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: SingleChildScrollView(

File diff suppressed because it is too large Load Diff

View File

@ -15,9 +15,8 @@ class WithdrawalPage extends StatefulWidget {
}
class _WithdrawalPageState extends State<WithdrawalPage> {
bool _isAgreed = false; //
bool _isAgreed = false; //
final TextEditingController _passwordController = TextEditingController(); //
String _oauthType = 'idpw';
@override
@ -36,7 +35,10 @@ class _WithdrawalPageState extends State<WithdrawalPage> {
@override
Widget build(BuildContext context) {
// oauth_type == 'google' =>
//
final screenWidth = MediaQuery.of(context).size.width;
// oauth_type == 'google'
final isGoogleUser = (_oauthType.toLowerCase() == 'google');
return Scaffold(
@ -49,87 +51,105 @@ class _WithdrawalPageState extends State<WithdrawalPage> {
onPressed: () => Navigator.pop(context),
),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'회원탈퇴를 진행합니다.\n현재 비밀번호를 입력해주세요.',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18),
),
const SizedBox(height: 20),
//
if (!isGoogleUser) ...[
TextField(
controller: _passwordController,
obscureText: true,
decoration: InputDecoration(
hintText: '비밀번호 입력',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.black),
// SingleChildScrollView
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
// Column이
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 20),
const Center(
child: Text(
'회원탈퇴를 진행합니다.\n현재 비밀번호를 입력해주세요.',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 18),
),
),
const SizedBox(height: 20),
//
if (!isGoogleUser) ...[
TextField(
controller: _passwordController,
obscureText: true,
decoration: InputDecoration(
hintText: '비밀번호 입력',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
borderSide: const BorderSide(color: Colors.black),
),
contentPadding: const EdgeInsets.all(10),
),
),
const SizedBox(height: 20),
],
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black54, width: 1),
borderRadius: BorderRadius.circular(10),
),
padding: const EdgeInsets.all(16.0),
child: const Text(
'[회원 탈퇴 안내]\n'
'회원 탈퇴를 진행하시겠습니까?\n'
' - 회원 탈퇴 시 등록하신 모든 개인정보(ID, 비밀번호, 닉네임, 이메일 주소, 소속, 자기소개 등)는 즉시 삭제되며 복구가 불가능합니다.\n'
' - 탈퇴 후 동일한 아이디로 재가입이 불가능할 수 있습니다.\n'
' - 관련 법령에 따라 일정 기간 보관이 필요한 경우 해당 기간 동안 법령이 허용하는 범위 내에서만 보관됩니다.\n'
'탈퇴를 원하시면 아래의 "동의" 버튼을 눌러주시기 바랍니다.',
textAlign: TextAlign.left,
style: TextStyle(fontSize: 12),
),
),
const SizedBox(height: 20),
Row(
children: [
Checkbox(
value: _isAgreed,
activeColor: Colors.black,
checkColor: Colors.white,
onChanged: (value) {
setState(() {
_isAgreed = value ?? false;
});
},
),
const Expanded(
child: Text(
'회원탈퇴에 동의합니다.',
style: TextStyle(fontSize: 16),
),
),
],
),
const SizedBox(height: 20),
// "탈퇴하기"
Center(
child: ElevatedButton(
onPressed: () {
_requestWithdrawal(_passwordController.text, _isAgreed);
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.black54,
//
padding: EdgeInsets.symmetric(
vertical: 12,
horizontal: screenWidth * 0.15,
),
),
child: const Text(
'탈퇴하기',
style: TextStyle(color: Colors.white, fontSize: 16),
),
contentPadding: const EdgeInsets.all(10),
),
),
const SizedBox(height: 20),
],
Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black54, width: 1), //
borderRadius: BorderRadius.circular(10), //
),
padding: const EdgeInsets.all(16.0), //
child: const Text(
'[회원 탈퇴 안내]\n'
'회원 탈퇴를 진행하시겠습니까?\n'
' - 회원 탈퇴 시 등록하신 모든 개인정보(ID, 비밀번호, 닉네임, 이메일 주소, 소속, 자기소개 등)는 즉시 삭제되며 복구가 불가능합니다.\n'
' - 탈퇴 후 동일한 아이디로 재가입이 불가능할 수 있습니다.\n'
' - 관련 법령에 따라 일정 기간 보관이 필요한 경우 해당 기간 동안 법령이 허용하는 범위 내에서만 보관됩니다.\n'
'탈퇴를 원하시면 아래의 "동의" 버튼을 눌러주시기 바랍니다.',
textAlign: TextAlign.left,
style: TextStyle(fontSize: 12),
),
),
const SizedBox(height: 20),
Row(
children: [
Checkbox(
value: _isAgreed, //
activeColor: Colors.black, //
checkColor: Colors.white, //
onChanged: (value) {
setState(() {
_isAgreed = value ?? false; //
});
},
),
const Expanded(
child: Text(
'회원탈퇴에 동의합니다.',
style: TextStyle(fontSize: 16),
),
),
],
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
//
_requestWithdrawal(_passwordController.text, _isAgreed);
},
style: ElevatedButton.styleFrom(
backgroundColor: Colors.black54, //
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 60), //
),
child: const Text(
'탈퇴하기',
style: TextStyle(color: Colors.white, fontSize: 16), //
),
),
],
),
),
),
);
@ -137,19 +157,17 @@ class _WithdrawalPageState extends State<WithdrawalPage> {
Future<void> _requestWithdrawal(String password, bool isAgreed) async {
if (!isAgreed) {
//
showResponseDialog(context, '회원탈퇴 동의 확인', '회원탈퇴 동의 체크가 필요합니다.');
return;
}
//
//
if (_oauthType != 'google' && password.isEmpty) {
//
showResponseDialog(context, '비밀번호 확인', '비밀번호를 입력해야 합니다.');
return;
}
//
// ''
if (password.isEmpty) {
password = '';
}
@ -157,7 +175,7 @@ class _WithdrawalPageState extends State<WithdrawalPage> {
final response = await Api.serverRequest(
uri: '/user/withdraw/user',
body: {
'user_pw': Utils.hashPassword(password), //
'user_pw': Utils.hashPassword(password),
'oauth_type': _oauthType,
},
);
@ -165,17 +183,20 @@ class _WithdrawalPageState extends State<WithdrawalPage> {
if (response['result'] == 'OK') {
final serverResponse = response['response'];
if (serverResponse['result'] == 'OK') {
//
// &
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.remove('auth_token'); //
await prefs.remove('auth_token');
await showResponseDialog(context, '회원탈퇴 완료', '회원탈퇴가 완료되었습니다.');
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const LoginPage()), //
MaterialPageRoute(builder: (context) => const LoginPage()),
);
} else {
showResponseDialog(context, serverResponse['response_info']['msg_title'], serverResponse['response_info']['msg_content']);
showResponseDialog(
context,
serverResponse['response_info']['msg_title'],
serverResponse['response_info']['msg_content'],
);
}
} else {
showResponseDialog(context, '회원탈퇴 실패', '서버에 문제가 있습니다. 관리자에게 문의해주세요.');

View File

@ -41,6 +41,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.11.0"
auto_size_text:
dependency: "direct main"
description:
name: auto_size_text
sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
boolean_selector:
dependency: transitive
description:

View File

@ -1,7 +1,7 @@
name: allscore_app
description: "A new Flutter project."
publish_to: 'none'
version: 1.0.0+1
version: 1.0.3+4
environment:
sdk: ^3.6.0
@ -26,6 +26,7 @@ dependencies:
fluttertoast: ^8.0.9
flutter_launcher_icons: ^0.12.0
flutter_native_splash: ^2.2.15
auto_size_text: ^3.0.0
dev_dependencies:
flutter_test: