199 lines
5.1 KiB
Dart
199 lines
5.1 KiB
Dart
import 'dart:async';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:yx_tracking_flutter/yx_tracking_flutter.dart';
|
|
|
|
Future<void> main() async {
|
|
WidgetsFlutterBinding.ensureInitialized();
|
|
|
|
await Analytics.init(
|
|
const AnalyticsConfig(
|
|
systemCode: 'SDK-TEST-FLUTTER',
|
|
endpointBaseUrl: 'http://192.168.2.7:18828/api/',
|
|
clientType: 3,
|
|
enableDebug: true,
|
|
batchSize: 5,
|
|
flushInterval: 30,
|
|
allowInsecureHttp: true,
|
|
),
|
|
);
|
|
|
|
Analytics.bindLifecycleObserver();
|
|
|
|
runApp(const DemoApp());
|
|
}
|
|
|
|
class DemoApp extends StatelessWidget {
|
|
const DemoApp({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return const MaterialApp(home: DemoPage());
|
|
}
|
|
}
|
|
|
|
class DemoPage extends StatefulWidget {
|
|
const DemoPage({super.key});
|
|
|
|
@override
|
|
State<DemoPage> createState() => _DemoPageState();
|
|
}
|
|
|
|
class _DemoPageState extends State<DemoPage> {
|
|
int _cacheCount = 0;
|
|
List<RecentEventSummary> _recent = const <RecentEventSummary>[];
|
|
bool _flushing = false;
|
|
bool _refreshingConfig = false;
|
|
Timer? _pollTimer;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_refreshCount();
|
|
_pollTimer = Timer.periodic(const Duration(seconds: 2), (_) {
|
|
_refreshCount();
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_pollTimer?.cancel();
|
|
super.dispose();
|
|
}
|
|
|
|
Future<void> _refreshCount() async {
|
|
final results = await Future.wait(<Future<Object>>[
|
|
Analytics.cachedEventCount(),
|
|
Analytics.cachedRecentEvents(limit: 20),
|
|
]);
|
|
final count = results[0] as int;
|
|
final recent = results[1] as List<RecentEventSummary>;
|
|
if (!mounted) {
|
|
return;
|
|
}
|
|
setState(() {
|
|
_cacheCount = count;
|
|
_recent = recent;
|
|
});
|
|
}
|
|
|
|
Future<void> _trackDemoEvent() async {
|
|
await Analytics.track(
|
|
'DEMO_BUTTON_CLICK',
|
|
eventParams: const <String, dynamic>{
|
|
'page': 'demo',
|
|
'Url': 'https://example.com/demo',
|
|
'ButtonId': 'demo_btn_01',
|
|
},
|
|
customTags: const <String, dynamic>{'tenantId': 't1', 'feature': 'demo'},
|
|
);
|
|
await _refreshCount();
|
|
}
|
|
|
|
Future<void> _flushNow() async {
|
|
if (_flushing) {
|
|
return;
|
|
}
|
|
setState(() {
|
|
_flushing = true;
|
|
});
|
|
try {
|
|
await Analytics.flush(force: true);
|
|
} finally {
|
|
if (mounted) {
|
|
setState(() {
|
|
_flushing = false;
|
|
});
|
|
}
|
|
await _refreshCount();
|
|
}
|
|
}
|
|
|
|
Future<void> _refreshConfig() async {
|
|
if (_refreshingConfig) {
|
|
return;
|
|
}
|
|
setState(() {
|
|
_refreshingConfig = true;
|
|
});
|
|
try {
|
|
await Analytics.refreshConfig(force: true);
|
|
} finally {
|
|
if (mounted) {
|
|
setState(() {
|
|
_refreshingConfig = false;
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('YX Tracking Demo')),
|
|
body: Padding(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
Text(
|
|
'本地缓存事件数:$_cacheCount',
|
|
style: Theme.of(context).textTheme.titleMedium,
|
|
),
|
|
const SizedBox(height: 16),
|
|
Wrap(
|
|
spacing: 12,
|
|
runSpacing: 12,
|
|
children: <Widget>[
|
|
ElevatedButton(
|
|
onPressed: _trackDemoEvent,
|
|
child: const Text('Track Demo Event'),
|
|
),
|
|
ElevatedButton(
|
|
onPressed: _flushing ? null : _flushNow,
|
|
child: Text(_flushing ? 'Flushing...' : 'Flush Now'),
|
|
),
|
|
OutlinedButton(
|
|
onPressed: _refreshingConfig ? null : _refreshConfig,
|
|
child: Text(
|
|
_refreshingConfig ? 'Refreshing...' : 'Refresh Config',
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 12),
|
|
const Text(
|
|
'说明:已对接 SDK-TEST-FLUTTER 系统,'
|
|
'点击 Track 按钮记录事件,点击 Flush 上报。',
|
|
),
|
|
const SizedBox(height: 12),
|
|
Text(
|
|
'最近事件(最多 20 条)',
|
|
style: Theme.of(context).textTheme.titleSmall,
|
|
),
|
|
const SizedBox(height: 8),
|
|
Expanded(
|
|
child: _recent.isEmpty
|
|
? const Text('暂无事件')
|
|
: ListView.separated(
|
|
itemCount: _recent.length,
|
|
separatorBuilder: (_, __) => const Divider(height: 1),
|
|
itemBuilder: (context, index) {
|
|
final item = _recent[index];
|
|
return ListTile(
|
|
dense: true,
|
|
title: Text(item.eventType),
|
|
subtitle: Text(
|
|
'${item.createTime.toIso8601String()} · retry=${item.retryCount}',
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|