home_controller.dart 3.29 KB
import 'package:doublefeel_flutter/core/services/user_state_service.dart';
import 'package:doublefeel_flutter/data/local/local_storage.dart';
import 'package:doublefeel_flutter/pigeon/platform_api.g.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';

import '../../../routes/app_pages.dart';
import '../../purchase/purchase_route_args.dart';
import '../../app_review_prompt/logic/app_review_prompt_logic.dart';
import '../../report_common/models/report_period.dart';
import 'trend/trend_controller.dart';

class HomeController extends GetxController {
  static const trendTabIndex = 1;
  static const _mainChannel = MethodChannel('doublefeel_flutter_main_channel');

  final AppReviewPromptLogic _appReviewPromptLogic = AppReviewPromptLogic(
    storage: Get.find<LocalStorage>(),
  );
  final LocalStorage _storage = Get.find<LocalStorage>();
  final UserStateService userStateService = Get.find<UserStateService>();

  /// 当前选中的底部 tab 索引
  final selectedIndex = 0.obs;
  final lastFlutterUrl = ''.obs;

  @override
  void onInit() {
    super.onInit();
    _mainChannel.setMethodCallHandler(_handleNativeMethodCall);
  }

  @override
  void onClose() {
    _mainChannel.setMethodCallHandler(null);
    super.onClose();
  }

  @override
  void onReady() async {
    final unhandedUrl = await PlatformHostApi().requestUnhandedUrl();
    debugPrint(
      '[HomeController] requestUnhandedUrl: '
      'result: ${unhandedUrl}',
    );
  }

  Future<Object?> _handleNativeMethodCall(MethodCall call) async {
    switch (call.method) {
      case 'handleFlutterUrl':
        return handleFlutterUrl(call.arguments);
      default:
        debugPrint(
          '[HomeController] unhandled native method: ${call.method}, '
          'arguments: ${call.arguments}',
        );
        return null;
    }
  }

  Future<bool> handleFlutterUrl(Object? arguments) async {
    final url = switch (arguments) {
      {'url': final String value} => value.trim(),
      final String value => value.trim(),
      _ => '',
    };
    lastFlutterUrl.value = url;
    debugPrint('[HomeController.handleFlutterUrl] url: $url');
    return url.isNotEmpty;
  }

  Future<void> maybeShowAppReviewPrompt(BuildContext context) {
    return _appReviewPromptLogic.maybeShowPrompt(context);
  }

  Future<bool> maybeShowMembershipOffer() async {
    if (userStateService.isVip) return false;

    final userId = userStateService.userId;
    if (userId <= 0) return false;

    final today = _dateKey(DateTime.now());
    final alreadyShownToday = _storage.homeMembershipOfferPromptDate == today;
    final sameAccount = _storage.homeMembershipOfferPromptUserId == userId;
    if (alreadyShownToday && sameAccount) return false;

    await _storage.setHomeMembershipOfferPromptState(
      date: today,
      userId: userId,
    );
    await Get.toNamed(
      Routes.PURCHASE,
      arguments: {PurchaseRouteArgs.showCloseButton: true},
    );
    return true;
  }

  void changeTab(int index) {
    selectedIndex.value = index;
  }

  void openTrend(TrendType type, {DateTime? date, ReportPeriod? period}) {
    Get.find<TrendController>().selectType(type, date: date, period: period);
    changeTab(trendTabIndex);
  }

  int _dateKey(DateTime date) =>
      date.year * 10000 + date.month * 100 + date.day;
}