Browse Source

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
Ivan Iskandar 3 năm trước cách đây
mục cha
commit
cb71d44024

+ 1 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaController.kt

@@ -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? {

+ 3 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackAdapter.kt

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

+ 44 - 17
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackHolder.kt

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

+ 43 - 62
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackSearchAdapter.kt

@@ -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
-
-class TrackSearchAdapter(context: Context) :
-    ArrayAdapter<TrackSearch>(context, R.layout.track_search_item, mutableListOf<TrackSearch>()) {
-
-    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
-        } else {
-            holder = v.tag as TrackSearchHolder
+import eu.kanade.tachiyomi.util.view.applyElevationOverlay
+
+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))
+            }
         }
-        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)
+    var items = emptyList<TrackSearch>()
+        set(value) {
+            if (field != value) {
+                field = value
+                selectedItemPosition = value.indexOfFirst { it.tracking_url == currentTrackUrl }
+                notifyDataSetChanged()
             }
+        }
 
-            val hasStatus = track.publishing_status.isNotBlank()
-            binding.trackSearchStatus.isVisible = hasStatus
-            binding.trackSearchStatusResult.isVisible = hasStatus
-            if (hasStatus) {
-                binding.trackSearchStatusResult.text = track.publishing_status.capitalize()
-            }
+    override fun getItemCount(): Int = items.size
 
-            val hasType = track.publishing_type.isNotBlank()
-            binding.trackSearchType.isVisible = hasType
-            binding.trackSearchTypeResult.isVisible = hasType
-            if (hasType) {
-                binding.trackSearchTypeResult.text = track.publishing_type.capitalize()
-            }
+    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)
+    }
 
-            val hasStartDate = track.start_date.isNotBlank()
-            binding.trackSearchStart.isVisible = hasStartDate
-            binding.trackSearchStartResult.isVisible = hasStartDate
-            if (hasStartDate) {
-                binding.trackSearchStartResult.text = track.start_date
-            }
+    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 {
+            super.onBindViewHolder(holder, position, payloads)
         }
     }
+
+    companion object {
+        private object UncheckPayload
+    }
 }

+ 127 - 61
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackSearchDialog.kt

@@ -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
-    }
+        // 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()
+                }
+            }
+            true
+        }
+        binding!!.toolbar.menu.findItem(R.id.remove).isVisible = currentTrackUrl != null
 
-    fun onViewCreated(view: View, savedState: Bundle?) {
         // Create adapter
-        val adapter = TrackSearchAdapter(view.context)
-        this.adapter = adapter
-        binding!!.trackSearchList.adapter = adapter
+        adapter = TrackSearchAdapter(currentTrackUrl) { which ->
+            binding!!.toolbar.menu.findItem(R.id.done).isEnabled = which != null
+        }
+        binding!!.trackSearchRecyclerview.adapter = adapter
 
-        // Set listeners
-        selectedItem = null
+        // Do an initial search based on the manga's 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)
 
-        binding!!.trackSearchList.itemClicks()
-            .onEach { position ->
-                selectedItem = adapter.getItem(position)
+        // 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)
             }
-            .launchIn(trackController.viewScope)
+        }
 
-        // 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)
+        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"
     }
 }

+ 61 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackSearchHolder.kt

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

+ 2 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackSheet.kt

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

+ 1 - 0
app/src/main/java/eu/kanade/tachiyomi/util/system/ContextExtensions.kt

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

+ 25 - 0
app/src/main/java/eu/kanade/tachiyomi/util/view/ViewExtensions.kt

@@ -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 - 0
app/src/main/res/anim/fade_in_short.xml

@@ -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 - 0
app/src/main/res/anim/fade_out_short.xml

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

+ 1 - 2
app/src/main/res/layout/track_controller.xml

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

+ 143 - 141
app/src/main/res/layout/track_item.xml

@@ -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" />
+                android:layout_gravity="center"
+                android:layout_marginStart="16dp"
+                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>
+            <TextView
+                android:id="@+id/track_title"
+                android:layout_width="match_parent"
+                android:layout_height="48dp"
+                android:ellipsize="end"
+                android:foreground="?attr/selectableItemBackgroundBorderless"
+                android:gravity="center_vertical"
+                android:maxLines="1"
+                android:paddingHorizontal="16dp"
+                android:textAppearance="?attr/textAppearanceSubtitle1"
+                tools:text="Title" />
 
         </LinearLayout>
 
-        <View
-            android:id="@+id/top_divider"
-            android:layout_width="match_parent"
-            android:layout_height="1dp"
-            android:background="?android:divider" />
+    </LinearLayout>
+
+    <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:id="@+id/middle_row"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content">
+            android:layout_height="wrap_content"
+            android:orientation="vertical"
+            android:paddingHorizontal="12dp"
+            android:paddingVertical="8dp">
 
-            <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:ellipsize="end"
-                android:gravity="center"
-                android:maxLines="1"
-                android:padding="16dp"
-                tools:text="Reading" />
+            <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:layout_marginTop="8dp"
-                android:layout_marginBottom="8dp"
-                android:background="?android:divider"
-                app:layout_constraintTop_toTopOf="parent" />
+                android:background="?android:divider" />
 
-            <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" />
+                <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: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" />
+                <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>
+            </LinearLayout>
 
-        <View
-            android:id="@+id/bottom_divider"
-            android:layout_width="match_parent"
-            android:layout_height="1dp"
-            android:background="?android:divider" />
+            <View
+                android:id="@+id/bottom_divider"
+                android:layout_width="match_parent"
+                android:layout_height="1dp"
 
-        <LinearLayout
-            android:id="@+id/bottom_row"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content">
+                android:background="?android:divider" />
 
-            <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" />
+            <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:layout_marginTop="8dp"
-                android:layout_marginBottom="8dp"
-                android:background="?android:divider"
-                app:layout_constraintBottom_toBottomOf="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>
 
-            <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>
+    </com.google.android.material.card.MaterialCardView>
 
-</androidx.cardview.widget.CardView>
+</LinearLayout>

+ 77 - 49
app/src/main/res/layout/track_search_dialog.xml

@@ -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">
-
-        <com.google.android.material.textfield.TextInputEditText
-            android:id="@+id/track_search"
+        android:layout_height="wrap_content">
+
+        <androidx.appcompat.widget.Toolbar
+            android:id="@+id/toolbar"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:hint="@string/title"
-            android:inputType="text" />
+            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.textfield.TextInputLayout>
+    </com.google.android.material.appbar.AppBarLayout>
 
-    <FrameLayout
+    <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1">
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        app:layout_behavior="@string/appbar_scrolling_view_behavior">
 
-        <com.google.android.material.progressindicator.CircularProgressIndicator
-            android:id="@+id/progress"
-            android:layout_width="wrap_content"
+        <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: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_marginHorizontal="12dp"
+            android:layout_marginTop="8dp"
+            android:hint="@string/title">
+
+            <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" />
+
+        </com.google.android.material.textfield.TextInputLayout>
+
+        <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" />
-
-    </FrameLayout>
-
-</LinearLayout>
+            android:layout_height="0dp"
+            android:layout_weight="1">
+
+            <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" />
+
+            <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>

+ 53 - 51
app/src/main/res/layout/track_search_item.xml

@@ -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 - 0
app/src/main/res/menu/track_search.xml

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

+ 2 - 2
app/src/main/res/values/strings.xml

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

+ 19 - 18
app/src/main/res/values/styles.xml

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