add a loader for purchasing, refactor some stuff and fix issues, make IAP not reset on hard reset

This commit is contained in:
IvarK 2022-08-13 20:24:19 +03:00
parent c8748a22f4
commit 2010c63e6c
6 changed files with 81 additions and 24 deletions

View File

@ -1,4 +1,6 @@
const Payments = {
interval: null,
windowReference: null,
init: () => {
// We have unfinished checkouts
if (player.IAP.checkoutSession.id) {
@ -6,6 +8,7 @@ const Payments = {
}
},
buyMoreSTD: async STD => {
player.IAP.checkoutSession = { id: true };
const res = await fetch("https://antimatterdimensionspayments.ew.r.appspot.com/purchase", {
method: "POST",
headers: {
@ -14,20 +17,25 @@ const Payments = {
body: JSON.stringify({ amount: STD })
});
const data = await res.json();
const windowReference = window.open(
Payments.windowReference = window.open(
data.url,
"antimatterDimensionsPurchase",
"popup,width=500,height=500,left=100,top=100"
);
player.IAP.checkoutSession = { id: data.id, amount: STD };
GameStorage.save();
Payments.pollForPurchases(windowReference);
Payments.pollForPurchases();
},
pollForPurchases: (windowReference = undefined) => {
pollForPurchases: () => {
console.log("Polling for purchases...");
const { id, amount } = player.IAP.checkoutSession;
let pollAmount = 0;
const polling = setInterval(async() => {
window.onbeforeunload = async() => {
if (!Payments.interval) return;
Payments.windowReference?.close();
await Payments.cancelPurchase();
};
Payments.interval = setInterval(async() => {
pollAmount++;
const statusRes = await fetch(
`https://antimatterdimensionspayments.ew.r.appspot.com/validate?sessionId=${id}`
@ -35,10 +43,10 @@ const Payments = {
const { completed, failure } = await statusRes.json();
if (completed) {
windowReference?.close();
Payments.windowReference?.close();
player.IAP.totalSTD += amount;
GameUI.notify.success(`Purchase of ${amount} STDs was successful, thank you for your support! ❤️`, 10000);
clearInterval(polling);
Payments.clearInterval();
player.IAP.checkoutSession = { id: false };
GameStorage.save();
Modal.hide();
@ -46,28 +54,37 @@ const Payments = {
if (failure) {
windowReference?.close();
clearInterval(polling);
Payments.windowReference?.close();
Payments.clearInterval();
GameUI.notify.error(`Purchase failed!`, 10000);
player.IAP.checkoutSession = { id: false };
GameStorage.save();
return;
}
// 30 minutes of polling is the maximum
if (!completed && (windowReference?.closed || pollAmount >= 20 * 30)) {
clearInterval(polling);
await fetch("https://antimatterdimensionspayments.ew.r.appspot.com/expire", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ sessionId: id })
});
GameUI.notify.error(`Purchase failed!`, 10000);
player.IAP.checkoutSession = { id: false };
GameStorage.save();
if (!completed && (Payments.windowReference?.closed || pollAmount >= 20 * 30)) {
await Payments.cancelPurchase();
}
}, 3000);
},
async cancelPurchase() {
Payments.windowReference?.close();
Payments.clearInterval();
await fetch("https://antimatterdimensionspayments.ew.r.appspot.com/expire", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ sessionId: player.IAP.checkoutSession.id })
});
GameUI.notify.error(`Purchase failed!`, 10000);
player.IAP.checkoutSession = { id: false };
GameStorage.save();
},
clearInterval() {
clearInterval(Payments.interval);
window.onbeforeunload = () => true;
}
};

View File

@ -27,9 +27,9 @@ GameDatabase.shopPurchases = {
},
replicantiPurchases: {
key: "replicantiPurchases",
cost: 40,
description: "Triple your Replicanti gain. (additive)",
multiplier: purchases => (purchases === 0 ? 1 : 3 * purchases),
cost: 60,
description: "Double your Replicanti gain. (additive)",
multiplier: purchases => (purchases === 0 ? 1 : 2 * purchases),
},
dilatedTimePurchases: {
key: "dilatedTimePurchases",

View File

@ -186,7 +186,9 @@ export const GameStorage = {
},
hardReset() {
const IAP = JSON.parse(JSON.stringify(player.IAP));
this.loadPlayerObject(Player.defaultStart);
player.IAP = IAP;
this.save(true);
Tab.dimensions.antimatter.show();
},

19
package-lock.json generated
View File

@ -26,6 +26,7 @@
"vis-util": "^4.0.0",
"vue": "^2.6.11",
"vue-gtag": "^1.16.1",
"vue-loading-overlay": "^3.4.2",
"vue-splitpane": "^1.0.6",
"vuedraggable": "^2.24.3"
},
@ -15724,6 +15725,18 @@
"node": ">=8"
}
},
"node_modules/vue-loading-overlay": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/vue-loading-overlay/-/vue-loading-overlay-3.4.2.tgz",
"integrity": "sha512-xcB+NPjl76eA0uggm707x3ZFgrNosZXpynHipyS3K+rrK1NztOV49R1LY+/4ij5W1KYANp7eRI2EIHrxCpmWAw==",
"engines": {
"node": ">=6.9.0",
"npm": ">=3.10.0"
},
"peerDependencies": {
"vue": "^2.0.0"
}
},
"node_modules/vue-resize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-1.0.1.tgz",
@ -28342,6 +28355,12 @@
}
}
},
"vue-loading-overlay": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/vue-loading-overlay/-/vue-loading-overlay-3.4.2.tgz",
"integrity": "sha512-xcB+NPjl76eA0uggm707x3ZFgrNosZXpynHipyS3K+rrK1NztOV49R1LY+/4ij5W1KYANp7eRI2EIHrxCpmWAw==",
"requires": {}
},
"vue-resize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-1.0.1.tgz",

View File

@ -27,6 +27,7 @@
"vis-util": "^4.0.0",
"vue": "^2.6.11",
"vue-gtag": "^1.16.1",
"vue-loading-overlay": "^3.4.2",
"vue-splitpane": "^1.0.6",
"vuedraggable": "^2.24.3"
},

View File

@ -1,14 +1,22 @@
<script>
import "vue-loading-overlay/dist/vue-loading.css";
import Loading from "vue-loading-overlay";
import Payments from "../../../../javascripts/core/payments";
import ShopButton from "./ShopButton";
export default {
name: "ShopTab",
components: {
ShopButton
ShopButton,
Loading
},
data() {
return {
STD: 0,
isLoading: false
};
},
computed: {
@ -22,11 +30,15 @@ export default {
methods: {
update() {
this.STD = player.IAP.totalSTD - player.IAP.spentSTD;
this.isLoading = Boolean(player.IAP.checkoutSession.id);
},
showStore() {
SecretAchievement(33).unlock();
Modal.shop.show();
},
onCancel() {
Payments.cancelPurchase();
}
},
};
</script>
@ -57,6 +69,12 @@ export default {
:purchase="purchase"
/>
</div>
<loading
:active="isLoading"
:can-cancel="true"
:on-cancel="onCancel"
:is-full-page="true"
/>
</div>
</template>