diff --git a/app/src/main/java/com/dna/beyoureyes/AssignActivity.kt b/app/src/main/java/com/dna/beyoureyes/AssignActivity.kt index 9730540..3d05589 100644 --- a/app/src/main/java/com/dna/beyoureyes/AssignActivity.kt +++ b/app/src/main/java/com/dna/beyoureyes/AssignActivity.kt @@ -4,6 +4,7 @@ import android.content.Intent import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.fragment.app.Fragment +import com.dna.beyoureyes.model.Allergen import com.dna.beyoureyes.model.FirebaseHelper import com.dna.beyoureyes.model.UserInfo import com.dna.beyoureyes.ui.FragmentNavigationListener @@ -21,6 +22,7 @@ class AssignActivity : AppCompatActivity(), FragmentNavigationListener { private var currentStep = 0 private var disease : ArrayList = ArrayList() private var allergy : ArrayList = ArrayList() + private var allergens : MutableSet = mutableSetOf() private var profile : String = "" override fun onNavigateToFragment(fragment: Fragment) { @@ -43,8 +45,8 @@ class AssignActivity : AppCompatActivity(), FragmentNavigationListener { this.disease = userDiseaseList } - override fun onAllergyInputRecieved(userAllergyList: ArrayList) { - this.allergy = userAllergyList + override fun onAllergyInputRecieved(userAllergySet: MutableSet) { + this.allergens = userAllergySet } override fun onBackPressed() { @@ -97,7 +99,7 @@ class AssignActivity : AppCompatActivity(), FragmentNavigationListener { val dateFormat = SimpleDateFormat("yyyyMMdd", Locale.getDefault()) val birthDate = dateFormat.parse(birth ?: "") ?: Date() val birthTimeStamp = Timestamp(birthDate) - AppUser.info = UserInfo(name?:"", gender?:0, birthTimeStamp, disease, allergy) + AppUser.info = UserInfo(name?:"", gender?:0, birthTimeStamp, disease, allergens.ifEmpty { null }) val userInfo = hashMapOf( "userId" to Firebase.auth.currentUser?.uid, "userName" to name!!, @@ -107,6 +109,9 @@ class AssignActivity : AppCompatActivity(), FragmentNavigationListener { "userAllergy" to allergy, "userProfile" to profile ) + if (allergens.isNotEmpty()) { + userInfo["userAllergens"] = allergens.map{ it.name } + } FirebaseHelper.sendData(userInfo, "userInfo") } diff --git a/app/src/main/java/com/dna/beyoureyes/AssignAllergyFragment.kt b/app/src/main/java/com/dna/beyoureyes/AssignAllergyFragment.kt index 144b9b9..9e28d97 100644 --- a/app/src/main/java/com/dna/beyoureyes/AssignAllergyFragment.kt +++ b/app/src/main/java/com/dna/beyoureyes/AssignAllergyFragment.kt @@ -1,73 +1,80 @@ package com.dna.beyoureyes import android.os.Bundle +import android.util.Log +import android.view.Gravity import androidx.fragment.app.Fragment import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.LinearLayout import com.dna.beyoureyes.databinding.FragmentAssignAllergyBinding -import com.dna.beyoureyes.databinding.FragmentAssignBirthBinding +import com.dna.beyoureyes.model.Allergen import com.dna.beyoureyes.ui.CustomToolbar import com.dna.beyoureyes.ui.FragmentNavigationListener import com.google.android.material.chip.Chip -// TODO: Rename parameter arguments, choose names that match -// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER -private const val ARG_PARAM1 = "param1" -private const val ARG_PARAM2 = "param2" -/** - * A simple [Fragment] subclass. - * Use the [AssignAllergyFragment.newInstance] factory method to - * create an instance of this fragment. - */ class AssignAllergyFragment : Fragment() { - // TODO: Rename and change types of parameters - private var param1: String? = null - private var param2: String? = null + private lateinit var binding : FragmentAssignAllergyBinding private var allergyArray : ArrayList = ArrayList() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - arguments?.let { - param1 = it.getString(ARG_PARAM1) - param2 = it.getString(ARG_PARAM2) - } - } + private var allergenSet : MutableSet = mutableSetOf() + private val chipIdToAllergenMap = HashMap() // 칩 ID와 Allergen Enum 값을 매핑하는 HashMap override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { + ): View { binding = FragmentAssignAllergyBinding.inflate(inflater, container, false) - binding.assignAllergyChipGroup.setOnCheckedStateChangeListener{ group, checkedIds -> - // "없음" 클릭 시 다른 칩 해제 - if (checkedIds.contains(R.id.chip_none)) { - for (chipId in group.checkedChipIds) { - if (chipId != R.id.chip_none) { - group.findViewById(chipId).isChecked = false - } + + Allergen.entries.forEach { alg -> + // 칩 스타일 및 표시 관련 설정 + val chip = Chip(context) + chip.text =if (alg.displayName.length == 1) " ${alg.displayName} " else alg.displayName + chip.isCheckable = true + chip.layoutParams = LinearLayout.LayoutParams( + resources.getDimensionPixelSize(R.dimen.checkable_chip_width), + resources.getDimensionPixelSize(R.dimen.checkable_chip_height) + ).also { it.gravity = Gravity.CENTER } + + // 칩 ID 할당 + chip.id = View.generateViewId() + chipIdToAllergenMap[chip.id] = alg // [칩 ID] - [알러지 정보] hashMap 등록 + + // 알레르기 칩 check 상태 변경 리스너 + chip.setOnCheckedChangeListener { _, isChecked -> + if(isChecked) { + allergenSet.add(alg) + binding.chipNone.isChecked = false // "없음" 칩 해제 + } else { + allergenSet.remove(alg) } - } - // 다른 칩 클릭 시 "없음" 해제 - else { - group.findViewById(R.id.chip_none)?.isChecked = false + Log.d("ASSIGN_ALLERGY", + "selected chips: ${allergenSet.joinToString(", ") { it.displayName }}") } - // 선택된 칩 리스트 업데이트 - allergyArray.clear() - for (chipId in group.checkedChipIds) { - val chip: Chip = group.findViewById(chipId) - allergyArray.add(resources.getResourceEntryName(chip.id).substring(5)) - } + // 그룹에 칩 추가 + binding.assignAllergyChipGroup.addView(chip) } + // 없음 칩 check 상태 변경 리스너 + val chipGroup = binding.assignAllergyChipGroup + binding.chipNone.setOnCheckedChangeListener { _, isChecked -> + if (isChecked) { + for (id in chipGroup.checkedChipIds.intersect(chipIdToAllergenMap.keys)){ + chipGroup.findViewById(id).isChecked = false // 선택된 알레르기 칩 해제 + } + allergenSet.clear() // 저장된 거 비우기 + Log.d("ASSIGN_ALLERGY", + "selected chips: ${allergenSet.joinToString(", ") { it.displayName }}") + } + } // Inflate the layout for this fragment val listener = activity as? FragmentNavigationListener binding.nextBtn.setOnClickListener { - listener?.onAllergyInputRecieved(allergyArray) + listener?.onAllergyInputRecieved(allergenSet) listener?.onBtnClick(this, true) } binding.toolbar.backButtonClickListener = object : CustomToolbar.ButtonClickListener { @@ -78,27 +85,4 @@ class AssignAllergyFragment : Fragment() { return binding.root } - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - } - - companion object { - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment AssignAllergyFragment. - */ - // TODO: Rename and change types and number of parameters - @JvmStatic - fun newInstance(param1: String, param2: String) = - AssignAllergyFragment().apply { - arguments = Bundle().apply { - putString(ARG_PARAM1, param1) - putString(ARG_PARAM2, param2) - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/dna/beyoureyes/AssignBirthFragment.kt b/app/src/main/java/com/dna/beyoureyes/AssignBirthFragment.kt index 748a038..556eea9 100644 --- a/app/src/main/java/com/dna/beyoureyes/AssignBirthFragment.kt +++ b/app/src/main/java/com/dna/beyoureyes/AssignBirthFragment.kt @@ -11,29 +11,11 @@ import com.dna.beyoureyes.ui.CustomToolbar import com.dna.beyoureyes.ui.FragmentNavigationListener import java.util.Calendar -// TODO: Rename parameter arguments, choose names that match -// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER -private const val ARG_PARAM1 = "param1" -private const val ARG_PARAM2 = "param2" - -/** - * A simple [Fragment] subclass. - * Use the [AssignBirthFragment.newInstance] factory method to - * create an instance of this fragment. - */ + class AssignBirthFragment : Fragment() { - // TODO: Rename and change types of parameters - private var param1: String? = null - private var param2: String? = null + private lateinit var binding : FragmentAssignBirthBinding private var birth = "" - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - arguments?.let { - param1 = it.getString(ARG_PARAM1) - param2 = it.getString(ARG_PARAM2) - } - } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -129,24 +111,4 @@ class AssignBirthFragment : Fragment() { return displayValues.toTypedArray() } - - companion object { - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment AssignBirthFragment. - */ - // TODO: Rename and change types and number of parameters - @JvmStatic - fun newInstance(param1: String, param2: String) = - AssignBirthFragment().apply { - arguments = Bundle().apply { - putString(ARG_PARAM1, param1) - putString(ARG_PARAM2, param2) - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/dna/beyoureyes/AssignDiseaseFragment.kt b/app/src/main/java/com/dna/beyoureyes/AssignDiseaseFragment.kt index c122ccb..64fa2bd 100644 --- a/app/src/main/java/com/dna/beyoureyes/AssignDiseaseFragment.kt +++ b/app/src/main/java/com/dna/beyoureyes/AssignDiseaseFragment.kt @@ -14,10 +14,6 @@ import com.dna.beyoureyes.ui.FragmentNavigationListener class AssignDiseaseFragment : Fragment() { private lateinit var binding : FragmentAssignDiseaseBinding private lateinit var diseaseArray: Array - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, diff --git a/app/src/main/java/com/dna/beyoureyes/AssignGenderFragment.kt b/app/src/main/java/com/dna/beyoureyes/AssignGenderFragment.kt index 5d9494c..fe6ce44 100644 --- a/app/src/main/java/com/dna/beyoureyes/AssignGenderFragment.kt +++ b/app/src/main/java/com/dna/beyoureyes/AssignGenderFragment.kt @@ -7,34 +7,12 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import com.dna.beyoureyes.databinding.FragmentAssignGenderBinding -import com.dna.beyoureyes.databinding.FragmentAssignNameBinding import com.dna.beyoureyes.ui.CustomToolbar import com.dna.beyoureyes.ui.FragmentNavigationListener -// TODO: Rename parameter arguments, choose names that match -// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER -private const val ARG_PARAM1 = "param1" -private const val ARG_PARAM2 = "param2" - -/** - * A simple [Fragment] subclass. - * Use the [AssignGenderFragment.newInstance] factory method to - * create an instance of this fragment. - */ class AssignGenderFragment : Fragment() { - // TODO: Rename and change types of parameters - private var param1: String? = null - private var param2: String? = null private lateinit var binding : FragmentAssignGenderBinding - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - arguments?.let { - param1 = it.getString(ARG_PARAM1) - param2 = it.getString(ARG_PARAM2) - } - } - override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -79,24 +57,4 @@ class AssignGenderFragment : Fragment() { else if(binding.chipMale.isChecked) return 1 else return -1 } - - companion object { - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment AssignGenderFragment. - */ - // TODO: Rename and change types and number of parameters - @JvmStatic - fun newInstance(param1: String, param2: String) = - AssignGenderFragment().apply { - arguments = Bundle().apply { - putString(ARG_PARAM1, param1) - putString(ARG_PARAM2, param2) - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/dna/beyoureyes/AssignNameFragment.kt b/app/src/main/java/com/dna/beyoureyes/AssignNameFragment.kt index 8a3b3b3..52ad69c 100644 --- a/app/src/main/java/com/dna/beyoureyes/AssignNameFragment.kt +++ b/app/src/main/java/com/dna/beyoureyes/AssignNameFragment.kt @@ -21,30 +21,11 @@ import com.dna.beyoureyes.ui.CustomToolbar import com.dna.beyoureyes.ui.FragmentNavigationListener import kotlinx.coroutines.launch -// TODO: Rename parameter arguments, choose names that match -// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER -private const val ARG_PARAM1 = "param1" -private const val ARG_PARAM2 = "param2" private var isDuplicateNickname = 0 -/** - * A simple [Fragment] subclass. - * Use the [AssignNameFragment.newInstance] factory method to - * create an instance of this fragment. - */ class AssignNameFragment : Fragment() { - // TODO: Rename and change types of parameters - private var param1: String? = null - private var param2: String? = null - private lateinit var binding: FragmentAssignNameBinding - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - arguments?.let { - param1 = it.getString(ARG_PARAM1) - param2 = it.getString(ARG_PARAM2) - } - } + private lateinit var binding: FragmentAssignNameBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -177,23 +158,4 @@ class AssignNameFragment : Fragment() { return binding.root } - companion object { - /** - * Use this factory method to create a new instance of - * this fragment using the provided parameters. - * - * @param param1 Parameter 1. - * @param param2 Parameter 2. - * @return A new instance of fragment AssignNameFragment. - */ - // TODO: Rename and change types and number of parameters - @JvmStatic - fun newInstance(param1: String, param2: String) = - AssignNameFragment().apply { - arguments = Bundle().apply { - putString(ARG_PARAM1, param1) - putString(ARG_PARAM2, param2) - } - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/dna/beyoureyes/model/Allergen.kt b/app/src/main/java/com/dna/beyoureyes/model/Allergen.kt new file mode 100644 index 0000000..5d8e75a --- /dev/null +++ b/app/src/main/java/com/dna/beyoureyes/model/Allergen.kt @@ -0,0 +1,26 @@ +package com.dna.beyoureyes.model + +// 총 19개 +// displayName은 칩에 표시할 한글명 +// ocrKeywords는 ocr 분석 시 검색할 키워드 정보(그간의 표시 기준 변화로 인해 여러 개의 키워드 고려 필요) +enum class Allergen(val displayName: String, val ocrKeywords: List) { + BUCKWHEAT("메밀", listOf("메밀")), + WHEAT("밀", listOf("밀")), + SOYBEAN("대두", listOf("대두")), + PEANUT("땅콩", listOf("땅콩")), + WALNUT("호두", listOf("호두")), + PINE_NUT("잣", listOf("잣")), + SULFUROUS_ACIDS("아황산류", listOf("아황산류")), + PEACH("복숭아", listOf("복숭아")), + TOMATO("토마토", listOf("토마토")), + EGGS("난류", listOf("난류", "계란")), // 가금류 한함 + MILK("우유", listOf("우유")), + SHRIMP("새우", listOf("새우")), + MACKEREL("고등어", listOf("고등어")), + SQUID("오징어", listOf("오징어")), + CRAB("게", listOf("게")), + SHELLFISH("조개류", listOf("조개류", "굴", "전복", "홍합")), // 굴, 전복, 홍합 포함 + PORK("돼지고기", listOf("돼지고기")), + BEEF("쇠고기", listOf("쇠고기")), + CHICKEN("닭고기", listOf("닭고기")) +} \ No newline at end of file diff --git a/app/src/main/java/com/dna/beyoureyes/model/FirebaseHelper.kt b/app/src/main/java/com/dna/beyoureyes/model/FirebaseHelper.kt index 9f5569d..ff46d25 100644 --- a/app/src/main/java/com/dna/beyoureyes/model/FirebaseHelper.kt +++ b/app/src/main/java/com/dna/beyoureyes/model/FirebaseHelper.kt @@ -67,9 +67,9 @@ class FirebaseHelper { val userGender = document.data.get("userGender") as Long val userBirth = document.data.get("userBirth") as Timestamp val userDisease = document.data.get("userDisease") as ArrayList - val userAllergy = document.data.get("userAllergy") as ArrayList + val userAllergens = document.data.get("userAllergens") as? ArrayList val profile = document.data.get("userProfile") as String? - AppUser.setInfo(userName, userGender.toInt(), userBirth, userDisease, userAllergy, profile) + AppUser.setInfo(userName, userGender.toInt(), userBirth, userDisease, userAllergens, profile) // 프로필 사진 uri 로드하여 저장 profile?.let{ diff --git a/app/src/main/java/com/dna/beyoureyes/model/Food.kt b/app/src/main/java/com/dna/beyoureyes/model/Food.kt index d40245a..e230f22 100644 --- a/app/src/main/java/com/dna/beyoureyes/model/Food.kt +++ b/app/src/main/java/com/dna/beyoureyes/model/Food.kt @@ -3,7 +3,7 @@ package com.dna.beyoureyes.model data class Food( private var _kcal:Int? = null, private var _nutritions: List?= null, - private var _allergy:Set?= null) { + private var _allergy:Set?= null) { val kcal get() = _kcal val nutritions get() = _nutritions @@ -14,9 +14,8 @@ data class Food( _nutritions?.forEach{ it.scaleQuantityByFactor(factor) } } - fun setAllergyData(algSet:Set?) { + fun setAllergyData(algSet:Set?) { _allergy = algSet } - } \ No newline at end of file diff --git a/app/src/main/java/com/dna/beyoureyes/model/UserInfo.kt b/app/src/main/java/com/dna/beyoureyes/model/UserInfo.kt index 3594bc2..aac7437 100644 --- a/app/src/main/java/com/dna/beyoureyes/model/UserInfo.kt +++ b/app/src/main/java/com/dna/beyoureyes/model/UserInfo.kt @@ -1,6 +1,7 @@ package com.dna.beyoureyes.model import android.net.Uri +import android.util.Log import com.dna.beyoureyes.NutrientDailyValues import com.google.firebase.Timestamp import com.google.firebase.firestore.QueryDocumentSnapshot @@ -19,7 +20,7 @@ class UserInfo ( var gender : Int, // 사용자 성별 var birth : Timestamp, // 사용자 생일 var disease : MutableSet, // 사용자 질병 정보(nullable - 해당사항 없을 수 있으므로) - var allergic : MutableSet, // 사용자 알레르기 정보(nullable - 해당사항 없을 수 있으므로 + var allergens : MutableSet?, // 사용자 알레르기 정보(nullable - 해당사항 없을 수 있으므로 var age : Int, var profileImgPath: String? = null // 프로필 사진 DB 저장 경로 ) { @@ -30,45 +31,26 @@ class UserInfo ( age = getAge(birth) } - constructor(name:String, gender:Int, birth: Timestamp, disease:ArrayList, allergy:ArrayList) - :this(name, gender, birth, disease.toMutableSet(), allergy.toMutableSet(), getAge(birth)) + // assign에서 활용하는 생성자(프로필 이미지 등록x) + constructor(name:String, gender:Int, birth: Timestamp, + disease:ArrayList, allergens: MutableSet?) + :this(name, gender, birth, disease.toMutableSet(), allergens, getAge(birth)) - constructor(name:String, gender:Int, birth: Timestamp, disease:ArrayList, allergy:ArrayList, profile:String) - :this(name, gender, birth, disease.toMutableSet(), allergy.toMutableSet(), getAge(birth), profile) + // firebase에서 데이터 불러올 때 활용하는 생성자(프로필 이미지 O 유효성 상관X) + constructor(name:String, gender:Int, birth: Timestamp, + disease:ArrayList, allergy:ArrayList, profile:String) + :this(name, gender, birth, disease.toMutableSet(), allergy.toAllergenSet(), getAge(birth), profile) + /* constructor(name:String, gender:Int, birth: Timestamp, profile: String) :this(name, gender, birth, mutableSetOf(), mutableSetOf(), getAge(birth), profile) + */ + fun setProfileImgUri(uri:Uri) { _profileImgUri = uri } - // 사용자 맞춤 권장량 정보를 제공하는 get 메소드 - fun getDailyValues() : NutrientDailyValues { - return NutrientDailyValues(gender, age, disease.toTypedArray()) - } - - fun hasDisease() : Boolean { - return disease.isNotEmpty() - } - - fun hasAllergy() : Boolean { - return allergic.isNotEmpty() - } - - fun getNutrisToCare() : Array { - val list = mutableListOf() - disease.forEach { - when (it) { - "고지혈증" -> list.addAll(arrayOf("지방", "포화지방", "콜레스테롤")) - "고혈압" -> list.addAll(arrayOf("나트륨", "포화지방", "콜레스테롤")) - "당뇨" -> list.addAll(arrayOf("당류", "콜레스테롤")) - } - } - val set = list.toSet() // 중복 없애기 - return set.toTypedArray() - } - fun getDailyEnergyRequirement(): Int { return if (gender == Gender.WOMAN.ordinal) { // 여성 when(age){ @@ -92,23 +74,22 @@ class UserInfo ( } } - fun findMatchingAllergy(foodAllergy: Set) : Set { - val engToKor = mutableMapOf( - "buckwheat" to "메밀", - "wheat" to "밀", - "bean" to "대두", - "peanut" to "땅콩", - "walnut" to "호두", - "pinenut" to "잣" , - "acid" to "아황산", - "peach" to "복숭아", - "tomato" to "토마토" - ) - return foodAllergy.intersect(allergic.mapNotNull { engToKor[it] }.toSet()) + fun findMatchingAllergy(foodAllergens: Set) : Set? { + return allergens?.intersect(foodAllergens) } companion object { + private fun ArrayList.toAllergenSet(): MutableSet? { + return this.mapNotNull { algName -> + try { + Allergen.valueOf(algName) + } catch (e: IllegalArgumentException) { + null + } + }.toMutableSet().ifEmpty { null } + } + fun getAge(birth: Timestamp) : Int { val calendar = Calendar.getInstance() val currentYear = calendar.get(Calendar.YEAR) @@ -127,6 +108,7 @@ class UserInfo ( } return age } + /* fun parseFirebaseDoc(document: QueryDocumentSnapshot) : UserInfo? { val name = document.data.get("userName") as? String val birth = document.data.get("userBirth") as? Timestamp @@ -148,5 +130,7 @@ class UserInfo ( } return null } + + */ } } \ No newline at end of file diff --git a/app/src/main/java/com/dna/beyoureyes/ui/FragmentNavigationListener.kt b/app/src/main/java/com/dna/beyoureyes/ui/FragmentNavigationListener.kt index a149964..7998729 100644 --- a/app/src/main/java/com/dna/beyoureyes/ui/FragmentNavigationListener.kt +++ b/app/src/main/java/com/dna/beyoureyes/ui/FragmentNavigationListener.kt @@ -1,6 +1,7 @@ package com.dna.beyoureyes.ui import androidx.fragment.app.Fragment +import com.dna.beyoureyes.model.Allergen interface FragmentNavigationListener { fun onNavigateToFragment(fragment: Fragment) @@ -9,5 +10,5 @@ interface FragmentNavigationListener { fun onGenderInputRecieved(gender : Int) fun onBirthInputRecieved(birth : String) fun onDiseaseInputRecieved(userDiseaseList : ArrayList) - fun onAllergyInputRecieved(userAllergyList : ArrayList) + fun onAllergyInputRecieved(userAllergySet : MutableSet) } \ No newline at end of file diff --git a/app/src/main/java/com/dna/beyoureyes/ui/foodAnalysis/FoodViewModel.kt b/app/src/main/java/com/dna/beyoureyes/ui/foodAnalysis/FoodViewModel.kt index c467e45..550682b 100644 --- a/app/src/main/java/com/dna/beyoureyes/ui/foodAnalysis/FoodViewModel.kt +++ b/app/src/main/java/com/dna/beyoureyes/ui/foodAnalysis/FoodViewModel.kt @@ -4,7 +4,6 @@ import android.net.Uri import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel -import androidx.lifecycle.map import com.dna.beyoureyes.AppUser import com.dna.beyoureyes.model.Food @@ -17,14 +16,6 @@ class FoodViewModel : ViewModel() { val capturedImageUri: LiveData = _capturedImageUri val processedImageUri: LiveData = _processedImageUri - /* - // foodData 라이브 데이터에 map을 활용하여 필요한 상세 정보를 아래와 같이 또 다른 라이브 데이터로 정의 가능 - // foodData의 알레르기 정보 중 유저 정보와의 교집합을 라이브 데이터로 정의한 예시. - val allergiesToAlert : LiveData?> = _foodData.map { food -> - food.allergy?.let{ AppUser.info?.findMatchingAllergy(it) } - } - */ - fun isCaptureSuccessful() : Boolean { return _capturedImageUri.value != null } diff --git a/app/src/main/java/com/dna/beyoureyes/ui/foodDetail/ResultAllergyCautionFragment.kt b/app/src/main/java/com/dna/beyoureyes/ui/foodDetail/ResultAllergyCautionFragment.kt index 401cdf7..af80c75 100644 --- a/app/src/main/java/com/dna/beyoureyes/ui/foodDetail/ResultAllergyCautionFragment.kt +++ b/app/src/main/java/com/dna/beyoureyes/ui/foodDetail/ResultAllergyCautionFragment.kt @@ -16,47 +16,31 @@ class ResultAllergyCautionFragment : Fragment() { private var _binding: FragmentResultAlgCautionBinding? = null private val binding get() = _binding!! private val viewModel: FoodViewModel by activityViewModels() - private val userAllergyData = AppUser.info?.allergic?: mutableSetOf() - private val detectedAllergyData = mutableSetOf() - val korToEng = mutableMapOf( - "메밀" to "buckwheat", - "밀" to "wheat", - "대두" to "bean", - "땅콩" to "peanut", - "호두" to "walnut", - "잣" to "pinenut", - "아황산" to "acid", - "복숭아" to "peach", - "토마토" to "tomato" - ) - val engToKor = korToEng.entries.associate { (key, value) -> value to key } - private var allergyCautionString = "" - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { + ): View { // Inflate the layout for this fragment _binding = FragmentResultAlgCautionBinding.inflate(inflater, container, false) viewModel.foodData.observe(viewLifecycleOwner) { food -> - food.allergy?.forEach { allergy -> - if (korToEng.containsKey(allergy)) { - detectedAllergyData.add(korToEng[allergy]!!) + food.allergy?.let { foodAlgs -> + AppUser.info?.findMatchingAllergy(foodAlgs)?.let { commonAlgs -> + binding.algCautionText2.text = buildString { + append("이 식품에 ") + append( + commonAlgs.joinToString(", "){ it.displayName } + .addSubjectMarker() // 조사 붙이기 + ) + append(" 함유되어 있어요") + } } } - val commonAllergies = userAllergyData.intersect(detectedAllergyData.toSet()) - val commonAllergyInKorean = commonAllergies.mapNotNull { engToKor[it] } - allergyCautionString = commonAllergyInKorean.joinToString(", ") - Log.d("Allergy Caution", "${detectedAllergyData} ${userAllergyData} ${commonAllergies}") - binding.algCautionText2.setText("이 식품에 ${allergyCautionString.addSubjectMarker()} 함유되어있어요") } - - binding.algCautionText1.setText(AppUser.info?.name + binding.algCautionText1.text) - + AppUser.info?.name?.let { userName -> + binding.algCautionText1.text = userName + binding.algCautionText1.text + } return binding.root } diff --git a/app/src/main/java/com/dna/beyoureyes/ui/foodDetail/ResultAllergyFragment.kt b/app/src/main/java/com/dna/beyoureyes/ui/foodDetail/ResultAllergyFragment.kt index 9f5cd61..4cd78a3 100644 --- a/app/src/main/java/com/dna/beyoureyes/ui/foodDetail/ResultAllergyFragment.kt +++ b/app/src/main/java/com/dna/beyoureyes/ui/foodDetail/ResultAllergyFragment.kt @@ -29,27 +29,24 @@ class ResultAllergyFragment : Fragment() { _binding = FragmentResultAlgBinding.inflate(inflater, container, false) viewModel.foodData.observe(viewLifecycleOwner) { food -> - food.allergy?.forEach { - Log.d("Allergy", "${it}") + food.allergy?.forEach { alg -> + // 칩 텍스트 및 사용자 조작 관련 설정 + val chip = Chip(context) + chip.text = + if (alg.displayName.length == 1) " ${alg.displayName} " // 한 글자면 width 설정 불가 + else alg.displayName + chip.isChecked = true // 클릭된 상태로 설정 + chip.isClickable = false // 클릭 불가능 - val chip = Chip(requireContext()) - chip.text = it - if (chip.text.length == 1) { - chip.text = " " + it + " " // 한글자인 경우에는 width 설정이 안됐음ㅜㅜ... - } - val params = LinearLayout.LayoutParams( + // 표시 관련 설정 + chip.layoutParams = LinearLayout.LayoutParams( resources.getDimensionPixelSize(R.dimen.chip_width), // 85dp resources.getDimensionPixelSize(R.dimen.chip_height) // 40dp - ) - params.gravity = Gravity.CENTER - chip.layoutParams = params - + ).also { params -> params.gravity = Gravity.CENTER } chip.setTextAppearanceResource(R.style.chipTextMyInfo) - chip.isChecked = true // 클릭된 상태로 설정 - chip.isClickable = false // 클릭 불가능 - //chip.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.blue_50)) chip.setChipBackgroundColorResource(R.color.blue_50) chip.setChipStrokeColorResource(R.color.blue_300) + binding.resultAlgChipGroup.addView(chip) } } diff --git a/app/src/main/java/com/dna/beyoureyes/ui/myInfo/FoodHistoryAdapter.kt b/app/src/main/java/com/dna/beyoureyes/ui/myInfo/FoodHistoryAdapter.kt index 9ca8209..6c3fb24 100644 --- a/app/src/main/java/com/dna/beyoureyes/ui/myInfo/FoodHistoryAdapter.kt +++ b/app/src/main/java/com/dna/beyoureyes/ui/myInfo/FoodHistoryAdapter.kt @@ -9,17 +9,13 @@ class FoodHistoryAdapter( private val onItemClickListener: (FoodHistory) -> Unit) : RecyclerView.Adapter() { - init { - sortItems() - } - // 뷰 홀더 생성 inner class FoodHistoryViewHolder(val historyView: FoodHistoryView) : RecyclerView.ViewHolder(historyView) { fun bind(history: FoodHistory) { historyView.setData(history.timestamp, history.kcal, history.imgUri) - historyView.setOnClickListener{ onItemClickListener(history) } + historyView.cardView.setOnClickListener{ onItemClickListener(history) } } } @@ -36,15 +32,4 @@ class FoodHistoryAdapter( override fun getItemCount() = items.size - // 데이터 업데이트 시 정렬 - fun updateItems(newItems: List) { - sortItems(newItems) - notifyDataSetChanged() - } - - // 데이터 정렬 - private fun sortItems(newItems: List = items) { - - } - } \ No newline at end of file diff --git a/app/src/main/java/com/dna/beyoureyes/ui/myInfo/FoodHistoryView.kt b/app/src/main/java/com/dna/beyoureyes/ui/myInfo/FoodHistoryView.kt index 64bcf10..3d0f4d2 100644 --- a/app/src/main/java/com/dna/beyoureyes/ui/myInfo/FoodHistoryView.kt +++ b/app/src/main/java/com/dna/beyoureyes/ui/myInfo/FoodHistoryView.kt @@ -6,6 +6,7 @@ import android.net.Uri import android.util.AttributeSet import android.util.Log import android.view.LayoutInflater +import android.widget.FrameLayout import android.widget.ImageView import android.widget.TextView import androidx.cardview.widget.CardView @@ -21,19 +22,20 @@ import java.text.SimpleDateFormat import java.util.Locale class FoodHistoryView(context: Context, attrs: AttributeSet?) : - CardView(context, attrs) { + FrameLayout(context, attrs) { // 뷰 컴포넌트들을 클래스 속성으로 정의 private val historyImg : ImageView private val historyLabel : TextView private val kcalTextView : TextView + val cardView: CardView init { // Bar View의 XML 레이아웃을 인플레이트 LayoutInflater.from(context).inflate(R.layout.food_history_item, this, true) // 레이아웃 파라미터 설정 layoutParams = ConstraintLayout.LayoutParams( - ConstraintLayout.LayoutParams.MATCH_PARENT, + ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT ) @@ -41,7 +43,7 @@ class FoodHistoryView(context: Context, attrs: AttributeSet?) : historyImg = findViewById(R.id.imageView) historyLabel = findViewById(R.id.label) kcalTextView = findViewById(R.id.kcal) - + cardView = findViewById(R.id.cardView) // attrs 입력값 속성 처리 attrs?.let{ diff --git a/app/src/main/java/com/dna/beyoureyes/ui/myInfo/MyInfoFragment.kt b/app/src/main/java/com/dna/beyoureyes/ui/myInfo/MyInfoFragment.kt index 8086a2b..aee1418 100644 --- a/app/src/main/java/com/dna/beyoureyes/ui/myInfo/MyInfoFragment.kt +++ b/app/src/main/java/com/dna/beyoureyes/ui/myInfo/MyInfoFragment.kt @@ -53,7 +53,8 @@ class MyInfoFragment : Fragment() { // 정의한 어댑터와 레이아웃 매니저를 식사 기록 리사이클러 뷰에 세팅 binding.historyRecyclerView.apply { - layoutManager = LinearLayoutManager(requireContext()) + layoutManager = LinearLayoutManager(requireContext(), + LinearLayoutManager.HORIZONTAL, false) adapter = foodHistoryAdapter } @@ -108,22 +109,9 @@ class MyInfoFragment : Fragment() { "highblood" to binding.highblood, "hyperlipidemia" to binding.hyperlipidemia ) - // 알레르기 성분 DB 필드명 -> 한글 성분명 맵 - val allergyMap = mapOf( - "buckwheat" to "메밀", - "wheat" to "밀", - "bean" to "대두", - "peanut" to "땅콩", - "walnut" to "호두", - "pinenut" to "잣", - "acid" to "아황산", - "peach" to "복숭아", - "tomato" to "토마토" - ) - // 사용자 질환, 알레르기 정보 가져오기 + // 사용자 질환 정보 가져오기 val userDiseases = AppUser.info?.disease?.toSet() ?: emptySet() - val userAllergy = AppUser.info?.allergic?.toSet() ?: emptySet() // 이름 설정 binding.profileName.setText(AppUser.info?.name?:"") @@ -149,33 +137,26 @@ class MyInfoFragment : Fragment() { binding.allergyChipGroup.layoutParams = layoutParams */ - // 알레르기 설정 - AppUser.info?.allergic?.forEach { - if (it != "none") { - val chip = Chip(requireContext()) - chip.text = allergyMap[it] - if (chip.text.length == 1) { - chip.text = " " + allergyMap[it] + " " // 한글자인 경우에는 width 설정이 안됐음ㅜㅜ... - } - val params = LinearLayout.LayoutParams( - resources.getDimensionPixelSize(R.dimen.chip_width), // 85dp - resources.getDimensionPixelSize(R.dimen.chip_height) // 40dp - ) - params.gravity = Gravity.CENTER - chip.layoutParams = params - - chip.setTextAppearanceResource(R.style.chipTextMyInfo) - chip.isChecked = true // 클릭된 상태로 설정 - chip.isClickable = false // 클릭 불가능 - //chip.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.blue_50)) - chip.setChipBackgroundColorResource(R.color.blue_50) - chip.setChipStrokeColorResource(R.color.blue_300) - binding.allergyChipGroup.addView(chip) - - chip.post { - Log.d("ChipWidth", "Chip ${chip.text} width: ${chip.width} px") - } - } + // 알레르기 칩 설정 + AppUser.info?.allergens?.forEach { alg -> + // 칩 텍스트 및 사용자 조작 관련 설정 + val chip = Chip(context) + chip.text = + if (alg.displayName.length == 1) " ${alg.displayName} " // 한 글자면 width 설정 불가 + else alg.displayName + chip.isChecked = true // 클릭된 상태로 설정 + chip.isClickable = false // 클릭 불가능 + + // 표시 관련 설정 + chip.layoutParams = LinearLayout.LayoutParams( + resources.getDimensionPixelSize(R.dimen.chip_width), // 85dp + resources.getDimensionPixelSize(R.dimen.chip_height) // 40dp + ).also { params -> params.gravity = Gravity.CENTER } + chip.setTextAppearanceResource(R.style.chipTextMyInfo) + chip.setChipBackgroundColorResource(R.color.blue_50) + chip.setChipStrokeColorResource(R.color.blue_300) + + binding.allergyChipGroup.addView(chip) // 칩 추가 } } diff --git a/app/src/main/java/com/dna/beyoureyes/userId.kt b/app/src/main/java/com/dna/beyoureyes/userId.kt index ef440a3..8d86291 100644 --- a/app/src/main/java/com/dna/beyoureyes/userId.kt +++ b/app/src/main/java/com/dna/beyoureyes/userId.kt @@ -17,22 +17,6 @@ object AppUser { var id : String? = null var info : UserInfo? = null - fun hasDisease() : Boolean { - info?.let { - return it.disease.isNotEmpty() - }?: run { - return false - } - } - - fun hasAllergy() : Boolean { - info?.let { - return it.allergic.isNotEmpty() - }?: run { - return false - } - } - fun setInfo(name : String, gender: Int, birth: Timestamp, disease : ArrayList?, allergy : ArrayList?, profile: String?) { val info = UserInfo(name, gender, birth, disease?: ArrayList(), allergy?:ArrayList(), profile?:"") this.info = info diff --git a/app/src/main/java/com/dna/beyoureyes/util/FoodTextRecognizer.kt b/app/src/main/java/com/dna/beyoureyes/util/FoodTextRecognizer.kt index d53fcb1..917933f 100644 --- a/app/src/main/java/com/dna/beyoureyes/util/FoodTextRecognizer.kt +++ b/app/src/main/java/com/dna/beyoureyes/util/FoodTextRecognizer.kt @@ -3,6 +3,7 @@ package com.dna.beyoureyes.util import android.content.Context import android.net.Uri import android.util.Log +import com.dna.beyoureyes.model.Allergen import com.dna.beyoureyes.model.Carbs import com.dna.beyoureyes.model.Cholesterol import com.dna.beyoureyes.model.Fat @@ -219,20 +220,21 @@ class FoodTextRecognizer(private val context: Context) { } // 알레르기 추출 함수 - private fun extractAllergyData(lines: List): Set? { - val targetWordsRegex = Regex(ALLERGY_KEYWORDS.joinToString("|")) // 정규식 생성 - + private fun extractAllergyData(lines: List): Set? { val targetEndIndex = lines.indexOfFirst { it.contains("함유") } // "함유" 위치 찾기 - if (targetEndIndex != -1) { - val targetLines = - lines.subList(maxOf(0, targetEndIndex - 1), lines.size) // 대상 줄 추출(바로 직전과 현재 line) - val extractedData = targetLines.flatMap { line -> - Log.d("Allergy", "Line : ${line}") - targetWordsRegex.findAll(line).map { it.value }.distinct() // 단어 추출 및 중복 제거 - }.toSet() - Log.d("Allergy", "${extractedData}") - return extractedData - } - return null + + if (targetEndIndex == -1) return null + val targetLines = + lines.subList(maxOf(0, targetEndIndex - 1), lines.size) + // "함유" 키워드가 존재하는 라인과 바로 직전 라인을 targetLines로 추출 + + // 추출값 저장할 Mutable Set + val extractedAllergens = targetLines.flatMap { line -> + Allergen.entries.filter { allergen -> + // Allergen Enum에 등록된 ocr 키워드를 필터링 조건으로 활용 + allergen.ocrKeywords.any { keyword -> line.contains(keyword) } + } + }.toSet() + return extractedAllergens } } \ No newline at end of file diff --git a/app/src/main/java/com/dna/beyoureyes/util/TTSManager.kt b/app/src/main/java/com/dna/beyoureyes/util/TTSManager.kt index 555701a..fc954ed 100644 --- a/app/src/main/java/com/dna/beyoureyes/util/TTSManager.kt +++ b/app/src/main/java/com/dna/beyoureyes/util/TTSManager.kt @@ -87,31 +87,37 @@ class TTSManager(context: Context) : } fun speakNutritionalInfo(food: Food) { - val calorieMsg: String? = food.kcal?.let {"해당 식품의 칼로리는 $it kcal 입니다. "} + val calorieMsg: String? = + food.kcal?.let {"해당 식품의 칼로리는 $it kcal 입니다. "} - val allergyMsg: String? = food.allergy?.let { - "해당 식품에는 ${it.joinToString(", ").addSubjectMarker()} 함유되어 있습니다. " - } - val commonAllergyMsg: String? = food.allergy?.let { foodAllergy -> - AppUser.info?.findMatchingAllergy(foodAllergy)?.let { commonAllergy -> // 인식 정보 O - if (commonAllergy.isEmpty()) { // 사용자 - 식품 알러지 교집합 X - "당신의 알러지 성분은 함유되어 있지 않네요. " - } else { // 사용자 - 식품 알러지 교집합 O - "주의하세요. 해당 식품에는 당신이 유의해야 할, ${commonAllergy.joinToString(", ").addSubjectMarker()} 함유되어 있습니다. " - } + val allergyMsg: String? = + food.allergy?.let { allergens -> + "해당 식품에는 ${allergens.joinToString(", ") + { it.displayName }.addSubjectMarker()} 함유되어 있습니다. " + } + + val commonAllergyMsg: String? = + food.allergy?.let { foodAllergy -> + AppUser.info?.findMatchingAllergy(foodAllergy)?.let { commonAllergy -> + "주의하세요. 해당 식품에는 당신이 유의해야 할, " + + commonAllergy.joinToString(", "){ + it.displayName + }.addSubjectMarker() + " 함유되어 있습니다. " // 사용자 - 식품 알러지 교집합 O + } ?:run { "당신의 알러지 성분은 함유되어 있지 않네요. " } // 사용자 - 식품 알러지 교집합 X } - } ?: run { null } // 인식 정보 X - val caloricNutrientMsg: String? = food.nutritions?.filterIsInstance() - ?.let { caloricNutris -> + val caloricNutrientMsg: String? = + food.nutritions?.filterIsInstance()?.let { caloricNutris -> val total = caloricNutris.sumOf { it.kcal } val percentTexts = caloricNutris.joinToString(", ") { "${it.name}이 ${(it.kcal.toDouble() / total.toDouble() * 100).toInt()}%" } "해당 식품의 에너지 성분 비율은 $percentTexts 입니다. " - }?: run { null } + }?: run { null } - val nutrientMsg: String? = food.nutritions?.joinToString(", ") - { nutri -> "${nutri.name}은 ${nutri.percentageOfDailyValue}" } + val nutrientMsg: String? = + food.nutritions?.joinToString(", ") { + nutri -> "${nutri.name}은 ${nutri.percentageOfDailyValue}" + } val analysisFailMsg: String? = if (food.allergy == null ) diff --git a/app/src/main/res/layout/food_history_item.xml b/app/src/main/res/layout/food_history_item.xml index d9ff2e7..b336da8 100644 --- a/app/src/main/res/layout/food_history_item.xml +++ b/app/src/main/res/layout/food_history_item.xml @@ -1,52 +1,59 @@ - + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@color/gray_50" + android:paddingEnd="16dp"> - - android:layout_width="match_parent" - android:layout_height="match_parent"> + + android:layout_width="match_parent" + android:layout_height="match_parent"> - + - - - \ No newline at end of file + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_assign_allergy.xml b/app/src/main/res/layout/fragment_assign_allergy.xml index a18bb87..d59aa00 100644 --- a/app/src/main/res/layout/fragment_assign_allergy.xml +++ b/app/src/main/res/layout/fragment_assign_allergy.xml @@ -83,6 +83,8 @@ android:layout_height="58dp" android:layout_marginBottom="60dp" android:text="@string/allergy_buckwheat" + android:visibility="gone" + tools:visibility="visible" android:textAlignment="center" android:textAppearance="@style/chipText" app:chipMinTouchTargetSize="0dp" /> @@ -93,6 +95,8 @@ android:layout_height="58dp" android:layout_marginBottom="60dp" android:text="@string/allergy_wheat" + android:visibility="gone" + tools:visibility="visible" android:textAlignment="center" android:textAppearance="@style/chipText" app:chipMinTouchTargetSize="0dp" /> @@ -103,69 +107,13 @@ android:layout_height="58dp" android:layout_marginBottom="60dp" android:text="@string/allergy_bean" + android:visibility="gone" + tools:visibility="visible" android:textAlignment="center" android:textAppearance="@style/chipText" app:chipMinTouchTargetSize="0dp" /> - - - - - - - - - - diff --git a/app/src/main/res/layout/fragment_my_info.xml b/app/src/main/res/layout/fragment_my_info.xml index d65bfe8..8ed280d 100644 --- a/app/src/main/res/layout/fragment_my_info.xml +++ b/app/src/main/res/layout/fragment_my_info.xml @@ -329,7 +329,6 @@ android:id="@+id/historyRecyclerView" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_marginEnd="16dp" android:orientation="horizontal" /> 85dp 40dp + 98dp + 58dp \ No newline at end of file