IOS 채팅기능 추가 및 방설정버그 수정 적용 배포 버전1.1.0
This commit is contained in:
parent
d07c6f93dd
commit
67faa04935
@ -20,8 +20,8 @@ android {
|
|||||||
applicationId "com.allscore_app"
|
applicationId "com.allscore_app"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 34
|
targetSdkVersion 34
|
||||||
versionCode 18
|
versionCode 19
|
||||||
versionName "1.0.18"
|
versionName "1.1.0"
|
||||||
}
|
}
|
||||||
signingConfigs {
|
signingConfigs {
|
||||||
release {
|
release {
|
||||||
|
@ -6,9 +6,9 @@ class Config {
|
|||||||
// 실제 광고 단위 ID - ios
|
// 실제 광고 단위 ID - ios
|
||||||
// static const String realAdUnitId = 'ca-app-pub-6461991944599918/9704216771';
|
// static const String realAdUnitId = 'ca-app-pub-6461991944599918/9704216771';
|
||||||
// 테스트 광고 단위 ID
|
// 테스트 광고 단위 ID
|
||||||
static const String adUnitId = 'ca-app-pub-3940256099942544/6300978111'; // 테스트
|
// static const String adUnitId = 'ca-app-pub-3940256099942544/6300978111'; // 테스트
|
||||||
// static const String adUnitId = 'ca-app-pub-6461991944599918/5107596297'; // android
|
// static const String adUnitId = 'ca-app-pub-6461991944599918/5107596297'; // android
|
||||||
// static const String adUnitId = 'ca-app-pub-6461991944599918/9704216771'; // ios
|
static const String adUnitId = 'ca-app-pub-6461991944599918/9704216771'; // ios
|
||||||
// 서버 주소
|
// 서버 주소
|
||||||
static const String baseUrl = 'https://d2zcnlqji5t7mh.cloudfront.net';
|
static const String baseUrl = 'https://d2zcnlqji5t7mh.cloudfront.net';
|
||||||
// 이미지 업로드 주소
|
// 이미지 업로드 주소
|
||||||
|
@ -79,9 +79,9 @@ class _ChatDialogState extends State<ChatDialog> {
|
|||||||
|
|
||||||
_chatRef = FirebaseDatabase.instance.ref(path);
|
_chatRef = FirebaseDatabase.instance.ref(path);
|
||||||
|
|
||||||
// orderByKey()를 사용하여 메시지 ID(timestamp) 기준으로 정렬
|
// orderByChild('timestamp')를 사용하여 timestamp 기준으로 정렬
|
||||||
_chatSubscription = _chatRef
|
_chatSubscription = _chatRef
|
||||||
.orderByKey()
|
.orderByChild('timestamp')
|
||||||
.onValue
|
.onValue
|
||||||
.listen((event) {
|
.listen((event) {
|
||||||
if (!event.snapshot.exists) {
|
if (!event.snapshot.exists) {
|
||||||
@ -103,6 +103,9 @@ class _ChatDialogState extends State<ChatDialog> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// timestamp 기준으로 정렬
|
||||||
|
messages.sort((a, b) => a.timestamp.compareTo(b.timestamp));
|
||||||
|
|
||||||
setState(() => _messages = messages);
|
setState(() => _messages = messages);
|
||||||
_scrollToBottom();
|
_scrollToBottom();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -162,6 +165,7 @@ class _ChatDialogState extends State<ChatDialog> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Dialog(
|
return Dialog(
|
||||||
|
backgroundColor: Colors.white,
|
||||||
child: Container(
|
child: Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.8,
|
width: MediaQuery.of(context).size.width * 0.8,
|
||||||
height: MediaQuery.of(context).size.height * 0.7,
|
height: MediaQuery.of(context).size.height * 0.7,
|
||||||
@ -190,8 +194,11 @@ class _ChatDialogState extends State<ChatDialog> {
|
|||||||
Container(
|
Container(
|
||||||
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
margin: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.grey[200],
|
color: Colors.grey[100],
|
||||||
borderRadius: BorderRadius.circular(25),
|
borderRadius: BorderRadius.circular(25),
|
||||||
|
border: Border.all(
|
||||||
|
color: Colors.grey[300]!,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
@ -211,7 +218,7 @@ class _ChatDialogState extends State<ChatDialog> {
|
|||||||
boxShadow: _selectedChatType == ChatType.all
|
boxShadow: _selectedChatType == ChatType.all
|
||||||
? [
|
? [
|
||||||
BoxShadow(
|
BoxShadow(
|
||||||
color: Colors.grey.withOpacity(0.3),
|
color: Colors.grey.withOpacity(0.1),
|
||||||
blurRadius: 4,
|
blurRadius: 4,
|
||||||
offset: const Offset(0, 2),
|
offset: const Offset(0, 2),
|
||||||
)
|
)
|
||||||
@ -260,7 +267,7 @@ class _ChatDialogState extends State<ChatDialog> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const Divider(),
|
Divider(color: Colors.grey[300]),
|
||||||
],
|
],
|
||||||
// 채팅 내용이 표시될 영역
|
// 채팅 내용이 표시될 영역
|
||||||
Expanded(
|
Expanded(
|
||||||
@ -269,6 +276,7 @@ class _ChatDialogState extends State<ChatDialog> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.grey[100],
|
color: Colors.grey[100],
|
||||||
borderRadius: BorderRadius.circular(12),
|
borderRadius: BorderRadius.circular(12),
|
||||||
|
border: Border.all(color: Colors.grey[200]!),
|
||||||
),
|
),
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
controller: _scrollController,
|
controller: _scrollController,
|
||||||
@ -279,34 +287,49 @@ class _ChatDialogState extends State<ChatDialog> {
|
|||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||||
child: Row(
|
child: Column(
|
||||||
mainAxisAlignment: isMyMessage
|
crossAxisAlignment: isMyMessage ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
||||||
? MainAxisAlignment.end
|
|
||||||
: MainAxisAlignment.start,
|
|
||||||
children: [
|
children: [
|
||||||
if (!isMyMessage) ...[
|
if (!isMyMessage)
|
||||||
Text(
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 12.0, bottom: 4.0),
|
||||||
|
child: Text(
|
||||||
message.senderNickname,
|
message.senderNickname,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
maxLines: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
ConstrainedBox(
|
||||||
],
|
constraints: BoxConstraints(
|
||||||
Container(
|
maxWidth: MediaQuery.of(context).size.width * 0.7,
|
||||||
|
),
|
||||||
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 12,
|
horizontal: 12,
|
||||||
vertical: 8,
|
vertical: 8,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isMyMessage ? Colors.blue[100] : Colors.white,
|
color: isMyMessage ? Colors.grey[800] : Colors.white,
|
||||||
borderRadius: BorderRadius.circular(16),
|
borderRadius: BorderRadius.circular(16),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Colors.grey[300]!,
|
color: Colors.grey[300]!,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Text(message.message),
|
child: Text(
|
||||||
|
message.message,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 14,
|
||||||
|
height: 1.3,
|
||||||
|
color: isMyMessage ? Colors.white : Colors.black,
|
||||||
|
),
|
||||||
|
softWrap: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -338,7 +361,10 @@ class _ChatDialogState extends State<ChatDialog> {
|
|||||||
),
|
),
|
||||||
const SizedBox(width: 8),
|
const SizedBox(width: 8),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: const Icon(Icons.send),
|
icon: const Icon(
|
||||||
|
Icons.send,
|
||||||
|
color: Colors.black, // 아이콘 색상을 검은색으로
|
||||||
|
),
|
||||||
onPressed: _sendMessage,
|
onPressed: _sendMessage,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -385,7 +411,11 @@ class ChatButton extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return FloatingActionButton(
|
return FloatingActionButton(
|
||||||
onPressed: () => _openChatDialog(context),
|
onPressed: () => _openChatDialog(context),
|
||||||
child: const Icon(Icons.chat),
|
child: const Icon(
|
||||||
|
Icons.chat,
|
||||||
|
color: Colors.white, // 아이콘 색상을 흰색으로
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.black, // 버튼 배경색을 검은색으로
|
||||||
mini: true,
|
mini: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -271,22 +271,17 @@ class _SignUpDialogState extends State<SignUpDialog> {
|
|||||||
AppleIDAuthorizationScopes.fullName,
|
AppleIDAuthorizationScopes.fullName,
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
print('appleCredential: $appleCredential');
|
|
||||||
|
|
||||||
// 2. Firebase credential 생성
|
// 2. Firebase credential 생성
|
||||||
final oauthProvider = OAuthProvider('apple.com');
|
final oauthProvider = OAuthProvider('apple.com');
|
||||||
print('oauthProvider: $oauthProvider');
|
|
||||||
final credential = oauthProvider.credential(
|
final credential = oauthProvider.credential(
|
||||||
idToken: appleCredential.identityToken,
|
idToken: appleCredential.identityToken,
|
||||||
accessToken: appleCredential.authorizationCode,
|
accessToken: appleCredential.authorizationCode,
|
||||||
);
|
);
|
||||||
print('credential: $credential');
|
|
||||||
|
|
||||||
// 3. Firebase 인증
|
// 3. Firebase 인증
|
||||||
final userCredential = await FirebaseAuth.instance.signInWithCredential(credential);
|
final userCredential = await FirebaseAuth.instance.signInWithCredential(credential);
|
||||||
print('userCredential: $userCredential');
|
|
||||||
final user = userCredential.user;
|
final user = userCredential.user;
|
||||||
print('user: $user');
|
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
showResponseDialog(context, 'Error', 'Apple account authentication failed.');
|
showResponseDialog(context, 'Error', 'Apple account authentication failed.');
|
||||||
|
@ -153,6 +153,11 @@ class _PlayingPrivatePageState extends State<PlayingPrivatePage> {
|
|||||||
final List<Map<String, dynamic>> rawList = [];
|
final List<Map<String, dynamic>> rawList = [];
|
||||||
userInfoData.forEach((uSeq, uData) {
|
userInfoData.forEach((uSeq, uData) {
|
||||||
uSeq = uSeq.toString().replaceAll('_', '');
|
uSeq = uSeq.toString().replaceAll('_', '');
|
||||||
|
// 채팅 데이터 세팅
|
||||||
|
if (uSeq.toString() == mySeq) {
|
||||||
|
_teamName = uData['team_name'] ?? '';
|
||||||
|
_myNickname = uData['nickname'] ?? '';
|
||||||
|
}
|
||||||
// Mark room master (방장 표시)
|
// Mark room master (방장 표시)
|
||||||
if (uSeq == roomInfoData['master_user_seq'].toString()) {
|
if (uSeq == roomInfoData['master_user_seq'].toString()) {
|
||||||
uData['nickname'] = '★' + (uData['nickname'] ?? 'User');
|
uData['nickname'] = '★' + (uData['nickname'] ?? 'User');
|
||||||
@ -161,11 +166,6 @@ class _PlayingPrivatePageState extends State<PlayingPrivatePage> {
|
|||||||
// Mark admin (사회자 표시)
|
// Mark admin (사회자 표시)
|
||||||
uData['nickname'] = '☆' + (uData['nickname'] ?? 'User');
|
uData['nickname'] = '☆' + (uData['nickname'] ?? 'User');
|
||||||
}
|
}
|
||||||
// 채팅 데이터 세팅
|
|
||||||
if (uSeq.toString() == mySeq) {
|
|
||||||
_teamName = uData['team_name'] ?? '';
|
|
||||||
_myNickname = uData['nickname'] ?? '';
|
|
||||||
}
|
|
||||||
rawList.add({
|
rawList.add({
|
||||||
'user_seq': uSeq,
|
'user_seq': uSeq,
|
||||||
'participant_type': (uData['participant_type'] ?? '').toString().toUpperCase(),
|
'participant_type': (uData['participant_type'] ?? '').toString().toUpperCase(),
|
||||||
|
@ -155,6 +155,11 @@ class _PlayingTeamPageState extends State<PlayingTeamPage> {
|
|||||||
final List<Map<String, dynamic>> rawList = [];
|
final List<Map<String, dynamic>> rawList = [];
|
||||||
userInfoData.forEach((uSeq, uData) {
|
userInfoData.forEach((uSeq, uData) {
|
||||||
uSeq = uSeq.toString().replaceAll('_', '');
|
uSeq = uSeq.toString().replaceAll('_', '');
|
||||||
|
// 채팅 데이터 세팅
|
||||||
|
if (uSeq.toString() == mySeq) {
|
||||||
|
_teamName = uData['team_name'] ?? '';
|
||||||
|
_myNickname = uData['nickname'] ?? '';
|
||||||
|
}
|
||||||
// Mark room master
|
// Mark room master
|
||||||
if (uSeq.toString() == roomInfoData['master_user_seq'].toString()) {
|
if (uSeq.toString() == roomInfoData['master_user_seq'].toString()) {
|
||||||
// 방장 표시
|
// 방장 표시
|
||||||
@ -163,11 +168,6 @@ class _PlayingTeamPageState extends State<PlayingTeamPage> {
|
|||||||
// 관리자(사회자) 표시
|
// 관리자(사회자) 표시
|
||||||
uData['nickname'] = '☆' + (uData['nickname'] ?? 'User');
|
uData['nickname'] = '☆' + (uData['nickname'] ?? 'User');
|
||||||
}
|
}
|
||||||
// 채팅 데이터 세팅
|
|
||||||
if (uSeq.toString() == mySeq) {
|
|
||||||
_teamName = uData['team_name'] ?? '';
|
|
||||||
_myNickname = uData['nickname'] ?? '';
|
|
||||||
}
|
|
||||||
rawList.add({
|
rawList.add({
|
||||||
'user_seq': uSeq,
|
'user_seq': uSeq,
|
||||||
'participant_type': (uData['participant_type'] ?? '').toString().toUpperCase(),
|
'participant_type': (uData['participant_type'] ?? '').toString().toUpperCase(),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
name: allscore_app
|
name: allscore_app
|
||||||
description: "A new Flutter project."
|
description: "A new Flutter project."
|
||||||
publish_to: 'none'
|
publish_to: 'none'
|
||||||
version: 1.0.18+18
|
version: 1.1.0+19
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.5.3 <4.0.0'
|
sdk: '>=3.5.3 <4.0.0'
|
||||||
flutter: ">=3.16.0"
|
flutter: ">=3.16.0"
|
||||||
|
Loading…
Reference in New Issue
Block a user