Files
sendico/frontend/pweb/lib/services/posthog.dart
2025-12-11 17:41:25 +03:00

137 lines
3.7 KiB
Dart

import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:posthog_flutter/posthog_flutter.dart';
import 'package:pshared/config/constants.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 PosthogService {
static final _logger = Logger('service.posthog');
static String? _identifiedUserId;
static bool _initialized = false;
static bool get isEnabled => _initialized;
static Future<void> initialize() async {
final apiKey = Constants.posthogApiKey;
if (apiKey.isEmpty) {
_logger.warning('PostHog API key is not configured, analytics disabled.');
return;
}
try {
final config = PostHogConfig(apiKey)
..host = Constants.posthogHost
..captureApplicationLifecycleEvents = true;
await Posthog().setup(config);
await Posthog().register('client_id', Constants.clientId);
_initialized = true;
_logger.info('PostHog initialized with host ${Constants.posthogHost}');
} catch (e, st) {
_initialized = false;
_logger.warning('Failed to initialize PostHog: $e', e, st);
}
}
static Future<void> identify(Account account) async {
if (!_initialized) return;
if (_identifiedUserId == account.id) return;
await Posthog().identify(
userId: account.id,
userProperties: {
'email': account.login,
'name': account.name,
'locale': account.locale,
'created_at': account.createdAt.toIso8601String(),
},
);
_identifiedUserId = account.id;
}
static Future<void> reset() async {
if (!_initialized) return;
_identifiedUserId = null;
await Posthog().reset();
}
static Future<void> login({required bool pending}) async {
if (!_initialized) return;
await _capture(
'login',
properties: {
'result': pending ? 'pending' : 'success',
},
);
}
static Future<void> pageOpened(PayoutDestination page, {String? path, String? uiSource}) async {
if (!_initialized) return;
return _capture(
'pageOpened',
properties: {
'page': page.name,
if (path != null) 'path': path,
if (uiSource != null) 'uiSource': uiSource,
},
);
}
static Future<void> localeChanged(Locale locale) async {
if (!_initialized) return;
return _capture(
'localeChanged',
properties: {'locale': locale.toLanguageTag()},
);
}
static Future<void> recipientAddCompleted(
RecipientType type,
RecipientStatus status,
Set<PaymentType> methods,
) async {
if (!_initialized) return;
return _capture(
'recipientAddCompleted',
properties: {
'methods': methods.map((m) => m.name).toList(),
'type': type.name,
'status': status.name,
},
);
}
static Future<void> paymentInitiated({PaymentType? method}) async {
if (!_initialized) return;
return _capture(
'paymentInitiated',
properties: {
if (method != null) 'method': method.name,
},
);
}
static Future<void> _capture(
String eventName, {
Map<String, Object?>? properties,
}) async {
if (!_initialized) return;
final filtered = <String, Object>{};
if (properties != null) {
for (final entry in properties.entries) {
final value = entry.value;
if (value != null) filtered[entry.key] = value;
}
}
await Posthog().capture(eventName: eventName, properties: filtered.isEmpty ? null : filtered);
}
}