Skip to content

Commit

Permalink
Update performer card UI (#465)
Browse files Browse the repository at this point in the history
- Use a different color & size for the performer's disambiguation
- Use the performer's death date when calculating age

Also removes a few unused fields from `PerformerData` which will save a
couple queries and refactors a few things.
  • Loading branch information
damontecres authored Nov 16, 2024
1 parent fde534f commit 6809d49
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 24 deletions.
7 changes: 1 addition & 6 deletions app/src/main/graphql/FindPerformers.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -73,19 +73,13 @@ fragment PerformerData on Performer {
image_count
gallery_count
group_count
performer_count
o_counter
created_at
updated_at
tags {
...SlimTagData
__typename
}
stash_ids {
stash_id
endpoint
__typename
}
rating100
details
death_date
Expand All @@ -100,5 +94,6 @@ fragment SlimPerformerData on Performer {
disambiguation
gender
birthdate
death_date
__typename
}
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,8 @@ class MainFragment : BrowseSupportFragment() {
if (row is FrontPageParser.FrontPageRow.Success) {
filterList.add(row.filter)

val adapter = ArrayObjectAdapter(StashPresenter.SELECTOR)
val adapter =
ArrayObjectAdapter(StashPresenter.defaultClassPresenterSelector())
adapter.addAll(0, row.data)
adapter.add(row.filter)
adapters.add(adapter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class PerformerDetailsFragment : DetailsFragment() {
addRow(R.string.stashapp_age, "$age (${perf.birthdate})")
}
}
addRow(R.string.stashapp_death_date, perf.death_date)
addRow(R.string.stashapp_country, perf.country)
addRow(R.string.stashapp_ethnicity, perf.ethnicity)
addRow(R.string.stashapp_hair_color, perf.hair_color)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class SearchForFragment : SearchSupportFragment(), SearchSupportFragment.SearchR
private var query: String? = null

private val adapter = SparseArrayObjectAdapter(ListRowPresenter())
private val searchResultsAdapter = ArrayObjectAdapter(StashPresenter.SELECTOR)
private val searchResultsAdapter = ArrayObjectAdapter()
private var perPage by Delegates.notNull<Int>()
private var createNewAdapter =
SingleItemObjectAdapter(CreateNewPresenter(), StashAction.CREATE_NEW)
Expand All @@ -87,7 +87,8 @@ class SearchForFragment : SearchSupportFragment(), SearchSupportFragment.SearchR
.getInt("maxSearchResults", 25)
title =
requireActivity().intent.getStringExtra(TITLE_KEY) ?: getString(dataType.pluralStringId)
searchResultsAdapter.presenterSelector = StashPresenter.SELECTOR

searchResultsAdapter.presenterSelector = StashPresenter.defaultClassPresenterSelector()
adapter.set(
RESULTS_POS,
ListRow(HeaderItem(getString(R.string.waiting_for_query)), ArrayObjectAdapter()),
Expand Down Expand Up @@ -163,6 +164,8 @@ class SearchForFragment : SearchSupportFragment(), SearchSupportFragment.SearchR
override fun onResume() {
super.onResume()
if (dataType in DATA_TYPE_SUGGESTIONS) {
val presenterSelector = StashPresenter.defaultClassPresenterSelector()

viewLifecycleOwner.lifecycleScope.launch(
StashCoroutineExceptionHandler {
Toast.makeText(
Expand All @@ -172,7 +175,7 @@ class SearchForFragment : SearchSupportFragment(), SearchSupportFragment.SearchR
)
},
) {
val resultsAdapter = ArrayObjectAdapter(StashPresenter.SELECTOR)
val resultsAdapter = ArrayObjectAdapter(presenterSelector)
val sortBy =
when (dataType) {
DataType.GALLERY -> "images_count"
Expand Down Expand Up @@ -228,7 +231,7 @@ class SearchForFragment : SearchSupportFragment(), SearchSupportFragment.SearchR
listOf()
}
}
val results = ArrayObjectAdapter(StashPresenter.SELECTOR)
val results = ArrayObjectAdapter(presenterSelector)
if (items.isNotEmpty()) {
Log.v(
TAG,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ class StashGridFragment() : Fragment() {
var backPressScrollEnabled = true

/**
* The presenter for the items, defaults to [StashPresenter.SELECTOR]
* The presenter for the items, defaults to [StashPresenter.defaultClassPresenterSelector]
*/
var presenterSelector: PresenterSelector = StashPresenter.SELECTOR
var presenterSelector: PresenterSelector = StashPresenter.defaultClassPresenterSelector()

/**
* The item clicked listener, will default to [StashItemViewClickListener] in [onViewCreated] if not specified before
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class StashSearchFragment : SearchSupportFragment(), SearchSupportFragment.Searc
)
val queryEngine = QueryEngine(StashServer.requireCurrentServer())
DataType.entries.forEach {
val adapter = ArrayObjectAdapter(StashPresenter.SELECTOR)
val adapter = ArrayObjectAdapter(StashPresenter.defaultClassPresenterSelector())
rowsAdapter.set(
it.ordinal,
ListRow(HeaderItem(getString(it.pluralStringId)), adapter),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class SearchPickerFragment(
private var query: String? = null

private val adapter = SparseArrayObjectAdapter(ListRowPresenter())
private val searchResultsAdapter = ArrayObjectAdapter(StashPresenter.SELECTOR)
private val searchResultsAdapter = ArrayObjectAdapter()
private var perPage by Delegates.notNull<Int>()

private val exceptionHandler =
Expand All @@ -72,7 +72,7 @@ class SearchPickerFragment(
.getInt("maxSearchResults", 25)
title =
requireActivity().intent.getStringExtra(TITLE_KEY) ?: getString(dataType.pluralStringId)
searchResultsAdapter.presenterSelector = StashPresenter.SELECTOR
searchResultsAdapter.presenterSelector = StashPresenter.defaultClassPresenterSelector()
adapter.set(
RESULTS_POS,
ListRow(HeaderItem(getString(R.string.waiting_for_query)), ArrayObjectAdapter()),
Expand Down Expand Up @@ -117,7 +117,8 @@ class SearchPickerFragment(
)
},
) {
val resultsAdapter = ArrayObjectAdapter(StashPresenter.SELECTOR)
val resultsAdapter =
ArrayObjectAdapter(StashPresenter.defaultClassPresenterSelector())
val sortBy =
when (dataType) {
DataType.GALLERY -> SortOption.IMAGES_COUNT
Expand Down Expand Up @@ -163,7 +164,8 @@ class SearchPickerFragment(
Log.v(TAG, "Got ${mostRecentIds.size} recent items")
if (mostRecentIds.isNotEmpty()) {
val items = queryEngine.getByIds(dataType, mostRecentIds)
val results = ArrayObjectAdapter(StashPresenter.SELECTOR)
val results =
ArrayObjectAdapter(StashPresenter.defaultClassPresenterSelector())
if (items.isNotEmpty()) {
Log.v(
TAG,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package com.github.damontecres.stashapp.presenters

import android.graphics.Color
import android.os.Build
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import android.text.style.RelativeSizeSpan
import com.github.damontecres.stashapp.R
import com.github.damontecres.stashapp.api.fragment.PerformerData
import com.github.damontecres.stashapp.data.DataType
import com.github.damontecres.stashapp.util.ageInYears
import com.github.damontecres.stashapp.util.isNotNullOrBlank
import java.util.EnumMap

open class PerformerPresenter(callback: LongClickCallBack<PerformerData>? = null) :
Expand All @@ -13,9 +18,19 @@ open class PerformerPresenter(callback: LongClickCallBack<PerformerData>? = null
cardView: StashImageCardView,
item: PerformerData,
) {
val title =
item.name + (if (!item.disambiguation.isNullOrBlank()) " (${item.disambiguation})" else "")
cardView.titleText = title
cardView.titleText =
SpannableStringBuilder().apply {
append(item.name)
val start = length
if (item.disambiguation.isNotNullOrBlank()) {
append(" (")
append(item.disambiguation)
append(")")
}
val end = length
setSpan(RelativeSizeSpan(.75f), start, end, 0)
setSpan(ForegroundColorSpan(Color.LTGRAY), start, end, 0)
}

cardView.contentText = getContentText(cardView, item)

Expand Down Expand Up @@ -47,6 +62,8 @@ open class PerformerPresenter(callback: LongClickCallBack<PerformerData>? = null
return if (item.birthdate != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val yearsOldStr = cardView.context.getString(R.string.stashapp_years_old)
"${item.ageInYears} $yearsOldStr"
} else if (item.birthdate.isNotNullOrBlank()) {
item.birthdate
} else {
null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ abstract class StashPresenter<T>(private val callback: LongClickCallBack<T>? = n
companion object {
private const val TAG = "StashPresenter"

val SELECTOR: ClassPresenterSelector =
ClassPresenterSelector()
fun defaultClassPresenterSelector(): ClassPresenterSelector {
return ClassPresenterSelector()
.addClassPresenter(PerformerData::class.java, PerformerPresenter())
.addClassPresenter(SlimSceneData::class.java, ScenePresenter())
.addClassPresenter(StudioData::class.java, StudioPresenter())
Expand All @@ -167,6 +167,7 @@ abstract class StashPresenter<T>(private val callback: LongClickCallBack<T>? = n
.addClassPresenter(OCounter::class.java, OCounterPresenter())
.addClassPresenter(CreateMarkerAction::class.java, CreateMarkerActionPresenter())
.addClassPresenter(GroupRelationshipData::class.java, GroupRelationshipPresenter())
}

fun glideError(context: Context): RequestBuilder<PictureDrawable> {
return Glide.with(context).`as`(PictureDrawable::class.java)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,14 @@ val PerformerData.ageInYears: Int?
if (birthdate != null) {
Period.between(
LocalDate.parse(birthdate, DateTimeFormatter.ISO_LOCAL_DATE),
LocalDate.now(),
if (death_date.isNotNullOrBlank()) {
LocalDate.parse(
death_date,
DateTimeFormatter.ISO_LOCAL_DATE,
)
} else {
LocalDate.now()
},
).years
} else {
null
Expand Down

0 comments on commit 6809d49

Please sign in to comment.