mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 22:57:21 +01:00
Confirmation prompts (replace browser confirmation prompts)
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
<template>
|
||||
<b-modal
|
||||
id="buy-modal"
|
||||
:hide-header="true"
|
||||
@change="onChange($event)"
|
||||
>
|
||||
<div>
|
||||
<b-modal
|
||||
id="buy-modal"
|
||||
:hide-header="true"
|
||||
@change="onChange($event)"
|
||||
>
|
||||
<span
|
||||
v-if="withPin"
|
||||
class="badge-dialog"
|
||||
@@ -226,7 +227,9 @@
|
||||
:amount-needed="item.value"
|
||||
/>
|
||||
</div>
|
||||
</b-modal>
|
||||
</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,11 +876,11 @@ 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)
|
||||
) {
|
||||
return;
|
||||
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') {
|
||||
|
||||
65
website/client/src/components/shops/purchaseConfirmModal.vue
Normal file
65
website/client/src/components/shops/purchaseConfirmModal.vue
Normal 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>
|
||||
@@ -1,9 +1,10 @@
|
||||
<template>
|
||||
<b-modal
|
||||
id="buy-quest-modal"
|
||||
:hide-header="true"
|
||||
@change="onChange($event)"
|
||||
>
|
||||
<div>
|
||||
<b-modal
|
||||
id="buy-quest-modal"
|
||||
:hide-header="true"
|
||||
@change="onChange($event)"
|
||||
>
|
||||
<span
|
||||
v-if="withPin"
|
||||
class="badge-dialog"
|
||||
@@ -114,7 +115,9 @@
|
||||
:amount-needed="item.value"
|
||||
/>
|
||||
</div>
|
||||
</b-modal>
|
||||
</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);
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<template>
|
||||
<b-modal
|
||||
id="broken-task-modal"
|
||||
title="Broken Challenge"
|
||||
size="sm"
|
||||
:hide-footer="true"
|
||||
>
|
||||
<div>
|
||||
<b-modal
|
||||
id="broken-task-modal"
|
||||
title="Broken Challenge"
|
||||
size="sm"
|
||||
:hide-footer="true"
|
||||
>
|
||||
<div
|
||||
v-if="brokenChallengeTask && brokenChallengeTask.challenge"
|
||||
class="modal-body"
|
||||
@@ -64,7 +65,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</b-modal>
|
||||
</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();
|
||||
},
|
||||
|
||||
@@ -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>
|
||||
@@ -1,8 +1,9 @@
|
||||
<template>
|
||||
<div
|
||||
class="task-wrapper"
|
||||
draggable
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="task-wrapper"
|
||||
draggable
|
||||
>
|
||||
<div
|
||||
class="task transition"
|
||||
:class="[{
|
||||
@@ -418,6 +419,8 @@
|
||||
:group="group"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<deleteTaskConfirmModal />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<b-modal
|
||||
id="task-modal"
|
||||
<div>
|
||||
<b-modal
|
||||
id="task-modal"
|
||||
:no-close-on-esc="true"
|
||||
:no-close-on-backdrop="true"
|
||||
size="sm"
|
||||
@@ -606,7 +607,9 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</b-modal>
|
||||
</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');
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user