206 lines
5.9 KiB
Dart
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),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|