watch_theme_controller.dart 3.32 KB
import 'dart:async';

import 'package:doublefeel_flutter/app/routes/app_pages.dart';
import 'package:doublefeel_flutter/core/constants/intent_keys.dart';
import 'package:doublefeel_flutter/core/network/api/theme_api.dart';
import 'package:doublefeel_flutter/core/network/api/vip_api.dart';
import 'package:doublefeel_flutter/core/result/app_result.dart';
import 'package:doublefeel_flutter/data/local/user_preferences_storage.dart';
import 'package:doublefeel_flutter/data/models/local/user_preferences.dart';
import 'package:get/get.dart';
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';

import '../models/watch_theme_models.dart';

class WatchThemeController extends GetxController {
  WatchThemeController(this._themeApi, this._vipApi);

  final ThemeApi _themeApi;
  final VipApi _vipApi;

  final isPremium = false.obs;
  final isLoadingThemes = false.obs;
  final officialThemeItems = <WatchThemeItem>[].obs;
  final customThemeItems = <WatchThemeItem>[].obs;
  final selectedThemeItem = Rx<WatchThemeItem?>(null);

  @override
  void onInit() {
    super.onInit();

    unawaited(loadThemeList());
    unawaited(_refreshVip());
  }

  Future<void> loadThemeList() async {
    isLoadingThemes.value = true;
    final themeListFuture = _themeApi.getThemeList(errorHandlingPolicy: null);
    final activeThemeFuture =
        _themeApi.getCurrentTheme(errorHandlingPolicy: null);
    final result = await themeListFuture;
    final activeResult = await activeThemeFuture;
    isLoadingThemes.value = false;

    if (activeResult case AppSuccess<WatchThemeItem>(data: final theme)) {
      selectedThemeItem.value = theme;
    } else {
      selectedThemeItem.value = null;
    }

    if (result is! AppSuccess<WatchThemeResponse>) {
      return;
    }

    final themes = result.data.themes;
    final official = themes.where((theme) => theme.isOfficialTheme).toList();
    final custom = themes.where((theme) => theme.isCustomTheme).toList();
    officialThemeItems.assignAll(official);
    customThemeItems.assignAll(custom);
    isPremium.value = isPremium.value;
  }

  void executeBackLogic() {
    Get.back();
  }

  Future<void> selectOfficialTheme(int index) async {
    await Get.toNamed(Routes.WATCH_THEME_PREVIEW, arguments: {
      'theme': officialThemeItems[index],
    });
    await loadThemeList();
  }

  Future<void> createCustomTheme() async {
    if (isPremium.value) {
      await Get.toNamed(Routes.WATCH_THEME_CREATE);
      await loadThemeList();
    } else {
      // 进入会员页
      _toPremiumPage();
    }
  }

  _refreshVip() async {
    final vipResult = await _vipApi.getVipInfo();
    if (vipResult case AppSuccess(data: final vip)) {
      try {
        final vipPrefs = UserPreferencesVipInfo.fromVipInfo(vip);
        await Get.find<UserPreferencesStorage>().updateVipInfo(vipPrefs);
        isPremium.value = vipPrefs.isVip;
      } on Exception catch (_) {
        // Keep the current membership state when local persistence fails.
      }
    }
  }

  Future<void> _toPremiumPage() async {
    await Get.toNamed(Routes.PURCHASE, arguments: {
      IntentKeys.channelType: l10n.watchThemePurchaseChannel,
    });
    await _refreshVip();
  }

  Future<void> previewCustomTheme(WatchThemeItem theme) async {
    await Get.toNamed(Routes.WATCH_THEME_CUSTOM_PREVIEW, arguments: {
      'theme': theme,
    });
    await loadThemeList();
  }
}