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..9f400a8 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools">
+
-
+
+
+
+
diff --git a/app/src/main/java/com/example/manolja/data/Coupon.kt b/app/src/main/java/com/example/manolja/data/Coupon.kt
new file mode 100644
index 0000000..9dc9088
--- /dev/null
+++ b/app/src/main/java/com/example/manolja/data/Coupon.kt
@@ -0,0 +1,8 @@
+package com.example.manolja.data
+
+data class Coupon(
+ val name: String,
+ val location: String,
+ val discount: String,
+ val content: String
+)
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/com/example/manolja/data/Quest.kt b/app/src/main/java/com/example/manolja/data/Quest.kt
new file mode 100644
index 0000000..421c26f
--- /dev/null
+++ b/app/src/main/java/com/example/manolja/data/Quest.kt
@@ -0,0 +1,7 @@
+package com.example.manolja.data
+
+data class Quest(
+ val name: String,
+ val location: String,
+ val reward: String
+)
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/domain/Coupon.kt b/app/src/main/java/com/example/manolja/domain/Coupon.kt
new file mode 100644
index 0000000..3e86c5d
--- /dev/null
+++ b/app/src/main/java/com/example/manolja/domain/Coupon.kt
@@ -0,0 +1,8 @@
+package com.example.manolja.domain
+
+data class Coupon(
+ val name: String,
+ val location: String,
+ val discount: String,
+ val content: String
+)
diff --git a/app/src/main/java/com/example/manolja/domain/Message.kt b/app/src/main/java/com/example/manolja/domain/Message.kt
new file mode 100644
index 0000000..8ad7b2d
--- /dev/null
+++ b/app/src/main/java/com/example/manolja/domain/Message.kt
@@ -0,0 +1,8 @@
+package com.example.manolja.domain
+
+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/com/example/manolja/domain/Quest.kt b/app/src/main/java/com/example/manolja/domain/Quest.kt
new file mode 100644
index 0000000..18a2f16
--- /dev/null
+++ b/app/src/main/java/com/example/manolja/domain/Quest.kt
@@ -0,0 +1,7 @@
+package com.example.manolja.domain
+
+data class Quest(
+ val name: String,
+ val location: String,
+ val reward: String
+)
diff --git a/app/src/main/java/com/example/manolja/domain/RecordItem.kt b/app/src/main/java/com/example/manolja/domain/RecordItem.kt
new file mode 100644
index 0000000..f1b3804
--- /dev/null
+++ b/app/src/main/java/com/example/manolja/domain/RecordItem.kt
@@ -0,0 +1,7 @@
+package com.example.manolja.domain
+
+data class RecordItem(
+ val date: String,
+ var caption: String,
+ val imageUrl: String
+)
diff --git a/app/src/main/java/com/example/manolja/ui/activity/CertActivity.kt b/app/src/main/java/com/example/manolja/ui/activity/CertActivity.kt
new file mode 100644
index 0000000..bac4691
--- /dev/null
+++ b/app/src/main/java/com/example/manolja/ui/activity/CertActivity.kt
@@ -0,0 +1,93 @@
+package com.example.manolja.ui.activity
+
+import android.app.ProgressDialog
+import android.content.Intent
+import android.graphics.Bitmap
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.Looper
+import android.provider.MediaStore
+import android.widget.Button
+import android.widget.ImageView
+import android.widget.Toast
+import androidx.appcompat.app.AppCompatActivity
+import com.example.manolja.R
+import java.io.IOException
+
+class CertActivity : AppCompatActivity() {
+
+ private val PICK_IMAGE_REQUEST = 1
+ private lateinit var imageViewPreview: ImageView
+ private var imageUri: Uri? = null
+ private lateinit var progressDialog: ProgressDialog
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_cert)
+
+ imageViewPreview = findViewById(R.id.imageViewPreview)
+ val buttonUpload: Button = findViewById(R.id.buttonUpload)
+ val buttonConfirm: Button = findViewById(R.id.buttonConfirm)
+ val buttonCancel: Button = findViewById(R.id.buttonCancel)
+
+ // ProgressDialog 초기화
+ progressDialog = ProgressDialog(this).apply {
+ setMessage("인증 중...")
+ setCancelable(false)
+ }
+
+ // 사진 업로드 버튼 클릭 리스너
+ buttonUpload.setOnClickListener { openFileChooser() }
+
+ // 확인 버튼 클릭 리스너
+ buttonConfirm.setOnClickListener {
+ if (imageUri != null) {
+ // 로딩 창 표시
+ progressDialog.show()
+
+ // 사진 업로드 로직 구현 (예: 서버에 업로드)
+ // 여기서는 업로드가 완료된 후 로직을 직접 호출합니다.
+ uploadImageAndFinish()
+ } else {
+ Toast.makeText(this, "사진을 선택해 주세요.", Toast.LENGTH_SHORT).show()
+ }
+ }
+
+ // 취소 버튼 클릭 리스너
+ buttonCancel.setOnClickListener { finish() } // 액티비티 종료
+ }
+
+ private fun openFileChooser() {
+ val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
+ intent.type = "image/*"
+ startActivityForResult(intent, PICK_IMAGE_REQUEST)
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.data != null) {
+ imageUri = data.data
+ try {
+ val bitmap: Bitmap = MediaStore.Images.Media.getBitmap(contentResolver, imageUri)
+ imageViewPreview.setImageBitmap(bitmap)
+ } catch (e: IOException) {
+ e.printStackTrace()
+ }
+ }
+ }
+
+ private fun uploadImageAndFinish() {
+ // 업로드 시뮬레이션을 위해 3초 지연
+ Handler(Looper.getMainLooper()).postDelayed({
+ // 로딩 창 닫기
+ progressDialog.dismiss()
+
+ // 결과 전달: 인증 성공
+ val resultIntent = Intent()
+ resultIntent.putExtra("upload_success", true)
+ setResult(RESULT_OK, resultIntent)
+ finish() // CertActivity 종료
+ }, 3000) // 3000ms = 3초
+ }
+}
\ No newline at end of file
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..35e5e1b
--- /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.domain.Message
+import com.example.manolja.ui.adapter.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/adapter/MessageAdapter.kt b/app/src/main/java/com/example/manolja/ui/adapter/MessageAdapter.kt
new file mode 100644
index 0000000..d5b3b70
--- /dev/null
+++ b/app/src/main/java/com/example/manolja/ui/adapter/MessageAdapter.kt
@@ -0,0 +1,41 @@
+package com.example.manolja.ui.adapter
+
+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.domain.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/adapter/QuestAdapter.kt b/app/src/main/java/com/example/manolja/ui/adapter/QuestAdapter.kt
new file mode 100644
index 0000000..16607ec
--- /dev/null
+++ b/app/src/main/java/com/example/manolja/ui/adapter/QuestAdapter.kt
@@ -0,0 +1,65 @@
+package com.example.manolja.ui.adapter
+
+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.domain.Coupon
+
+class QuestAdapter(
+ private val couponItems: MutableList = mutableListOf(),
+ private var itemsEnabled: Boolean = false
+) : RecyclerView.Adapter() {
+
+ private var itemClickListener: ((String) -> Unit)? = null
+
+ inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val tvCoupon: TextView = itemView.findViewById(R.id.tvCoupon)
+ val tvLocation: TextView = itemView.findViewById(R.id.tvLocation)
+ val tvDiscount: TextView = itemView.findViewById(R.id.tvDiscount)
+ val tvContent: TextView = itemView.findViewById(R.id.tvContent)
+
+ init {
+ itemView.setOnClickListener {
+ if (itemsEnabled) {
+ val couponName = tvCoupon.text.toString()
+ itemClickListener?.invoke(couponName)
+ }
+ }
+ }
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.quest_item, parent, false)
+ return ViewHolder(view)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val item = couponItems[position]
+ holder.tvCoupon.text = item.name
+ holder.tvLocation.text = item.location
+ holder.tvDiscount.text = item.discount
+ holder.tvContent.text = item.content
+ holder.itemView.isEnabled = itemsEnabled
+ }
+
+ override fun getItemCount(): Int = couponItems.size
+
+ fun setItemsEnabled(enabled: Boolean) {
+ itemsEnabled = enabled
+ notifyDataSetChanged()
+ }
+
+ fun setOnItemClickListener(listener: (String) -> Unit) {
+ itemClickListener = listener
+ }
+
+ fun addCoupons(newCoupons: List) {
+ couponItems.clear()
+ couponItems.addAll(newCoupons)
+ notifyDataSetChanged()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/manolja/ui/fragment/RecordAdapter.kt b/app/src/main/java/com/example/manolja/ui/adapter/RecordAdapter.kt
similarity index 97%
rename from app/src/main/java/com/example/manolja/ui/fragment/RecordAdapter.kt
rename to app/src/main/java/com/example/manolja/ui/adapter/RecordAdapter.kt
index 9363e92..5b00789 100644
--- a/app/src/main/java/com/example/manolja/ui/fragment/RecordAdapter.kt
+++ b/app/src/main/java/com/example/manolja/ui/adapter/RecordAdapter.kt
@@ -1,3 +1,5 @@
+package com.example.manolja.ui.adapter
+
import android.app.AlertDialog
import android.view.LayoutInflater
import android.view.View
@@ -8,7 +10,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.domain.RecordItem
class RecordAdapter(private val recordItems: List) : RecyclerView.Adapter() {
diff --git a/app/src/main/java/com/example/manolja/ui/fragment/HomeFragment.kt b/app/src/main/java/com/example/manolja/ui/fragment/HomeFragment.kt
index 1fb7cff..ece322a 100644
--- a/app/src/main/java/com/example/manolja/ui/fragment/HomeFragment.kt
+++ b/app/src/main/java/com/example/manolja/ui/fragment/HomeFragment.kt
@@ -1,18 +1,111 @@
package com.example.manolja.ui.fragment
+import android.app.AlertDialog
+import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.widget.Button
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.TextView
import androidx.fragment.app.Fragment
import com.example.manolja.R
class HomeFragment : Fragment() {
+ private lateinit var ivMail: ImageView
+ private lateinit var tvQuestPrompt: TextView
+ private lateinit var textContainer: LinearLayout
+ private lateinit var ivCoupon: ImageView
+ private lateinit var couponDialog: Dialog
+ private lateinit var layoutTextContainer: LinearLayout
+ private lateinit var tvNoCoupons: TextView
+ private var isCouponUsed: Boolean = false
+ private lateinit var ivHpBar: ImageView
+ private lateinit var ivBoogiEgg: ImageView
+
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
- return inflater.inflate(R.layout.fragment_home, container, false)
+ val view = inflater.inflate(R.layout.fragment_home, container, false)
+ var hp: Int = 1
+
+ ivMail = view.findViewById(R.id.ivMail)
+ tvQuestPrompt = view.findViewById(R.id.tvQuestPrompt)
+ textContainer = view.findViewById(R.id.textContainer)
+ ivCoupon = view.findViewById(R.id.ivCoupon)
+ ivHpBar = view.findViewById(R.id.ivHpBar)
+ ivBoogiEgg = view.findViewById(R.id.ivBoogiEgg)
+
+ ivMail.setOnClickListener {
+ tvQuestPrompt.visibility = View.INVISIBLE
+ ivMail.visibility = View.INVISIBLE
+ textContainer.visibility = View.VISIBLE
+ }
+
+ ivCoupon.setOnClickListener {
+ showCouponDialog()
+ }
+
+ updateImages(hp)
+ return view
+ }
+
+ private fun showCouponDialog() {
+ val dialogView = LayoutInflater.from(context).inflate(R.layout.coupon_dialog, null)
+ val btnUseCoupon = dialogView.findViewById