import 'dart:convert'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:flutter_debouncer/flutter_debouncer.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:yumi/app_localizations.dart'; import 'package:yumi/ui_kit/components/sc_compontent.dart'; import 'package:yumi/ui_kit/components/text/sc_text.dart'; import 'package:yumi/ui_kit/components/sc_tts.dart'; import 'package:yumi/ui_kit/theme/socialchat_theme.dart'; import 'package:yumi/app/constants/sc_global_config.dart'; import 'package:yumi/app/config/business_logic_strategy.dart'; import 'package:yumi/shared/tools/sc_gift_vap_svga_manager.dart'; import 'package:yumi/shared/data_sources/sources/local/user_manager.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_room_repository_imp.dart'; import 'package:yumi/shared/business_logic/models/res/login_res.dart'; import 'package:yumi/main.dart'; import 'package:provider/provider.dart'; import 'package:yumi/app/constants/sc_room_msg_type.dart'; import 'package:yumi/app/constants/sc_screen.dart'; import 'package:yumi/app/routes/sc_fluro_navigator.dart'; import 'package:yumi/shared/tools/sc_dialog_utils.dart'; import 'package:yumi/shared/data_sources/sources/local/floating_screen_manager.dart'; import 'package:yumi/shared/business_logic/models/res/gift_res.dart'; import 'package:yumi/shared/business_logic/models/res/mic_res.dart'; import 'package:yumi/services/general/sc_app_general_manager.dart'; import 'package:yumi/services/audio/rtc_manager.dart'; import 'package:yumi/services/audio/rtm_manager.dart'; import 'package:yumi/services/auth/user_profile_manager.dart'; import 'package:yumi/ui_kit/widgets/countdown_timer.dart'; import 'package:yumi/ui_kit/widgets/room/room_msg_item.dart'; import 'package:yumi/modules/wallet/wallet_route.dart'; import 'package:yumi/modules/gift/gift_tab_page.dart'; import '../../shared/data_sources/models/enum/sc_gift_type.dart'; import '../../shared/data_sources/models/message/sc_floating_message.dart'; import '../../shared/business_logic/usecases/sc_fixed_width_tabIndicator.dart'; class GiftPage extends StatefulWidget { SocialChatUserProfile? toUser; GiftPage({super.key, this.toUser}); @override _GiftPageState createState() => _GiftPageState(); } class _GiftPageState extends State with SingleTickerProviderStateMixin { late TabController _tabController; /// 业务逻辑策略访问器 BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy; // int checkedIndex = 0; SocialChatGiftRes? checkedGift; final List _pages = []; final List _tabs = []; RtcProvider? rtcProvider; bool isAll = false; List listMai = []; bool noShowNumber = false; ///选中人员 Set set = {}; ///数量的箭头是否朝上 bool isNumberUp = true; ///数量 int number = 1; int giveType = 1; int giftType = 0; Debouncer debouncer = Debouncer(); void _giftFxLog(String message) { debugPrint('[GiftFX][Send] $message'); } void _handleGiftSelected( SocialChatGiftRes? gift, { required int nextGiftType, }) { checkedGift = gift; if (gift != null && (gift.giftSourceUrl ?? "").isNotEmpty && scGiftHasFullScreenEffect(gift.special)) { SCGiftVapSvgaManager().preload(gift.giftSourceUrl!, highPriority: true); _giftFxLog( 'preload selected gift ' 'giftId=${gift.id} ' 'giftName=${gift.giftName} ' 'giftSourceUrl=${gift.giftSourceUrl} ' 'special=${gift.special}', ); } number = 1; noShowNumber = false; setState(() { giftType = nextGiftType; }); } @override void initState() { super.initState(); rtcProvider = Provider.of(context, listen: false); Provider.of(context, listen: false).giftList(); Provider.of(context, listen: false).giftActivityList(); // Provider.of(context, listen: false).giftBackpack(); Provider.of(context, listen: false).balance(); _pages.add( GiftTabPage("ALL", (int checkedI) { var all = Provider.of( context, listen: false, ).giftByTab["ALL"]; _handleGiftSelected( all != null ? all[checkedI] : null, nextGiftType: 0, ); }), ); _tabController = TabController(length: _pages.length, vsync: this); _tabController.addListener(() {}); // 监听切换 rtcProvider?.roomWheatMap.forEach((k, v) { if (v.user != null) { if (v.user?.id == AccountStorage().getCurrentUser()?.userProfile?.id) { listMai.add(HeadSelect(true, v)); } else { listMai.add(HeadSelect(false, v)); } } isAll = true; for (var mai in listMai) { if (!mai.isSelect) { isAll = false; } } }); } @override Widget build(BuildContext context) { _tabs.clear(); _tabs.add(Tab(text: SCAppLocalizations.of(context)!.gift)); return Consumer( builder: (context, ref, child) { return SafeArea( top: false, child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisAlignment: MainAxisAlignment.end, children: [ SCGlobalConfig.isReview ? Container() : ((AccountStorage() .getCurrentUser() ?.userProfile ?.firstRecharge ?? false) ? GestureDetector( child: Stack( alignment: AlignmentDirectional.bottomEnd, children: [ Transform.flip( flipX: SCGlobalConfig.lang == "ar" ? true : false, // 水平翻转 flipY: false, // 垂直翻转设为 false child: Image.asset( _strategy .getGiftPageFirstRechargeRoomTagIcon(), height: 75.w, ), ), SCGlobalConfig.lang == "ar" ? PositionedDirectional( end: 22.w, bottom: 38.w, child: Image.asset( _strategy .getGiftPageFirstRechargeTextIcon( 'ar', ), height: 13.w, ), ) : PositionedDirectional( end: 16.w, bottom: 38.w, child: Image.asset( _strategy .getGiftPageFirstRechargeTextIcon( 'en', ), height: 13.w, ), ), PositionedDirectional( end: 34.w, bottom: 13.w, child: CountdownTimer( expiryDate: DateTime.fromMillisecondsSinceEpoch( AccountStorage() .getCurrentUser() ?.userProfile ?.firstRechargeEndTime ?? 0, ), color: Colors.white, fontSize: 12.w, ), ), ], ), onTap: () { SCDialogUtils.showFirstRechargeDialog( navigatorKey.currentState!.context, ); }, ) : Container()), ], ), _buildGiftHead(), ClipRRect( borderRadius: BorderRadius.only( topLeft: Radius.circular(12.0), topRight: Radius.circular(12.0), ), child: BackdropFilter( filter: ui.ImageFilter.blur(sigmaX: 15, sigmaY: 15), child: Container( color: Color(0xff09372E).withOpacity(0.5), constraints: BoxConstraints(maxHeight: 430.w), child: Column( children: [ SizedBox(height: 12.w), Row( children: [ SizedBox(width: 8.w), widget.toUser == null ? Builder( builder: (ct) { return GestureDetector( child: Image.asset( isAll ? "sc_images/room/sc_icon_gift_all_en.png" : "sc_images/room/sc_icon_gift_all_no.png", width: 28.w, height: 28.w, ), onTap: () { isAll = !isAll; for (var mai in listMai) { mai.isSelect = isAll; } setState(() {}); // showGiveTypeDialog(ct); }, ); }, ) : Container(), SizedBox(width: 8.w), widget.toUser == null ? Expanded( child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: listMai .map((e) => _maiHead(e)) .toList(), ), ), ) : Stack( alignment: AlignmentDirectional.center, children: [ Container( padding: EdgeInsets.all(2.w), child: netImage( url: widget.toUser?.userAvatar ?? "", width: 26.w, defaultImg: _strategy .getMePageDefaultAvatarImage(), shape: BoxShape.circle, ), ), PositionedDirectional( bottom: 0, end: 0, child: Image.asset( "sc_images/login/sc_icon_login_ser_select.png", width: 10.w, height: 10.w, ), ), ], ), SizedBox(width: 12.w), ], ), Row( children: [ SizedBox(width: 5.w), Expanded( child: Container( height: 28.w, child: TabBar( tabAlignment: TabAlignment.start, labelPadding: EdgeInsets.symmetric( horizontal: 8.w, ), labelColor: SocialChatTheme.primaryLight, indicatorWeight: 0, isScrollable: true, indicator: SCFixedWidthTabIndicator( width: 15.w, color: SocialChatTheme.primaryLight, ), unselectedLabelColor: Colors.white54, labelStyle: TextStyle(fontSize: 14.sp), unselectedLabelStyle: TextStyle( fontSize: 12.sp, ), indicatorColor: Colors.transparent, dividerColor: Colors.transparent, controller: _tabController, tabs: _tabs, ), ), ), SizedBox(width: 5.w), ], ), Expanded( child: TabBarView( physics: NeverScrollableScrollPhysics(), controller: _tabController, children: _pages, ), ), Row( children: [ SizedBox(width: 15.w), GestureDetector( onTap: () { SmartDialog.dismiss(tag: "showGiftControl"); SCNavigatorUtils.push( navigatorKey.currentState!.context, WalletRoute.recharge, replace: false, ); }, child: Container( padding: EdgeInsets.symmetric( vertical: 8.w, horizontal: 8.w, ), width: 120.w, decoration: BoxDecoration( color: Colors.white10, borderRadius: BorderRadius.circular(5), ), child: Row( children: [ Image.asset( _strategy.getGiftPageGoldCoinIcon(), width: 14.w, height: 14.w, ), SizedBox(width: 5.w), Consumer( builder: (context, ref, child) { return Expanded( child: text( "${ref.myBalance}", fontSize: 12.sp, ), ); }, ), SizedBox(width: 5.w), Icon( Icons.arrow_forward_ios, color: Colors.white, size: 14.w, ), ], ), ), ), Spacer(), Builder( builder: (ct) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { if (noShowNumber) { return; } isNumberUp = false; _showNumber(ct); setState(() {}); }, child: Container( decoration: BoxDecoration( color: Colors.white10, borderRadius: BorderRadius.circular(5), ), child: Row( children: [ SizedBox(width: 10.w), text("$number", fontSize: 12.sp), Icon( isNumberUp ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down, color: Colors.white, size: 20.w, ), SizedBox(width: 5.w), GestureDetector( onTap: () { giveGifts(); }, child: Container( padding: EdgeInsets.symmetric( vertical: 8.w, horizontal: 20.w, ), decoration: BoxDecoration( color: SocialChatTheme.primaryLight, borderRadius: BorderRadius.circular(5), ), child: text( SCAppLocalizations.of( context, )!.send, fontSize: 14.sp, ), ), ), ], ), ), ); }, ), SizedBox(width: 15.w), ], ), SizedBox(height: 15.w), ], ), ), ), ), ], ), ); }, ); } void showGiveTypeDialog(BuildContext ct) { SmartDialog.showAttach( tag: "showGiveType", targetContext: ct, alignment: Alignment.bottomCenter, animationType: SmartAnimationType.fade, scalePointBuilder: (selfSize) => Offset(selfSize.width, 10), builder: (_) { return Container( height: 135.w, width: 200.w, decoration: BoxDecoration( image: DecorationImage( image: AssetImage(_strategy.getGiftPageGiveTypeBackground()), fit: BoxFit.fill, ), ), padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.w), child: Column( children: [ SizedBox(height: 5.w), Expanded( child: GestureDetector( child: Row( children: [ Image.asset( _strategy.getGiftPageAllOnMicrophoneIcon(), height: 18.w, width: 18.w, ), SizedBox(width: 8.w), Expanded( child: text( SCAppLocalizations.of(context)!.allOnMicrophone, fontSize: 14.sp, textColor: Colors.white54, ), ), SizedBox(width: 8.w), Image.asset( giveType == 0 ? _strategy.getCommonSelectIcon() : _strategy.getCommonUnselectIcon(), width: 15.w, height: 15.w, ), ], ), onTap: () { giveType = 0; SmartDialog.dismiss(tag: "showGiveType"); selecteAllMicUsers(); setState(() {}); }, ), ), Expanded( child: GestureDetector( child: Row( children: [ Image.asset( _strategy.getGiftPageUsersOnMicrophoneIcon(), height: 18.w, width: 18.w, ), SizedBox(width: 8.w), Expanded( child: text( SCAppLocalizations.of(context)!.usersOnMicrophone, fontSize: 14.sp, textColor: Colors.white54, ), ), SizedBox(width: 8.w), Image.asset( giveType == 1 ? _strategy.getCommonSelectIcon() : _strategy.getCommonUnselectIcon(), width: 15.w, height: 15.w, ), ], ), onTap: () { giveType = 1; SmartDialog.dismiss(tag: "showGiveType"); setState(() {}); }, ), ), Expanded( child: GestureDetector( onTap: () { giveType = 2; SmartDialog.dismiss(tag: "showGiveType"); setState(() {}); }, behavior: HitTestBehavior.opaque, child: Row( children: [ Image.asset( _strategy.getGiftPageAllInTheRoomIcon(), height: 18.w, width: 18.w, ), SizedBox(width: 8.w), Expanded( child: text( SCAppLocalizations.of(context)!.allInTheRoom, fontSize: 14.sp, textColor: Colors.white54, ), ), SizedBox(width: 8.w), Image.asset( giveType == 2 ? _strategy.getCommonSelectIcon() : _strategy.getCommonUnselectIcon(), width: 15.w, height: 15.w, ), ], ), ), ), ], ), ); }, ); } Widget _maiHead(HeadSelect shead) { // 是否选中 return GestureDetector( onTap: () { isAll = true; for (var mai in listMai) { if (shead.mic?.user?.id == mai.mic?.user?.id) { mai.isSelect = !mai.isSelect; } if (!mai.isSelect) { isAll = false; } } setState(() {}); }, child: Stack( alignment: Alignment.bottomCenter, clipBehavior: Clip.none, children: [ Stack( alignment: AlignmentDirectional.center, children: [ Container( padding: EdgeInsets.all(2.w), child: netImage( url: shead.mic?.user?.userAvatar ?? "", width: 26.w, defaultImg: _strategy.getMePageDefaultAvatarImage(), shape: BoxShape.circle, ), ), PositionedDirectional( bottom: 0, end: 0, child: Container( alignment: AlignmentDirectional.center, width: 12.w, height: 12.w, decoration: BoxDecoration( color: Colors.black38, shape: BoxShape.circle, border: shead.isSelect ? Border.all( color: SocialChatTheme.primaryLight, width: 1.w, ) : null, ), child: text( "${shead.mic?.micIndex}", textColor: Colors.white, fontSize: 8.sp, ), ), ), shead.isSelect ? PositionedDirectional( bottom: 0, end: 0, child: Image.asset( "sc_images/login/sc_icon_login_ser_select.png", width: 12.w, height: 12.w, ), ) : Container(), ], ), ], ), ); } ///数量选项 void _showNumber(BuildContext ct) { SmartDialog.showAttach( tag: "showNumber", targetContext: ct, maskColor: Colors.transparent, alignment: Alignment.topLeft, animationType: SmartAnimationType.fade, scalePointBuilder: (selfSize) => Offset(selfSize.width, 10), onDismiss: () { isNumberUp = true; setState(() {}); }, builder: (_) { return Transform.translate( offset: Offset(SCGlobalConfig.lang == "ar" ? 20 : -20, -5), child: CheckNumber( onNumberChanged: (number) { this.number = number; isNumberUp = true; setState(() {}); }, ), ); }, ); } ///选中所有在座位上的用户 void selecteAllMicUsers() { for (var mai in listMai) { mai.isSelect = true; } } ///赠送礼物 void giveGifts() { List acceptUserIds = []; List acceptUsers = []; if (widget.toUser != null) { acceptUserIds.add(widget.toUser?.id ?? ""); acceptUsers.add(MicRes(user: widget.toUser)); } else { ///所有在线 if (giveType == 2) { for (var value in Provider.of(context, listen: false).onlineUsers) { acceptUsers.add(MicRes(user: value)); acceptUserIds.add(value.id ?? ""); } } else { for (var mu in listMai) { if (mu.isSelect) { acceptUsers.add(mu.mic!); acceptUserIds.add(mu.mic!.user!.id ?? ""); } } } } if (acceptUserIds.isEmpty) { SCTts.show(SCAppLocalizations.of(context)!.pleaseSelectTheRecipient); return; } if (checkedGift == null) { return; } SCChatRoomRepository() .giveGift( acceptUserIds, checkedGift!.id ?? "", number, false, roomId: rtcProvider?.currenRoom?.roomProfile?.roomProfile?.id ?? "", ) .then((result) { _giftFxLog( 'giveGift success giftId=${checkedGift?.id} ' 'giftName=${checkedGift?.giftName} ' 'giftSourceUrl=${checkedGift?.giftSourceUrl} ' 'special=${checkedGift?.special} ' 'giftTab=${checkedGift?.giftTab} ' 'number=$number ' 'acceptUserIds=${acceptUserIds.join(",")} ' 'roomId=${rtcProvider?.currenRoom?.roomProfile?.roomProfile?.id}', ); // SCTts.show(SCAppLocalizations.of(context)!.giftGivingSuccessful); sendGiftMsg(acceptUsers); Provider.of( context, listen: false, ).updateBalance(result); }) .catchError((e) { _giftFxLog( 'giveGift failed giftId=${checkedGift?.id} ' 'giftName=${checkedGift?.giftName} ' 'error=$e', ); }); } void sendGiftMsg(List acceptUsers) { ///发送一条IM消息 for (var u in acceptUsers) { final special = checkedGift?.special ?? ""; final giftSourceUrl = checkedGift?.giftSourceUrl ?? ""; final hasSource = giftSourceUrl.isNotEmpty; final hasAnimation = scGiftHasAnimationSpecial(special); final hasGlobalGift = special.contains(SCGiftType.GLOBAL_GIFT.name); final hasFullScreenEffect = scGiftHasFullScreenEffect(special); _giftFxLog( 'dispatch gift msg ' 'giftId=${checkedGift?.id} ' 'giftName=${checkedGift?.giftName} ' 'toUserId=${u.user?.id} ' 'toUserName=${u.user?.userNickname} ' 'giftSourceUrl=$giftSourceUrl ' 'special=$special ' 'hasSource=$hasSource ' 'hasAnimation=$hasAnimation ' 'hasGlobalGift=$hasGlobalGift ' 'hasFullScreenEffect=$hasFullScreenEffect ' 'effectsEnabled=${SCGlobalConfig.isGiftSpecialEffects}', ); Provider.of( navigatorKey.currentState!.context, listen: false, ).dispatchMessage( Msg( groupId: rtcProvider?.currenRoom?.roomProfile?.roomProfile?.roomAccount, gift: checkedGift, user: AccountStorage().getCurrentUser()?.userProfile, toUser: u.user, number: number, type: SCRoomMsgType.gift, role: Provider.of( navigatorKey.currentState!.context, listen: false, ).currenRoom?.entrants?.roles ?? "", msg: rtcProvider?.currenRoom?.roomProfile?.roomProfile?.id ?? "", ), addLocal: true, ); if (rtcProvider?.currenRoom?.roomProfile?.roomSetting?.showHeartbeat ?? false) { debouncer.debounce( duration: Duration(milliseconds: 350), onDebounce: () { Provider.of( navigatorKey.currentState!.context, listen: false, ).retrieveMicrophoneList(); }, ); } num coins = checkedGift!.giftCandy! * number; if (coins > 9999) { var fMsg = SCFloatingMessage( type: 1, userAvatarUrl: AccountStorage().getCurrentUser()?.userProfile?.userAvatar ?? "", userName: AccountStorage().getCurrentUser()?.userProfile?.userNickname ?? "", toUserName: u.user?.userNickname ?? "", giftUrl: checkedGift?.giftPhoto ?? "", roomId: rtcProvider?.currenRoom?.roomProfile?.roomProfile?.id ?? "", coins: coins, number: number, ); OverlayManager().addMessage(fMsg); } if (checkedGift!.giftSourceUrl != null && checkedGift!.special != null) { if (scGiftHasFullScreenEffect(checkedGift!.special)) { if (SCGlobalConfig.isGiftSpecialEffects) { _giftFxLog( 'local trigger player play ' 'path=${checkedGift!.giftSourceUrl} ' 'giftId=${checkedGift?.id} ' 'giftName=${checkedGift?.giftName}', ); SCGiftVapSvgaManager().play(checkedGift!.giftSourceUrl!); } else { _giftFxLog( 'skip local play because isGiftSpecialEffects=false ' 'giftId=${checkedGift?.id}', ); } } else { _giftFxLog( 'skip local play because special does not include ' '${SCGiftType.ANIMSCION.name}/$kSCGiftAnimationSpecialAlias/${SCGiftType.GLOBAL_GIFT.name} ' 'giftId=${checkedGift?.id} special=${checkedGift?.special}', ); } } else { _giftFxLog( 'skip local play because giftSourceUrl or special is null ' 'giftId=${checkedGift?.id} ' 'giftSourceUrl=${checkedGift?.giftSourceUrl} ' 'special=${checkedGift?.special}', ); } } } /// 将数字giftType转换为字符串类型,用于活动礼物头部背景 String _giftTypeToString(int giftType) { switch (giftType) { case 1: // ACTIVITY return 'ACTIVITY'; case 2: // LUCKY_GIFT -> LUCK return 'LUCK'; case 3: // CP return 'CP'; case 5: // MAGIC return 'MAGIC'; default: return 'ACTIVITY'; } } _buildGiftHead() { if (giftType == 1 || giftType == 2 || giftType == 3 || giftType == 5) { // 获取基础路径 String basePath = _strategy.getGiftPageActivityGiftHeadBackground( _giftTypeToString(giftType), ); // 添加语言后缀 String imagePath; if (SCGlobalConfig.lang == "ar") { // 移除扩展名,添加 _ar 后缀,然后重新添加扩展名 if (basePath.endsWith('.png')) { imagePath = basePath.substring(0, basePath.length - 4) + '_ar.png'; } else { imagePath = basePath + '_ar'; } } else { if (basePath.endsWith('.png')) { imagePath = basePath.substring(0, basePath.length - 4) + '_en.png'; } else { imagePath = basePath + '_en'; } } // 确定高度 double height = giftType == 5 ? 80.w : 65.w; return Container( margin: EdgeInsets.symmetric(horizontal: 10.w), child: Image.asset(imagePath, height: height, fit: BoxFit.fill), ); } return Container(); } ///发送一条消息,幸运礼物,房间里所有人都能看到礼物飘向麦位的动画 void sendLuckGiftAnimOtherMsg(List acceptUsers) { Provider.of( navigatorKey.currentState!.context, listen: false, ).dispatchMessage( Msg( groupId: rtcProvider?.currenRoom?.roomProfile?.roomProfile?.roomAccount, gift: checkedGift, type: SCRoomMsgType.luckGiftAnimOther, msg: jsonEncode(acceptUsers.map((u) => u.user?.id).toList()), ), addLocal: false, ); } } class CheckNumber extends StatelessWidget { final Function(int) onNumberChanged; late BuildContext context; CheckNumber({super.key, required this.onNumberChanged}); @override Widget build(BuildContext context) { this.context = context; return Container( alignment: AlignmentDirectional.topEnd, margin: EdgeInsets.only(right: width(22)), child: ClipRRect( borderRadius: BorderRadius.all(Radius.circular(12.w)), child: BackdropFilter( filter: ui.ImageFilter.blur(sigmaX: 25, sigmaY: 25), child: Container( decoration: BoxDecoration( color: Colors.white10, borderRadius: BorderRadius.all(Radius.circular(height(6))), ), width: width(75), child: Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox(height: height(10)), _item(1), _item(7), _item(17), _item(77), _item(777), _item(7777), SizedBox(height: height(10)), ], ), ), ), ), ); } _item(int number) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { SmartDialog.dismiss(tag: "showNumber"); onNumberChanged(number); }, child: SizedBox( height: height(24), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SizedBox(width: width(10)), Text( "$number", style: TextStyle( fontSize: sp(14), color: Colors.white, fontWeight: FontWeight.w400, decoration: TextDecoration.none, ), ), SizedBox(width: width(10)), ], ), ), ); } } class HeadSelect { bool isSelect = false; MicRes? mic; HeadSelect(this.isSelect, this.mic); }