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:
Ivan Iskandar 2021-06-28 22:33:26 +07:00 committed by GitHub
parent 7e3ea9074c
commit cb71d44024
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 662 additions and 434 deletions

View File

@ -1118,8 +1118,7 @@ class MangaController :
fun onTrackingSearchResultsError(error: Throwable) { fun onTrackingSearchResultsError(error: Throwable) {
Timber.e(error) Timber.e(error)
activity?.toast(error.message) getTrackingSearchDialog()?.onSearchResultsError(error.message)
getTrackingSearchDialog()?.onSearchResultsError()
} }
private fun getTrackingSearchDialog(): TrackSearchDialog? { private fun getTrackingSearchDialog(): TrackSearchDialog? {

View File

@ -4,6 +4,8 @@ import android.view.LayoutInflater
import android.view.ViewGroup import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import eu.kanade.tachiyomi.databinding.TrackItemBinding 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>() { 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 { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TrackHolder {
binding = TrackItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) binding = TrackItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
binding.card.applyElevationOverlay()
return TrackHolder(binding, this) return TrackHolder(binding, this)
} }

View File

@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.manga.track
import android.annotation.SuppressLint import android.annotation.SuppressLint
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.databinding.TrackItemBinding import eu.kanade.tachiyomi.databinding.TrackItemBinding
import uy.kohesive.injekt.injectLazy import uy.kohesive.injekt.injectLazy
@ -37,38 +38,64 @@ class TrackHolder(private val binding: TrackItemBinding, adapter: TrackAdapter)
fun bind(item: TrackItem) { fun bind(item: TrackItem) {
val track = item.track val track = item.track
binding.trackLogo.setImageResource(item.service.getLogo()) binding.trackLogo.setImageResource(item.service.getLogo())
binding.logoContainer.setBackgroundColor(item.service.getLogoColor()) binding.logoContainer.setCardBackgroundColor(item.service.getLogoColor())
binding.trackSet.isVisible = track == null binding.trackSet.isVisible = track == null
binding.trackTitle.isVisible = track != null binding.trackTitle.isVisible = track != null
binding.topDivider.isVisible = track != null
binding.middleRow.isVisible = track != null binding.middleRow.isVisible = track != null
binding.bottomDivider.isVisible = track != null binding.bottomDivider.isVisible = track != null
binding.bottomRow.isVisible = track != null binding.bottomRow.isVisible = track != null
binding.card.isVisible = track != null
if (track != null) { if (track != null) {
val ctx = binding.trackTitle.context
binding.trackTitle.text = track.title binding.trackTitle.text = track.title
binding.trackChapters.text = "${track.last_chapter_read}/" + binding.trackChapters.text = track.last_chapter_read.toString()
if (track.total_chapters > 0) track.total_chapters else "-" if (track.total_chapters > 0) {
binding.trackChapters.text = "${binding.trackChapters.text} / ${track.total_chapters}"
}
binding.trackStatus.text = item.service.getStatus(track.status) binding.trackStatus.text = item.service.getStatus(track.status)
if (item.service.getScoreList().isEmpty()) { val supportsScoring = item.service.getScoreList().isNotEmpty()
binding.trackScore.isVisible = false if (supportsScoring) {
binding.vertDivider2.isVisible = false if (track.score != 0F) {
} else { item.service.getScoreList()
binding.trackScore.text = if (track.score == 0f) "-" else item.service.displayScore(track) 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) { val supportsReadingDates = item.service.supportsReadingDates
binding.trackStartDate.text = if (supportsReadingDates) {
if (track.started_reading_date != 0L) dateFormat.format(track.started_reading_date) else "-" if (track.started_reading_date != 0L) {
binding.trackFinishDate.text = binding.trackStartDate.text = dateFormat.format(track.started_reading_date)
if (track.finished_reading_date != 0L) dateFormat.format(track.finished_reading_date) else "-" binding.trackStartDate.alpha = SET_STATUS_TEXT_ALPHA
} else { } else {
binding.bottomDivider.isVisible = false binding.trackStartDate.text = ctx.getString(R.string.track_started_reading_date)
binding.bottomRow.isVisible = false 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
}
} }

View File

@ -1,76 +1,57 @@
package eu.kanade.tachiyomi.ui.manga.track package eu.kanade.tachiyomi.ui.manga.track
import android.content.Context import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ArrayAdapter import androidx.recyclerview.widget.RecyclerView
import androidx.core.view.isVisible
import coil.clear
import coil.load
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.databinding.TrackSearchItemBinding import eu.kanade.tachiyomi.databinding.TrackSearchItemBinding
import eu.kanade.tachiyomi.util.view.inflate import eu.kanade.tachiyomi.util.view.applyElevationOverlay
class TrackSearchAdapter(context: Context) : class TrackSearchAdapter(
ArrayAdapter<TrackSearch>(context, R.layout.track_search_item, mutableListOf<TrackSearch>()) { 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 items = emptyList<TrackSearch>()
var v = view set(value) {
// Get the data item for this position if (field != value) {
val track = getItem(position)!! field = value
// Check if an existing view is being reused, otherwise inflate the view selectedItemPosition = value.indexOfFirst { it.tracking_url == currentTrackUrl }
val holder: TrackSearchHolder // view lookup cache stored in tag notifyDataSetChanged()
if (v == null) { }
v = parent.inflate(R.layout.track_search_item) }
holder = TrackSearchHolder(v)
v.tag = holder 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 { } else {
holder = v.tag as TrackSearchHolder super.onBindViewHolder(holder, position, payloads)
} }
holder.onSetValues(track)
return v
} }
fun setItems(syncs: List<TrackSearch>) { companion object {
setNotifyOnChange(false) private object UncheckPayload
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
}
}
} }
} }

View File

@ -2,29 +2,31 @@ package eu.kanade.tachiyomi.ui.manga.track
import android.app.Dialog import android.app.Dialog
import android.os.Bundle import android.os.Bundle
import android.view.KeyEvent
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View 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.os.bundleOf
import androidx.core.view.WindowCompat
import androidx.core.view.isVisible import androidx.core.view.isVisible
import com.afollestad.materialdialogs.MaterialDialog import dev.chrisbanes.insetter.applyInsetter
import com.afollestad.materialdialogs.customview.customView
import eu.kanade.tachiyomi.R 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.TrackManager
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.databinding.TrackSearchDialogBinding import eu.kanade.tachiyomi.databinding.TrackSearchDialogBinding
import eu.kanade.tachiyomi.ui.base.controller.DialogController import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.ui.manga.MangaController 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.filter
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import reactivecircus.flowbinding.android.widget.itemClicks import reactivecircus.flowbinding.android.widget.editorActionEvents
import reactivecircus.flowbinding.android.widget.textChanges
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.util.concurrent.TimeUnit
class TrackSearchDialog : DialogController { class TrackSearchDialog : DialogController {
@ -32,59 +34,130 @@ class TrackSearchDialog : DialogController {
private var adapter: TrackSearchAdapter? = null private var adapter: TrackSearchAdapter? = null
private var selectedItem: Track? = null
private val service: TrackService private val service: TrackService
private val currentTrackUrl: String?
private val trackController private val trackController
get() = targetController as MangaController get() = targetController as MangaController
constructor(target: MangaController, service: TrackService) : super( private lateinit var currentlySearched: String
bundleOf(KEY_SERVICE to service.id)
) { constructor(
target: MangaController,
_service: TrackService,
_currentTrackUrl: String?
) : super(bundleOf(KEY_SERVICE to _service.id, KEY_CURRENT_URL to _currentTrackUrl)) {
targetController = target targetController = target
this.service = service service = _service
currentTrackUrl = _currentTrackUrl
} }
@Suppress("unused") @Suppress("unused")
constructor(bundle: Bundle) : super(bundle) { constructor(bundle: Bundle) : super(bundle) {
service = Injekt.get<TrackManager>().getService(bundle.getInt(KEY_SERVICE))!! service = Injekt.get<TrackManager>().getService(bundle.getInt(KEY_SERVICE))!!
currentTrackUrl = bundle.getString(KEY_CURRENT_URL)
} }
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
override fun onCreateDialog(savedViewState: Bundle?): Dialog { override fun onCreateDialog(savedViewState: Bundle?): Dialog {
binding = TrackSearchDialogBinding.inflate(LayoutInflater.from(activity!!)) 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) // Toolbar stuff
binding!!.toolbar.setNavigationOnClickListener { dialog?.dismiss() }
return dialog binding!!.toolbar.setOnMenuItemClickListener {
} when (it.itemId) {
R.id.done -> {
fun onViewCreated(view: View, savedState: Bundle?) { val adapter = adapter ?: return@setOnMenuItemClickListener true
// Create adapter val item = adapter.items.getOrNull(adapter.selectedItemPosition)
val adapter = TrackSearchAdapter(view.context) if (item != null) {
this.adapter = adapter trackController.presenter.registerTracking(item, service)
binding!!.trackSearchList.adapter = adapter dialog?.dismiss()
}
// Set listeners }
selectedItem = null R.id.remove -> {
trackController.presenter.unregisterTracking(service)
binding!!.trackSearchList.itemClicks() dialog?.dismiss()
.onEach { position -> }
selectedItem = adapter.getItem(position)
} }
.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 // Do an initial search based on the manga's title
if (savedState == null) { if (savedViewState == null) {
val title = trackController.presenter.manga.title currentlySearched = trackController.presenter.manga.title
binding!!.trackSearch.append(title) binding!!.titleInput.editText?.append(currentlySearched)
search(title) }
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 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) { private fun search(query: String) {
val binding = binding ?: return val binding = binding ?: return
binding.progress.isVisible = true binding.progress.isVisible = true
binding.trackSearchList.isVisible = false binding.trackSearchRecyclerview.isVisible = false
binding.message.isVisible = false
trackController.presenter.trackingSearch(query, service) trackController.presenter.trackingSearch(query, service)
} }
fun onSearchResults(results: List<TrackSearch>) { fun onSearchResults(results: List<TrackSearch>) {
selectedItem = null
val binding = binding ?: return val binding = binding ?: return
binding.progress.isVisible = false 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 val binding = binding ?: return
binding.progress.isVisible = false binding.progress.isVisible = false
binding.trackSearchList.isVisible = false binding.trackSearchRecyclerview.isVisible = false
adapter?.setItems(emptyList()) binding.message.isVisible = true
} binding.message.text = message ?: binding.message.context.getString(R.string.unknown_error)
adapter?.items = emptyList()
private fun onPositiveButtonClick() {
trackController.presenter.registerTracking(selectedItem, service)
}
private fun onRemoveButtonClick() {
trackController.presenter.unregisterTracking(service)
} }
private companion object { private companion object {
const val KEY_SERVICE = "service_id" const val KEY_SERVICE = "service_id"
const val KEY_CURRENT_URL = "current_url"
} }
} }

View File

@ -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
}
}

View File

@ -96,7 +96,8 @@ class TrackSheet(
} }
} }
} else { } 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)
} }
} }

View File

@ -38,6 +38,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.lang.truncateCenter import eu.kanade.tachiyomi.util.lang.truncateCenter
import timber.log.Timber import timber.log.Timber
import uy.kohesive.injekt.api.get
import java.io.File import java.io.File
import kotlin.math.roundToInt import kotlin.math.roundToInt

View File

@ -4,10 +4,12 @@ package eu.kanade.tachiyomi.util.view
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.graphics.Point import android.graphics.Point
import android.text.TextUtils
import android.view.Gravity import android.view.Gravity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.TextView
import androidx.annotation.MenuRes import androidx.annotation.MenuRes
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.appcompat.view.menu.MenuBuilder import androidx.appcompat.view.menu.MenuBuilder
@ -16,12 +18,17 @@ import androidx.appcompat.widget.TooltipCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.forEach import androidx.core.view.forEach
import androidx.recyclerview.widget.RecyclerView 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.Chip
import com.google.android.material.chip.ChipGroup 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.floatingactionbutton.ExtendedFloatingActionButton
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.system.getResourceColor import eu.kanade.tachiyomi.util.system.getResourceColor
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
/** /**
* Returns coordinates of view. * Returns coordinates of view.
@ -174,3 +181,21 @@ inline fun ChipGroup.setChips(
addView(chip) 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
}

View 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" />

View 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" />

View File

@ -5,6 +5,5 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clipToPadding="false" android:clipToPadding="false"
android:paddingTop="8dp" android:paddingVertical="8dp"
android:paddingBottom="8dp"
tools:listitem="@layout/track_item" /> tools:listitem="@layout/track_item" />

View File

@ -1,192 +1,194 @@
<?xml version="1.0" encoding="utf-8"?> <?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:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/track" android:id="@+id/track"
style="@style/Widget.Tachiyomi.CardView.Item" android:layout_width="match_parent"
android:padding="0dp"> android:layout_height="wrap_content"
android:clipToPadding="false"
android:orientation="vertical"
android:paddingHorizontal="16dp"
android:paddingVertical="8dp">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" 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 <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal">
<LinearLayout <Button
android:id="@+id/logo_container" android:id="@+id/track_set"
android:layout_width="48dp" style="?attr/borderlessButtonStyle"
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
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:layout_gravity="center"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginStart="16dp"
app:layout_constraintStart_toStartOf="parent" android:text="@string/add_tracking"
app:layout_constraintTop_toTopOf="parent"> android:visibility="gone" />
<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">
<TextView <TextView
android:id="@+id/track_status" android:id="@+id/track_title"
style="@style/TextAppearance.Regular.Body1.Secondary" android:layout_width="match_parent"
android:layout_weight="1" android:layout_height="48dp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/list_item_selector"
android:ellipsize="end" android:ellipsize="end"
android:gravity="center" android:foreground="?attr/selectableItemBackgroundBorderless"
android:gravity="center_vertical"
android:maxLines="1" android:maxLines="1"
android:padding="16dp" android:paddingHorizontal="16dp"
tools:text="Reading" /> android:textAppearance="?attr/textAppearanceSubtitle1"
tools:text="Title" />
<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" />
</LinearLayout> </LinearLayout>
</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>

View File

@ -1,62 +1,90 @@
<?xml version="1.0" encoding="utf-8"?> <?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:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent">
android:orientation="vertical">
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
app:boxBackgroundMode="filled"
app:endIconMode="clear_text"
app:hintEnabled="false">
<com.google.android.material.textfield.TextInputEditText <androidx.appcompat.widget.Toolbar
android:id="@+id/track_search" 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_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:hint="@string/title" android:layout_marginHorizontal="12dp"
android:inputType="text" /> 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 </com.google.android.material.textfield.TextInputLayout>
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<com.google.android.material.progressindicator.CircularProgressIndicator <FrameLayout
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"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="0dp"
android:choiceMode="singleChoice" android:layout_weight="1">
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" />
</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>

View File

@ -1,65 +1,69 @@
<?xml version="1.0" encoding="utf-8"?> <?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:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
style="@style/Widget.Tachiyomi.CardView.Item" android:id="@+id/container"
android:layout_margin="0dp" android:layout_width="match_parent"
android:padding="0dp"> 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 <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/linearLayout" android:id="@+id/linearLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="216dp" android:layout_height="wrap_content"
android:background="@drawable/list_item_selector"
android:orientation="horizontal"> android:orientation="horizontal">
<ImageView <ImageView
android:id="@+id/track_search_cover" android:id="@+id/track_search_cover"
android:layout_width="135dp" android:layout_width="130dp"
android:layout_height="match_parent" android:layout_height="180dp"
android:contentDescription="@string/description_cover" android:contentDescription="@string/description_cover"
android:scaleType="centerCrop" android:scaleType="centerCrop"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
tools:src="@mipmap/ic_launcher" /> tools:src="@mipmap/ic_launcher" />
<TextView <TextView
android:id="@+id/track_search_title" android:id="@+id/track_search_title"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="8dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="8dp" android:layout_marginEnd="36dp"
android:maxLines="3" android:ellipsize="end"
android:textAppearance="@style/TextAppearance.Regular.Body1.Bold" android:maxLines="2"
android:textSize="16sp" android:textAppearance="?attr/textAppearanceHeadline6"
android:textSize="17sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/track_search_cover" app:layout_constraintStart_toEndOf="@id/track_search_cover"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="One Piece" /> tools:text="@string/app_name" />
<TextView <TextView
android:id="@+id/track_search_type" android:id="@+id/track_search_type"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:maxLines="1" android:maxLines="1"
android:text="@string/track_type" android:text="@string/track_type"
android:textAppearance="@style/TextAppearance.Regular.Body1.Bold" android:textAppearance="?attr/textAppearanceSubtitle2"
android:textSize="12sp" app:layout_constraintStart_toStartOf="@+id/track_search_title"
app:layout_constraintStart_toEndOf="@id/track_search_cover"
app:layout_constraintTop_toBottomOf="@id/track_search_title" /> app:layout_constraintTop_toBottomOf="@id/track_search_title" />
<TextView <TextView
android:id="@+id/track_search_type_result" android:id="@+id/track_search_type_result"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="4dp"
android:layout_marginEnd="12dp"
android:maxLines="1" android:maxLines="1"
android:textAppearance="@style/TextAppearance.Regular.Body1.Secondary" android:textAppearance="?attr/textAppearanceBody2"
android:textSize="12sp" android:textColor="?android:attr/textColorSecondary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/track_search_type" app:layout_constraintStart_toEndOf="@id/track_search_type"
app:layout_constraintTop_toBottomOf="@id/track_search_title" app:layout_constraintTop_toBottomOf="@id/track_search_title"
tools:text="Manga" /> tools:text="Manga" />
@ -68,22 +72,23 @@
android:id="@+id/track_search_start" android:id="@+id/track_search_start"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:maxLines="1" android:maxLines="1"
android:text="@string/track_start_date" android:text="@string/track_start_date"
android:textAppearance="@style/TextAppearance.Regular.Body1.Bold" android:textAppearance="?attr/textAppearanceSubtitle2"
android:textSize="12sp" app:layout_constraintStart_toStartOf="@+id/track_search_type"
app:layout_constraintStart_toEndOf="@id/track_search_cover"
app:layout_constraintTop_toBottomOf="@id/track_search_type" /> app:layout_constraintTop_toBottomOf="@id/track_search_type" />
<TextView <TextView
android:id="@+id/track_search_start_result" android:id="@+id/track_search_start_result"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="8dp" android:layout_marginStart="4dp"
android:layout_marginEnd="12dp"
android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:textAppearance="@style/TextAppearance.Regular.Body1.Secondary" android:textAppearance="?attr/textAppearanceBody2"
android:textSize="12sp" android:textColor="?android:attr/textColorSecondary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/track_search_start" app:layout_constraintStart_toEndOf="@id/track_search_start"
app:layout_constraintTop_toBottomOf="@id/track_search_type" app:layout_constraintTop_toBottomOf="@id/track_search_type"
tools:text="2018-10-01" /> tools:text="2018-10-01" />
@ -92,22 +97,24 @@
android:id="@+id/track_search_status" android:id="@+id/track_search_status"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:ellipsize="end"
android:maxLines="1" android:maxLines="1"
android:text="@string/track_status" android:text="@string/track_status"
android:textAppearance="@style/TextAppearance.Regular.Body1.Bold" android:textAppearance="?attr/textAppearanceSubtitle2"
android:textSize="12sp" app:layout_constraintStart_toStartOf="@+id/track_search_start"
app:layout_constraintStart_toEndOf="@id/track_search_cover"
app:layout_constraintTop_toBottomOf="@id/track_search_start" /> app:layout_constraintTop_toBottomOf="@id/track_search_start" />
<TextView <TextView
android:id="@+id/track_search_status_result" android:id="@+id/track_search_status_result"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="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:maxLines="1"
android:textAppearance="@style/TextAppearance.Regular.Body1.Secondary" android:textAppearance="?attr/textAppearanceBody2"
android:textSize="12sp" android:textColor="?android:attr/textColorSecondary"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/track_search_status" app:layout_constraintStart_toEndOf="@id/track_search_status"
app:layout_constraintTop_toBottomOf="@id/track_search_start" app:layout_constraintTop_toBottomOf="@id/track_search_start"
tools:text="Ongoing" /> tools:text="Ongoing" />
@ -116,22 +123,17 @@
android:id="@+id/track_search_summary" android:id="@+id/track_search_summary"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="16dp" android:layout_marginEnd="12dp"
android:layout_marginBottom="8dp" android:layout_marginBottom="8dp"
android:ellipsize="end" android:textAppearance="?attr/textAppearanceCaption"
android:maxLines="7" android:textColor="?android:attr/textColorSecondary"
android:textAppearance="@style/TextAppearance.Regular.Body1.Secondary"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="@+id/track_search_status"
app:layout_constraintStart_toEndOf="@id/track_search_cover"
app:layout_constraintTop_toBottomOf="@+id/track_search_status" app:layout_constraintTop_toBottomOf="@+id/track_search_status"
app:layout_constraintVertical_bias="0.333" 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." />
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 " />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView> </com.google.android.material.card.MaterialCardView>

View 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>

View File

@ -605,8 +605,8 @@
<string name="status">Status</string> <string name="status">Status</string>
<string name="track_status">Status</string> <string name="track_status">Status</string>
<string name="track_start_date">Started</string> <string name="track_start_date">Started</string>
<string name="track_started_reading_date">Started reading date</string> <string name="track_started_reading_date">Start date</string>
<string name="track_finished_reading_date">Finished reading date</string> <string name="track_finished_reading_date">Finish date</string>
<string name="track_type">Type</string> <string name="track_type">Type</string>
<string name="track_author">Author</string> <string name="track_author">Author</string>
<string name="error_invalid_date_supplied">Invalid date supplied</string> <string name="error_invalid_date_supplied">Invalid date supplied</string>

View File

@ -148,24 +148,6 @@
<!--Widgets--> <!--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"> <style name="Widget.Tachiyomi.GridView" parent="android:Widget">
<item name="android:smoothScrollbar">true</item> <item name="android:smoothScrollbar">true</item>
<item name="android:numColumns">auto_fit</item> <item name="android:numColumns">auto_fit</item>
@ -307,4 +289,23 @@
<item name="md_button_selector">@drawable/md_btn_selector_dark</item> <item name="md_button_selector">@drawable/md_btn_selector_dark</item>
</style> </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> </resources>