콘텐츠 메인

- 채널 검색 추가
This commit is contained in:
2025-01-09 03:54:02 +09:00
parent d00a5475ce
commit 2667e29bb9
4 changed files with 225 additions and 0 deletions

View File

@@ -48,6 +48,7 @@ import kr.co.vividnext.sodalive.explorer.ExplorerSectionAdapter
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
import kr.co.vividnext.sodalive.explorer.profile.series.UserProfileSeriesListAdapter
import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.main.MainActivity
import kr.co.vividnext.sodalive.mypage.alarm.AlarmListActivity
import kr.co.vividnext.sodalive.settings.event.EventDetailActivity
import kr.co.vividnext.sodalive.settings.notification.MemberRole
@@ -149,6 +150,10 @@ class AudioContentMainFragment : BaseFragment<FragmentAudioContentMainBinding>(
)
)
}
binding.flSearchChannel.setOnClickListener {
(requireActivity() as MainActivity).showSearchBar()
}
}
private fun setupCreatorRank() {

View File

@@ -1,6 +1,7 @@
package kr.co.vividnext.sodalive.main
import android.Manifest
import android.app.Service
import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
@@ -8,11 +9,14 @@ import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.content.res.ColorStateList
import android.graphics.Rect
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.activity.addCallback
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat
import androidx.media3.common.MediaItem
@@ -21,12 +25,17 @@ import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.session.MediaController
import androidx.media3.session.SessionToken
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.transform.RoundedCornersTransformation
import com.google.firebase.messaging.FirebaseMessaging
import com.gun0912.tedpermission.PermissionListener
import com.gun0912.tedpermission.normal.TedPermission
import com.jakewharton.rxbinding4.widget.textChanges
import com.orhanobut.logger.Logger
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.schedulers.Schedulers
import kr.co.vividnext.sodalive.R
import kr.co.vividnext.sodalive.audio_content.AudioContentPlayService
import kr.co.vividnext.sodalive.audio_content.detail.AudioContentDetailActivity
@@ -40,19 +49,26 @@ import kr.co.vividnext.sodalive.common.LoadingDialog
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
import kr.co.vividnext.sodalive.databinding.ActivityMainBinding
import kr.co.vividnext.sodalive.databinding.ItemMainTabBinding
import kr.co.vividnext.sodalive.explorer.ExplorerViewModel
import kr.co.vividnext.sodalive.explorer.profile.UserProfileActivity
import kr.co.vividnext.sodalive.extensions.dpToPx
import kr.co.vividnext.sodalive.live.LiveFragment
import kr.co.vividnext.sodalive.message.MessageFragment
import kr.co.vividnext.sodalive.message.SelectMessageRecipientAdapter
import kr.co.vividnext.sodalive.mypage.MyPageFragment
import kr.co.vividnext.sodalive.settings.event.EventDetailActivity
import kr.co.vividnext.sodalive.settings.notification.NotificationSettingsDialog
import org.koin.android.ext.android.inject
import java.util.concurrent.TimeUnit
@UnstableApi
class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::inflate) {
private val viewModel: MainViewModel by inject()
private val explorerViewModel: ExplorerViewModel by inject()
private lateinit var searchChannelAdapter: SelectMessageRecipientAdapter
private lateinit var imm: InputMethodManager
private lateinit var liveFragment: LiveFragment
private lateinit var loadingDialog: LoadingDialog
@@ -61,6 +77,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
private var mediaController: MediaController? = null
private val handler = Handler(Looper.getMainLooper())
private val audioContentReceiver = AudioContentReceiver()
private var isShowSearchBar = false
private val preferenceChangeListener =
SharedPreferences.OnSharedPreferenceChangeListener { sharedPreferences, key ->
@@ -174,6 +191,10 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
imm = getSystemService(
Service.INPUT_METHOD_SERVICE
) as InputMethodManager
checkPermissions()
pushTokenUpdate()
gaidUpdate()
@@ -189,6 +210,15 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
}
handler.postDelayed({ executeDeeplink(intent) }, 500)
onBackPressedDispatcher.addCallback {
if (isShowSearchBar) {
hideSearchBar()
} else {
isEnabled = false
onBackPressedDispatcher.onBackPressed()
}
}
}
override fun onDestroy() {
@@ -239,6 +269,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
}
setupBottomTabLayout()
setupSearchChannelView()
}
private fun executeDeeplink(intent: Intent) {
@@ -497,6 +528,96 @@ class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::infl
}
}
private fun setupSearchChannelView() {
searchChannelAdapter = SelectMessageRecipientAdapter {
hideKeyboard()
val intent = Intent(applicationContext, UserProfileActivity::class.java)
intent.putExtra(Constants.EXTRA_USER_ID, it.id)
startActivity(intent)
}
binding.rvSearchChannel.layoutManager = LinearLayoutManager(
this,
LinearLayoutManager.VERTICAL,
false
)
binding.rvSearchChannel.addItemDecoration(object : RecyclerView.ItemDecoration() {
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
outRect.left = 13.3f.dpToPx().toInt()
outRect.right = 13.3f.dpToPx().toInt()
outRect.top = 13.3f.dpToPx().toInt()
outRect.bottom = 13.3f.dpToPx().toInt()
}
})
binding.rvSearchChannel.adapter = searchChannelAdapter
compositeDisposable.add(
binding.etSearchChannel.textChanges().skip(1)
.debounce(500, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe {
if (it.length >= 2) {
explorerViewModel.searchChannel(it.toString())
binding.rvSearchChannel.visibility = View.VISIBLE
binding.tvResultX.visibility = View.GONE
} else {
binding.rvSearchChannel.visibility = View.GONE
binding.tvResultX.visibility = View.VISIBLE
}
}
)
explorerViewModel.searchChannelLiveData.observe(this) {
searchChannelAdapter.items.clear()
if (it.isNotEmpty()) {
searchChannelAdapter.items.addAll(it)
binding.rvSearchChannel.visibility = View.VISIBLE
binding.tvResultX.visibility = View.GONE
} else {
binding.rvSearchChannel.visibility = View.GONE
binding.tvResultX.visibility = View.VISIBLE
}
searchChannelAdapter.notifyDataSetChanged()
}
}
private fun hideKeyboard() {
handler.postDelayed({
imm.hideSoftInputFromWindow(
window.decorView.applicationWindowToken,
InputMethodManager.HIDE_NOT_ALWAYS
)
}, 100)
}
private fun hideSearchBar() {
isShowSearchBar = false
binding.nsSearch.visibility = View.GONE
binding.etSearchChannel.setText("")
}
fun showSearchBar() {
isShowSearchBar = true
binding.nsSearch.visibility = View.VISIBLE
binding.etSearchChannel.setText("")
binding.etSearchChannel.requestFocus()
binding.etSearchChannel.post {
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(binding.etSearchChannel, InputMethodManager.SHOW_IMPLICIT)
}
}
inner class AudioContentReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val contentId = intent?.getLongExtra(Constants.EXTRA_AUDIO_CONTENT_ID, 0)