feat(tile): dwie linie tytulu + zdejmowanie powtorzonej nazwy studia

Pomiar na 200 tys. grywalnych scen >=60 s (2026-08-13): przy JEDNEJ linii
pelny tytul widzialo **14,3%** scen. Mediana tytulu to 46 znakow, a w
kolumnie dwukolumnowej siatki miesci sie ~24 na linie, wiec 85,7% tytulow
bylo przycietych. Przy dwoch liniach pelny tytul widzi 54,4%.

To SWIADOMIE odwraca czesc wczesniejszej decyzji ("Jan feedback: wieksze
miniaturki, mniej tekstu" w docstringu tego pliku) — uzgodnione, bo tamta
uwaga dotyczyla nadmiaru metadanych, nie przycinania samego tytulu.
Miniaturka zostaje w tym samym rozmiarze, rosnie tylko blok tekstu (~18 px).

Do tego `titleWithoutStudio`: gdy druga linia pokazuje studio, zdejmujemy
jego nazwe z PRZODU tytulu ("MYLF - Aria's MILF Temptation" nad meta
"MYLF"). Dotyczy 8,2% scen. Zdejmujemy tylko przedrostek, wiec studio na
koncu tytulu ("… - ATKGirlfriends") zostaje nietkniete. Gdy po zdjeciu
zostaje <12 znakow, oddajemy tytul nietkniety, bo "Scene 1" jest gorsze
niz powtorzenie. 9 przypadkow testowych na realnych tytulach.

Korekta wlasnej diagnozy z przegladu: napisalem tam, ze tytul i studio
maja niemal rowna wage. Nieprawda — 14 px display/fg vs 10 px mono/muted
wersalikami. Hierarchia byla w porzadku, problemem bylo obciecie.
This commit is contained in:
goon-foss 2026-08-14 09:58:20 +02:00
parent 7deda639bf
commit 2a163cbf2c
2 changed files with 36 additions and 3 deletions

View file

@ -16,6 +16,14 @@ export type ChangelogEntry = {
};
export const CHANGELOG: ChangelogEntry[] = [
{
id: '2026-08-13e',
date: 'August 2026',
items: [
'Scene titles get two lines instead of one, so you can actually read them. Before, only about one title in seven fitted; now more than half do.',
'When a title just repeats the studio name that is already shown underneath, that part is dropped, so the space goes to the title itself.',
],
},
{
id: '2026-08-13d',
date: 'August 2026',

View file

@ -4,7 +4,9 @@
*
* Per impeccable.style/slop + Jan feedback "większe miniaturki, mniej tekstu":
* - Thumb wypełnia szerokość kolumny (aspect 16:9)
* - Title 1 linijka, weight 600, letter-spacing -0.2
* - Title do 2 linijek, weight 600, letter-spacing -0.2 (przy 1 linijce pełny tytuł
* widziało tylko 14,3% scen, mediana tytułu to 46 znaków). Gdy druga linia to studio,
* zdejmujemy jego nazwę z przodu tytułu, patrz `titleWithoutStudio`.
* - Pod tytułem: 1 linia uppercase micro-meta (studio | performers | tag, wybór per ekran)
* - Overlay na thumb: fav (top-left), duration (bottom-right), NEW (top-right gdy seenSince),
* ✓watched (top-right gdy finished)
@ -50,6 +52,25 @@ interface Props {
onLongPress?: () => void;
}
/**
* Tytuł bez nazwy studia sklejonej z przodu, bo studio stoi linijkę niżej.
*
* Dotyczy 8,2% scen (pomiar na 200 tys. grywalnych, 2026-08-13): „MYLF - Aria's MILF
* Temptation" nad metą „MYLF", „Thicc 18 - POV Action…" nad „THICC 18". Powtórzenie zjada
* znaki w miejscu, gdzie ich brakuje najbardziej: mediana tytułu to 46 znaków, a w kolumnie
* mieści się ~24 na linię.
*
* Gdy po zdjęciu zostaje mniej niż 12 znaków, ODDAJEMY tytuł nietknięty — lepsze
* powtórzenie niż ogryzek w rodzaju „Scene 1".
*/
function titleWithoutStudio(title: string, studio?: string | null): string {
const t = title.trim();
const s = (studio || '').trim();
if (!s || t.toLowerCase().indexOf(s.toLowerCase()) !== 0) return t;
const rest = t.slice(s.length).replace(/^[\s\-–—:|·]+/, '');
return rest.length >= 12 ? rest : t;
}
function SceneTileBase({ scene, secondLine = 'studio', seenSince, onLongPress }: Props) {
const navigation =
useNavigation<NativeStackNavigationProp<RootStackParamList>>();
@ -156,8 +177,12 @@ function SceneTileBase({ scene, secondLine = 'studio', seenSince, onLongPress }:
</Pressable>
) : null}
</View>
<Text style={[styles.title, dim && styles.titleDim]} numberOfLines={1}>
{scene.title}
{/* Dwie linie zamiast jednej: przy jednej pełny tytuł widziało 14,3% scen, przy
dwóch widzi 54,4%. Kafelek rośnie o ~18 px, miniaturka zostaje bez zmian. */}
<Text style={[styles.title, dim && styles.titleDim]} numberOfLines={2}>
{secondLine === 'studio'
? titleWithoutStudio(scene.title, scene.studio?.name)
: scene.title}
</Text>
{meta ? (
<Text style={styles.meta} numberOfLines={1}>