Android build v1.0.38
This commit is contained in:
Binary file not shown.
@@ -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
@@ -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);
|
||||||
|
|||||||
@@ -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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user