Android build v1.0.38

This commit is contained in:
Warren H
2026-06-20 18:06:39 -04:00
parent bab2dce6c3
commit f8a1fbc5e2
4 changed files with 210 additions and 15 deletions
Binary file not shown.
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId "com.warren.iwanttoheal" applicationId "com.warren.iwanttoheal"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 57 versionCode 58
versionName "1.0.37" versionName "1.0.38"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions { aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
+176 -11
View File
@@ -1683,7 +1683,8 @@ h2 {
.equipment-screen .equipment-layout, .equipment-screen .equipment-layout,
.equipment-screen .crafting-panel, .equipment-screen .crafting-panel,
.talent-screen .talent-tree { .talent-screen .talent-tree,
.talent-screen .spell-effect-layout {
flex: 1; flex: 1;
min-height: 0; min-height: 0;
} }
@@ -3474,6 +3475,8 @@ h2 {
.effect-pool-panel { .effect-pool-panel {
background: #191b25; background: #191b25;
border: 2px solid #090a0d; border: 2px solid #090a0d;
display: flex;
flex-direction: column;
min-height: 0; min-height: 0;
outline: 2px solid #3a3944; outline: 2px solid #3a3944;
padding: 12px; padding: 12px;
@@ -3581,24 +3584,30 @@ h2 {
} }
.effect-pool { .effect-pool {
align-content: start;
display: grid; display: grid;
flex: 1;
gap: 10px; gap: 10px;
grid-template-columns: repeat(3, minmax(0, 1fr)); grid-template-columns: repeat(4, minmax(0, 1fr));
grid-template-rows: repeat(2, 62px);
margin-top: 12px; margin-top: 12px;
min-height: 0;
overflow: hidden;
} }
.effect-pool > button { .effect-pool > button {
align-items: center; align-content: center;
background: #20222d; background: #20222d;
border: 2px solid #090a0d; border: 2px solid #090a0d;
color: var(--ink); color: var(--ink);
cursor: pointer; cursor: pointer;
display: grid; display: grid;
gap: 10px; gap: 6px;
grid-template-columns: 34px minmax(0, 1fr) auto; grid-template-columns: 26px minmax(0, 1fr);
min-height: 72px; min-height: 0;
outline: 2px solid #3a3944; outline: 2px solid #3a3944;
padding: 9px; overflow: hidden;
padding: 7px;
text-align: left; text-align: left;
} }
@@ -3623,7 +3632,7 @@ h2 {
color: var(--gold); color: var(--gold);
display: flex; display: flex;
font-family: 'Press Start 2P', monospace; font-family: 'Press Start 2P', monospace;
height: 34px; height: 26px;
justify-content: center; justify-content: center;
} }
@@ -3634,17 +3643,54 @@ h2 {
.effect-pool strong { .effect-pool strong {
font-family: 'Press Start 2P', monospace; font-family: 'Press Start 2P', monospace;
font-size: 8px; font-size: 7px;
line-height: 1.35; line-height: 1.35;
} }
.effect-pool small { .effect-pool small {
color: var(--muted); color: var(--muted);
font-size: 14px; font-size: 11px;
line-height: 1; line-height: 1;
margin-top: 5px; margin-top: 5px;
} }
.effect-pool > button i {
grid-column: 1 / -1;
line-height: 1;
}
.effect-pager {
align-items: center;
display: flex;
gap: 8px;
justify-content: flex-end;
margin-top: 8px;
}
.effect-pager button {
background: #15161c;
border: 2px solid #090a0d;
color: var(--ink);
cursor: pointer;
font-family: 'Press Start 2P', monospace;
font-size: 7px;
min-height: 28px;
outline: 2px solid #41404a;
padding: 4px 8px;
text-transform: uppercase;
}
.effect-pager button:disabled {
color: #676773;
cursor: not-allowed;
}
.effect-pager span {
color: var(--gold);
font-family: 'Press Start 2P', monospace;
font-size: 8px;
}
@media (max-width: 800px) { @media (max-width: 800px) {
.spell-effect-layout { .spell-effect-layout {
grid-template-columns: 1fr; grid-template-columns: 1fr;
@@ -3655,7 +3701,7 @@ h2 {
} }
.effect-pool { .effect-pool {
grid-template-columns: 1fr; grid-template-columns: repeat(2, minmax(0, 1fr));
} }
.selected-effect-strip { .selected-effect-strip {
@@ -7576,6 +7622,125 @@ h2 {
margin-top: 4px; margin-top: 4px;
} }
.workshop-shell .spell-effect-layout {
gap: 6px;
grid-template-columns: 172px minmax(0, 1fr);
margin-top: 5px;
overflow: hidden;
}
.workshop-shell .effect-slots-panel,
.workshop-shell .effect-pool-panel {
padding: 5px;
}
.workshop-shell .effect-slots-panel {
gap: 5px;
grid-auto-rows: minmax(43px, 1fr);
}
.workshop-shell .effect-slot {
min-height: 0;
overflow: hidden;
padding: 5px;
}
.workshop-shell .effect-slot span,
.workshop-shell .effect-pool > button i,
.workshop-shell .effect-panel-heading > span,
.workshop-shell .effect-pager span {
font-size: 6px;
}
.workshop-shell .effect-slot strong {
font-size: 6px;
line-height: 1.15;
margin-top: 3px;
}
.workshop-shell .effect-slot small {
font-size: 9px;
line-height: 1;
margin-top: 2px;
max-height: 18px;
overflow: hidden;
}
.workshop-shell .effect-panel-heading h2 {
font-size: 9px;
line-height: 1.1;
}
.workshop-shell .selected-effect-strip {
gap: 6px;
grid-template-columns: minmax(0, 1fr) auto;
margin-top: 5px;
padding: 5px;
}
.workshop-shell .selected-effect-strip .eyebrow {
display: none;
}
.workshop-shell .selected-effect-strip strong {
font-size: 7px;
line-height: 1.1;
margin-top: 0;
}
.workshop-shell .selected-effect-strip small {
font-size: 10px;
line-height: 1;
margin-top: 3px;
max-height: 20px;
overflow: hidden;
}
.workshop-shell .selected-effect-strip .primary-button {
font-size: 7px;
min-height: 25px;
min-width: 72px;
padding: 3px 6px;
}
.workshop-shell .effect-pool {
gap: 5px;
grid-template-columns: repeat(4, minmax(0, 1fr));
grid-template-rows: repeat(2, 52px);
margin-top: 5px;
}
.workshop-shell .effect-pool > button {
gap: 4px;
grid-template-columns: 22px minmax(0, 1fr);
padding: 4px;
}
.workshop-shell .effect-pool > button > span {
height: 22px;
}
.workshop-shell .effect-pool strong {
font-size: 6px;
line-height: 1.15;
}
.workshop-shell .effect-pool small {
font-size: 9px;
margin-top: 2px;
}
.workshop-shell .effect-pager {
gap: 5px;
margin-top: 4px;
}
.workshop-shell .effect-pager button {
font-size: 6px;
min-height: 22px;
padding: 2px 5px;
}
.workshop-shell .talent-tier { .workshop-shell .talent-tier {
gap: 6px; gap: 6px;
grid-template-columns: 66px minmax(0, 1fr); grid-template-columns: 66px minmax(0, 1fr);
+32 -2
View File
@@ -16,6 +16,7 @@ type Props = {
const EFFECT_SLOT_LEVELS = [5, 10, 15, 20] as const const EFFECT_SLOT_LEVELS = [5, 10, 15, 20] as const
const EFFECT_CLASS_ID = 1 const EFFECT_CLASS_ID = 1
const EFFECTS_PER_PAGE = 8
const EFFECT_SOURCE_LABELS: Record<string, string> = { const EFFECT_SOURCE_LABELS: Record<string, string> = {
mend: 'Mend', mend: 'Mend',
radiance: 'Radiance', radiance: 'Radiance',
@@ -42,6 +43,7 @@ export function TalentScreen({ profile, onBack, onUpdated, embedded = false }: P
const [busyTalentId, setBusyTalentId] = useState<number | null>(null) const [busyTalentId, setBusyTalentId] = useState<number | null>(null)
const [resetting, setResetting] = useState(false) const [resetting, setResetting] = useState(false)
const [selectedTalentId, setSelectedTalentId] = useState<number | null>(null) const [selectedTalentId, setSelectedTalentId] = useState<number | null>(null)
const [effectPage, setEffectPage] = useState(0)
const [message, setMessage] = useState('') const [message, setMessage] = useState('')
const scrollRef = useRef<number>(0) const scrollRef = useRef<number>(0)
const gameClass = profile.classes.find( const gameClass = profile.classes.find(
@@ -54,6 +56,11 @@ export function TalentScreen({ profile, onBack, onUpdated, embedded = false }: P
?? selectedEffects[0] ?? selectedEffects[0]
?? gameClass.talents[0] ?? gameClass.talents[0]
?? null ?? null
const effectPageCount = Math.max(1, Math.ceil(gameClass.talents.length / EFFECTS_PER_PAGE))
const visibleTalents = gameClass.talents.slice(
effectPage * EFFECTS_PER_PAGE,
effectPage * EFFECTS_PER_PAGE + EFFECTS_PER_PAGE,
)
useEffect(() => { useEffect(() => {
window.scrollTo(0, scrollRef.current) window.scrollTo(0, scrollRef.current)
@@ -64,6 +71,10 @@ export function TalentScreen({ profile, onBack, onUpdated, embedded = false }: P
setSelectedTalentId(selectedTalent?.id ?? null) setSelectedTalentId(selectedTalent?.id ?? null)
}, [gameClass.talents, selectedTalent?.id, selectedTalentId]) }, [gameClass.talents, selectedTalent?.id, selectedTalentId])
useEffect(() => {
setEffectPage((page) => Math.min(page, effectPageCount - 1))
}, [effectPageCount])
function saveScroll() { function saveScroll() {
scrollRef.current = window.scrollY scrollRef.current = window.scrollY
} }
@@ -225,7 +236,7 @@ export function TalentScreen({ profile, onBack, onUpdated, embedded = false }: P
)} )}
</div> </div>
<div className="effect-pool"> <div className="effect-pool">
{gameClass.talents.map((talent) => { {visibleTalents.map((talent) => {
const reason = lockReason(talent) const reason = lockReason(talent)
const active = talent.rank > 0 const active = talent.rank > 0
const selected = selectedTalent?.id === talent.id const selected = selectedTalent?.id === talent.id
@@ -244,13 +255,32 @@ export function TalentScreen({ profile, onBack, onUpdated, embedded = false }: P
<span>{talent.glyph}</span> <span>{talent.glyph}</span>
<div> <div>
<strong>{talent.name}</strong> <strong>{talent.name}</strong>
<small>{talent.description}</small> <small>{EFFECT_SOURCE_LABELS[effectSource(talent.effectType)] ?? 'Spell'}</small>
</div> </div>
<i>{isBusy ? 'Saving' : active ? 'Active' : reason || 'Available'}</i> <i>{isBusy ? 'Saving' : active ? 'Active' : reason || 'Available'}</i>
</button> </button>
) )
})} })}
</div> </div>
{effectPageCount > 1 && (
<div className="effect-pager">
<button
disabled={effectPage === 0}
onClick={() => setEffectPage((page) => Math.max(0, page - 1))}
type="button"
>
Prev
</button>
<span>{effectPage + 1}/{effectPageCount}</span>
<button
disabled={effectPage >= effectPageCount - 1}
onClick={() => setEffectPage((page) => Math.min(effectPageCount - 1, page + 1))}
type="button"
>
Next
</button>
</div>
)}
</section> </section>
</div> </div>
)} )}