210 lines
7.8 KiB
Dart
210 lines
7.8 KiB
Dart
import 'package:amplitude_flutter/amplitude.dart';
|
||
import 'package:amplitude_flutter/configuration.dart';
|
||
import 'package:amplitude_flutter/constants.dart' as amp;
|
||
import 'package:amplitude_flutter/events/base_event.dart';
|
||
import 'package:flutter/widgets.dart';
|
||
import 'package:pshared/models/account/account.dart';
|
||
import 'package:pshared/models/payment/type.dart';
|
||
import 'package:pshared/models/recipient/status.dart';
|
||
import 'package:pshared/models/recipient/type.dart';
|
||
import 'package:pweb/widgets/sidebar/destinations.dart';
|
||
|
||
|
||
class AmplitudeService {
|
||
static late Amplitude _analytics;
|
||
|
||
static Amplitude _amp() => _analytics;
|
||
|
||
static Future<void> initialize() async {
|
||
_analytics = Amplitude(Configuration(
|
||
apiKey: '12345', //TODO define through App Contants
|
||
serverZone: amp.ServerZone.eu, //TODO define through App Contants
|
||
));
|
||
await _analytics.isBuilt;
|
||
}
|
||
|
||
static Future<void> identify(Account account) async =>
|
||
_amp().setUserId(account.id);
|
||
|
||
|
||
static Future<void> login(Account account) async =>
|
||
_logEvent(
|
||
'login',
|
||
userProperties: {
|
||
// 'email': account.email, TODO Add email into account
|
||
'locale': account.locale,
|
||
},
|
||
);
|
||
|
||
static Future<void> logout() async => _logEvent("logout");
|
||
|
||
static Future<void> pageOpened(PayoutDestination page, {String? path, String? uiSource}) async {
|
||
return _logEvent("pageOpened", eventProperties: {
|
||
"page": page,
|
||
if (path != null) "path": path,
|
||
if (uiSource != null) "uiSource": uiSource,
|
||
});
|
||
}
|
||
|
||
//TODO Add when registration is ready. User properties {user_id, registration_date, has_wallet (true/false), wallet_balance (should concider loggin it as: 0 / <100 / 100–500 / 500+), preferred_method (Wallet/Card/Bank/IBAN), total_transactions, total_amount, last_payout_date, last_login_date , marketing_source}
|
||
|
||
// static Future<void> registrationStarted(String method, String country) async =>
|
||
// _logEvent("registrationStarted", eventProperties: {"method": method, "country": country});
|
||
|
||
// static Future<void> registrationCompleted(String method, String country) async =>
|
||
// _logEvent("registrationCompleted", eventProperties: {"method": method, "country": country});
|
||
|
||
static Future<void> pageNotFound(String url) async =>
|
||
_logEvent("pageNotFound", eventProperties: {"url": url});
|
||
|
||
static Future<void> localeChanged(Locale locale) async =>
|
||
_logEvent("localeChanged", eventProperties: {"locale": locale.toString()});
|
||
|
||
static Future<void> localeMatched(String locale, bool haveRequested) async => //DO we need it?
|
||
_logEvent("localeMatched", eventProperties: {
|
||
"locale": locale,
|
||
"have_requested_locale": haveRequested
|
||
});
|
||
|
||
static Future<void> recipientAddStarted() async =>
|
||
_logEvent("recipientAddStarted");
|
||
|
||
static Future<void> recipientAddCompleted(
|
||
RecipientType type,
|
||
RecipientStatus status,
|
||
Set<PaymentType> methods,
|
||
) async {
|
||
_logEvent(
|
||
"recipientAddCompleted",
|
||
eventProperties: {
|
||
"methods": methods.map((m) => m.name).toList(),
|
||
"type": type.name,
|
||
"status": status.name,
|
||
},
|
||
);
|
||
}
|
||
|
||
static Future<void> _paymentEvent(
|
||
String evt,
|
||
double amount,
|
||
double fee,
|
||
bool payerCoversFee,
|
||
PaymentType source,
|
||
PaymentType recpientPaymentMethod, {
|
||
String? message,
|
||
String? errorType,
|
||
Map<String, dynamic>? extraProps,
|
||
}) async {
|
||
final props = {
|
||
"amount": amount,
|
||
"fee": fee,
|
||
"feeCoveredBy": payerCoversFee ? 'payer' : 'recipient',
|
||
"source": source,
|
||
"recipient_method": recpientPaymentMethod,
|
||
if (message != null) "message": message,
|
||
if (errorType != null) "error_type": errorType,
|
||
if (extraProps != null) ...extraProps,
|
||
};
|
||
return _logEvent(evt, eventProperties: props);
|
||
}
|
||
|
||
static Future<void> paymentPrepared(double amount, double fee,
|
||
bool payerCoversFee, PaymentType source, PaymentType recpientPaymentMethod) async =>
|
||
_paymentEvent("paymentPrepared", amount, fee, payerCoversFee, source, recpientPaymentMethod);
|
||
//TODO Rework paymentStarted (do i need all those properties or is the event enough? Mb properties should be passed at paymentPrepared)
|
||
static Future<void> paymentStarted(double amount, double fee,
|
||
bool payerCoversFee, PaymentType source, PaymentType recpientPaymentMethod) async =>
|
||
_paymentEvent("paymentStarted", amount, fee, payerCoversFee, source, recpientPaymentMethod);
|
||
|
||
static Future<void> paymentFailed(double amount, double fee, bool payerCoversFee,
|
||
PaymentType source, PaymentType recpientPaymentMethod, String errorType, String message) async =>
|
||
_paymentEvent("paymentFailed", amount, fee, payerCoversFee, source, recpientPaymentMethod,
|
||
errorType: errorType, message: message);
|
||
|
||
static Future<void> paymentError(double amount, double fee, bool payerCoversFee,
|
||
PaymentType source,PaymentType recpientPaymentMethod, String message) async =>
|
||
_paymentEvent("paymentError", amount, fee, payerCoversFee, source, recpientPaymentMethod,
|
||
message: message);
|
||
|
||
static Future<void> paymentSuccess({
|
||
required double amount,
|
||
required double fee,
|
||
required bool payerCoversFee,
|
||
required PaymentType source,
|
||
required PaymentType recpientPaymentMethod,
|
||
required String transactionId,
|
||
String? comment,
|
||
required int durationMs,
|
||
}) async {
|
||
return _paymentEvent(
|
||
"paymentSuccess",
|
||
amount,
|
||
fee,
|
||
payerCoversFee,
|
||
source,
|
||
recpientPaymentMethod,
|
||
message: comment,
|
||
extraProps: {
|
||
"transaction_id": transactionId,
|
||
"duration_ms": durationMs, //How do i calculate duration here?
|
||
"\$revenue": amount, //How do i calculate revenue here?
|
||
"\$revenueType": "payment", //Do we need to get revenue type?
|
||
},
|
||
);
|
||
}
|
||
|
||
//TODO add when support is ready
|
||
// static Future<void> supportOpened(String fromPage, String trigger) async =>
|
||
// _logEvent("supportOpened", eventProperties: {"from_page": fromPage, "trigger": trigger});
|
||
|
||
// static Future<void> supportMessageSent(String category, bool resolved) async =>
|
||
// _logEvent("supportMessageSent", eventProperties: {"category": category, "resolved": resolved});
|
||
|
||
|
||
static Future<void> walletTopUp(double amount, PaymentType method) async =>
|
||
_logEvent("walletTopUp", eventProperties: {"amount": amount, "method": method});
|
||
|
||
|
||
//TODO Decide do we need uiElementClicked or pageOpened is enough?
|
||
static Future<void> uiElementClicked(String elementName, String page, String uiSource) async =>
|
||
_logEvent("uiElementClicked", eventProperties: {
|
||
"element_name": elementName,
|
||
"page": page,
|
||
"uiSource": uiSource
|
||
});
|
||
|
||
static final Map<String, int> _stepStartTimes = {};
|
||
//TODO Consider it as part of payment flow or registration flow or adding recipient and rework accordingly
|
||
static Future<void> stepStarted(String stepName, {String? context}) async {
|
||
_stepStartTimes[stepName] = DateTime.now().millisecondsSinceEpoch;
|
||
return _logEvent("stepStarted", eventProperties: {
|
||
"step_name": stepName,
|
||
if (context != null) "context": context,
|
||
});
|
||
}
|
||
|
||
static Future<void> stepCompleted(String stepName, bool success) async {
|
||
final now = DateTime.now().millisecondsSinceEpoch;
|
||
final start = _stepStartTimes[stepName] ?? now;
|
||
final duration = now - start;
|
||
return _logEvent("stepCompleted", eventProperties: {
|
||
"step_name": stepName,
|
||
"duration_ms": duration,
|
||
"success": success
|
||
});
|
||
}
|
||
|
||
static Future<void> _logEvent(
|
||
String eventType, {
|
||
Map<String, dynamic>? eventProperties,
|
||
Map<String, dynamic>? userProperties,
|
||
}) async {
|
||
final event = BaseEvent(
|
||
eventType,
|
||
eventProperties: eventProperties,
|
||
userProperties: userProperties,
|
||
);
|
||
_amp().track(event);
|
||
print(event.toString()); //TODO delete when everything is ready
|
||
}
|
||
} |