Update: 2026-05-08 05:24:38

This commit is contained in:
Hamza-Ayed
2026-05-08 05:24:38 +03:00
parent d2d345b6a0
commit df92a44878
11 changed files with 1245 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import '../network/dio_client.dart';
/// Home Screen Widget Service
/// Manages data for native iOS/Android home screen widgets.
///
/// Widgets show:
/// - Quick stats (invoice count, pending, quota)
/// - Quick scan shortcut
/// - Today's activity summary
///
/// Uses MethodChannel to communicate with native widget code.
class HomeWidgetService extends GetxService {
static const _channel = MethodChannel('com.musadaq.widget');
// Widget data
final totalInvoices = 0.obs;
final pendingInvoices = 0.obs;
final quotaUsed = 0.obs;
final quotaLimit = 0.obs;
final lastUpdate = ''.obs;
@override
void onInit() {
super.onInit();
// Listen for widget tap events
_channel.setMethodCallHandler(_handleWidgetAction);
refreshWidgetData();
}
/// Refresh widget data from API
Future<void> refreshWidgetData() async {
try {
final res = await DioClient().client.get('/v1/dashboard/stats');
if (res.data['success'] == true) {
final data = res.data['data'];
totalInvoices.value = data['invoices']?['total'] ?? 0;
pendingInvoices.value = data['invoices']?['pending'] ?? 0;
}
final subRes = await DioClient().client.get('/v1/subscriptions/current');
if (subRes.data['success'] == true) {
final sub = subRes.data['data'];
quotaUsed.value = sub['invoices']?['used'] ?? 0;
quotaLimit.value = sub['invoices']?['limit'] ?? 0;
}
lastUpdate.value = DateTime.now().toString().substring(0, 16);
// Push data to native widget
await _updateNativeWidget();
} catch (e) {
// Widget update failure is non-critical
}
}
/// Push data to native home screen widget
Future<void> _updateNativeWidget() async {
try {
await _channel.invokeMethod('updateWidget', {
'total_invoices': totalInvoices.value,
'pending_invoices': pendingInvoices.value,
'quota_used': quotaUsed.value,
'quota_limit': quotaLimit.value,
'quota_percent': quotaLimit.value > 0
? ((quotaUsed.value / quotaLimit.value) * 100).round()
: 0,
'last_update': lastUpdate.value,
});
} on MissingPluginException {
// Widget not supported on this platform
} catch (e) {
// Non-critical
}
}
/// Handle taps from the native widget
Future<dynamic> _handleWidgetAction(MethodCall call) async {
switch (call.method) {
case 'openScanner':
Get.toNamed('/scanner');
break;
case 'openInvoices':
Get.toNamed('/main');
break;
case 'refreshData':
await refreshWidgetData();
break;
}
}
/// Get widget display data as a map
Map<String, dynamic> getWidgetData() {
return {
'total_invoices': totalInvoices.value,
'pending_invoices': pendingInvoices.value,
'quota_used': quotaUsed.value,
'quota_limit': quotaLimit.value,
'quota_percent': quotaLimit.value > 0
? ((quotaUsed.value / quotaLimit.value) * 100).round()
: 0,
'last_update': lastUpdate.value,
};
}
}