mirror of
https://github.com/jonasbark/swiftcontrol.git
synced 2026-02-18 00:17:40 +01:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
661d72fa8c | ||
|
|
38df962e43 | ||
|
|
e02563733f | ||
|
|
c246d2d1fe | ||
|
|
8dbed9a8b5 | ||
|
|
6ea4fa82a7 |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -335,9 +335,7 @@ jobs:
|
||||
run: msstore reconfigure --tenantId $ --clientId $ --clientSecret $ --sellerId $
|
||||
|
||||
- name: Create MSIX package
|
||||
run: |
|
||||
$version = "${{ env.VERSION }}" -replace '\+', '.'
|
||||
dart run msix:create --version $version
|
||||
run: dart run msix:create
|
||||
|
||||
- name: Publish MSIX to the Microsoft Store
|
||||
if: false
|
||||
|
||||
@@ -302,7 +302,7 @@ abstract class BluetoothDevice extends BaseDevice {
|
||||
),
|
||||
if (firmwareVersion != null)
|
||||
DeviceInfo(
|
||||
title: context.i18n.signal,
|
||||
title: context.i18n.firmware,
|
||||
icon: this is ZwiftDevice && firmwareVersion != (this as ZwiftDevice).latestFirmwareVersion
|
||||
? Icons.warning
|
||||
: Icons.text_fields_sharp,
|
||||
|
||||
@@ -52,7 +52,7 @@ class OpenBikeControlMdnsEmulator extends TrainerConnection {
|
||||
throw 'Could not find network interface';
|
||||
}
|
||||
|
||||
_createTcpServer();
|
||||
await _createTcpServer();
|
||||
|
||||
if (kDebugMode) {
|
||||
enableLogging(LogTopic.calls);
|
||||
|
||||
@@ -63,7 +63,7 @@ class FtmsMdnsEmulator extends TrainerConnection {
|
||||
throw 'Could not find network interface';
|
||||
}
|
||||
|
||||
_createTcpServer();
|
||||
await _createTcpServer();
|
||||
|
||||
if (kDebugMode) {
|
||||
enableLogging(LogTopic.calls);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:bike_control/bluetooth/messages/notification.dart';
|
||||
import 'package:bike_control/main.dart';
|
||||
import 'package:bike_control/utils/core.dart';
|
||||
import 'package:bike_control/utils/iap/iap_manager.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
@@ -14,7 +16,7 @@ class WindowsIAPService {
|
||||
static const int trialDays = 7;
|
||||
static const int dailyCommandLimit = 15;
|
||||
|
||||
static const String _purchaseStatusKey = 'iap_purchase_status';
|
||||
static const String _purchaseStatusKey = 'iap_purchase_status_2';
|
||||
static const String _dailyCommandCountKey = 'iap_daily_command_count';
|
||||
static const String _lastCommandDateKey = 'iap_last_command_date';
|
||||
|
||||
@@ -51,13 +53,15 @@ class WindowsIAPService {
|
||||
Future<void> _checkExistingPurchase() async {
|
||||
// First check if we have a stored purchase status
|
||||
final storedStatus = await _prefs.read(key: _purchaseStatusKey);
|
||||
core.connection.signalNotification(LogNotification('Is purchased status: $storedStatus'));
|
||||
if (storedStatus == "true") {
|
||||
IAPManager.instance.isPurchased.value = true;
|
||||
return;
|
||||
}
|
||||
final trial = await _windowsIapPlugin.getTrialStatusAndRemainingDays();
|
||||
core.connection.signalNotification(LogNotification('Trial status: $trial'));
|
||||
trialDaysRemaining = trial.remainingDays;
|
||||
if (!trial.isTrial && trial.remainingDays <= 0) {
|
||||
if (trial.isActive && !trial.isTrial && trial.remainingDays <= 0) {
|
||||
IAPManager.instance.isPurchased.value = true;
|
||||
await _prefs.write(key: _purchaseStatusKey, value: "true");
|
||||
} else {
|
||||
@@ -71,6 +75,7 @@ class WindowsIAPService {
|
||||
try {
|
||||
final status = await _windowsIapPlugin.makePurchase(productId);
|
||||
if (status == StorePurchaseStatus.succeeded || status == StorePurchaseStatus.alreadyPurchased) {
|
||||
IAPManager.instance.isPurchased.value = true;
|
||||
/*buildToast(
|
||||
navigatorKey.currentContext!,
|
||||
title: 'Purchase Successful',
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-only</key>
|
||||
<true/>
|
||||
<key>keychain-access-groups</key>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
name: bike_control
|
||||
description: "BikeControl - Control your virtual riding"
|
||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
version: 4.2.0+59
|
||||
version: 4.2.2+62
|
||||
|
||||
environment:
|
||||
sdk: ^3.9.0
|
||||
|
||||
@@ -123,7 +123,7 @@ Future<void> main() async {
|
||||
required Widget child,
|
||||
}) => CustomFrame(
|
||||
platform: size.type,
|
||||
title: 'BikeControl connects to any controller',
|
||||
title: 'Control your favorite trainer app using ANY controller',
|
||||
device: device,
|
||||
child: child,
|
||||
),
|
||||
|
||||
@@ -1,6 +1,18 @@
|
||||
class Trial {
|
||||
final bool isTrial;
|
||||
final int remainingDays;
|
||||
final bool isActive;
|
||||
final bool isTrialOwnedByThisUser;
|
||||
|
||||
Trial({required this.isTrial, required this.remainingDays});
|
||||
Trial({
|
||||
required this.isTrial,
|
||||
required this.remainingDays,
|
||||
required this.isActive,
|
||||
required this.isTrialOwnedByThisUser,
|
||||
});
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Trial{isTrial: $isTrial, remainingDays: $remainingDays, isActive: $isActive, isTrialOwnedByThisUser: $isTrialOwnedByThisUser}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@ const _escapeMap = {
|
||||
};
|
||||
|
||||
/// A [RegExp] that matches whitespace characters that should be escaped.
|
||||
var _escapeRegExp = RegExp('[\\x00-\\x07\\x0E-\\x1F${_escapeMap.keys.map(_getHexLiteral).join()}]');
|
||||
var _escapeRegExp = RegExp(
|
||||
'[\\x00-\\x07\\x0E-\\x1F${_escapeMap.keys.map(_getHexLiteral).join()}]');
|
||||
|
||||
/// Returns [str] with all whitespace characters represented as their escape
|
||||
/// sequences.
|
||||
@@ -51,7 +52,8 @@ class MethodChannelWindowsIap extends WindowsIapPlatform {
|
||||
|
||||
@override
|
||||
Future<StorePurchaseStatus?> makePurchase(String storeId) async {
|
||||
final result = await methodChannel.invokeMethod<int>('makePurchase', {'storeId': storeId});
|
||||
final result = await methodChannel
|
||||
.invokeMethod<int>('makePurchase', {'storeId': storeId});
|
||||
if (result == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -72,9 +74,12 @@ class MethodChannelWindowsIap extends WindowsIapPlatform {
|
||||
|
||||
@override
|
||||
Stream<List<Product>> productsStream() {
|
||||
return const EventChannel('windows_iap_event_products').receiveBroadcastStream().map((event) {
|
||||
return const EventChannel('windows_iap_event_products')
|
||||
.receiveBroadcastStream()
|
||||
.map((event) {
|
||||
if (event is String) {
|
||||
return parseListNotNull(json: jsonDecode(escape(event)), fromJson: Product.fromJson);
|
||||
return parseListNotNull(
|
||||
json: jsonDecode(escape(event)), fromJson: Product.fromJson);
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
@@ -87,20 +92,26 @@ class MethodChannelWindowsIap extends WindowsIapPlatform {
|
||||
if (result == null) {
|
||||
return [];
|
||||
}
|
||||
return parseListNotNull(json: jsonDecode(escape(result)), fromJson: Product.fromJson);
|
||||
return parseListNotNull(
|
||||
json: jsonDecode(escape(result)), fromJson: Product.fromJson);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> checkPurchase({required String storeId}) async {
|
||||
final result = await methodChannel.invokeMethod<bool>('checkPurchase', {'storeId': storeId});
|
||||
final result = await methodChannel
|
||||
.invokeMethod<bool>('checkPurchase', {'storeId': storeId});
|
||||
return result ?? false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Trial> getTrialStatusAndRemainingDays() async {
|
||||
final result = await methodChannel.invokeMethod<Map>('getTrialStatusAndRemainingDays');
|
||||
final result =
|
||||
await methodChannel.invokeMethod<Map>('getTrialStatusAndRemainingDays');
|
||||
return Trial(
|
||||
isTrial: result?['isTrial'] as bool? ?? false,
|
||||
isActive: result?['isActive'] as bool? ?? false,
|
||||
isTrialOwnedByThisUser:
|
||||
result?['isTrialOwnedByThisUser'] as bool? ?? false,
|
||||
remainingDays: result?['remainingDays'] as int? ?? 0,
|
||||
);
|
||||
}
|
||||
@@ -111,6 +122,7 @@ class MethodChannelWindowsIap extends WindowsIapPlatform {
|
||||
if (result == null) {
|
||||
return {};
|
||||
}
|
||||
return result.map((key, value) => MapEntry(key.toString(), StoreLicense.fromJson(jsonDecode(value))));
|
||||
return result.map((key, value) =>
|
||||
MapEntry(key.toString(), StoreLicense.fromJson(jsonDecode(value))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,54 +27,63 @@ using namespace Windows::Services::Store;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
namespace foundation = Windows::Foundation;
|
||||
|
||||
namespace windows_iap {
|
||||
namespace windows_iap
|
||||
{
|
||||
|
||||
//////////////////////////////////////////////////////////////////////// BEGIN OF MY CODE //////////////////////////////////////////////////////////////
|
||||
flutter::PluginRegistrarWindows* _registrar;
|
||||
flutter::PluginRegistrarWindows *_registrar;
|
||||
|
||||
HWND GetRootWindow(flutter::FlutterView* view) {
|
||||
HWND GetRootWindow(flutter::FlutterView *view)
|
||||
{
|
||||
return ::GetAncestor(view->GetNativeWindow(), GA_ROOT);
|
||||
}
|
||||
|
||||
StoreContext getStore() {
|
||||
StoreContext getStore()
|
||||
{
|
||||
StoreContext store = StoreContext::GetDefault();
|
||||
auto initWindow = store.try_as<IInitializeWithWindow>();
|
||||
if (initWindow != nullptr) {
|
||||
if (initWindow != nullptr)
|
||||
{
|
||||
initWindow->Initialize(GetRootWindow(_registrar->GetView()));
|
||||
}
|
||||
return store;
|
||||
}
|
||||
|
||||
std::wstring s2ws(const std::string& s)
|
||||
std::wstring s2ws(const std::string &s)
|
||||
{
|
||||
int len;
|
||||
int slength = (int)s.length() + 1;
|
||||
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
|
||||
wchar_t* buf = new wchar_t[len];
|
||||
wchar_t *buf = new wchar_t[len];
|
||||
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
|
||||
std::wstring r(buf);
|
||||
delete[] buf;
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string debugString(std::vector<std::string> vt) {
|
||||
std::string debugString(std::vector<std::string> vt)
|
||||
{
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "( ";
|
||||
for (auto t : vt) {
|
||||
for (auto t : vt)
|
||||
{
|
||||
ss << t << ", ";
|
||||
}
|
||||
ss << " )\n";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string getExtendedErrorString(winrt::hresult error) {
|
||||
std::string getExtendedErrorString(winrt::hresult error)
|
||||
{
|
||||
const HRESULT IAP_E_UNEXPECTED = 0x803f6107L;
|
||||
std::string message;
|
||||
if (error.value == IAP_E_UNEXPECTED) {
|
||||
if (error.value == IAP_E_UNEXPECTED)
|
||||
{
|
||||
message = "This Product has not been properly configured.";
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
message = "ExtendedError: " + std::to_string(error.value);
|
||||
}
|
||||
return message;
|
||||
@@ -84,12 +93,14 @@ namespace windows_iap {
|
||||
{
|
||||
StorePurchaseResult result = co_await getStore().RequestPurchaseAsync(storeId);
|
||||
|
||||
if (result.ExtendedError().value != S_OK) {
|
||||
if (result.ExtendedError().value != S_OK)
|
||||
{
|
||||
resultCallback->Error(std::to_string(result.ExtendedError().value), getExtendedErrorString(result.ExtendedError().value));
|
||||
co_return;
|
||||
}
|
||||
int32_t returnCode;
|
||||
switch (result.Status()) {
|
||||
switch (result.Status())
|
||||
{
|
||||
case StorePurchaseStatus::AlreadyPurchased:
|
||||
returnCode = 1;
|
||||
break;
|
||||
@@ -111,7 +122,7 @@ namespace windows_iap {
|
||||
break;
|
||||
|
||||
default:
|
||||
auto status = reinterpret_cast<int32_t*>(result.Status());
|
||||
auto status = reinterpret_cast<int32_t *>(result.Status());
|
||||
resultCallback->Error(std::to_string(*status), "Product was not purchased due to an unknown error.");
|
||||
co_return;
|
||||
break;
|
||||
@@ -120,10 +131,12 @@ namespace windows_iap {
|
||||
resultCallback->Success(flutter::EncodableValue(returnCode));
|
||||
}
|
||||
|
||||
std::string productsToString(std::vector<StoreProduct> products) {
|
||||
std::string productsToString(std::vector<StoreProduct> products)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "[";
|
||||
for (int i = 0; i < products.size(); i++) {
|
||||
for (int i = 0; i < products.size(); i++)
|
||||
{
|
||||
auto product = products.at(i);
|
||||
ss << "{";
|
||||
ss << "\"title\":\"" << to_string(product.Title()) << "\",";
|
||||
@@ -133,7 +146,8 @@ namespace windows_iap {
|
||||
ss << "\"productKind\":\"" << to_string(product.ProductKind()) << "\",";
|
||||
ss << "\"storeId\":\"" << to_string(product.StoreId()) << "\"";
|
||||
ss << "}";
|
||||
if (i != products.size() - 1) {
|
||||
if (i != products.size() - 1)
|
||||
{
|
||||
ss << ",";
|
||||
}
|
||||
}
|
||||
@@ -142,16 +156,19 @@ namespace windows_iap {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
foundation::IAsyncAction getProducts(std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> resultCallback) {
|
||||
auto result = co_await getStore().GetAssociatedStoreProductsAsync({ L"Consumable", L"Durable", L"UnmanagedConsumable" });
|
||||
if (result.ExtendedError().value != S_OK) {
|
||||
foundation::IAsyncAction getProducts(std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> resultCallback)
|
||||
{
|
||||
auto result = co_await getStore().GetAssociatedStoreProductsAsync({L"Consumable", L"Durable", L"UnmanagedConsumable"});
|
||||
if (result.ExtendedError().value != S_OK)
|
||||
{
|
||||
resultCallback->Error(std::to_string(result.ExtendedError().value), getExtendedErrorString(result.ExtendedError()));
|
||||
}
|
||||
else if (result.Products().Size() == 0) {
|
||||
else if (result.Products().Size() == 0)
|
||||
{
|
||||
resultCallback->Success(flutter::EncodableValue("[]"));
|
||||
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
std::vector<StoreProduct> products;
|
||||
for (IKeyValuePair<hstring, StoreProduct> addOn : result.Products())
|
||||
{
|
||||
@@ -163,7 +180,8 @@ namespace windows_iap {
|
||||
}
|
||||
}
|
||||
|
||||
std::string getStoreLicenseString(StoreLicense license) {
|
||||
std::string getStoreLicenseString(StoreLicense license)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "{";
|
||||
ss << "\"isActive\":" << (license.IsActive() ? "true" : "false") << ",";
|
||||
@@ -175,7 +193,8 @@ namespace windows_iap {
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
foundation::IAsyncAction getAddonLicenses(std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> resultCallback) {
|
||||
foundation::IAsyncAction getAddonLicenses(std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> resultCallback)
|
||||
{
|
||||
auto result = co_await getStore().GetAppLicenseAsync();
|
||||
auto addonLicenses = result.AddOnLicenses();
|
||||
|
||||
@@ -192,10 +211,12 @@ namespace windows_iap {
|
||||
/// <summary>
|
||||
/// need to test in real app on store
|
||||
/// </summary>
|
||||
foundation::IAsyncAction checkPurchase(std::string storeId, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> resultCallback) {
|
||||
foundation::IAsyncAction checkPurchase(std::string storeId, std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> resultCallback)
|
||||
{
|
||||
auto result = co_await getStore().GetAppLicenseAsync();
|
||||
|
||||
if (result.IsActive()) {
|
||||
if (result.IsActive())
|
||||
{
|
||||
|
||||
auto addonLicenses = result.AddOnLicenses();
|
||||
|
||||
@@ -203,69 +224,79 @@ namespace windows_iap {
|
||||
{
|
||||
StoreLicense license = addonLicense.Value();
|
||||
|
||||
if (storeId.compare("") == 0) {
|
||||
if (storeId.compare("") == 0)
|
||||
{
|
||||
// Truong hop storeId empty => bat ky Add-on nao co IsActive = true deu return true
|
||||
if (license.IsActive()) {
|
||||
if (license.IsActive())
|
||||
{
|
||||
resultCallback->Success(flutter::EncodableValue(true));
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// Truong hop storeId not empty => check key = storeId
|
||||
auto key = to_string(addonLicense.Key());
|
||||
if (key.compare(storeId) == 0) {
|
||||
if (key.compare(storeId) == 0)
|
||||
{
|
||||
resultCallback->Success(flutter::EncodableValue(license.IsActive()));
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// truong hop duyet het add-on license nhung vang khong tim thay IsActive = true thi return false
|
||||
resultCallback->Success(flutter::EncodableValue(false));
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
resultCallback->Success(flutter::EncodableValue(false));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// need to test in real app on store
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// need to test in real app on store
|
||||
/// </summary>
|
||||
foundation::IAsyncAction getTrialStatusAndRemainingDays(
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> resultCallback)
|
||||
{
|
||||
auto license = co_await getStore().GetAppLicenseAsync();
|
||||
/// <summary>
|
||||
/// need to test in real app on store
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// need to test in real app on store
|
||||
/// </summary>
|
||||
foundation::IAsyncAction getTrialStatusAndRemainingDays(
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> resultCallback)
|
||||
{
|
||||
auto store = getStore();
|
||||
auto license = co_await store.GetAppLicenseAsync();
|
||||
|
||||
flutter::EncodableMap result;
|
||||
result[flutter::EncodableValue("isTrial")] = flutter::EncodableValue(false);
|
||||
result[flutter::EncodableValue("remainingDays")] = flutter::EncodableValue(0);
|
||||
flutter::EncodableMap result;
|
||||
result[flutter::EncodableValue("isTrial")] = flutter::EncodableValue(true);
|
||||
result[flutter::EncodableValue("remainingDays")] = flutter::EncodableValue(0);
|
||||
result[flutter::EncodableValue("isActive")] = flutter::EncodableValue(license.IsActive());
|
||||
result[flutter::EncodableValue("isTrialOwnedByThisUser")] = flutter::EncodableValue(license.IsTrialOwnedByThisUser());
|
||||
|
||||
|
||||
if (!license.IsActive()) {
|
||||
resultCallback->Success(flutter::EncodableValue(result));
|
||||
co_return;
|
||||
}
|
||||
if (!license.IsActive())
|
||||
{
|
||||
resultCallback->Success(flutter::EncodableValue(result));
|
||||
co_return;
|
||||
}
|
||||
|
||||
if (license.IsTrial()) {
|
||||
result[flutter::EncodableValue("isTrial")] = flutter::EncodableValue(true);
|
||||
if (license.IsTrial())
|
||||
{
|
||||
result[flutter::EncodableValue("isTrial")] = flutter::EncodableValue(true);
|
||||
|
||||
winrt::Windows::Foundation::TimeSpan expiration = license.TrialTimeRemaining();
|
||||
const auto inDays = std::chrono::duration_cast<std::chrono::hours>(expiration).count() / 24.0;
|
||||
|
||||
result[flutter::EncodableValue("remainingDays")] = flutter::EncodableValue(inDays);
|
||||
}
|
||||
|
||||
resultCallback->Success(flutter::EncodableValue(result));
|
||||
}
|
||||
result[flutter::EncodableValue("remainingDays")] = flutter::EncodableValue(inDays);
|
||||
}
|
||||
|
||||
resultCallback->Success(flutter::EncodableValue(result));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////// END OF MY CODE //////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////// END OF MY CODE //////////////////////////////////////////////////////////////
|
||||
|
||||
// static
|
||||
// static
|
||||
void WindowsIapPlugin::RegisterWithRegistrar(
|
||||
flutter::PluginRegistrarWindows* registrar) {
|
||||
flutter::PluginRegistrarWindows *registrar)
|
||||
{
|
||||
_registrar = registrar;
|
||||
|
||||
auto channel =
|
||||
@@ -276,9 +307,10 @@ namespace windows_iap {
|
||||
auto plugin = std::make_unique<WindowsIapPlugin>();
|
||||
|
||||
channel->SetMethodCallHandler(
|
||||
[plugin_pointer = plugin.get()](const auto& call, auto result) {
|
||||
plugin_pointer->HandleMethodCall(call, std::move(result));
|
||||
});
|
||||
[plugin_pointer = plugin.get()](const auto &call, auto result)
|
||||
{
|
||||
plugin_pointer->HandleMethodCall(call, std::move(result));
|
||||
});
|
||||
|
||||
registrar->AddPlugin(std::move(plugin));
|
||||
}
|
||||
@@ -288,30 +320,37 @@ namespace windows_iap {
|
||||
WindowsIapPlugin::~WindowsIapPlugin() {}
|
||||
|
||||
void WindowsIapPlugin::HandleMethodCall(
|
||||
const flutter::MethodCall<flutter::EncodableValue>& method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
|
||||
if (method_call.method_name().compare("makePurchase") == 0) {
|
||||
const flutter::MethodCall<flutter::EncodableValue> &method_call,
|
||||
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
|
||||
{
|
||||
if (method_call.method_name().compare("makePurchase") == 0)
|
||||
{
|
||||
auto args = std::get<flutter::EncodableMap>(*method_call.arguments());
|
||||
auto storeId = std::get<std::string>(args[flutter::EncodableValue("storeId")]);
|
||||
makePurchase(to_hstring(storeId), std::move(result));
|
||||
}
|
||||
else if (method_call.method_name().compare("getProducts") == 0) {
|
||||
else if (method_call.method_name().compare("getProducts") == 0)
|
||||
{
|
||||
getProducts(std::move(result));
|
||||
}
|
||||
else if (method_call.method_name().compare("checkPurchase") == 0) {
|
||||
else if (method_call.method_name().compare("checkPurchase") == 0)
|
||||
{
|
||||
auto args = std::get<flutter::EncodableMap>(*method_call.arguments());
|
||||
auto storeId = std::get<std::string>(args[flutter::EncodableValue("storeId")]);
|
||||
checkPurchase(storeId, std::move(result));
|
||||
}
|
||||
else if (method_call.method_name().compare("getAddonLicenses") == 0) {
|
||||
else if (method_call.method_name().compare("getAddonLicenses") == 0)
|
||||
{
|
||||
getAddonLicenses(std::move(result));
|
||||
}
|
||||
else if (method_call.method_name().compare("getTrialStatusAndRemainingDays") == 0) {
|
||||
getTrialStatusAndRemainingDays(std::move(result));
|
||||
else if (method_call.method_name().compare("getTrialStatusAndRemainingDays") == 0)
|
||||
{
|
||||
getTrialStatusAndRemainingDays(std::move(result));
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
result->NotImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace windows_iap
|
||||
} // namespace windows_iap
|
||||
|
||||
Reference in New Issue
Block a user