bind_partner_controller.dart 9.92 KB
import 'package:doublefeel_flutter/app/models/dialog_meta_data.dart';
import 'package:doublefeel_flutter/app/modules/user_onboarding/widget/guide_common_scaffold.dart';
import 'package:doublefeel_flutter/app/modules/user_onboarding/widget/onboarding_common_widgets.dart';
import 'package:doublefeel_flutter/app/routes/app_pages.dart';
import 'package:doublefeel_flutter/app/utils/dialog_utils.dart';
import 'package:doublefeel_flutter/core/error/app_error.dart';
import 'package:doublefeel_flutter/core/error/http_error_handling_policy.dart';
import 'package:doublefeel_flutter/core/network/api/friend_api.dart';
import 'package:doublefeel_flutter/core/result/app_result.dart';
import 'package:doublefeel_flutter/core/services/user_state_service.dart';
import 'package:doublefeel_flutter/data/local/user_preferences_storage.dart';
import 'package:doublefeel_flutter/data/models/friend/friend_models.dart';
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:lottie/lottie.dart';
import 'package:share_plus/share_plus.dart';

class BindPartnerController extends GetxController {
  BindPartnerController(this._friendApi);

  final FriendApi _friendApi;

  final TextEditingController partnerIdController = TextEditingController();

  final RxString partnerIdInput = ''.obs;

  final RxBool isSubmitting = false.obs;

  final RxString myInviteCode = ''.obs;

  late bool isShowAppBarBack;
  late bool isShowSkipButton;

  @override
  void onInit() {
    super.onInit();
    final from = Get.arguments?['from'] ?? '';
    if (from == 'onboarding') {
      isShowAppBarBack = false;
      isShowSkipButton = true;
    } else {
      isShowAppBarBack = true;
      isShowSkipButton = false;
    }

    partnerIdController.addListener(() {
      partnerIdInput.value = partnerIdController.text.trim();
    });

    final userPrefs = Get.find<UserPreferencesStorage>();
    myInviteCode.value =
        userPrefs.preferences.value.meUserInfo?.uniqueCode ?? '';
  }

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

  bool get canSubmit => partnerIdInput.value.isNotEmpty;

  void onShareMyCode() {
    Share.share("""嘿 ❤️ 我发现了一个叫 DoubleFeel 的 App!
它可以帮我们互相关心 — 记录压力和睡眠、查看 HRV 与身体状态、及时了解彼此的健康状况。
快来一起使用吧 👉 https://Xxxxxxx
我的好友id:${myInviteCode.value}""");
  }

  Future<void> onSubmitPartnerId() async {
    if (!canSubmit || isSubmitting.value) return;
    isSubmitting.value = true;
    try {
      final result = await _friendApi.addFriendHandleError(
          partnerIdInput.value,
          HttpErrorHandlingPolicy(
              excludeErrorCodeList: {-1011201, -1011202, -1011203}));

      switch (result) {
        case AppFailure(error: final err):
          if (err is AppHttpError) {
            switch (err.businessCode) {
              case -1011201:
                DialogUtils.showCommonDialog(DialogMetaData(
                  title: '该ID不存在',
                  message: '这个ID不存在哦,请检查后重新输入',
                  confirmText: '我知道了',
                  iconAsset: null,
                ));
                break;
              case -1011202:
                DialogUtils.showCommonDialog(DialogMetaData(
                  title: '添加失败',
                  message: '该用户不允许被添加好友,无法添加Ta哦',
                  confirmText: '我知道了',
                  iconAsset: null,
                ));
                break;
              case -1011203:
                DialogUtils.showCommonDialog(DialogMetaData(
                  title: '对方已经是你的好友啦',
                  message: '请不要重复添加哦',
                  confirmText: '我知道了',
                  iconAsset: null,
                ));
                break;
            }
          }
          break;
        case AppSuccess(data: final friendItem):
          if (isShowAppBarBack) {
            Get.back();
          } else {
            Get.to(_BindSuccessPage(friendItem));
          }
          break;
      }
      // if (result is AppFailure) {
      // if (result.error is AppHttpError) {
      //   var error = result.error as AppHttpError;

      //   switch (error.businessCode) {
      //     case -1011201:
      //       DialogUtils.showCommonDialog(DialogMetaData(
      //         title: '该ID不存在',
      //         message: '这个ID不存在哦,请检查后重新输入',
      //         confirmText: '我知道了',
      //         iconAsset: null,
      //       ));
      //       break;
      //     case -1011202:
      //       DialogUtils.showCommonDialog(DialogMetaData(
      //         title: '添加失败',
      //         message: '该用户不允许被添加好友,无法添加Ta哦',
      //         confirmText: '我知道了',
      //         iconAsset: null,
      //       ));
      //       break;
      //     case -1011203:
      //       DialogUtils.showCommonDialog(DialogMetaData(
      //         title: '对方已经是你的好友啦',
      //         message: '请不要重复添加哦',
      //         confirmText: '我知道了',
      //         iconAsset: null,
      //       ));
      //       break;
      //   }
      // }
      //   return;
      // }
      // if (result is AppSuccess) {}
    } catch (e) {
    } finally {
      isSubmitting.value = false;
    }
  }

  void onSkip() {
    final userStateService = Get.find<UserStateService>();
    if (!userStateService.isVip) {
      Get.toNamed(
        Routes.MEMBERSHIP_OFFER,
        arguments: {'from': 'onboarding'},
      );
    } else {
      Get.offAllNamed(AppRoutes.home);
    }
    // Get.to(_BindSuccessPage(FriendItem(
    //     avatar: 'https://cdn.couple360.net/couple360/themes/im_theme7.png')));
  }
}

class _BindSuccessPage extends StatelessWidget {
  const _BindSuccessPage(this.friendItem);
  final FriendItem friendItem;
  @override
  Widget build(BuildContext context) {
    final l10n = context.l10n;
    final userPrefs = Get.find<UserPreferencesStorage>();
    final preferences = userPrefs.preferences.value;
    final me = preferences.meUserInfo;
    return GuideCommonScaffold(
      onBackPressed: () => Get.back(),
      bottom: OnboardingBottomButton(
        label: l10n.continueButton,
        enabled: true,
        onPressed: () {
          final userStateService = Get.find<UserStateService>();
          if (!userStateService.isVip) {
            Get.toNamed(
              Routes.MEMBERSHIP_OFFER,
              arguments: {'from': 'onboarding'},
            );
          } else {
            Get.offAllNamed(AppRoutes.home);
          }
        },
      ),
      child: OnboardingPageScrollBody(
        horizontalPadding: 0,
        topPadding: 0,
        child: Stack(
          children: [
            Lottie.asset('assets/lottie/scatter_flowers.json'),
            Column(
              mainAxisAlignment: MainAxisAlignment.start,
              mainAxisSize: MainAxisSize.min,
              children: [
                SizedBox(
                  height: 509,
                  child: TweenAnimationBuilder<double>(
                    tween: Tween(begin: 160.0, end: 46.0),
                    duration: const Duration(milliseconds: 800),
                    curve: Curves.easeOut,
                    builder: (context, offset, _) {
                      final avatar = Container(
                        width: 100,
                        height: 100,
                        decoration: ShapeDecoration(
                          image: DecorationImage(
                            image: NetworkImage(me?.avatar ?? ''),
                            fit: BoxFit.cover,
                          ),
                          shape: OvalBorder(
                            side: BorderSide(width: 1.79, color: Colors.white),
                          ),
                        ),
                      );
                      final friendAvatar = Container(
                        width: 100,
                        height: 100,
                        decoration: ShapeDecoration(
                          image: DecorationImage(
                            image: NetworkImage(friendItem.avatar ?? ''),
                            fit: BoxFit.cover,
                          ),
                          shape: OvalBorder(
                            side: BorderSide(width: 1.79, color: Colors.white),
                          ),
                        ),
                      );
                      return Stack(
                        alignment: Alignment(0.5, 0.5),
                        children: [
                          Transform.translate(
                            offset: Offset(offset, 0),
                            child: friendAvatar,
                          ),
                          Transform.translate(
                            offset: Offset(-offset, 0),
                            child: avatar,
                          ),
                        ],
                      );
                    },
                  ),
                ),
                const SizedBox(height: 16),
                OnboardingTitleText(
                  context.l10n.healthCompanionIsNowAvailable,
                  maxWidth: 310,
                ),
                const SizedBox(height: 8),
                Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 16),
                  child: Text(
                    l10n.youCanNowViewEachOtherSHrvStressLevelsAndSleepPatternsAndReachOutToCheckInWhenTheOtherPersonSeemsTired,
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      color: Colors.black,
                      fontSize: 12,
                      fontWeight: FontWeight.w400,
                    ),
                  ),
                )
              ],
            ),
          ],
        ),
      ),
    );
  }
}