Add Cancel button to character-creation Revise flows
Clicking Revise on basic records, techniques, or J/Q/K assignment now offers a Cancel button that throws away any edits made since Revise and restores the previously-saved values. Basic-records cancel is a pure client-side toggle; techniques/face cancel re-submit a snapshot taken at Revise time (since Revise immediately unsubmits/unassigns server-side). Also added Cancel to the recruit-creation basic-records revise. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2
TODO.md
2
TODO.md
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
- [x] **Modal name popup**. When a Pi-Rat gains a name, they get a modal popup they have to fill out before continuing, rather than an optional box on their character sheet
|
- [x] **Modal name popup**. When a Pi-Rat gains a name, they get a modal popup they have to fill out before continuing, rather than an optional box on their character sheet
|
||||||
|
|
||||||
- [ ] **Cancel Revise**. In character creation, if you click "Revise" and then don't want to make any changes after all, there should be a cancel button that throws away any edits you've made since you clicked revise.
|
- [x] **Cancel Revise**. In character creation, if you click "Revise" and then don't want to make any changes after all, there should be a cancel button that throws away any edits you've made since you clicked revise.
|
||||||
|
|
||||||
- [ ] **Teaching mode**. The creator/admin should have an option to seed themselves as the player who is forced to be the Deep for the first scene
|
- [ ] **Teaching mode**. The creator/admin should have an option to seed themselves as the player who is forced to be the Deep for the first scene
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,11 @@
|
|||||||
editingBasic = true;
|
editingBasic = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Discard any edits made since clicking Revise and return to the saved view.
|
||||||
|
function cancelReviseBasic() {
|
||||||
|
editingBasic = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Like/Hate tasks are assigned automatically when character creation starts.
|
// Like/Hate tasks are assigned automatically when character creation starts.
|
||||||
// This is a fallback for games that entered the phase before assignments existed.
|
// This is a fallback for games that entered the phase before assignments existed.
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
@@ -63,6 +68,10 @@
|
|||||||
let tech1 = '', tech2 = '', tech3 = '';
|
let tech1 = '', tech2 = '', tech3 = '';
|
||||||
let savingTechs = false;
|
let savingTechs = false;
|
||||||
let techError = '';
|
let techError = '';
|
||||||
|
// True while editing previously-submitted techniques (vs. first-time entry),
|
||||||
|
// so we know to offer a Cancel button. techSnapshot holds the saved values.
|
||||||
|
let revisingTechs = false;
|
||||||
|
let techSnapshot = [];
|
||||||
|
|
||||||
async function submitTechniques() {
|
async function submitTechniques() {
|
||||||
savingTechs = true;
|
savingTechs = true;
|
||||||
@@ -71,6 +80,7 @@
|
|||||||
await apiRequest(`/game/${state.game.id}/player/${state.player.id}/submit-techniques`, 'POST', {
|
await apiRequest(`/game/${state.game.id}/player/${state.player.id}/submit-techniques`, 'POST', {
|
||||||
tech1, tech2, tech3
|
tech1, tech2, tech3
|
||||||
});
|
});
|
||||||
|
revisingTechs = false;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
techError = e.message;
|
techError = e.message;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -79,12 +89,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function reviseTechniques() {
|
async function reviseTechniques() {
|
||||||
|
techSnapshot = [...createdTechniques];
|
||||||
[tech1 = '', tech2 = '', tech3 = ''] = createdTechniques;
|
[tech1 = '', tech2 = '', tech3 = ''] = createdTechniques;
|
||||||
|
revisingTechs = true;
|
||||||
techError = '';
|
techError = '';
|
||||||
try {
|
try {
|
||||||
await apiRequest(`/game/${state.game.id}/player/${state.player.id}/unsubmit-techniques`, 'POST');
|
await apiRequest(`/game/${state.game.id}/player/${state.player.id}/unsubmit-techniques`, 'POST');
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
techError = e.message;
|
techError = e.message;
|
||||||
|
revisingTechs = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Throw away edits and re-submit the techniques as they were before Revise.
|
||||||
|
async function cancelReviseTechniques() {
|
||||||
|
savingTechs = true;
|
||||||
|
techError = '';
|
||||||
|
try {
|
||||||
|
await apiRequest(`/game/${state.game.id}/player/${state.player.id}/submit-techniques`, 'POST', {
|
||||||
|
tech1: techSnapshot[0] || '',
|
||||||
|
tech2: techSnapshot[1] || '',
|
||||||
|
tech3: techSnapshot[2] || ''
|
||||||
|
});
|
||||||
|
revisingTechs = false;
|
||||||
|
} catch(e) {
|
||||||
|
techError = e.message;
|
||||||
|
} finally {
|
||||||
|
savingTechs = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,6 +158,9 @@
|
|||||||
let jackTech = '', queenTech = '', kingTech = '';
|
let jackTech = '', queenTech = '', kingTech = '';
|
||||||
let assigningFace = false;
|
let assigningFace = false;
|
||||||
let faceError = '';
|
let faceError = '';
|
||||||
|
// True while revising a previously-assigned J/Q/K layout, so we offer Cancel.
|
||||||
|
let revisingFace = false;
|
||||||
|
let faceSnapshot = {};
|
||||||
|
|
||||||
async function assignFaceTechniques() {
|
async function assignFaceTechniques() {
|
||||||
assigningFace = true;
|
assigningFace = true;
|
||||||
@@ -137,6 +171,7 @@
|
|||||||
queen: queenTech,
|
queen: queenTech,
|
||||||
king: kingTech
|
king: kingTech
|
||||||
});
|
});
|
||||||
|
revisingFace = false;
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
faceError = e.message;
|
faceError = e.message;
|
||||||
} finally {
|
} finally {
|
||||||
@@ -145,14 +180,39 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function reviseFaceTechniques() {
|
async function reviseFaceTechniques() {
|
||||||
|
faceSnapshot = {
|
||||||
|
jack: state.player.tech_jack,
|
||||||
|
queen: state.player.tech_queen,
|
||||||
|
king: state.player.tech_king
|
||||||
|
};
|
||||||
jackTech = state.player.tech_jack;
|
jackTech = state.player.tech_jack;
|
||||||
queenTech = state.player.tech_queen;
|
queenTech = state.player.tech_queen;
|
||||||
kingTech = state.player.tech_king;
|
kingTech = state.player.tech_king;
|
||||||
|
revisingFace = true;
|
||||||
faceError = '';
|
faceError = '';
|
||||||
try {
|
try {
|
||||||
await apiRequest(`/game/${state.game.id}/player/${state.player.id}/unassign-face-techniques`, 'POST');
|
await apiRequest(`/game/${state.game.id}/player/${state.player.id}/unassign-face-techniques`, 'POST');
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
faceError = e.message;
|
faceError = e.message;
|
||||||
|
revisingFace = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Throw away edits and re-assign the J/Q/K layout as it was before Revise.
|
||||||
|
async function cancelReviseFaceTechniques() {
|
||||||
|
assigningFace = true;
|
||||||
|
faceError = '';
|
||||||
|
try {
|
||||||
|
await apiRequest(`/game/${state.game.id}/player/${state.player.id}/assign-face-techniques`, 'POST', {
|
||||||
|
jack: faceSnapshot.jack,
|
||||||
|
queen: faceSnapshot.queen,
|
||||||
|
king: faceSnapshot.king
|
||||||
|
});
|
||||||
|
revisingFace = false;
|
||||||
|
} catch(e) {
|
||||||
|
faceError = e.message;
|
||||||
|
} finally {
|
||||||
|
assigningFace = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,7 +305,12 @@
|
|||||||
{#if devMode}<button type="button" class="btn btn-secondary btn-small" on:click={() => basicDetails.good_at_math = getSuggestion('good_at_math')}>Suggest</button>{/if}
|
{#if devMode}<button type="button" class="btn btn-secondary btn-small" on:click={() => basicDetails.good_at_math = getSuggestion('good_at_math')}>Suggest</button>{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary btn-full" disabled={savingBasic}>Save Records</button>
|
<div class="input-row mt-4">
|
||||||
|
<button type="submit" class="btn btn-primary btn-full" disabled={savingBasic}>Save Records</button>
|
||||||
|
{#if basicComplete}
|
||||||
|
<button type="button" class="btn btn-secondary" disabled={savingBasic} on:click={cancelReviseBasic}>Cancel</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
@@ -350,6 +415,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary btn-full glow-effect" disabled={savingTechs}>Submit Techniques to Swap Pool</button>
|
<button type="submit" class="btn btn-primary btn-full glow-effect" disabled={savingTechs}>Submit Techniques to Swap Pool</button>
|
||||||
|
{#if revisingTechs}
|
||||||
|
<button type="button" class="btn btn-secondary btn-full mt-4" disabled={savingTechs} on:click={cancelReviseTechniques}>Cancel — keep my original techniques</button>
|
||||||
|
{/if}
|
||||||
</form>
|
</form>
|
||||||
{:else if phase === 'character_creation'}
|
{:else if phase === 'character_creation'}
|
||||||
<div class="submitted-techniques text-center mt-4">
|
<div class="submitted-techniques text-center mt-4">
|
||||||
@@ -470,6 +538,13 @@
|
|||||||
>
|
>
|
||||||
{assigningFace ? 'Assigning...' : 'Assign to Cards'}
|
{assigningFace ? 'Assigning...' : 'Assign to Cards'}
|
||||||
</button>
|
</button>
|
||||||
|
{#if revisingFace}
|
||||||
|
<button
|
||||||
|
class="btn btn-secondary w-full mt-4"
|
||||||
|
disabled={assigningFace}
|
||||||
|
on:click={cancelReviseFaceTechniques}
|
||||||
|
>Cancel — keep my original assignment</button>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
|
|||||||
@@ -56,6 +56,11 @@
|
|||||||
editingBasic = true;
|
editingBasic = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Discard any edits made since clicking Revise and return to the saved view.
|
||||||
|
function cancelReviseBasic() {
|
||||||
|
editingBasic = false;
|
||||||
|
}
|
||||||
|
|
||||||
$: basicComplete = !!(me.avatar_look && me.avatar_smell && me.first_words && me.good_at_math);
|
$: basicComplete = !!(me.avatar_look && me.avatar_smell && me.first_words && me.good_at_math);
|
||||||
$: likeDone = !me.other_like_from_player_id || !!me.other_like;
|
$: likeDone = !me.other_like_from_player_id || !!me.other_like;
|
||||||
$: hateDone = !me.other_hate_from_player_id || !!me.other_hate;
|
$: hateDone = !me.other_hate_from_player_id || !!me.other_hate;
|
||||||
@@ -191,7 +196,12 @@
|
|||||||
{#if devMode}<button type="button" class="btn btn-secondary btn-small" on:click={() => basicDetails.good_at_math = getSuggestion('good_at_math')}>Suggest</button>{/if}
|
{#if devMode}<button type="button" class="btn btn-secondary btn-small" on:click={() => basicDetails.good_at_math = getSuggestion('good_at_math')}>Suggest</button>{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button type="submit" class="btn btn-primary btn-full" disabled={savingBasic}>Save Records</button>
|
<div class="input-row mt-4">
|
||||||
|
<button type="submit" class="btn btn-primary btn-full" disabled={savingBasic}>Save Records</button>
|
||||||
|
{#if basicComplete}
|
||||||
|
<button type="button" class="btn btn-secondary" disabled={savingBasic} on:click={cancelReviseBasic}>Cancel</button>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user