developer_options_controller.dart 4.02 KB
import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../../../core/logging/app_logger.dart';
import '../../../../core/services/health_raw_data_core_service.dart';
import '../../../../data/local/user_preferences_storage.dart';
import '../../../../pigeon/platform_api.g.dart';
import '../../../routes/app_pages.dart';

class DeveloperOptionsItem {
  const DeveloperOptionsItem({
    required this.title,
    this.routeName,
    this.action,
  });

  final String title;
  final String? routeName;
  final DeveloperOptionsAction? action;
}

enum DeveloperOptionsAction {
  shareHealthRawDataDatabase,
  shareHealthRawUploadLog,
  clearHealthRawDataDatabaseAndUploadLog,
}

class DeveloperOptionsController extends GetxController {
  DeveloperOptionsController(
    this._userPreferencesStorage,
    this._healthRawDataCoreService,
  );

  final UserPreferencesStorage _userPreferencesStorage;
  final HealthRawDataCoreService _healthRawDataCoreService;
  final PlatformHostApi _platformHostApi = PlatformHostApi();
  final TextEditingController tokenController = TextEditingController();

  final List<DeveloperOptionsItem> options = const [
    DeveloperOptionsItem(
      title: 'User Information',
      routeName: Routes.USER_INFORMATION,
    ),
    DeveloperOptionsItem(
      title: 'Route List',
      routeName: Routes.ROUTE_LIST,
    ),
    DeveloperOptionsItem(
      title: 'Token Login',
      routeName: Routes.TOKEN_LOGIN,
    ),
    DeveloperOptionsItem(
      title: 'Share HealthRawData Database',
      action: DeveloperOptionsAction.shareHealthRawDataDatabase,
    ),
    DeveloperOptionsItem(
      title: '本地上传日志',
      action: DeveloperOptionsAction.shareHealthRawUploadLog,
    ),
    DeveloperOptionsItem(
      title: '清除本地数据库、上传日志',
      action: DeveloperOptionsAction.clearHealthRawDataDatabaseAndUploadLog,
    ),
  ];

  @override
  void onInit() {
    super.onInit();
    tokenController.text = _userPreferencesStorage.accessToken;
  }

  Future<void> optionItemOnTap(DeveloperOptionsItem item) async {
    final routeName = item.routeName;
    if (routeName != null) {
      Get.toNamed(routeName);
      return;
    }

    switch (item.action) {
      case DeveloperOptionsAction.shareHealthRawDataDatabase:
        await shareHealthRawDataDatabase();
        break;
      case DeveloperOptionsAction.shareHealthRawUploadLog:
        await shareHealthRawUploadLog();
        break;
      case DeveloperOptionsAction.clearHealthRawDataDatabaseAndUploadLog:
        await clearHealthRawDataDatabaseAndUploadLog();
        break;
      case null:
        break;
    }
  }

  Future<void> shareHealthRawDataDatabase() async {
    try {
      final bytes = await _healthRawDataCoreService.readDatabaseFileBytes();
      await _platformHostApi.shareFileData(bytes);
    } catch (error, stackTrace) {
      AppLogger.e('Share HealthRawData database failed', error, stackTrace);
      Get.snackbar('Share failed', error.toString());
    }
  }

  Future<void> shareHealthRawUploadLog() async {
    try {
      final text = await _healthRawDataCoreService.readUploadApiLogText();
      await _platformHostApi.shareText(text);
    } catch (error, stackTrace) {
      AppLogger.e('Share HealthRawData upload log failed', error, stackTrace);
      Get.snackbar('Share failed', error.toString());
    }
  }

  Future<void> clearHealthRawDataDatabaseAndUploadLog() async {
    try {
      await _healthRawDataCoreService.clearLocalDatabaseAndUploadLog();
      Get.snackbar('已清除', '本地数据库和上传日志已清除');
    } catch (error, stackTrace) {
      AppLogger.e(
        'Clear HealthRawData database and upload log failed',
        error,
        stackTrace,
      );
      Get.snackbar('Clear failed', error.toString());
    }
  }

  Future<void> saveAccessToken() async {
    final token = tokenController.text.trim();
    await _userPreferencesStorage.updateAccessToken(token);
    Get.offAllNamed(AppRoutes.home);
  }

  @override
  void onClose() {
    tokenController.dispose();
    super.onClose();
  }
}