1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-14 00:14:18 +00:00
JUCE/examples/InAppPurchase/Source/VoicePurchases.h

207 lines
7.6 KiB
C++

/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2017 - ROLI Ltd.
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 5 End-User License
Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
27th April 2017).
End User License Agreement: www.juce.com/juce-5-licence
Privacy Policy: www.juce.com/juce-5-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
//==============================================================================
class VoicePurchases : private InAppPurchases::Listener
{
public:
//==============================================================================
struct VoiceProduct
{
const char* identifier;
const char* humanReadable;
bool isPurchased, priceIsKnown, purchaseInProgress;
String purchasePrice;
};
//==============================================================================
VoicePurchases (AsyncUpdater& asyncUpdater)
: guiUpdater (asyncUpdater)
{
voiceProducts = Array<VoiceProduct>(
{VoiceProduct {"robot", "Robot", true, true, false, "Free" },
VoiceProduct {"jules", "Jules", false, false, false, "Retrieving price..." },
VoiceProduct {"fabian", "Fabian", false, false, false, "Retrieving price..." },
VoiceProduct {"ed", "Ed", false, false, false, "Retrieving price..." },
VoiceProduct {"lukasz", "Lukasz", false, false, false, "Retrieving price..." },
VoiceProduct {"jb", "JB", false, false, false, "Retrieving price..." } });
}
~VoicePurchases()
{
inAppPurchases.removeListener (this);
}
//==============================================================================
VoiceProduct getPurchase (int voiceIndex)
{
if (! havePurchasesBeenRestored)
{
havePurchasesBeenRestored = true;
inAppPurchases.addListener (this);
inAppPurchases.restoreProductsBoughtList (true);
}
return voiceProducts[voiceIndex];
}
void purchaseVoice (int voiceIndex)
{
if (havePricesBeenFetched && isPositiveAndBelow (voiceIndex, voiceProducts.size()))
{
auto& product = voiceProducts.getReference (voiceIndex);
if (! product.isPurchased)
{
product.purchaseInProgress = true;
inAppPurchases.purchaseProduct (product.identifier, false);
}
}
}
StringArray getVoiceNames() const
{
StringArray names;
for (auto& voiceProduct : voiceProducts)
names.add (voiceProduct.humanReadable);
return names;
}
private:
//==============================================================================
void productsInfoReturned (const Array<InAppPurchases::Product>& products) override
{
if (! inAppPurchases.isInAppPurchasesSupported())
{
for (auto idx = 1; idx < voiceProducts.size(); ++idx)
{
auto& voiceProduct = voiceProducts.getReference (idx);
voiceProduct.isPurchased = false;
voiceProduct.priceIsKnown = false;
voiceProduct.purchasePrice = "In-App purcahses unavailable";
}
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
"In-app purchase is unavailable!",
"In-App purchases are not available. This either means you are trying "
"to use IAP on a platform that does not support IAP or you haven't setup "
"your app correctly to work with IAP.",
"OK");
}
else
{
for (auto product : products)
{
auto idx = findVoiceIndexFromIdentifier (product.identifier);
if (isPositiveAndBelow (idx, voiceProducts.size()))
{
auto& voiceProduct = voiceProducts.getReference (idx);
voiceProduct.priceIsKnown = true;
voiceProduct.purchasePrice = product.price;
}
}
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
"Your credit card will be charged!",
"You are running the sample code for JUCE In-App purchases. "
"Although this is only sample code, it will still CHARGE YOUR CREDIT CARD!",
"Understood!");
}
guiUpdater.triggerAsyncUpdate();
}
void productPurchaseFinished (const PurchaseInfo& info, bool success, const String&) override
{
auto idx = findVoiceIndexFromIdentifier (info.purchase.productId);
if (isPositiveAndBelow (idx, voiceProducts.size()))
{
auto& voiceProduct = voiceProducts.getReference (idx);
voiceProduct.isPurchased = success;
voiceProduct.purchaseInProgress = false;
guiUpdater.triggerAsyncUpdate();
}
}
void purchasesListRestored (const Array<PurchaseInfo>& infos, bool success, const String&) override
{
if (success)
{
for (auto& info : infos)
{
auto idx = findVoiceIndexFromIdentifier (info.purchase.productId);
if (isPositiveAndBelow (idx, voiceProducts.size()))
{
auto& voiceProduct = voiceProducts.getReference (idx);
voiceProduct.isPurchased = true;
}
}
guiUpdater.triggerAsyncUpdate();
}
if (! havePricesBeenFetched)
{
havePricesBeenFetched = true;
StringArray identifiers;
for (auto& voiceProduct : voiceProducts)
identifiers.add (voiceProduct.identifier);
inAppPurchases.getProductsInformation(identifiers);
}
}
//==============================================================================
int findVoiceIndexFromIdentifier (String identifier) const
{
identifier = identifier.toLowerCase();
for (auto i = 0; i < voiceProducts.size(); ++i)
if (String (voiceProducts.getReference (i).identifier) == identifier)
return i;
return -1;
}
//==============================================================================
AsyncUpdater& guiUpdater;
bool havePurchasesBeenRestored = false, havePricesBeenFetched = false;
InAppPurchases inAppPurchases;
Array<VoiceProduct> voiceProducts;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (VoicePurchases)
};