Compare commits

..

1 Commits

Author SHA1 Message Date
Warren H 66f5af4484 Android build v1.0.40 2026-06-20 20:16:20 -04:00
5 changed files with 21 additions and 36 deletions
Binary file not shown.
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId "com.warren.iwanttoheal"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 59
versionName "1.0.39"
versionCode 60
versionName "1.0.40"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
-10
View File
@@ -1952,16 +1952,6 @@ h2 {
grid-template-columns: 1fr;
}
.part-start-row {
display: grid;
gap: 8px;
grid-template-columns: minmax(0, 1fr) minmax(82px, 0.38fr);
}
.hard-mode-button {
border-color: #c25b4b;
}
.part-setup-panel .primary-button {
min-height: 54px;
}
+14 -19
View File
@@ -88,7 +88,6 @@ function App() {
const [roguelikeUpgradeTiming, setRoguelikeUpgradeTiming] = useState<RoguelikeUpgradeTiming>('encounter')
const [roguelikeAbilityLabelMode, setRoguelikeAbilityLabelMode] = useState<RoguelikeAbilityLabelMode>('ability')
const [pvpContentType, setPvpContentType] = useState<PvpContentType>('dungeon')
const [selectedPart, setSelectedPart] = useState(1)
const [selectedMarathonMode, setSelectedMarathonMode] = useState(false)
const [activityPage, setActivityPage] = useState(0)
const [combatContentId, setCombatContentId] = useState(1)
@@ -233,7 +232,6 @@ function App() {
const roguelikePool = profile.dungeons
.filter((candidate) => candidate.contentType === roguelikeKind)
.flatMap((candidate) => candidate.encounters)
const startPart = selectedPart
return (
<CombatScreen
difficulty={difficulty}
@@ -245,7 +243,7 @@ function App() {
roguelikeUpgradeTiming={combatContentId < 0 ? roguelikeUpgradeTiming : undefined}
roguelikeAbilityLabelMode={combatContentId < 0 ? roguelikeAbilityLabelMode : undefined}
roguelikeEncounterPool={combatContentId < 0 ? roguelikePool : undefined}
startPart={startPart}
startPart={1}
onExit={() => {
setScreen(combatContentId < 0 ? 'roguelike' : dungeon.contentType === 'raid' ? 'raids' : 'dungeons')
}}
@@ -298,7 +296,6 @@ function App() {
setCombatContentId(-1)
setSelectedDifficultyId(baseDungeon?.difficulties[0]?.id ?? 1)
}
setSelectedPart(1)
setSelectedMarathonMode(false)
setScreen('combat')
}
@@ -318,24 +315,24 @@ function App() {
?? tierOptions.slice().reverse().find((candidate) => profile.character.level >= candidate.unlockLevel)
?? tierOptions[0]
const selectedTierItemLevel = selectedTier?.droppedItemLevel ?? 0
const tierActivityOptions = activityOptions.filter((option) =>
option.difficulties.some((difficulty) => difficulty.droppedItemLevel === selectedTierItemLevel),
)
const activityPageCount = Math.max(1, Math.ceil(tierActivityOptions.length / ACTIVITY_PAGE_SIZE))
const activityPageCount = Math.max(1, Math.ceil(activityOptions.length / ACTIVITY_PAGE_SIZE))
const currentActivityPage = Math.min(activityPage, activityPageCount - 1)
const pagedActivityOptions = tierActivityOptions.slice(
const pagedActivityOptions = activityOptions.slice(
currentActivityPage * ACTIVITY_PAGE_SIZE,
currentActivityPage * ACTIVITY_PAGE_SIZE + ACTIVITY_PAGE_SIZE,
)
const activityPageStart = activityOptions.length === 0
? 0
: currentActivityPage * ACTIVITY_PAGE_SIZE + 1
const activityPageEnd = Math.min(activityOptions.length, (currentActivityPage + 1) * ACTIVITY_PAGE_SIZE)
const selectedActivityId = screen === 'raids' && raid ? raid.id : dungeon.id
const activity = tierActivityOptions.find((candidate) => candidate.id === selectedActivityId)
?? tierActivityOptions[0]
const activity = activityOptions.find((candidate) => candidate.id === selectedActivityId)
?? activityOptions[0]
?? (screen === 'raids' && raid ? raid : dungeon)
const selectedDifficulty = activity.difficulties.find(
(candidate) => candidate.droppedItemLevel === selectedTierItemLevel,
) ?? activity.difficulties[0]
const difficultyLocked = profile.character.level < selectedDifficulty.unlockLevel
const sectionName = activity.contentType === 'raid' ? 'Phase' : 'Part'
const activityCompletionCount = activity.completionCount ?? 0
const marathonUnlocked = activityCompletionCount >= 10
const cloudSync = getCloudSyncStatus()
@@ -652,7 +649,7 @@ function App() {
>
Prev
</button>
<span>{currentActivityPage + 1}/{activityPageCount}</span>
<span>{activityPageStart}-{activityPageEnd} of {activityOptions.length}</span>
<button
disabled={currentActivityPage >= activityPageCount - 1}
onClick={() => setActivityPage((page) => Math.min(activityPageCount - 1, page + 1))}
@@ -764,7 +761,6 @@ function App() {
className="primary-button selected-part"
disabled={difficultyLocked}
onClick={() => {
setSelectedPart(1)
setSelectedMarathonMode(false)
setCombatContentId(activity.id)
setSelectedDifficultyId(selectedDifficulty.id)
@@ -778,7 +774,6 @@ function App() {
className={`primary-button ${selectedMarathonMode ? 'selected-part' : ''} ${!marathonUnlocked ? 'locked' : ''}`}
disabled={difficultyLocked || !marathonUnlocked}
onClick={() => {
setSelectedPart(1)
setSelectedMarathonMode(true)
setCombatContentId(activity.id)
setSelectedDifficultyId(selectedDifficulty.id)
@@ -900,10 +895,10 @@ function App() {
</p>
<div className="leaderboard-tabs">
{([
{ key: 'part_1', label: `${sectionName} 1` },
{ key: 'part_2', label: `${sectionName} 2` },
{ key: 'part_3', label: `${sectionName} 3` },
{ key: 'full_run', label: 'Full Run' },
{ key: 'part_1', label: 'Run' },
{ key: 'part_2', label: 'Legacy 2' },
{ key: 'part_3', label: 'Legacy 3' },
{ key: 'full_run', label: 'Legacy Full' },
] as const).map((tab) => (
<button
key={tab.key}
+5 -5
View File
@@ -402,7 +402,7 @@ export function CombatScreen({
})),
[dungeon.partySize, profile.character.name],
)
const sectionName = isRoguelike ? 'Stage' : dungeon.contentType === 'raid' ? 'Phase' : 'Part'
const sectionName = isRoguelike ? 'Stage' : 'Run'
const contentName = isRoguelike ? 'Roguelike' : dungeon.contentType === 'raid' ? 'Raid' : 'Dungeon'
const initialEncounterIndex = (startPart - 1) * 3
const enemyCount = hardMode ? 2 : 1
@@ -1365,7 +1365,7 @@ export function CombatScreen({
}).reverse()
const dualScreenState = useMemo<DualScreenCombatState>(() => ({
difficultyName: difficulty.name,
dungeonName: hardMode ? `${dungeon.name} Hard` : dungeon.name,
dungeonName: dungeon.name,
contentName,
encounterName: encounter.enemyName,
encounterDescription: encounter.description,
@@ -1444,7 +1444,7 @@ export function CombatScreen({
>
{!dualScreenEnabled && <header className="topbar">
<div>
<p className="eyebrow">{difficulty.name}{hardMode ? ' Hard' : ''} - Item Level {difficulty.droppedItemLevel}</p>
<p className="eyebrow">{difficulty.name} - Item Level {difficulty.droppedItemLevel}</p>
<h1>{dungeon.name}</h1>
</div>
<div className="combat-header-actions">
@@ -1467,7 +1467,7 @@ export function CombatScreen({
</div>
<div className="enemy-info">
<div className="bar-label">
<strong>{hardMode ? `${encounter.enemyName} x2` : encounter.enemyName}</strong>
<strong>{encounter.enemyName}</strong>
<span>{Math.ceil(enemyHealth)} / {encounterMaxHealth}</span>
</div>
{hardMode ? (
@@ -1796,7 +1796,7 @@ export function CombatScreen({
<div>
<p className="eyebrow">{sectionName} Complete</p>
<h2>{encounter.enemyName} Defeated</h2>
<p>{canContinueAfterPart ? `Proceed to ${sectionName} ${currentPart + 1} or end the run?` : 'Hard mode for this section is complete.'}</p>
<p>{canContinueAfterPart ? `Proceed to ${sectionName} ${currentPart + 1} or end the run?` : 'Run checkpoint complete.'}</p>
{canContinueAfterPart && (
<button
onClick={() => {