mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 15:17:25 +01:00
Confirmation prompts (replace browser confirmation prompts)
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<b-modal
|
<div>
|
||||||
id="buy-modal"
|
<b-modal
|
||||||
:hide-header="true"
|
id="buy-modal"
|
||||||
@change="onChange($event)"
|
:hide-header="true"
|
||||||
>
|
@change="onChange($event)"
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
v-if="withPin"
|
v-if="withPin"
|
||||||
class="badge-dialog"
|
class="badge-dialog"
|
||||||
@@ -226,7 +227,9 @@
|
|||||||
:amount-needed="item.value"
|
:amount-needed="item.value"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
|
<purchaseConfirmModal />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@@ -643,6 +646,7 @@ import EquipmentAttributesGrid from '../inventory/equipment/attributesGrid.vue';
|
|||||||
|
|
||||||
import Item from '@/components/inventory/item';
|
import Item from '@/components/inventory/item';
|
||||||
import Avatar from '@/components/avatar';
|
import Avatar from '@/components/avatar';
|
||||||
|
import purchaseConfirmModal from './purchaseConfirmModal.vue';
|
||||||
|
|
||||||
const dropEggs = eggs.drops;
|
const dropEggs = eggs.drops;
|
||||||
const dropPotions = hatchingPotions.drops;
|
const dropPotions = hatchingPotions.drops;
|
||||||
@@ -667,6 +671,7 @@ export default {
|
|||||||
PinBadge,
|
PinBadge,
|
||||||
CountdownBanner,
|
CountdownBanner,
|
||||||
numberIncrement,
|
numberIncrement,
|
||||||
|
purchaseConfirmModal,
|
||||||
},
|
},
|
||||||
mixins: [
|
mixins: [
|
||||||
avatarEditorUtilities,
|
avatarEditorUtilities,
|
||||||
@@ -851,10 +856,15 @@ export default {
|
|||||||
- ownedMounts
|
- ownedMounts
|
||||||
- ownedItems;
|
- ownedItems;
|
||||||
|
|
||||||
if (
|
if (petsRemaining < 0) {
|
||||||
petsRemaining < 0
|
const confirmed = await new Promise(resolve => {
|
||||||
&& !window.confirm(this.$t('purchasePetItemConfirm', { itemText: this.item.text })) // eslint-disable-line no-alert
|
this.$root.$emit('habitica:purchase-confirm', {
|
||||||
) return;
|
message: this.$t('purchasePetItemConfirm', { itemText: this.item.text }),
|
||||||
|
resolve,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
if (!confirmed) return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.item.purchaseType === 'customization') {
|
if (this.item.purchaseType === 'customization') {
|
||||||
@@ -866,11 +876,11 @@ export default {
|
|||||||
this.purchased(this.item.text);
|
this.purchased(this.item.text);
|
||||||
} else {
|
} else {
|
||||||
const shouldConfirmPurchase = this.item.currency === 'gems' || this.item.currency === 'hourglasses';
|
const shouldConfirmPurchase = this.item.currency === 'gems' || this.item.currency === 'hourglasses';
|
||||||
if (
|
if (shouldConfirmPurchase) {
|
||||||
shouldConfirmPurchase
|
const confirmed = await this.confirmPurchase(this.item.currency, this.item.value * this.selectedAmountToBuy);
|
||||||
&& !this.confirmPurchase(this.item.currency, this.item.value * this.selectedAmountToBuy)
|
if (!confirmed) {
|
||||||
) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
if (this.genericPurchase) {
|
if (this.genericPurchase) {
|
||||||
if (this.item.key === 'rebirth_orb') {
|
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>
|
<template>
|
||||||
<b-modal
|
<div>
|
||||||
id="buy-quest-modal"
|
<b-modal
|
||||||
:hide-header="true"
|
id="buy-quest-modal"
|
||||||
@change="onChange($event)"
|
:hide-header="true"
|
||||||
>
|
@change="onChange($event)"
|
||||||
|
>
|
||||||
<span
|
<span
|
||||||
v-if="withPin"
|
v-if="withPin"
|
||||||
class="badge-dialog"
|
class="badge-dialog"
|
||||||
@@ -114,7 +115,9 @@
|
|||||||
:amount-needed="item.value"
|
:amount-needed="item.value"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
|
<purchaseConfirmModal />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@@ -434,6 +437,7 @@ import numberIncrement from '@/components/shared/numberIncrement';
|
|||||||
import questDialogContent from './questDialogContent';
|
import questDialogContent from './questDialogContent';
|
||||||
import QuestRewards from './questRewards';
|
import QuestRewards from './questRewards';
|
||||||
import CloseIcon from '../../shared/closeIcon';
|
import CloseIcon from '../../shared/closeIcon';
|
||||||
|
import purchaseConfirmModal from '../purchaseConfirmModal.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -444,6 +448,7 @@ export default {
|
|||||||
questDialogContent,
|
questDialogContent,
|
||||||
CountdownBanner,
|
CountdownBanner,
|
||||||
numberIncrement,
|
numberIncrement,
|
||||||
|
purchaseConfirmModal,
|
||||||
},
|
},
|
||||||
mixins: [buyMixin, currencyMixin, notifications, numberInvalid],
|
mixins: [buyMixin, currencyMixin, notifications, numberInvalid],
|
||||||
props: {
|
props: {
|
||||||
@@ -510,8 +515,9 @@ export default {
|
|||||||
this.selectedAmountToBuy = 1;
|
this.selectedAmountToBuy = 1;
|
||||||
this.$emit('change', $event);
|
this.$emit('change', $event);
|
||||||
},
|
},
|
||||||
buyItem () {
|
async buyItem () {
|
||||||
if (!this.confirmPurchase(this.item.currency, this.item.value * this.selectedAmountToBuy)) {
|
const confirmed = await this.confirmPurchase(this.item.currency, this.item.value * this.selectedAmountToBuy);
|
||||||
|
if (!confirmed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.makeGenericPurchase(this.item, 'buyQuestModal', this.selectedAmountToBuy);
|
this.makeGenericPurchase(this.item, 'buyQuestModal', this.selectedAmountToBuy);
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<b-modal
|
<div>
|
||||||
id="broken-task-modal"
|
<b-modal
|
||||||
title="Broken Challenge"
|
id="broken-task-modal"
|
||||||
size="sm"
|
title="Broken Challenge"
|
||||||
:hide-footer="true"
|
size="sm"
|
||||||
>
|
:hide-footer="true"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
v-if="brokenChallengeTask && brokenChallengeTask.challenge"
|
v-if="brokenChallengeTask && brokenChallengeTask.challenge"
|
||||||
class="modal-body"
|
class="modal-body"
|
||||||
@@ -64,7 +65,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
|
<deleteTaskConfirmModal />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@@ -76,8 +79,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import { mapActions } from '@/libs/store';
|
import { mapActions } from '@/libs/store';
|
||||||
import notifications from '@/mixins/notifications';
|
import notifications from '@/mixins/notifications';
|
||||||
|
import deleteTaskConfirmModal from './deleteTaskConfirmModal.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
components: {
|
||||||
|
deleteTaskConfirmModal,
|
||||||
|
},
|
||||||
mixins: [notifications],
|
mixins: [notifications],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@@ -122,8 +129,14 @@ export default {
|
|||||||
});
|
});
|
||||||
this.close();
|
this.close();
|
||||||
},
|
},
|
||||||
removeTask () {
|
async removeTask () {
|
||||||
if (!window.confirm('Are you sure you want to delete this task?')) return; // eslint-disable-line no-alert
|
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.destroyTask(this.brokenChallengeTask);
|
||||||
this.close();
|
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>
|
<template>
|
||||||
<div
|
<div>
|
||||||
class="task-wrapper"
|
<div
|
||||||
draggable
|
class="task-wrapper"
|
||||||
>
|
draggable
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
class="task transition"
|
class="task transition"
|
||||||
:class="[{
|
:class="[{
|
||||||
@@ -418,6 +419,8 @@
|
|||||||
:group="group"
|
:group="group"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<deleteTaskConfirmModal />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -937,11 +940,13 @@ import scoreTask from '@/mixins/scoreTask';
|
|||||||
import sync from '@/mixins/sync';
|
import sync from '@/mixins/sync';
|
||||||
import approvalFooter from './approvalFooter';
|
import approvalFooter from './approvalFooter';
|
||||||
import MenuDropdown from '../ui/customMenuDropdown';
|
import MenuDropdown from '../ui/customMenuDropdown';
|
||||||
|
import deleteTaskConfirmModal from './deleteTaskConfirmModal.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
approvalFooter,
|
approvalFooter,
|
||||||
MenuDropdown,
|
MenuDropdown,
|
||||||
|
deleteTaskConfirmModal,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
markdown: markdownDirective,
|
markdown: markdownDirective,
|
||||||
@@ -1177,9 +1182,15 @@ export default {
|
|||||||
moveToBottom () {
|
moveToBottom () {
|
||||||
this.$emit('moveTo', this.task, 'bottom');
|
this.$emit('moveTo', this.task, 'bottom');
|
||||||
},
|
},
|
||||||
destroy () {
|
async destroy () {
|
||||||
const type = this.$t(this.task.type);
|
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.destroyTask(this.task);
|
||||||
this.$emit('taskDestroyed', this.task);
|
this.$emit('taskDestroyed', this.task);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<b-modal
|
<div>
|
||||||
id="task-modal"
|
<b-modal
|
||||||
|
id="task-modal"
|
||||||
:no-close-on-esc="true"
|
:no-close-on-esc="true"
|
||||||
:no-close-on-backdrop="true"
|
:no-close-on-backdrop="true"
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -606,7 +607,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</b-modal>
|
</b-modal>
|
||||||
|
<deleteTaskConfirmModal />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@@ -1050,6 +1053,7 @@ import chevronIcon from '@/assets/svg/chevron.svg?raw';
|
|||||||
import calendarIcon from '@/assets/svg/calendar.svg?raw';
|
import calendarIcon from '@/assets/svg/calendar.svg?raw';
|
||||||
import gripIcon from '@/assets/svg/grip.svg?raw';
|
import gripIcon from '@/assets/svg/grip.svg?raw';
|
||||||
import InformationIcon from '@/components/ui/informationIcon.vue';
|
import InformationIcon from '@/components/ui/informationIcon.vue';
|
||||||
|
import deleteTaskConfirmModal from './deleteTaskConfirmModal.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -1061,6 +1065,7 @@ export default {
|
|||||||
selectTranslatedArray,
|
selectTranslatedArray,
|
||||||
toggleCheckbox,
|
toggleCheckbox,
|
||||||
lockableLabel,
|
lockableLabel,
|
||||||
|
deleteTaskConfirmModal,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
markdown: markdownDirective,
|
markdown: markdownDirective,
|
||||||
@@ -1305,9 +1310,15 @@ export default {
|
|||||||
}
|
}
|
||||||
this.$root.$emit('bv::hide::modal', 'task-modal');
|
this.$root.$emit('bv::hide::modal', 'task-modal');
|
||||||
},
|
},
|
||||||
destroy () {
|
async destroy () {
|
||||||
const type = this.$t(this.task.type);
|
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.destroyTask(this.task);
|
||||||
this.$emit('taskDestroyed', this.task);
|
this.$emit('taskDestroyed', this.task);
|
||||||
this.$root.$emit('bv::hide::modal', 'task-modal');
|
this.$root.$emit('bv::hide::modal', 'task-modal');
|
||||||
|
|||||||
@@ -39,7 +39,13 @@ export default {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const purchaseForKey = currencyToPurchaseForKey[currency];
|
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