1차 최종
This commit is contained in:
parent
b34802b894
commit
7278c6e06e
@ -20,8 +20,8 @@ android {
|
||||
applicationId "com.allscore_app"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 34
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
versionCode 4
|
||||
versionName "1.0.3"
|
||||
}
|
||||
|
||||
// ...
|
||||
|
@ -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';
|
||||
// 이미지 업로드 주소
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
@ -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),
|
||||
|
||||
|
@ -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),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
|
@ -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
85
lib/plugins/admob.dart
Normal 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), // 배경 흰색
|
||||
);
|
||||
}
|
||||
}
|
@ -130,7 +130,7 @@ class _SurveyPageState extends State<SurveyPage> {
|
||||
}
|
||||
|
||||
final requestBody = {
|
||||
"QNA": qnaList.toString(),
|
||||
"QNA": qnaList,
|
||||
};
|
||||
|
||||
try {
|
||||
|
@ -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(),
|
||||
);
|
||||
}
|
||||
}
|
@ -369,7 +369,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
그러나 필수 항목에 대한 동의를 거부하실 경우 서비스 이용이 제한될 수 있습니다.
|
||||
|
||||
7. 개인정보 보호책임자
|
||||
연락처: eld_yeojh@naver.com
|
||||
연락처: eldyeojh@gmail.com
|
||||
|
||||
8. 개인정보의 안전성 확보 조치
|
||||
회사는 개인정보의 안전한 처리를 위하여 기술적, 관리적 보호조치를 시행하고 있습니다.
|
||||
|
@ -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(),
|
||||
);
|
||||
}
|
||||
}
|
@ -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'
|
||||
|
@ -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,
|
||||
|
@ -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(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -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(
|
||||
|
@ -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 전달
|
||||
|
@ -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: [
|
||||
// 검색창
|
||||
|
@ -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(
|
||||
|
@ -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
@ -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, '회원탈퇴 실패', '서버에 문제가 있습니다. 관리자에게 문의해주세요.');
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user