Confirmation prompts (replace browser confirmation prompts)

This commit is contained in:
Hafiz
2025-11-06 12:59:57 -06:00
parent 270ff2e034
commit ccc7e7d7a7
8 changed files with 231 additions and 44 deletions

View File

@@ -1,4 +1,5 @@
<template>
<div>
<b-modal
id="buy-modal"
:hide-header="true"
@@ -227,6 +228,8 @@
/>
</div>
</b-modal>
<purchaseConfirmModal />
</div>
</template>
<style lang="scss">
@@ -643,6 +646,7 @@ import EquipmentAttributesGrid from '../inventory/equipment/attributesGrid.vue';
import Item from '@/components/inventory/item';
import Avatar from '@/components/avatar';
import purchaseConfirmModal from './purchaseConfirmModal.vue';
const dropEggs = eggs.drops;
const dropPotions = hatchingPotions.drops;
@@ -667,6 +671,7 @@ export default {
PinBadge,
CountdownBanner,
numberIncrement,
purchaseConfirmModal,
},
mixins: [
avatarEditorUtilities,
@@ -851,10 +856,15 @@ export default {
- ownedMounts
- ownedItems;
if (
petsRemaining < 0
&& !window.confirm(this.$t('purchasePetItemConfirm', { itemText: this.item.text })) // eslint-disable-line no-alert
) return;
if (petsRemaining < 0) {
const confirmed = await new Promise(resolve => {
this.$root.$emit('habitica:purchase-confirm', {
message: this.$t('purchasePetItemConfirm', { itemText: this.item.text }),
resolve,
});
});
if (!confirmed) return;
}
}
if (this.item.purchaseType === 'customization') {
@@ -866,12 +876,12 @@ export default {
this.purchased(this.item.text);
} else {
const shouldConfirmPurchase = this.item.currency === 'gems' || this.item.currency === 'hourglasses';
if (
shouldConfirmPurchase
&& !this.confirmPurchase(this.item.currency, this.item.value * this.selectedAmountToBuy)
) {
if (shouldConfirmPurchase) {
const confirmed = await this.confirmPurchase(this.item.currency, this.item.value * this.selectedAmountToBuy);
if (!confirmed) {
return;
}
}
if (this.genericPurchase) {
if (this.item.key === 'rebirth_orb') {
localStorage.setItem('show-rebirth-confirmation', 'true');

View File

@@ -0,0 +1,65 @@
<template>
<b-modal
id="purchase-confirm-modal"
size="md"
:hide-footer="true"
>
<div class="text-center">
<h2 class="col-12">
{{ confirmationMessage }}
</h2>
</div>
<div class="modal-footer d-flex justify-content-between">
<button
class="btn btn-primary"
@click="confirm()"
>
{{ $t('confirm') }}
</button>
<button
class="btn btn-secondary"
@click="cancel()"
>
{{ $t('cancel') }}
</button>
</div>
</b-modal>
</template>
<script>
export default {
data () {
return {
confirmationMessage: '',
resolveCallback: null,
};
},
mounted () {
this.$root.$on('habitica:purchase-confirm', config => {
this.confirmationMessage = config.message;
this.resolveCallback = config.resolve;
this.$root.$emit('bv::show::modal', 'purchase-confirm-modal');
});
},
beforeDestroy () {
this.$root.$off('habitica:purchase-confirm');
},
methods: {
confirm () {
if (this.resolveCallback) {
this.resolveCallback(true);
}
this.close();
},
cancel () {
if (this.resolveCallback) {
this.resolveCallback(false);
}
this.close();
},
close () {
this.$root.$emit('bv::hide::modal', 'purchase-confirm-modal');
},
},
};
</script>

View File

@@ -1,4 +1,5 @@
<template>
<div>
<b-modal
id="buy-quest-modal"
:hide-header="true"
@@ -115,6 +116,8 @@
/>
</div>
</b-modal>
<purchaseConfirmModal />
</div>
</template>
<style lang="scss">
@@ -434,6 +437,7 @@ import numberIncrement from '@/components/shared/numberIncrement';
import questDialogContent from './questDialogContent';
import QuestRewards from './questRewards';
import CloseIcon from '../../shared/closeIcon';
import purchaseConfirmModal from '../purchaseConfirmModal.vue';
export default {
components: {
@@ -444,6 +448,7 @@ export default {
questDialogContent,
CountdownBanner,
numberIncrement,
purchaseConfirmModal,
},
mixins: [buyMixin, currencyMixin, notifications, numberInvalid],
props: {
@@ -510,8 +515,9 @@ export default {
this.selectedAmountToBuy = 1;
this.$emit('change', $event);
},
buyItem () {
if (!this.confirmPurchase(this.item.currency, this.item.value * this.selectedAmountToBuy)) {
async buyItem () {
const confirmed = await this.confirmPurchase(this.item.currency, this.item.value * this.selectedAmountToBuy);
if (!confirmed) {
return;
}
this.makeGenericPurchase(this.item, 'buyQuestModal', this.selectedAmountToBuy);

View File

@@ -1,4 +1,5 @@
<template>
<div>
<b-modal
id="broken-task-modal"
title="Broken Challenge"
@@ -65,6 +66,8 @@
</div>
</div>
</b-modal>
<deleteTaskConfirmModal />
</div>
</template>
<style scoped>
@@ -76,8 +79,12 @@
<script>
import { mapActions } from '@/libs/store';
import notifications from '@/mixins/notifications';
import deleteTaskConfirmModal from './deleteTaskConfirmModal.vue';
export default {
components: {
deleteTaskConfirmModal,
},
mixins: [notifications],
data () {
return {
@@ -122,8 +129,14 @@ export default {
});
this.close();
},
removeTask () {
if (!window.confirm('Are you sure you want to delete this task?')) return; // eslint-disable-line no-alert
async removeTask () {
const confirmed = await new Promise(resolve => {
this.$root.$emit('habitica:delete-task-confirm', {
message: 'Are you sure you want to delete this task?',
resolve,
});
});
if (!confirmed) return;
this.destroyTask(this.brokenChallengeTask);
this.close();
},

View File

@@ -0,0 +1,65 @@
<template>
<b-modal
id="delete-task-confirm-modal"
size="md"
:hide-footer="true"
>
<div class="text-center">
<h2 class="col-12">
{{ confirmationMessage }}
</h2>
</div>
<div class="modal-footer d-flex justify-content-between">
<button
class="btn btn-danger"
@click="confirm()"
>
{{ $t('delete') }}
</button>
<button
class="btn btn-secondary"
@click="cancel()"
>
{{ $t('cancel') }}
</button>
</div>
</b-modal>
</template>
<script>
export default {
data () {
return {
confirmationMessage: '',
resolveCallback: null,
};
},
mounted () {
this.$root.$on('habitica:delete-task-confirm', config => {
this.confirmationMessage = config.message;
this.resolveCallback = config.resolve;
this.$root.$emit('bv::show::modal', 'delete-task-confirm-modal');
});
},
beforeDestroy () {
this.$root.$off('habitica:delete-task-confirm');
},
methods: {
confirm () {
if (this.resolveCallback) {
this.resolveCallback(true);
}
this.close();
},
cancel () {
if (this.resolveCallback) {
this.resolveCallback(false);
}
this.close();
},
close () {
this.$root.$emit('bv::hide::modal', 'delete-task-confirm-modal');
},
},
};
</script>

View File

@@ -1,4 +1,5 @@
<template>
<div>
<div
class="task-wrapper"
draggable
@@ -419,6 +420,8 @@
/>
</div>
</div>
<deleteTaskConfirmModal />
</div>
</template>
<!-- eslint-disable max-len -->
@@ -937,11 +940,13 @@ import scoreTask from '@/mixins/scoreTask';
import sync from '@/mixins/sync';
import approvalFooter from './approvalFooter';
import MenuDropdown from '../ui/customMenuDropdown';
import deleteTaskConfirmModal from './deleteTaskConfirmModal.vue';
export default {
components: {
approvalFooter,
MenuDropdown,
deleteTaskConfirmModal,
},
directives: {
markdown: markdownDirective,
@@ -1177,9 +1182,15 @@ export default {
moveToBottom () {
this.$emit('moveTo', this.task, 'bottom');
},
destroy () {
async destroy () {
const type = this.$t(this.task.type);
if (!window.confirm(this.$t('sureDeleteType', { type }))) return; // eslint-disable-line no-alert
const confirmed = await new Promise(resolve => {
this.$root.$emit('habitica:delete-task-confirm', {
message: this.$t('sureDeleteType', { type }),
resolve,
});
});
if (!confirmed) return;
this.destroyTask(this.task);
this.$emit('taskDestroyed', this.task);
},

View File

@@ -1,4 +1,5 @@
<template>
<div>
<b-modal
id="task-modal"
:no-close-on-esc="true"
@@ -607,6 +608,8 @@
</form>
</div>
</b-modal>
<deleteTaskConfirmModal />
</div>
</template>
<style lang="scss">
@@ -1050,6 +1053,7 @@ import chevronIcon from '@/assets/svg/chevron.svg?raw';
import calendarIcon from '@/assets/svg/calendar.svg?raw';
import gripIcon from '@/assets/svg/grip.svg?raw';
import InformationIcon from '@/components/ui/informationIcon.vue';
import deleteTaskConfirmModal from './deleteTaskConfirmModal.vue';
export default {
components: {
@@ -1061,6 +1065,7 @@ export default {
selectTranslatedArray,
toggleCheckbox,
lockableLabel,
deleteTaskConfirmModal,
},
directives: {
markdown: markdownDirective,
@@ -1305,9 +1310,15 @@ export default {
}
this.$root.$emit('bv::hide::modal', 'task-modal');
},
destroy () {
async destroy () {
const type = this.$t(this.task.type);
if (!window.confirm(this.$t('sureDeleteType', { type }))) return; // eslint-disable-line no-alert
const confirmed = await new Promise(resolve => {
this.$root.$emit('habitica:delete-task-confirm', {
message: this.$t('sureDeleteType', { type }),
resolve,
});
});
if (!confirmed) return;
this.destroyTask(this.task);
this.$emit('taskDestroyed', this.task);
this.$root.$emit('bv::hide::modal', 'task-modal');

View File

@@ -39,7 +39,13 @@ export default {
};
const purchaseForKey = currencyToPurchaseForKey[currency];
return window.confirm(this.$t(purchaseForKey, { cost })); // eslint-disable-line no-alert
return new Promise(resolve => {
this.$root.$emit('habitica:purchase-confirm', {
message: this.$t(purchaseForKey, { cost }),
resolve,
});
});
},
},
};