mirror of
https://github.com/mihonapp/mihon.git
synced 2024-12-25 02:18:24 +01:00
Tracking sheet and search adjustments (#5427)
* Tracking sheet and search visual adjustments * Remove track item divider * Add start margin to "add tracking" button * Fix track search dialog crash when no item chosen * Show "remove" action only when track item is previously set * Remove placeholder for total chapters * Cleanups * Add track search error/empty result message * Make track search dialog fullscreen * Use AutofitRecyclerView for track search dialog * Fix text input overlapping * Run track search from IME action instead * Remove deprecated method * Reformat * Set track search error message on the placeholder * Use payload to notify track search item change * Fix track search action icon tint color
This commit is contained in:
parent
7e3ea9074c
commit
cb71d44024
@ -1118,8 +1118,7 @@ class MangaController :
|
||||
|
||||
fun onTrackingSearchResultsError(error: Throwable) {
|
||||
Timber.e(error)
|
||||
activity?.toast(error.message)
|
||||
getTrackingSearchDialog()?.onSearchResultsError()
|
||||
getTrackingSearchDialog()?.onSearchResultsError(error.message)
|
||||
}
|
||||
|
||||
private fun getTrackingSearchDialog(): TrackSearchDialog? {
|
||||
|
@ -4,6 +4,8 @@ import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.databinding.TrackItemBinding
|
||||
import eu.kanade.tachiyomi.util.view.applyElevationOverlay
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class TrackAdapter(listener: OnClickListener) : RecyclerView.Adapter<TrackHolder>() {
|
||||
|
||||
@ -29,6 +31,7 @@ class TrackAdapter(listener: OnClickListener) : RecyclerView.Adapter<TrackHolder
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TrackHolder {
|
||||
binding = TrackItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
binding.card.applyElevationOverlay()
|
||||
return TrackHolder(binding, this)
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.manga.track
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.databinding.TrackItemBinding
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
@ -37,38 +38,64 @@ class TrackHolder(private val binding: TrackItemBinding, adapter: TrackAdapter)
|
||||
fun bind(item: TrackItem) {
|
||||
val track = item.track
|
||||
binding.trackLogo.setImageResource(item.service.getLogo())
|
||||
binding.logoContainer.setBackgroundColor(item.service.getLogoColor())
|
||||
binding.logoContainer.setCardBackgroundColor(item.service.getLogoColor())
|
||||
|
||||
binding.trackSet.isVisible = track == null
|
||||
binding.trackTitle.isVisible = track != null
|
||||
|
||||
binding.topDivider.isVisible = track != null
|
||||
binding.middleRow.isVisible = track != null
|
||||
binding.bottomDivider.isVisible = track != null
|
||||
binding.bottomRow.isVisible = track != null
|
||||
|
||||
binding.card.isVisible = track != null
|
||||
|
||||
if (track != null) {
|
||||
val ctx = binding.trackTitle.context
|
||||
binding.trackTitle.text = track.title
|
||||
binding.trackChapters.text = "${track.last_chapter_read}/" +
|
||||
if (track.total_chapters > 0) track.total_chapters else "-"
|
||||
binding.trackChapters.text = track.last_chapter_read.toString()
|
||||
if (track.total_chapters > 0) {
|
||||
binding.trackChapters.text = "${binding.trackChapters.text} / ${track.total_chapters}"
|
||||
}
|
||||
binding.trackStatus.text = item.service.getStatus(track.status)
|
||||
|
||||
if (item.service.getScoreList().isEmpty()) {
|
||||
binding.trackScore.isVisible = false
|
||||
binding.vertDivider2.isVisible = false
|
||||
} else {
|
||||
binding.trackScore.text = if (track.score == 0f) "-" else item.service.displayScore(track)
|
||||
val supportsScoring = item.service.getScoreList().isNotEmpty()
|
||||
if (supportsScoring) {
|
||||
if (track.score != 0F) {
|
||||
item.service.getScoreList()
|
||||
binding.trackScore.text = item.service.displayScore(track)
|
||||
binding.trackScore.alpha = SET_STATUS_TEXT_ALPHA
|
||||
} else {
|
||||
binding.trackScore.text = ctx.getString(R.string.score)
|
||||
binding.trackScore.alpha = UNSET_STATUS_TEXT_ALPHA
|
||||
}
|
||||
}
|
||||
binding.trackScore.isVisible = supportsScoring
|
||||
binding.vertDivider2.isVisible = supportsScoring
|
||||
|
||||
if (item.service.supportsReadingDates) {
|
||||
binding.trackStartDate.text =
|
||||
if (track.started_reading_date != 0L) dateFormat.format(track.started_reading_date) else "-"
|
||||
binding.trackFinishDate.text =
|
||||
if (track.finished_reading_date != 0L) dateFormat.format(track.finished_reading_date) else "-"
|
||||
} else {
|
||||
binding.bottomDivider.isVisible = false
|
||||
binding.bottomRow.isVisible = false
|
||||
val supportsReadingDates = item.service.supportsReadingDates
|
||||
if (supportsReadingDates) {
|
||||
if (track.started_reading_date != 0L) {
|
||||
binding.trackStartDate.text = dateFormat.format(track.started_reading_date)
|
||||
binding.trackStartDate.alpha = SET_STATUS_TEXT_ALPHA
|
||||
} else {
|
||||
binding.trackStartDate.text = ctx.getString(R.string.track_started_reading_date)
|
||||
binding.trackStartDate.alpha = UNSET_STATUS_TEXT_ALPHA
|
||||
}
|
||||
if (track.finished_reading_date != 0L) {
|
||||
binding.trackFinishDate.text = dateFormat.format(track.finished_reading_date)
|
||||
binding.trackFinishDate.alpha = SET_STATUS_TEXT_ALPHA
|
||||
} else {
|
||||
binding.trackFinishDate.text = ctx.getString(R.string.track_finished_reading_date)
|
||||
binding.trackFinishDate.alpha = UNSET_STATUS_TEXT_ALPHA
|
||||
}
|
||||
}
|
||||
binding.bottomDivider.isVisible = supportsReadingDates
|
||||
binding.bottomRow.isVisible = supportsReadingDates
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SET_STATUS_TEXT_ALPHA = 1F
|
||||
private const val UNSET_STATUS_TEXT_ALPHA = 0.5F
|
||||
}
|
||||
}
|
||||
|
@ -1,76 +1,57 @@
|
||||
package eu.kanade.tachiyomi.ui.manga.track
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.core.view.isVisible
|
||||
import coil.clear
|
||||
import coil.load
|
||||
import eu.kanade.tachiyomi.R
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import eu.kanade.tachiyomi.databinding.TrackSearchItemBinding
|
||||
import eu.kanade.tachiyomi.util.view.inflate
|
||||
import eu.kanade.tachiyomi.util.view.applyElevationOverlay
|
||||
|
||||
class TrackSearchAdapter(context: Context) :
|
||||
ArrayAdapter<TrackSearch>(context, R.layout.track_search_item, mutableListOf<TrackSearch>()) {
|
||||
class TrackSearchAdapter(
|
||||
private val currentTrackUrl: String?,
|
||||
private val onSelectionChanged: (TrackSearch?) -> Unit
|
||||
) : RecyclerView.Adapter<TrackSearchHolder>() {
|
||||
var selectedItemPosition = -1
|
||||
set(value) {
|
||||
if (field != value) {
|
||||
val previousPosition = field
|
||||
field = value
|
||||
// Just notify the now-unselected item
|
||||
notifyItemChanged(previousPosition, UncheckPayload)
|
||||
onSelectionChanged(items.getOrNull(value))
|
||||
}
|
||||
}
|
||||
|
||||
override fun getView(position: Int, view: View?, parent: ViewGroup): View {
|
||||
var v = view
|
||||
// Get the data item for this position
|
||||
val track = getItem(position)!!
|
||||
// Check if an existing view is being reused, otherwise inflate the view
|
||||
val holder: TrackSearchHolder // view lookup cache stored in tag
|
||||
if (v == null) {
|
||||
v = parent.inflate(R.layout.track_search_item)
|
||||
holder = TrackSearchHolder(v)
|
||||
v.tag = holder
|
||||
var items = emptyList<TrackSearch>()
|
||||
set(value) {
|
||||
if (field != value) {
|
||||
field = value
|
||||
selectedItemPosition = value.indexOfFirst { it.tracking_url == currentTrackUrl }
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = items.size
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TrackSearchHolder {
|
||||
val binding = TrackSearchItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||
binding.container.applyElevationOverlay()
|
||||
return TrackSearchHolder(binding, this)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: TrackSearchHolder, position: Int) {
|
||||
holder.bind(items[position], position)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: TrackSearchHolder, position: Int, payloads: MutableList<Any>) {
|
||||
if (payloads.getOrNull(0) == UncheckPayload) {
|
||||
holder.setUnchecked()
|
||||
} else {
|
||||
holder = v.tag as TrackSearchHolder
|
||||
super.onBindViewHolder(holder, position, payloads)
|
||||
}
|
||||
holder.onSetValues(track)
|
||||
return v
|
||||
}
|
||||
|
||||
fun setItems(syncs: List<TrackSearch>) {
|
||||
setNotifyOnChange(false)
|
||||
clear()
|
||||
addAll(syncs)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
class TrackSearchHolder(private val view: View) {
|
||||
|
||||
private val binding = TrackSearchItemBinding.bind(view)
|
||||
|
||||
fun onSetValues(track: TrackSearch) {
|
||||
binding.trackSearchTitle.text = track.title
|
||||
binding.trackSearchSummary.text = track.summary
|
||||
binding.trackSearchCover.clear()
|
||||
if (track.cover_url.isNotEmpty()) {
|
||||
binding.trackSearchCover.load(track.cover_url)
|
||||
}
|
||||
|
||||
val hasStatus = track.publishing_status.isNotBlank()
|
||||
binding.trackSearchStatus.isVisible = hasStatus
|
||||
binding.trackSearchStatusResult.isVisible = hasStatus
|
||||
if (hasStatus) {
|
||||
binding.trackSearchStatusResult.text = track.publishing_status.capitalize()
|
||||
}
|
||||
|
||||
val hasType = track.publishing_type.isNotBlank()
|
||||
binding.trackSearchType.isVisible = hasType
|
||||
binding.trackSearchTypeResult.isVisible = hasType
|
||||
if (hasType) {
|
||||
binding.trackSearchTypeResult.text = track.publishing_type.capitalize()
|
||||
}
|
||||
|
||||
val hasStartDate = track.start_date.isNotBlank()
|
||||
binding.trackSearchStart.isVisible = hasStartDate
|
||||
binding.trackSearchStartResult.isVisible = hasStartDate
|
||||
if (hasStartDate) {
|
||||
binding.trackSearchStartResult.text = track.start_date
|
||||
}
|
||||
}
|
||||
companion object {
|
||||
private object UncheckPayload
|
||||
}
|
||||
}
|
||||
|
@ -2,29 +2,31 @@ package eu.kanade.tachiyomi.ui.manga.track
|
||||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.appcompat.app.AppCompatDialog
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.isVisible
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.customview.customView
|
||||
import dev.chrisbanes.insetter.applyInsetter
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.database.models.Track
|
||||
import eu.kanade.tachiyomi.data.track.TrackManager
|
||||
import eu.kanade.tachiyomi.data.track.TrackService
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import eu.kanade.tachiyomi.databinding.TrackSearchDialogBinding
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaController
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import eu.kanade.tachiyomi.util.view.setNavigationBarTransparentCompat
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import reactivecircus.flowbinding.android.widget.itemClicks
|
||||
import reactivecircus.flowbinding.android.widget.textChanges
|
||||
import reactivecircus.flowbinding.android.widget.editorActionEvents
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class TrackSearchDialog : DialogController {
|
||||
|
||||
@ -32,59 +34,130 @@ class TrackSearchDialog : DialogController {
|
||||
|
||||
private var adapter: TrackSearchAdapter? = null
|
||||
|
||||
private var selectedItem: Track? = null
|
||||
|
||||
private val service: TrackService
|
||||
private val currentTrackUrl: String?
|
||||
|
||||
private val trackController
|
||||
get() = targetController as MangaController
|
||||
|
||||
constructor(target: MangaController, service: TrackService) : super(
|
||||
bundleOf(KEY_SERVICE to service.id)
|
||||
) {
|
||||
private lateinit var currentlySearched: String
|
||||
|
||||
constructor(
|
||||
target: MangaController,
|
||||
_service: TrackService,
|
||||
_currentTrackUrl: String?
|
||||
) : super(bundleOf(KEY_SERVICE to _service.id, KEY_CURRENT_URL to _currentTrackUrl)) {
|
||||
targetController = target
|
||||
this.service = service
|
||||
service = _service
|
||||
currentTrackUrl = _currentTrackUrl
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
constructor(bundle: Bundle) : super(bundle) {
|
||||
service = Injekt.get<TrackManager>().getService(bundle.getInt(KEY_SERVICE))!!
|
||||
currentTrackUrl = bundle.getString(KEY_CURRENT_URL)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
override fun onCreateDialog(savedViewState: Bundle?): Dialog {
|
||||
binding = TrackSearchDialogBinding.inflate(LayoutInflater.from(activity!!))
|
||||
val dialog = MaterialDialog(activity!!)
|
||||
.customView(view = binding!!.root)
|
||||
.positiveButton(android.R.string.ok) { onPositiveButtonClick() }
|
||||
.negativeButton(android.R.string.cancel)
|
||||
.neutralButton(R.string.action_remove) { onRemoveButtonClick() }
|
||||
|
||||
onViewCreated(dialog.view, savedViewState)
|
||||
|
||||
return dialog
|
||||
}
|
||||
|
||||
fun onViewCreated(view: View, savedState: Bundle?) {
|
||||
// Create adapter
|
||||
val adapter = TrackSearchAdapter(view.context)
|
||||
this.adapter = adapter
|
||||
binding!!.trackSearchList.adapter = adapter
|
||||
|
||||
// Set listeners
|
||||
selectedItem = null
|
||||
|
||||
binding!!.trackSearchList.itemClicks()
|
||||
.onEach { position ->
|
||||
selectedItem = adapter.getItem(position)
|
||||
// Toolbar stuff
|
||||
binding!!.toolbar.setNavigationOnClickListener { dialog?.dismiss() }
|
||||
binding!!.toolbar.setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.done -> {
|
||||
val adapter = adapter ?: return@setOnMenuItemClickListener true
|
||||
val item = adapter.items.getOrNull(adapter.selectedItemPosition)
|
||||
if (item != null) {
|
||||
trackController.presenter.registerTracking(item, service)
|
||||
dialog?.dismiss()
|
||||
}
|
||||
}
|
||||
R.id.remove -> {
|
||||
trackController.presenter.unregisterTracking(service)
|
||||
dialog?.dismiss()
|
||||
}
|
||||
}
|
||||
.launchIn(trackController.viewScope)
|
||||
true
|
||||
}
|
||||
binding!!.toolbar.menu.findItem(R.id.remove).isVisible = currentTrackUrl != null
|
||||
|
||||
// Create adapter
|
||||
adapter = TrackSearchAdapter(currentTrackUrl) { which ->
|
||||
binding!!.toolbar.menu.findItem(R.id.done).isEnabled = which != null
|
||||
}
|
||||
binding!!.trackSearchRecyclerview.adapter = adapter
|
||||
|
||||
// Do an initial search based on the manga's title
|
||||
if (savedState == null) {
|
||||
val title = trackController.presenter.manga.title
|
||||
binding!!.trackSearch.append(title)
|
||||
search(title)
|
||||
if (savedViewState == null) {
|
||||
currentlySearched = trackController.presenter.manga.title
|
||||
binding!!.titleInput.editText?.append(currentlySearched)
|
||||
}
|
||||
search(currentlySearched)
|
||||
|
||||
// Input listener
|
||||
binding?.titleInput?.editText
|
||||
?.editorActionEvents {
|
||||
when (it.actionId) {
|
||||
EditorInfo.IME_ACTION_SEARCH -> {
|
||||
true
|
||||
}
|
||||
else -> {
|
||||
it.keyEvent?.action == KeyEvent.ACTION_DOWN && it.keyEvent?.keyCode == KeyEvent.KEYCODE_ENTER
|
||||
}
|
||||
}
|
||||
}
|
||||
?.filter { it.view.text.isNotBlank() }
|
||||
?.onEach {
|
||||
val query = it.view.text.toString()
|
||||
if (query != currentlySearched) {
|
||||
currentlySearched = query
|
||||
search(it.view.text.toString())
|
||||
it.view.context.getSystemService<InputMethodManager>()?.hideSoftInputFromWindow(it.view.windowToken, 0)
|
||||
it.view.clearFocus()
|
||||
}
|
||||
}
|
||||
?.launchIn(trackController.viewScope)
|
||||
|
||||
// Edge to edge
|
||||
binding!!.appbar.applyInsetter {
|
||||
type(navigationBars = true, statusBars = true) {
|
||||
padding(left = true, top = true, right = true)
|
||||
}
|
||||
}
|
||||
binding!!.titleInput.applyInsetter {
|
||||
type(navigationBars = true) {
|
||||
margin(horizontal = true)
|
||||
}
|
||||
}
|
||||
binding!!.progress.applyInsetter {
|
||||
type(navigationBars = true) {
|
||||
margin()
|
||||
}
|
||||
}
|
||||
binding!!.message.applyInsetter {
|
||||
type(navigationBars = true) {
|
||||
margin()
|
||||
}
|
||||
}
|
||||
binding!!.trackSearchRecyclerview.applyInsetter {
|
||||
type(navigationBars = true) {
|
||||
padding(vertical = true)
|
||||
margin(horizontal = true)
|
||||
}
|
||||
}
|
||||
|
||||
return AppCompatDialog(activity!!, R.style.ThemeOverlay_Tachiyomi_Dialog_Fullscreen).apply {
|
||||
setContentView(binding!!.root)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttach(view: View) {
|
||||
super.onAttach(view)
|
||||
dialog?.window?.let { window ->
|
||||
window.setNavigationBarTransparentCompat(window.context)
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,46 +167,39 @@ class TrackSearchDialog : DialogController {
|
||||
adapter = null
|
||||
}
|
||||
|
||||
override fun onAttach(view: View) {
|
||||
super.onAttach(view)
|
||||
binding!!.trackSearch.textChanges()
|
||||
.debounce(TimeUnit.SECONDS.toMillis(1))
|
||||
.filter { it.isNotBlank() }
|
||||
.onEach { search(it.toString()) }
|
||||
.launchIn(trackController.viewScope)
|
||||
}
|
||||
|
||||
private fun search(query: String) {
|
||||
val binding = binding ?: return
|
||||
binding.progress.isVisible = true
|
||||
binding.trackSearchList.isVisible = false
|
||||
binding.trackSearchRecyclerview.isVisible = false
|
||||
binding.message.isVisible = false
|
||||
trackController.presenter.trackingSearch(query, service)
|
||||
}
|
||||
|
||||
fun onSearchResults(results: List<TrackSearch>) {
|
||||
selectedItem = null
|
||||
val binding = binding ?: return
|
||||
binding.progress.isVisible = false
|
||||
binding.trackSearchList.isVisible = true
|
||||
adapter?.setItems(results)
|
||||
|
||||
val emptyResult = results.isEmpty()
|
||||
adapter?.items = results
|
||||
binding.trackSearchRecyclerview.isVisible = !emptyResult
|
||||
binding.trackSearchRecyclerview.scrollToPosition(0)
|
||||
binding.message.isVisible = emptyResult
|
||||
if (emptyResult) {
|
||||
binding.message.text = binding.message.context.getString(R.string.no_results_found)
|
||||
}
|
||||
}
|
||||
|
||||
fun onSearchResultsError() {
|
||||
fun onSearchResultsError(message: String?) {
|
||||
val binding = binding ?: return
|
||||
binding.progress.isVisible = false
|
||||
binding.trackSearchList.isVisible = false
|
||||
adapter?.setItems(emptyList())
|
||||
}
|
||||
|
||||
private fun onPositiveButtonClick() {
|
||||
trackController.presenter.registerTracking(selectedItem, service)
|
||||
}
|
||||
|
||||
private fun onRemoveButtonClick() {
|
||||
trackController.presenter.unregisterTracking(service)
|
||||
binding.trackSearchRecyclerview.isVisible = false
|
||||
binding.message.isVisible = true
|
||||
binding.message.text = message ?: binding.message.context.getString(R.string.unknown_error)
|
||||
adapter?.items = emptyList()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val KEY_SERVICE = "service_id"
|
||||
const val KEY_CURRENT_URL = "current_url"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,61 @@
|
||||
package eu.kanade.tachiyomi.ui.manga.track
|
||||
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import coil.clear
|
||||
import coil.load
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
import eu.kanade.tachiyomi.databinding.TrackSearchItemBinding
|
||||
import eu.kanade.tachiyomi.util.view.setMaxLinesAndEllipsize
|
||||
import java.util.Locale
|
||||
|
||||
class TrackSearchHolder(
|
||||
private val binding: TrackSearchItemBinding,
|
||||
private val adapter: TrackSearchAdapter
|
||||
) : RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(track: TrackSearch, position: Int) {
|
||||
binding.container.isChecked = position == adapter.selectedItemPosition
|
||||
binding.container.setOnClickListener {
|
||||
adapter.selectedItemPosition = position
|
||||
binding.container.isChecked = true
|
||||
}
|
||||
|
||||
binding.trackSearchTitle.text = track.title
|
||||
binding.trackSearchCover.clear()
|
||||
if (track.cover_url.isNotEmpty()) {
|
||||
binding.trackSearchCover.load(track.cover_url)
|
||||
}
|
||||
|
||||
val hasStatus = track.publishing_status.isNotBlank()
|
||||
binding.trackSearchStatus.isVisible = hasStatus
|
||||
binding.trackSearchStatusResult.isVisible = hasStatus
|
||||
if (hasStatus) {
|
||||
binding.trackSearchStatusResult.text = track.publishing_status.lowercase().replaceFirstChar {
|
||||
it.titlecase(Locale.getDefault())
|
||||
}
|
||||
}
|
||||
|
||||
val hasType = track.publishing_type.isNotBlank()
|
||||
binding.trackSearchType.isVisible = hasType
|
||||
binding.trackSearchTypeResult.isVisible = hasType
|
||||
if (hasType) {
|
||||
binding.trackSearchTypeResult.text = track.publishing_type.lowercase().replaceFirstChar {
|
||||
it.titlecase(Locale.getDefault())
|
||||
}
|
||||
}
|
||||
|
||||
val hasStartDate = track.start_date.isNotBlank()
|
||||
binding.trackSearchStart.isVisible = hasStartDate
|
||||
binding.trackSearchStartResult.isVisible = hasStartDate
|
||||
if (hasStartDate) {
|
||||
binding.trackSearchStartResult.text = track.start_date
|
||||
}
|
||||
|
||||
binding.trackSearchSummary.setMaxLinesAndEllipsize()
|
||||
binding.trackSearchSummary.text = track.summary
|
||||
}
|
||||
|
||||
fun setUnchecked() {
|
||||
binding.container.isChecked = false
|
||||
}
|
||||
}
|
@ -96,7 +96,8 @@ class TrackSheet(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
TrackSearchDialog(controller, item.service).showDialog(controller.router, TAG_SEARCH_CONTROLLER)
|
||||
TrackSearchDialog(controller, item.service, item.track?.tracking_url)
|
||||
.showDialog(controller.router, TAG_SEARCH_CONTROLLER)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.util.lang.truncateCenter
|
||||
import timber.log.Timber
|
||||
import uy.kohesive.injekt.api.get
|
||||
import java.io.File
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
|
@ -4,10 +4,12 @@ package eu.kanade.tachiyomi.util.view
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Point
|
||||
import android.text.TextUtils
|
||||
import android.view.Gravity
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.MenuRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.appcompat.view.menu.MenuBuilder
|
||||
@ -16,12 +18,17 @@ import androidx.appcompat.widget.TooltipCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.forEach
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.google.android.material.chip.Chip
|
||||
import com.google.android.material.chip.ChipGroup
|
||||
import com.google.android.material.elevation.ElevationOverlayProvider
|
||||
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
/**
|
||||
* Returns coordinates of view.
|
||||
@ -174,3 +181,21 @@ inline fun ChipGroup.setChips(
|
||||
addView(chip)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies elevation overlay to a MaterialCardView
|
||||
*/
|
||||
inline fun MaterialCardView.applyElevationOverlay() {
|
||||
if (Injekt.get<PreferencesHelper>().isDarkMode()) {
|
||||
val provider = ElevationOverlayProvider(context)
|
||||
setCardBackgroundColor(provider.compositeOverlay(cardBackgroundColor.defaultColor, cardElevation))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets TextView max lines dynamically. Can only be called when the view is already laid out.
|
||||
*/
|
||||
inline fun TextView.setMaxLinesAndEllipsize(_ellipsize: TextUtils.TruncateAt = TextUtils.TruncateAt.END) = post {
|
||||
maxLines = (measuredHeight - paddingTop - paddingBottom) / lineHeight
|
||||
ellipsize = _ellipsize
|
||||
}
|
||||
|
6
app/src/main/res/anim/fade_in_short.xml
Normal file
6
app/src/main/res/anim/fade_in_short.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:duration="100"
|
||||
android:fromAlpha="0.0"
|
||||
android:interpolator="@android:interpolator/linear"
|
||||
android:toAlpha="1.0" />
|
6
app/src/main/res/anim/fade_out_short.xml
Normal file
6
app/src/main/res/anim/fade_out_short.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:duration="100"
|
||||
android:fromAlpha="1.0"
|
||||
android:interpolator="@android:interpolator/linear"
|
||||
android:toAlpha="0.0" />
|
@ -5,6 +5,5 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingVertical="8dp"
|
||||
tools:listitem="@layout/track_item" />
|
||||
|
@ -1,192 +1,194 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<LinearLayout 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"
|
||||
android:id="@+id/track"
|
||||
style="@style/Widget.Tachiyomi.CardView.Item"
|
||||
android:padding="0dp">
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:paddingVertical="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/logo_container"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:foreground="?attr/selectableItemBackground"
|
||||
app:cardBackgroundColor="#2E51A2"
|
||||
app:cardElevation="0dp"
|
||||
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MaterialCardView.Tracker">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/track_logo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:importantForAccessibility="no"
|
||||
android:padding="4dp"
|
||||
tools:src="@drawable/ic_tracker_mal" />
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/logo_container"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="match_parent"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:padding="4dp"
|
||||
tools:background="#2E51A2">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/track_logo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:src="@drawable/ic_tracker_mal" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
<Button
|
||||
android:id="@+id/track_set"
|
||||
style="?attr/borderlessButtonStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<Button
|
||||
android:id="@+id/track_set"
|
||||
style="?attr/borderlessButtonStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text="@string/add_tracking"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_title"
|
||||
style="@style/TextAppearance.Regular.Body1.Secondary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/list_item_selector"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:padding="16dp"
|
||||
tools:text="Title" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/top_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?android:divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/middle_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="16dp"
|
||||
android:text="@string/add_tracking"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_status"
|
||||
style="@style/TextAppearance.Regular.Body1.Secondary"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/list_item_selector"
|
||||
android:id="@+id/track_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:foreground="?attr/selectableItemBackgroundBorderless"
|
||||
android:gravity="center_vertical"
|
||||
android:maxLines="1"
|
||||
android:padding="16dp"
|
||||
tools:text="Reading" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vert_divider_1"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="?android:divider"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_chapters"
|
||||
style="@style/TextAppearance.Regular.Body1.Secondary"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/list_item_selector"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:padding="16dp"
|
||||
tools:text="12/24" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vert_divider_2"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="?android:divider"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_score"
|
||||
style="@style/TextAppearance.Regular.Body1.Secondary"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/list_item_selector"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:padding="16dp"
|
||||
tools:text="10" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/bottom_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?android:divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bottom_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_start_date"
|
||||
style="@style/TextAppearance.Regular.Body1.Secondary"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/list_item_selector"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:padding="16dp"
|
||||
tools:text="4/16/2020" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vert_divider_3"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:background="?android:divider"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_finish_date"
|
||||
style="@style/TextAppearance.Regular.Body1.Secondary"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/list_item_selector"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/vert_divider_3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/bottom_divider"
|
||||
tools:text="4/16/2020" />
|
||||
android:paddingHorizontal="16dp"
|
||||
android:textAppearance="?attr/textAppearanceSubtitle1"
|
||||
tools:text="Title" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MaterialCardView.Tracker">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="12dp"
|
||||
android:paddingVertical="8dp">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/middle_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_status"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:foreground="?attr/selectableItemBackgroundBorderless"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:padding="12dp"
|
||||
android:textAppearance="?attr/textAppearanceBody2"
|
||||
tools:text="Reading" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vert_divider_1"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:divider" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_chapters"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:foreground="?attr/selectableItemBackgroundBorderless"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:padding="12dp"
|
||||
android:textAppearance="?attr/textAppearanceBody2"
|
||||
tools:text="12/24" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vert_divider_2"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:divider"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_score"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:foreground="?attr/selectableItemBackgroundBorderless"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:padding="12dp"
|
||||
android:textAppearance="?attr/textAppearanceBody2"
|
||||
tools:text="10" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/bottom_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
|
||||
android:background="?android:divider" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/bottom_row"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_start_date"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:foreground="?attr/selectableItemBackgroundBorderless"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:padding="12dp"
|
||||
android:textAppearance="?attr/textAppearanceBody2"
|
||||
tools:text="4/16/2020" />
|
||||
|
||||
<View
|
||||
android:id="@+id/vert_divider_3"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:divider" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_finish_date"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:foreground="?attr/selectableItemBackgroundBorderless"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:padding="12dp"
|
||||
android:textAppearance="?attr/textAppearanceBody2"
|
||||
tools:text="4/16/2020" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -1,62 +1,90 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout 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"
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:boxBackgroundMode="filled"
|
||||
app:endIconMode="clear_text"
|
||||
app:hintEnabled="false">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/track_search"
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:theme="?attr/actionBarTheme"
|
||||
app:contentInsetStartWithNavigation="0dp"
|
||||
app:menu="@menu/track_search"
|
||||
app:navigationIcon="@drawable/ic_close_24dp"
|
||||
app:title="@string/add_tracking" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/title_input"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/title"
|
||||
android:inputType="text" />
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:hint="@string/title">
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/title_input_edit_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:imeOptions="actionSearch"
|
||||
android:inputType="text"
|
||||
android:maxLines="1" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="invisible"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/track_search_list"
|
||||
style="@style/Widget.Tachiyomi.CardView"
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:choiceMode="singleChoice"
|
||||
android:clipToPadding="false"
|
||||
android:divider="@null"
|
||||
android:dividerHeight="10dp"
|
||||
android:footerDividersEnabled="true"
|
||||
android:headerDividersEnabled="true"
|
||||
android:listSelector="@drawable/list_item_selector"
|
||||
android:scrollbars="none"
|
||||
android:visibility="invisible"
|
||||
tools:listitem="@layout/track_search_item"
|
||||
tools:visibility="visible" />
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
</FrameLayout>
|
||||
<com.google.android.material.progressindicator.CircularProgressIndicator
|
||||
android:id="@+id/progress"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
<TextView
|
||||
android:id="@+id/message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:textAppearance="?attr/textAppearanceBody2"
|
||||
android:visibility="gone"
|
||||
tools:text="@string/no_results_found" />
|
||||
|
||||
<eu.kanade.tachiyomi.widget.AutofitRecyclerView
|
||||
android:id="@+id/track_search_recyclerview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:clipToPadding="false"
|
||||
android:columnWidth="330dp"
|
||||
android:paddingHorizontal="8dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:visibility="gone"
|
||||
tools:listitem="@layout/track_search_item"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
@ -1,65 +1,69 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<com.google.android.material.card.MaterialCardView 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"
|
||||
style="@style/Widget.Tachiyomi.CardView.Item"
|
||||
android:layout_margin="0dp"
|
||||
android:padding="0dp">
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
android:checkable="true"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.MaterialCardView.Tracker">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/linearLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="216dp"
|
||||
android:background="@drawable/list_item_selector"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/track_search_cover"
|
||||
android:layout_width="135dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="130dp"
|
||||
android:layout_height="180dp"
|
||||
android:contentDescription="@string/description_cover"
|
||||
android:scaleType="centerCrop"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
tools:src="@mipmap/ic_launcher" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_search_title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:maxLines="3"
|
||||
android:textAppearance="@style/TextAppearance.Regular.Body1.Bold"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginEnd="36dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="2"
|
||||
android:textAppearance="?attr/textAppearanceHeadline6"
|
||||
android:textSize="17sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/track_search_cover"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="One Piece" />
|
||||
tools:text="@string/app_name" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_search_type"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:maxLines="1"
|
||||
android:text="@string/track_type"
|
||||
android:textAppearance="@style/TextAppearance.Regular.Body1.Bold"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintStart_toEndOf="@id/track_search_cover"
|
||||
android:textAppearance="?attr/textAppearanceSubtitle2"
|
||||
app:layout_constraintStart_toStartOf="@+id/track_search_title"
|
||||
app:layout_constraintTop_toBottomOf="@id/track_search_title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_search_type_result"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Regular.Body1.Secondary"
|
||||
android:textSize="12sp"
|
||||
android:textAppearance="?attr/textAppearanceBody2"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/track_search_type"
|
||||
app:layout_constraintTop_toBottomOf="@id/track_search_title"
|
||||
tools:text="Manga" />
|
||||
@ -68,22 +72,23 @@
|
||||
android:id="@+id/track_search_start"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:maxLines="1"
|
||||
android:text="@string/track_start_date"
|
||||
android:textAppearance="@style/TextAppearance.Regular.Body1.Bold"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintStart_toEndOf="@id/track_search_cover"
|
||||
android:textAppearance="?attr/textAppearanceSubtitle2"
|
||||
app:layout_constraintStart_toStartOf="@+id/track_search_type"
|
||||
app:layout_constraintTop_toBottomOf="@id/track_search_type" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_search_start_result"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Regular.Body1.Secondary"
|
||||
android:textSize="12sp"
|
||||
android:textAppearance="?attr/textAppearanceBody2"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/track_search_start"
|
||||
app:layout_constraintTop_toBottomOf="@id/track_search_type"
|
||||
tools:text="2018-10-01" />
|
||||
@ -92,22 +97,24 @@
|
||||
android:id="@+id/track_search_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@string/track_status"
|
||||
android:textAppearance="@style/TextAppearance.Regular.Body1.Bold"
|
||||
android:textSize="12sp"
|
||||
app:layout_constraintStart_toEndOf="@id/track_search_cover"
|
||||
android:textAppearance="?attr/textAppearanceSubtitle2"
|
||||
app:layout_constraintStart_toStartOf="@+id/track_search_start"
|
||||
app:layout_constraintTop_toBottomOf="@id/track_search_start" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/track_search_status_result"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textAppearance="@style/TextAppearance.Regular.Body1.Secondary"
|
||||
android:textSize="12sp"
|
||||
android:textAppearance="?attr/textAppearanceBody2"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/track_search_status"
|
||||
app:layout_constraintTop_toBottomOf="@id/track_search_start"
|
||||
tools:text="Ongoing" />
|
||||
@ -116,22 +123,17 @@
|
||||
android:id="@+id/track_search_summary"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="7"
|
||||
android:textAppearance="@style/TextAppearance.Regular.Body1.Secondary"
|
||||
android:textSize="12sp"
|
||||
android:textAppearance="?attr/textAppearanceCaption"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@id/track_search_cover"
|
||||
app:layout_constraintStart_toStartOf="@+id/track_search_status"
|
||||
app:layout_constraintTop_toBottomOf="@+id/track_search_status"
|
||||
app:layout_constraintVertical_bias="0.333"
|
||||
tools:text="This is the summary of the manga that fits This is the summary of the manga that fits This is the summary of the manga that fits This is the summary of the manga that fits This is the summary of the manga that fits This is the summary of the manga that fits This is the summary of the manga that fits " />
|
||||
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas condimentum et turpis ut sollicitudin. Donec tellus dolor, rhoncus a mattis eget, tempor quis augue. Fusce eleifend dignissim turpis a molestie. Praesent tincidunt, risus sed egestas fringilla, urna orci ultrices libero, id iaculis sem lorem placerat lacus." />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
20
app/src/main/res/menu/track_search.xml
Normal file
20
app/src/main/res/menu/track_search.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/remove"
|
||||
android:icon="@drawable/ic_delete_24dp"
|
||||
android:title="@string/action_remove"
|
||||
android:visible="false"
|
||||
app:iconTint="?attr/colorOnToolbar"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/done"
|
||||
android:enabled="false"
|
||||
android:icon="@drawable/ic_check_24dp"
|
||||
android:title="@android:string/ok"
|
||||
app:iconTint="?attr/colorOnToolbar"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
@ -605,8 +605,8 @@
|
||||
<string name="status">Status</string>
|
||||
<string name="track_status">Status</string>
|
||||
<string name="track_start_date">Started</string>
|
||||
<string name="track_started_reading_date">Started reading date</string>
|
||||
<string name="track_finished_reading_date">Finished reading date</string>
|
||||
<string name="track_started_reading_date">Start date</string>
|
||||
<string name="track_finished_reading_date">Finish date</string>
|
||||
<string name="track_type">Type</string>
|
||||
<string name="track_author">Author</string>
|
||||
<string name="error_invalid_date_supplied">Invalid date supplied</string>
|
||||
|
@ -148,24 +148,6 @@
|
||||
<!--Widgets-->
|
||||
<!--=======-->
|
||||
|
||||
<style name="Widget.Tachiyomi.CardView" parent="CardView">
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:padding">16dp</item>
|
||||
<item name="android:layout_marginTop">8dp</item>
|
||||
<item name="android:layout_marginBottom">8dp</item>
|
||||
<item name="android:layout_marginStart">8dp</item>
|
||||
<item name="android:layout_marginEnd">8dp</item>
|
||||
<item name="cardBackgroundColor">?attr/colorSurface</item>
|
||||
<item name="cardCornerRadius">@dimen/card_radius</item>
|
||||
<item name="cardElevation">2dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Tachiyomi.CardView.Item">
|
||||
<item name="android:layout_marginTop">@dimen/space_between_cards</item>
|
||||
<item name="android:layout_marginBottom">@dimen/space_between_cards</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Tachiyomi.GridView" parent="android:Widget">
|
||||
<item name="android:smoothScrollbar">true</item>
|
||||
<item name="android:numColumns">auto_fit</item>
|
||||
@ -307,4 +289,23 @@
|
||||
<item name="md_button_selector">@drawable/md_btn_selector_dark</item>
|
||||
</style>
|
||||
|
||||
<!--================-->
|
||||
<!--Shape Appearance-->
|
||||
<!--================-->
|
||||
<style name="ShapeAppearanceOverlay.MaterialCardView.Tracker" parent="">
|
||||
<item name="cornerFamily">rounded</item>
|
||||
<item name="cornerSize">8dp</item>
|
||||
</style>
|
||||
|
||||
<style name="ThemeOverlay.Tachiyomi.Dialog.Fullscreen" parent="ThemeOverlay.MaterialComponents">
|
||||
<item name="android:windowIsFloating">false</item>
|
||||
<item name="android:windowBackground">?android:attr/colorBackground</item>
|
||||
<item name="android:windowAnimationStyle">@style/Animation.Tachiyomi.Dialog</item>
|
||||
</style>
|
||||
|
||||
<style name="Animation.Tachiyomi.Dialog" parent="Animation.AppCompat.Dialog">
|
||||
<item name="android:windowEnterAnimation">@anim/fade_in_short</item>
|
||||
<item name="android:windowExitAnimation">@anim/fade_out_short</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
Loading…
Reference in New Issue
Block a user