Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat : 1차 QA 반영 #225

Merged
merged 8 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
package com.dongyang.android.youdongknowme.standard.util

import android.app.Activity
import android.util.Log
import android.content.Context
import android.view.View
import android.view.inputmethod.InputMethodManager

fun View.showKeyboard(isForced: Boolean = false) {
val inputMethodManager = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.showSoftInput(this, if (isForced) InputMethodManager.SHOW_FORCED else InputMethodManager.SHOW_IMPLICIT)
val inputMethodManager =
context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.showSoftInput(
this,
if (isForced) InputMethodManager.SHOW_FORCED else InputMethodManager.SHOW_IMPLICIT
)
}

fun View.hideKeyboard() {
val inputMethodManager = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
val inputMethodManager =
context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
inputMethodManager.hideSoftInputFromWindow(windowToken, 0)
}

fun Int.dpToPx(context: Context): Int {
val density = context.resources.displayMetrics.density
return (this * density).toInt()
}


object ACTION {
const val FCM_ACTION_NAME = "com.google.firebase.MESSAGING_EVENT"
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ import android.annotation.SuppressLint
import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.dongyang.android.youdongknowme.R
import com.dongyang.android.youdongknowme.databinding.FragmentSearchBinding
import com.dongyang.android.youdongknowme.standard.base.BaseFragment
import com.dongyang.android.youdongknowme.standard.util.dpToPx
import com.dongyang.android.youdongknowme.ui.adapter.NoticeAdapter
import com.dongyang.android.youdongknowme.ui.view.detail.DetailActivity
import com.dongyang.android.youdongknowme.ui.view.util.EventObserver
Expand All @@ -24,8 +26,10 @@ class SearchFragment : BaseFragment<FragmentSearchBinding, SearchViewModel>() {
override val viewModel: SearchViewModel by viewModel()

private lateinit var adapter: NoticeAdapter
private var searchContent: String = ""

override fun initStartView() {
setupRecyclerViewMargin()
setupRecyclerview()
showKeyboardOnEditTextFocus()
setupHideKeyboardOnOutsideTouch()
Expand All @@ -43,17 +47,50 @@ class SearchFragment : BaseFragment<FragmentSearchBinding, SearchViewModel>() {

viewModel.searchNotices.observe(viewLifecycleOwner) { searchNotices ->
if (searchNotices.isNotEmpty()) {
setupRecyclerViewMargin()
adapter.submitList(searchNotices)

}
if (searchNotices.isNullOrEmpty()) {
setupRecyclerViewMargin()
}
}

viewModel.searchContent.observe(viewLifecycleOwner) { content ->
searchContent = content
}

viewModel.errorState.observe(viewLifecycleOwner, EventObserver { resId ->
showToast(getString(resId))
})

viewModel.noSearchResult.observe(viewLifecycleOwner) { noSearchResult ->
if (noSearchResult) {
binding.clSearchEmpty.visibility = View.VISIBLE
} else {
binding.clSearchEmpty.visibility = View.GONE
}
}
}

override fun initAfterBinding() = Unit

private fun setupRecyclerViewMargin() {
if (::adapter.isInitialized.not()) {
val marginDp = SEARCH_RESULT_RECYCLERVIEW_MARGIN_TOP_FOR_TOUCH
val marginPx = marginDp.dpToPx(requireContext())
val layoutParams = binding.rvSearchResult.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.topMargin = marginPx
binding.rvSearchResult.layoutParams = layoutParams
} else {
val marginDp = SEARCH_RESULT_RECYCLERVIEW_MARGIN_TOP_DEFAULT
val marginPx = marginDp.dpToPx(requireContext())
val layoutParams = binding.rvSearchResult.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.topMargin = marginPx
binding.rvSearchResult.layoutParams = layoutParams
}
}

private fun setupRecyclerview() {
adapter = NoticeAdapter(onItemClick = { url -> navigateToDetail(url) })
binding.rvSearchResult.apply {
Expand Down Expand Up @@ -109,7 +146,13 @@ class SearchFragment : BaseFragment<FragmentSearchBinding, SearchViewModel>() {
private fun onSearchBtnClickListener() {
binding.etSearchBar.setOnEditorActionListener { v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
viewModel.fetchSearchNotices()
if (validateSearchContentLength()) {
viewModel.fetchSearchNotices()
adapter.submitList(emptyList())
} else {
binding.etSearchBar.text.clear()
showToast(getString(R.string.search_minimum))
}
requireContext().hideKeyboard(binding.root)
true
} else {
Expand All @@ -118,6 +161,10 @@ class SearchFragment : BaseFragment<FragmentSearchBinding, SearchViewModel>() {
}
}

private fun validateSearchContentLength(): Boolean {
return searchContent.length >= SEARCH_CONTENT_MINIMUM_LENGTH
}

private fun navigateToDetail(url: String) {
val intent = DetailActivity.newIntent(requireContext(), url)
startActivity(intent)
Expand All @@ -138,4 +185,10 @@ class SearchFragment : BaseFragment<FragmentSearchBinding, SearchViewModel>() {
}
})
}

companion object {
private const val SEARCH_RESULT_RECYCLERVIEW_MARGIN_TOP_DEFAULT = 8
private const val SEARCH_RESULT_RECYCLERVIEW_MARGIN_TOP_FOR_TOUCH = 800
private const val SEARCH_CONTENT_MINIMUM_LENGTH = 2
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,17 @@ class SearchViewModel(
val isError: LiveData<Boolean> = _isError

private val _searchContent: MutableLiveData<String> = MutableLiveData()
private val searchContent: LiveData<String> = _searchContent
val searchContent: LiveData<String> = _searchContent

private val _searchClearVisibility: MutableLiveData<Boolean> = MutableLiveData()
val searchClearVisibility: LiveData<Boolean> get() = _searchClearVisibility

private val _myDepartment: MutableLiveData<String> = MutableLiveData()
val myDepartment: LiveData<String> = _myDepartment

private val _noSearchResult: MutableLiveData<Boolean> = MutableLiveData(false)
val noSearchResult: LiveData<Boolean> = _noSearchResult

private val _searchNotices: MutableLiveData<List<Notice>> = MutableLiveData()
val searchNotices: LiveData<List<Notice>> = _searchNotices

Expand Down Expand Up @@ -72,6 +75,7 @@ class SearchViewModel(
)) {
is NetworkResult.Success -> {
val updatedSearchResult = _searchNotices.value.orEmpty() + result.data
_noSearchResult.value = updatedSearchResult.isEmpty()
_searchNotices.postValue(updatedSearchResult)
_isError.postValue(false)
_isLoading.postValue(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class NoticeViewHolder(
noticeUrl = item.url

binding.tvNoticeTitle.text = item.title
binding.tvNoticeDate.text = item.date
binding.tvNoticeDate.text = item.date.replace("-", ".")
binding.tvNoticeAuthor.text = item.author
}
}
9 changes: 9 additions & 0 deletions app/src/main/res/drawable/ic_search_empty.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="26dp"
android:height="26dp"
android:viewportWidth="26"
android:viewportHeight="26">
<path
android:pathData="M24.759,22.691L19.246,17.178C20.573,15.411 21.29,13.26 21.288,11.05C21.288,5.405 16.695,0.813 11.05,0.813C5.405,0.813 0.813,5.405 0.813,11.05C0.813,16.695 5.405,21.288 11.05,21.288C13.26,21.29 15.411,20.573 17.178,19.246L22.691,24.759C22.97,25.009 23.334,25.142 23.708,25.131C24.082,25.121 24.438,24.968 24.703,24.703C24.968,24.438 25.121,24.082 25.131,23.708C25.142,23.334 25.009,22.97 24.759,22.691ZM3.737,11.05C3.737,9.604 4.166,8.19 4.97,6.987C5.773,5.785 6.915,4.848 8.252,4.294C9.588,3.741 11.058,3.596 12.477,3.878C13.895,4.16 15.198,4.857 16.221,5.879C17.243,6.902 17.94,8.205 18.222,9.623C18.504,11.042 18.359,12.512 17.806,13.848C17.252,15.185 16.315,16.327 15.113,17.13C13.91,17.934 12.496,18.362 11.05,18.362C9.111,18.36 7.253,17.589 5.882,16.218C4.511,14.847 3.74,12.989 3.737,11.05Z"
android:fillColor="#7F8295"/>
</vector>
62 changes: 41 additions & 21 deletions app/src/main/res/drawable/ic_symbol.xml
Original file line number Diff line number Diff line change
@@ -1,26 +1,46 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="512dp"
android:height="512dp"
android:viewportWidth="512"
android:viewportHeight="512">
android:width="100dp"
android:height="113dp"
android:viewportWidth="100"
android:viewportHeight="113">
<path
android:pathData="M35.33,36.33C35.33,33.57 37.57,31.33 40.33,31.33H79C81.76,31.33 84,33.57 84,36.33V76.33C84,79.09 81.76,81.33 79,81.33H40.33C37.57,81.33 35.33,79.09 35.33,76.33V36.33Z"
android:fillColor="#4967E1"
android:fillAlpha="0.9"/>
<path
android:pathData="M83.87,15.32L83.87,15.32A16.13,16.13 0,0 1,100 31.45L100,31.45A16.13,16.13 0,0 1,83.87 47.58L83.87,47.58A16.13,16.13 0,0 1,67.74 31.45L67.74,31.45A16.13,16.13 0,0 1,83.87 15.32z"
android:fillColor="#F7CE45"
android:fillAlpha="0.7"/>
<path
android:pathData="M0,5C0,2.24 2.24,0 5,0H18.39C34.96,0 48.39,13.43 48.39,30V32.21C48.39,48.78 34.96,62.21 18.39,62.21H5C2.24,62.21 0,59.97 0,57.21V5Z"
android:fillColor="#4967E1"
android:fillAlpha="0.58"/>
<group>
<clip-path
android:pathData="M0,0h512v512h-512z"/>
<group>
<clip-path
android:pathData="M512,0H0V512H512V0Z"/>
<path
android:pathData="M210.94,239.62C210.94,232.55 216.68,226.82 223.74,226.82H347.65C354.72,226.82 360.45,232.55 360.45,239.62V367.62C360.45,374.68 354.72,380.42 347.65,380.42H223.74C216.68,380.42 210.94,374.68 210.94,367.62V239.62Z"
android:fillColor="#4967E1"
android:fillAlpha="0.9"/>
<path
android:pathData="M360.05,177.63C332.68,177.63 310.5,199.81 310.5,227.18C310.5,254.54 332.68,276.73 360.05,276.73C387.42,276.73 409.6,254.54 409.6,227.18C409.6,199.81 387.42,177.63 360.05,177.63Z"
android:fillColor="#F7CE45"
android:fillAlpha="0.7"/>
<path
android:pathData="M102.4,143.36C102.4,136.29 108.13,130.56 115.2,130.56H174.24C216.66,130.56 251.04,164.95 251.04,207.36V244.88C251.04,287.29 216.66,321.67 174.24,321.67H115.2C108.13,321.67 102.4,315.95 102.4,308.87V143.36Z"
android:fillColor="#4967E1"
android:fillAlpha="0.5"/>
</group>
android:pathData="M0,97.33h100v14.71h-100z"/>
<path
android:pathData="M1.47,97.33C0.66,97.33 0,97.99 0,98.8V110.57C0,111.38 0.66,112.04 1.47,112.04H10.29C12.73,112.04 14.71,110.06 14.71,107.63V101.75C14.71,99.31 12.73,97.33 10.29,97.33H1.47ZM3.68,100.27C3.27,100.27 2.94,100.6 2.94,101.01V108.36C2.94,108.77 3.27,109.1 3.68,109.1H9.56C10.78,109.1 11.76,108.11 11.76,106.89V102.48C11.76,101.26 10.78,100.27 9.56,100.27H3.68Z"
android:fillColor="#36373F"
android:fillType="evenOdd"/>
<path
android:pathData="M17.06,100.27C17.06,98.65 18.38,97.33 20,97.33H22.94C23.33,97.33 23.69,97.41 24.03,97.54C24.27,97.64 24.55,97.64 24.79,97.54C25.13,97.41 25.5,97.33 25.88,97.33H28.82C30.45,97.33 31.76,98.65 31.76,100.27V111.01C31.76,111.58 31.3,112.04 30.74,112.04H29.85C29.28,112.04 28.82,111.58 28.82,111.01V101.01C28.82,100.6 28.49,100.27 28.09,100.27H26.62C26.21,100.27 25.88,100.6 25.88,101.01V111.01C25.88,111.58 25.42,112.04 24.85,112.04H23.97C23.4,112.04 22.94,111.58 22.94,111.01V101.01C22.94,100.6 22.61,100.27 22.21,100.27H20.74C20.33,100.27 20,100.6 20,101.01V111.01C20,111.58 19.54,112.04 18.97,112.04H18.09C17.52,112.04 17.06,111.58 17.06,111.01V100.27Z"
android:fillColor="#36373F"
android:fillType="evenOdd"/>
<path
android:pathData="M54.12,97.33C52.49,97.33 51.18,98.65 51.18,100.27V109.1C51.18,110.72 52.49,112.04 54.12,112.04H62.94C64.57,112.04 65.88,110.72 65.88,109.1V100.27C65.88,98.65 64.57,97.33 62.94,97.33H54.12ZM55.59,100.27C54.78,100.27 54.12,100.93 54.12,101.75V107.63C54.12,108.44 54.78,109.1 55.59,109.1H61.47C62.28,109.1 62.94,108.44 62.94,107.63V101.75C62.94,100.93 62.28,100.27 61.47,100.27H55.59Z"
android:fillColor="#36373F"
android:fillType="evenOdd"/>
<path
android:pathData="M34.12,100.27C34.12,98.65 35.43,97.33 37.06,97.33H47.79C48.36,97.33 48.82,97.79 48.82,98.36V99.25C48.82,99.81 48.36,100.27 47.79,100.27H38.09C37.52,100.27 37.06,100.74 37.06,101.3V111.01C37.06,111.58 36.6,112.04 36.03,112.04H35.15C34.58,112.04 34.12,111.58 34.12,111.01V100.27ZM38.53,104.54C38.53,105.11 38.99,105.57 39.56,105.57H46.91C47.48,105.57 47.94,105.11 47.94,104.54V103.66C47.94,103.09 47.48,102.63 46.91,102.63H39.56C38.99,102.63 38.53,103.09 38.53,103.66V104.54Z"
android:fillColor="#36373F"
android:fillType="evenOdd"/>
<path
android:pathData="M85.29,98.36C85.29,97.79 85.75,97.33 86.32,97.33H87.21C87.77,97.33 88.24,97.79 88.24,98.36V108.07C88.24,108.64 88.7,109.1 89.26,109.1H96.03C96.6,109.1 97.06,108.64 97.06,108.07V98.36C97.06,97.79 97.52,97.33 98.09,97.33H98.97C99.54,97.33 100,97.79 100,98.36V109.1C100,110.72 98.68,112.04 97.06,112.04H88.24C86.61,112.04 85.29,110.72 85.29,109.1V98.36Z"
android:fillColor="#36373F"
android:fillType="evenOdd"/>
<path
android:pathData="M69.26,97.33C68.7,97.33 68.24,97.79 68.24,98.36V105.13V111.01C68.24,111.58 68.7,112.04 69.26,112.04H70.15C70.72,112.04 71.18,111.58 71.18,111.01V106.89C71.18,106.49 71.51,106.16 71.91,106.16H74.82C74.97,106.16 75.1,106.24 75.2,106.34L80.52,111.66C80.93,112.07 81.58,112.07 81.98,111.66L82.6,111.04C83.01,110.64 83.01,109.99 82.6,109.58L79.76,106.74C79.54,106.52 79.7,106.16 80,106.16C81.62,106.16 82.94,104.84 82.94,103.22V100.27C82.94,98.65 81.62,97.33 80,97.33H70.15H69.26ZM71.76,100.27C71.44,100.27 71.18,100.54 71.18,100.86V102.63C71.18,102.95 71.44,103.22 71.76,103.22H78.97C79.54,103.22 80,102.75 80,102.19V101.3C80,100.74 79.54,100.27 78.97,100.27H71.76Z"
android:fillColor="#36373F"
android:fillType="evenOdd"/>
</group>
</vector>
22 changes: 7 additions & 15 deletions app/src/main/res/layout/activity_splash.xml
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto">
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.view.splash.SplashActivity">

<ImageView
android:id="@+id/iv_splash_symbol"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/ic_symbol"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ImageView
android:id="@+id/iv_splash_text_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_logo_text"
android:src="@drawable/ic_symbol"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_splash_symbol" />
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
43 changes: 43 additions & 0 deletions app/src/main/res/layout/fragment_search.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,48 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_search_bar"
tools:listitem="@layout/item_notice" />

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/cl_search_empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cl_search_bar">

<ImageView
android:id="@+id/iv_search_empty"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/ic_search_empty"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/tv_search_no_result"
style="@style/PretendardSemiBold20"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/search_no_result"
android:textColor="@color/gray500"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_search_empty" />

<TextView
style="@style/PretendardMedium16"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/search_another_search"
android:textColor="@color/gray400"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_search_no_result" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,7 @@

<!-- search -->
<string name="search_hint">검색어를 입력하세요.</string>
<string name="search_no_result">검색 결과를 찾을 수 없어요</string>
<string name="search_another_search">다른 키워드로 검색해보세요.</string>
<string name="search_minimum">2글자 이상 입력해야 합니다.</string>
</resources>
Loading