2019-06-09 16:55:34 +02:00
|
|
|
/* Copyright 2019 Joel Pyska
|
|
|
|
*
|
|
|
|
* This file is a part of Tusky.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
|
|
|
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
|
|
|
* License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
|
|
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
|
|
* Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License along with Tusky; if not,
|
|
|
|
* see <http://www.gnu.org/licenses>. */
|
|
|
|
|
|
|
|
package com.keylesspalace.tusky.components.report.fragments
|
|
|
|
|
|
|
|
import android.os.Bundle
|
|
|
|
import android.view.View
|
|
|
|
import androidx.core.app.ActivityOptionsCompat
|
|
|
|
import androidx.core.view.ViewCompat
|
|
|
|
import androidx.fragment.app.Fragment
|
2020-12-27 21:25:35 +01:00
|
|
|
import androidx.fragment.app.activityViewModels
|
2021-06-20 10:58:19 +02:00
|
|
|
import androidx.lifecycle.lifecycleScope
|
|
|
|
import androidx.paging.LoadState
|
2019-10-22 21:18:20 +02:00
|
|
|
import androidx.preference.PreferenceManager
|
2019-06-09 16:55:34 +02:00
|
|
|
import androidx.recyclerview.widget.DividerItemDecoration
|
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
|
|
|
import androidx.recyclerview.widget.SimpleItemAnimator
|
|
|
|
import com.google.android.material.snackbar.Snackbar
|
|
|
|
import com.keylesspalace.tusky.R
|
2022-02-25 18:57:31 +01:00
|
|
|
import com.keylesspalace.tusky.StatusListActivity
|
2019-06-09 16:55:34 +02:00
|
|
|
import com.keylesspalace.tusky.ViewMediaActivity
|
2022-01-11 19:55:17 +01:00
|
|
|
import com.keylesspalace.tusky.components.account.AccountActivity
|
2019-06-09 16:55:34 +02:00
|
|
|
import com.keylesspalace.tusky.components.report.ReportViewModel
|
|
|
|
import com.keylesspalace.tusky.components.report.Screen
|
|
|
|
import com.keylesspalace.tusky.components.report.adapter.AdapterHandler
|
|
|
|
import com.keylesspalace.tusky.components.report.adapter.StatusesAdapter
|
2021-03-13 21:27:20 +01:00
|
|
|
import com.keylesspalace.tusky.databinding.FragmentReportStatusesBinding
|
2019-06-09 16:55:34 +02:00
|
|
|
import com.keylesspalace.tusky.db.AccountManager
|
|
|
|
import com.keylesspalace.tusky.di.Injectable
|
|
|
|
import com.keylesspalace.tusky.di.ViewModelFactory
|
|
|
|
import com.keylesspalace.tusky.entity.Attachment
|
|
|
|
import com.keylesspalace.tusky.entity.Status
|
2020-12-23 19:13:37 +01:00
|
|
|
import com.keylesspalace.tusky.settings.PrefKeys
|
2020-10-25 18:36:00 +01:00
|
|
|
import com.keylesspalace.tusky.util.CardViewMode
|
|
|
|
import com.keylesspalace.tusky.util.StatusDisplayOptions
|
2021-03-13 21:27:20 +01:00
|
|
|
import com.keylesspalace.tusky.util.viewBinding
|
2021-06-20 10:58:19 +02:00
|
|
|
import com.keylesspalace.tusky.util.visible
|
2019-06-09 16:55:34 +02:00
|
|
|
import com.keylesspalace.tusky.viewdata.AttachmentViewData
|
2021-06-20 10:58:19 +02:00
|
|
|
import kotlinx.coroutines.flow.collectLatest
|
|
|
|
import kotlinx.coroutines.launch
|
2019-06-09 16:55:34 +02:00
|
|
|
import javax.inject.Inject
|
|
|
|
|
2020-12-27 21:25:35 +01:00
|
|
|
class ReportStatusesFragment : Fragment(R.layout.fragment_report_statuses), Injectable, AdapterHandler {
|
2019-06-09 16:55:34 +02:00
|
|
|
|
|
|
|
@Inject
|
|
|
|
lateinit var viewModelFactory: ViewModelFactory
|
|
|
|
|
|
|
|
@Inject
|
|
|
|
lateinit var accountManager: AccountManager
|
|
|
|
|
2020-12-27 21:25:35 +01:00
|
|
|
private val viewModel: ReportViewModel by activityViewModels { viewModelFactory }
|
2019-06-09 16:55:34 +02:00
|
|
|
|
2021-03-13 21:27:20 +01:00
|
|
|
private val binding by viewBinding(FragmentReportStatusesBinding::bind)
|
|
|
|
|
2019-06-09 16:55:34 +02:00
|
|
|
private lateinit var adapter: StatusesAdapter
|
|
|
|
|
|
|
|
private var snackbarErrorRetry: Snackbar? = null
|
|
|
|
|
|
|
|
override fun showMedia(v: View?, status: Status?, idx: Int) {
|
|
|
|
status?.actionableStatus?.let { actionable ->
|
|
|
|
when (actionable.attachments[idx].type) {
|
2019-09-08 19:35:43 +02:00
|
|
|
Attachment.Type.GIFV, Attachment.Type.VIDEO, Attachment.Type.IMAGE, Attachment.Type.AUDIO -> {
|
2019-06-09 16:55:34 +02:00
|
|
|
val attachments = AttachmentViewData.list(actionable)
|
2021-06-20 10:58:19 +02:00
|
|
|
val intent = ViewMediaActivity.newIntent(context, attachments, idx)
|
2019-06-09 16:55:34 +02:00
|
|
|
if (v != null) {
|
|
|
|
val url = actionable.attachments[idx].url
|
|
|
|
ViewCompat.setTransitionName(v, url)
|
2021-06-20 10:58:19 +02:00
|
|
|
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(requireActivity(), v, url)
|
2019-06-09 16:55:34 +02:00
|
|
|
startActivity(intent, options.toBundle())
|
|
|
|
} else {
|
|
|
|
startActivity(intent)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Attachment.Type.UNKNOWN -> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
|
|
handleClicks()
|
|
|
|
initStatusesView()
|
|
|
|
setupSwipeRefreshLayout()
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun setupSwipeRefreshLayout() {
|
2021-03-13 21:27:20 +01:00
|
|
|
binding.swipeRefreshLayout.setColorSchemeResources(R.color.tusky_blue)
|
2019-06-09 16:55:34 +02:00
|
|
|
|
2021-03-13 21:27:20 +01:00
|
|
|
binding.swipeRefreshLayout.setOnRefreshListener {
|
2019-06-09 16:55:34 +02:00
|
|
|
snackbarErrorRetry?.dismiss()
|
2021-06-20 10:58:19 +02:00
|
|
|
adapter.refresh()
|
2019-06-09 16:55:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun initStatusesView() {
|
|
|
|
val preferences = PreferenceManager.getDefaultSharedPreferences(requireContext())
|
2019-12-30 21:37:20 +01:00
|
|
|
val statusDisplayOptions = StatusDisplayOptions(
|
2021-06-28 21:13:24 +02:00
|
|
|
animateAvatars = false,
|
|
|
|
mediaPreviewEnabled = accountManager.activeAccount?.mediaPreviewEnabled ?: true,
|
|
|
|
useAbsoluteTime = preferences.getBoolean("absoluteTimeView", false),
|
|
|
|
showBotOverlay = false,
|
|
|
|
useBlurhash = preferences.getBoolean("useBlurhash", true),
|
|
|
|
cardViewMode = CardViewMode.NONE,
|
|
|
|
confirmReblogs = preferences.getBoolean("confirmReblogs", true),
|
2021-12-29 13:44:00 +01:00
|
|
|
confirmFavourites = preferences.getBoolean("confirmFavourites", false),
|
2021-06-28 21:13:24 +02:00
|
|
|
hideStats = preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false),
|
|
|
|
animateEmojis = preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false)
|
2019-12-30 21:37:20 +01:00
|
|
|
)
|
|
|
|
|
2021-06-20 10:58:19 +02:00
|
|
|
adapter = StatusesAdapter(statusDisplayOptions, viewModel.statusViewState, this)
|
2019-06-09 16:55:34 +02:00
|
|
|
|
2021-03-13 21:27:20 +01:00
|
|
|
binding.recyclerView.addItemDecoration(DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL))
|
|
|
|
binding.recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
|
|
|
binding.recyclerView.adapter = adapter
|
|
|
|
(binding.recyclerView.itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
|
2019-06-09 16:55:34 +02:00
|
|
|
|
2021-06-20 10:58:19 +02:00
|
|
|
lifecycleScope.launch {
|
|
|
|
viewModel.statusesFlow.collectLatest { pagingData ->
|
|
|
|
adapter.submitData(pagingData)
|
|
|
|
}
|
2020-10-25 18:36:00 +01:00
|
|
|
}
|
2019-06-09 16:55:34 +02:00
|
|
|
|
2021-06-20 10:58:19 +02:00
|
|
|
adapter.addLoadStateListener { loadState ->
|
2021-06-28 21:13:24 +02:00
|
|
|
if (loadState.refresh is LoadState.Error ||
|
|
|
|
loadState.append is LoadState.Error ||
|
|
|
|
loadState.prepend is LoadState.Error
|
|
|
|
) {
|
2021-06-20 10:58:19 +02:00
|
|
|
showError()
|
|
|
|
}
|
2019-06-09 16:55:34 +02:00
|
|
|
|
2021-06-20 10:58:19 +02:00
|
|
|
binding.progressBarBottom.visible(loadState.append == LoadState.Loading)
|
|
|
|
binding.progressBarTop.visible(loadState.prepend == LoadState.Loading)
|
|
|
|
binding.progressBarLoading.visible(loadState.refresh == LoadState.Loading && !binding.swipeRefreshLayout.isRefreshing)
|
2019-06-09 16:55:34 +02:00
|
|
|
|
2021-06-20 10:58:19 +02:00
|
|
|
if (loadState.refresh != LoadState.Loading) {
|
2021-03-13 21:27:20 +01:00
|
|
|
binding.swipeRefreshLayout.isRefreshing = false
|
2021-06-20 10:58:19 +02:00
|
|
|
}
|
2020-10-25 18:36:00 +01:00
|
|
|
}
|
2019-06-09 16:55:34 +02:00
|
|
|
}
|
|
|
|
|
2021-06-20 10:58:19 +02:00
|
|
|
private fun showError() {
|
2019-06-09 16:55:34 +02:00
|
|
|
if (snackbarErrorRetry?.isShown != true) {
|
2021-03-13 21:27:20 +01:00
|
|
|
snackbarErrorRetry = Snackbar.make(binding.swipeRefreshLayout, R.string.failed_fetch_statuses, Snackbar.LENGTH_INDEFINITE)
|
2019-06-09 16:55:34 +02:00
|
|
|
snackbarErrorRetry?.setAction(R.string.action_retry) {
|
2021-06-20 10:58:19 +02:00
|
|
|
adapter.retry()
|
2019-06-09 16:55:34 +02:00
|
|
|
}
|
|
|
|
snackbarErrorRetry?.show()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun handleClicks() {
|
2021-03-13 21:27:20 +01:00
|
|
|
binding.buttonCancel.setOnClickListener {
|
2019-06-09 16:55:34 +02:00
|
|
|
viewModel.navigateTo(Screen.Back)
|
|
|
|
}
|
|
|
|
|
2021-03-13 21:27:20 +01:00
|
|
|
binding.buttonContinue.setOnClickListener {
|
2019-08-17 09:08:58 +02:00
|
|
|
viewModel.navigateTo(Screen.Note)
|
2019-06-09 16:55:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun setStatusChecked(status: Status, isChecked: Boolean) {
|
|
|
|
viewModel.setStatusChecked(status, isChecked)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun isStatusChecked(id: String): Boolean {
|
|
|
|
return viewModel.isStatusChecked(id)
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onViewAccount(id: String) = startActivity(AccountActivity.getIntent(requireContext(), id))
|
|
|
|
|
2022-02-25 18:57:31 +01:00
|
|
|
override fun onViewTag(tag: String) = startActivity(StatusListActivity.newHashtagIntent(requireContext(), tag))
|
2019-06-09 16:55:34 +02:00
|
|
|
|
2022-02-25 18:57:31 +01:00
|
|
|
override fun onViewUrl(url: String) = viewModel.checkClickedUrl(url)
|
2019-06-09 16:55:34 +02:00
|
|
|
|
|
|
|
companion object {
|
|
|
|
fun newInstance() = ReportStatusesFragment()
|
|
|
|
}
|
|
|
|
}
|