yumi-flutter/lib/ui_kit/widgets/room/room_animation_switch_dialog.dart
2026-05-22 14:19:53 +08:00

206 lines
5.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:provider/provider.dart';
import 'package:yumi/app/constants/sc_global_config.dart';
import 'package:yumi/services/audio/rtc_manager.dart';
import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
import 'package:yumi/shared/tools/sc_room_top_layer_guard.dart';
import 'package:yumi/ui_kit/components/sc_debounce_widget.dart';
import 'package:yumi/ui_kit/components/text/sc_text.dart';
class RoomAnimationSwitchDialog extends StatefulWidget {
const RoomAnimationSwitchDialog({super.key});
static const String tag = "showRoomAnimationSwitchDialog";
static void show(BuildContext context) {
SmartDialog.show(
tag: tag,
alignment: Alignment.bottomCenter,
animationType: SmartAnimationType.fade,
debounce: true,
clickMaskDismiss: true,
maskColor: Colors.transparent,
builder:
(_) => const SCRoomTopLayerSuppressor(
reason: 'room_animation_switch_dialog',
child: RoomAnimationSwitchDialog(),
),
);
}
@override
State<RoomAnimationSwitchDialog> createState() =>
_RoomAnimationSwitchDialogState();
}
class _RoomAnimationSwitchDialogState extends State<RoomAnimationSwitchDialog> {
late bool _giftEffectsEnabled;
late bool _entryEffectsEnabled;
String? get _account =>
AccountStorage().getCurrentUser()?.userProfile?.account;
@override
void initState() {
super.initState();
_giftEffectsEnabled = SCGlobalConfig.isGiftSpecialEffects;
_entryEffectsEnabled = SCGlobalConfig.isEntryVehicleAnimation;
}
Future<void> _setGiftEffectsEnabled(bool enabled) async {
final next = SCGlobalConfig.clampVisualEffectPreference(enabled);
setState(() {
_giftEffectsEnabled = next;
});
SCGlobalConfig.isGiftSpecialEffects = next;
SCGlobalConfig.isLuckGiftSpecialEffects = next;
await Future.wait([
DataPersistence.setBool("$_account-GiftSpecialEffects", next),
DataPersistence.setBool("$_account-LuckGiftSpecialEffects", next),
]);
}
Future<void> _setEntryEffectsEnabled(bool enabled) async {
final next = SCGlobalConfig.clampVisualEffectPreference(enabled);
setState(() {
_entryEffectsEnabled = next;
});
SCGlobalConfig.isEntryVehicleAnimation = next;
Provider.of<RtcProvider>(
context,
listen: false,
).notifyRoomVisualEffectPreferenceChanged();
await DataPersistence.setBool("$_account-EntryVehicleAnimation", next);
}
@override
Widget build(BuildContext context) {
return Container(
width: ScreenUtil().screenWidth,
height: 151.w,
decoration: BoxDecoration(
color: const Color(0xff072121),
borderRadius: BorderRadius.only(
topLeft: Radius.circular(12.w),
topRight: Radius.circular(12.w),
),
),
child: Stack(
children: [
Positioned(
top: 16.w,
left: 0,
right: 0,
child: text(
"Animation",
fontSize: 18,
textColor: Colors.white,
fontWeight: FontWeight.w500,
lineHeight: 1,
textAlign: TextAlign.center,
),
),
_buildSwitchRow(
top: 59.w,
title: "Gift Animation",
value: _giftEffectsEnabled,
onTap: () => _setGiftEffectsEnabled(!_giftEffectsEnabled),
),
_buildSwitchRow(
top: 97.w,
title: "Vehicle Animation",
value: _entryEffectsEnabled,
onTap: () => _setEntryEffectsEnabled(!_entryEffectsEnabled),
),
],
),
);
}
Widget _buildSwitchRow({
required double top,
required String title,
required bool value,
required VoidCallback onTap,
}) {
return Positioned(
top: top - 8.w,
left: 0,
right: 0,
height: 30.w,
child: Stack(
children: [
Positioned(
left: 36.w,
top: 8.w,
height: 14.w,
child: Align(
alignment: Alignment.centerLeft,
child: text(
title,
fontSize: 14,
textColor: Colors.white,
fontWeight: FontWeight.w400,
lineHeight: 1,
),
),
),
SCDebounceWidget(
onTap: onTap,
child: Align(
alignment: Alignment.centerRight,
child: Padding(
padding: EdgeInsets.only(right: 24.w),
child: SizedBox(
width: 56.w,
height: 30.w,
child: Center(child: _FigmaAnimationSwitch(value: value)),
),
),
),
),
],
),
);
}
}
class _FigmaAnimationSwitch extends StatelessWidget {
const _FigmaAnimationSwitch({required this.value});
final bool value;
@override
Widget build(BuildContext context) {
final color = value ? const Color(0xff18F2B1) : const Color(0xff999999);
return SizedBox(
width: 32.w,
height: 14.w,
child: Stack(
children: [
Positioned.fill(
child: DecoratedBox(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(7.w),
border: Border.all(color: color, width: 1.w),
),
),
),
Positioned(
left: value ? 20.w : 2.w,
top: 2.w,
child: Container(
width: 10.w,
height: 10.w,
decoration: BoxDecoration(color: color, shape: BoxShape.circle),
),
),
],
),
);
}
}