From ce8f501ed54ce3c09479cfc1bca5291136795d9f Mon Sep 17 00:00:00 2001 From: jooiss Date: Wed, 14 Aug 2024 07:31:01 +0900 Subject: [PATCH 1/6] feat: Add chat function --- app/build.gradle.kts | 10 +++ app/google-services.json | 29 ++++++ app/src/main/AndroidManifest.xml | 9 +- .../java/com/example/manolja/data/Message.kt | 8 ++ .../example/manolja}/data/RecordItem.kt | 2 +- .../com/example/manolja/ui/MessageAdapter.kt | 41 +++++++++ .../manolja/ui/activity/ChatActivity.kt | 89 +++++++++++++++++++ .../manolja/ui/fragment/RecordAdapter.kt | 2 +- .../manolja/ui/fragment/RecordFragment.kt | 2 +- .../res/drawable/message_background_left.xml | 4 + .../res/drawable/message_background_right.xml | 4 + app/src/main/res/layout/activity_chat.xml | 39 ++++++++ app/src/main/res/layout/item_message_left.xml | 31 +++++++ .../main/res/layout/item_message_right.xml | 31 +++++++ app/src/main/res/values/strings.xml | 1 - build.gradle.kts | 1 + gradle/libs.versions.toml | 2 - 17 files changed, 297 insertions(+), 8 deletions(-) create mode 100644 app/google-services.json create mode 100644 app/src/main/java/com/example/manolja/data/Message.kt rename app/src/main/java/{ => com/example/manolja}/data/RecordItem.kt (74%) create mode 100644 app/src/main/java/com/example/manolja/ui/MessageAdapter.kt create mode 100644 app/src/main/java/com/example/manolja/ui/activity/ChatActivity.kt create mode 100644 app/src/main/res/drawable/message_background_left.xml create mode 100644 app/src/main/res/drawable/message_background_right.xml create mode 100644 app/src/main/res/layout/activity_chat.xml create mode 100644 app/src/main/res/layout/item_message_left.xml create mode 100644 app/src/main/res/layout/item_message_right.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 30a1d21..329a7ef 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -4,6 +4,8 @@ plugins { alias(libs.plugins.androidApplication) alias(libs.plugins.jetbrainsKotlinAndroid) id("kotlin-kapt") + id("com.google.gms.google-services") + } android { @@ -51,6 +53,14 @@ dependencies { // SendBird 라이브러리 추가 implementation(libs.sendbird.chat) + // Firebase 라이브러리 추가 + implementation(platform("com.google.firebase:firebase-bom:33.1.2")) + implementation("com.google.firebase:firebase-analytics") + + // Firebase Database 라이브러리 추가 + implementation(platform("com.google.firebase:firebase-bom:32.3.1")) + implementation("com.google.firebase:firebase-database-ktx") + implementation(libs.androidx.core.ktx) implementation(libs.androidx.appcompat) implementation(libs.material) diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..2a62be8 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "878525628040", + "project_id": "manolja-ef51e", + "storage_bucket": "manolja-ef51e.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:878525628040:android:d0bb43763de81365eba93d", + "android_client_info": { + "package_name": "com.example.manolja" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyAlWZzeOgPSr_KOxMBDFCeMVhWeWBnCNBs" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0068b78..a63df5b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,6 +3,7 @@ xmlns:tools="http://schemas.android.com/tools"> + - @@ -24,6 +24,11 @@ + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/manolja/data/Message.kt b/app/src/main/java/com/example/manolja/data/Message.kt new file mode 100644 index 0000000..e138f14 --- /dev/null +++ b/app/src/main/java/com/example/manolja/data/Message.kt @@ -0,0 +1,8 @@ +package com.example.manolja.data + +data class Message( + val sender: String = "", + val text: String = "", + val timestamp: Long = System.currentTimeMillis(), + val isCurrentUser: Boolean = false +) \ No newline at end of file diff --git a/app/src/main/java/data/RecordItem.kt b/app/src/main/java/com/example/manolja/data/RecordItem.kt similarity index 74% rename from app/src/main/java/data/RecordItem.kt rename to app/src/main/java/com/example/manolja/data/RecordItem.kt index 8a06e67..22be918 100644 --- a/app/src/main/java/data/RecordItem.kt +++ b/app/src/main/java/com/example/manolja/data/RecordItem.kt @@ -1,4 +1,4 @@ -package data +package com.example.manolja.data data class RecordItem( val date: String, diff --git a/app/src/main/java/com/example/manolja/ui/MessageAdapter.kt b/app/src/main/java/com/example/manolja/ui/MessageAdapter.kt new file mode 100644 index 0000000..2e80260 --- /dev/null +++ b/app/src/main/java/com/example/manolja/ui/MessageAdapter.kt @@ -0,0 +1,41 @@ +package com.example.manolja.ui + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView +import com.example.manolja.R +import com.example.manolja.data.Message + +class MessageAdapter(private val messages: List) : RecyclerView.Adapter() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessageViewHolder { + val view = LayoutInflater.from(parent.context).inflate(viewType, parent, false) + return MessageViewHolder(view) + } + + override fun onBindViewHolder(holder: MessageViewHolder, position: Int) { + val message = messages[position] + holder.bind(message) + } + + override fun getItemCount(): Int = messages.size + + override fun getItemViewType(position: Int): Int { + val message = messages[position] + return if (message.isCurrentUser) R.layout.item_message_right else R.layout.item_message_left + } + + class MessageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + private val messageText: TextView = itemView.findViewById(R.id.message_text) + private val messageTime: TextView = itemView.findViewById(R.id.message_time) + private val messageSender: TextView = itemView.findViewById(R.id.message_sender) + + fun bind(message: Message) { + messageText.text = message.text + messageTime.text = android.text.format.DateFormat.format("HH:mm", message.timestamp) + messageSender.text = message.sender + } + } +} diff --git a/app/src/main/java/com/example/manolja/ui/activity/ChatActivity.kt b/app/src/main/java/com/example/manolja/ui/activity/ChatActivity.kt new file mode 100644 index 0000000..a165721 --- /dev/null +++ b/app/src/main/java/com/example/manolja/ui/activity/ChatActivity.kt @@ -0,0 +1,89 @@ +package com.example.manolja.ui.activity + +import android.os.Bundle +import android.widget.Button +import android.widget.EditText +import androidx.appcompat.app.AppCompatActivity +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.example.manolja.R +import com.example.manolja.data.Message +import com.example.manolja.ui.MessageAdapter +import com.google.firebase.database.* + +class ChatActivity : AppCompatActivity() { + + private lateinit var messageRecyclerView: RecyclerView + private lateinit var messageAdapter: MessageAdapter + private lateinit var messageInput: EditText + private lateinit var sendButton: Button + + private lateinit var database: DatabaseReference + private lateinit var messages: MutableList + private val currentUser = "김주송" + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_chat) + + messageRecyclerView = findViewById(R.id.message_recycler_view) + messageInput = findViewById(R.id.message_input) + sendButton = findViewById(R.id.send_button) + + messages = mutableListOf() + messageAdapter = MessageAdapter(messages) + messageRecyclerView.layoutManager = LinearLayoutManager(this) + messageRecyclerView.adapter = messageAdapter + + // Firebase 데이터베이스 참조 설정 + database = FirebaseDatabase.getInstance().getReference("messages") + + // 메시지 전송 버튼 클릭 리스너 + sendButton.setOnClickListener { + val text = messageInput.text.toString().trim() + if (text.isNotEmpty()) { + sendMessage(text) + } + } + + // Firebase 데이터베이스에서 메시지 불러오기 + loadMessages() + } + + private fun loadMessages() { + database.addChildEventListener(object : ChildEventListener { + override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) { + val message = snapshot.getValue(Message::class.java) + message?.let { + val isCurrentUser = it.sender == currentUser + val newMessage = it.copy(isCurrentUser = isCurrentUser) + messages.add(newMessage) + messageAdapter.notifyItemInserted(messages.size - 1) + messageRecyclerView.scrollToPosition(messages.size - 1) + } + } + + override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) { + // 메시지가 수정된 경우 처리 + } + + override fun onChildRemoved(snapshot: DataSnapshot) { + // 메시지가 삭제된 경우 처리 + } + + override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) { + // 메시지가 이동된 경우 처리 + } + + override fun onCancelled(error: DatabaseError) { + // 데이터 로드 취소 시 처리할 코드 + } + }) + } + + private fun sendMessage(text: String) { + val message = Message(sender = currentUser, text = text, isCurrentUser = true) + database.push().setValue(message) + messageInput.text.clear() + } +} diff --git a/app/src/main/java/com/example/manolja/ui/fragment/RecordAdapter.kt b/app/src/main/java/com/example/manolja/ui/fragment/RecordAdapter.kt index 9363e92..a90b96f 100644 --- a/app/src/main/java/com/example/manolja/ui/fragment/RecordAdapter.kt +++ b/app/src/main/java/com/example/manolja/ui/fragment/RecordAdapter.kt @@ -8,7 +8,7 @@ import android.widget.TextView import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide import com.example.manolja.R -import data.RecordItem +import com.example.manolja.data.RecordItem class RecordAdapter(private val recordItems: List) : RecyclerView.Adapter() { diff --git a/app/src/main/java/com/example/manolja/ui/fragment/RecordFragment.kt b/app/src/main/java/com/example/manolja/ui/fragment/RecordFragment.kt index 92fd32d..46e3209 100644 --- a/app/src/main/java/com/example/manolja/ui/fragment/RecordFragment.kt +++ b/app/src/main/java/com/example/manolja/ui/fragment/RecordFragment.kt @@ -9,7 +9,7 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.RecyclerView import com.example.manolja.R -import data.RecordItem +import com.example.manolja.data.RecordItem class RecordFragment : Fragment() { diff --git a/app/src/main/res/drawable/message_background_left.xml b/app/src/main/res/drawable/message_background_left.xml new file mode 100644 index 0000000..eb79e2a --- /dev/null +++ b/app/src/main/res/drawable/message_background_left.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/drawable/message_background_right.xml b/app/src/main/res/drawable/message_background_right.xml new file mode 100644 index 0000000..c979793 --- /dev/null +++ b/app/src/main/res/drawable/message_background_right.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/layout/activity_chat.xml b/app/src/main/res/layout/activity_chat.xml new file mode 100644 index 0000000..231c9db --- /dev/null +++ b/app/src/main/res/layout/activity_chat.xml @@ -0,0 +1,39 @@ + + + + + + + + + +