yumi-flutter/lib/modules/user/settings/broadcast/broadcast_settings_page.dart
2026-05-08 19:41:18 +08:00

248 lines
8.7 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:yumi/app/constants/sc_global_config.dart';
import 'package:yumi/app_localizations.dart';
import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
import 'package:yumi/shared/data_sources/sources/local/floating_screen_manager.dart';
import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
import 'package:yumi/ui_kit/components/appbar/socialchat_appbar.dart';
import 'package:yumi/ui_kit/components/sc_debounce_widget.dart';
import 'package:yumi/ui_kit/components/text/sc_text.dart';
class BroadcastSettingsPage extends StatefulWidget {
const BroadcastSettingsPage({super.key});
@override
State<BroadcastSettingsPage> createState() => _BroadcastSettingsPageState();
}
class _BroadcastSettingsPageState extends State<BroadcastSettingsPage> {
static const String _scopePickerTag = "showBroadcastScopePicker";
late String _selectedScope;
@override
void initState() {
super.initState();
_selectedScope = _readSavedScope();
SCGlobalConfig.floatingBroadcastScope = _selectedScope;
}
String? get _account =>
AccountStorage().getCurrentUser()?.userProfile?.account;
String _readSavedScope() {
final savedScope = DataPersistence.getString(
SCGlobalConfig.floatingBroadcastScopeStorageKey(_account),
);
if (savedScope.isNotEmpty) {
return SCGlobalConfig.normalizeFloatingBroadcastScope(savedScope);
}
final isLegacyEnabled = DataPersistence.getBool(
SCGlobalConfig.legacyFloatingAnimationInGlobalStorageKey(_account),
defaultValue: true,
);
return isLegacyEnabled
? SCGlobalConfig.floatingBroadcastScopeAll
: SCGlobalConfig.floatingBroadcastScopeOff;
}
String _scopeTitle(BuildContext context, String scope) {
final l10n = SCAppLocalizations.of(context)!;
switch (SCGlobalConfig.normalizeFloatingBroadcastScope(scope)) {
case SCGlobalConfig.floatingBroadcastScopeOff:
return l10n.broadcastOff;
case SCGlobalConfig.floatingBroadcastScopeRoom:
return l10n.broadcastRoomOnly;
case SCGlobalConfig.floatingBroadcastScopeAll:
default:
return l10n.broadcastAllPlaces;
}
}
Future<void> _selectScope(String scope) async {
final normalizedScope = SCGlobalConfig.normalizeFloatingBroadcastScope(
scope,
);
setState(() {
_selectedScope = normalizedScope;
});
SCGlobalConfig.floatingBroadcastScope = normalizedScope;
OverlayManager().refreshDisplayPreference();
await DataPersistence.setString(
SCGlobalConfig.floatingBroadcastScopeStorageKey(_account),
normalizedScope,
);
await DataPersistence.setBool(
SCGlobalConfig.legacyFloatingAnimationInGlobalStorageKey(_account),
normalizedScope != SCGlobalConfig.floatingBroadcastScopeOff,
);
SmartDialog.dismiss(tag: _scopePickerTag);
}
void _showScopePicker() {
SmartDialog.show(
tag: _scopePickerTag,
alignment: Alignment.bottomCenter,
animationType: SmartAnimationType.fade,
builder: (_) {
return SafeArea(
top: false,
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(top: Radius.circular(10.w)),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_buildScopeOption(SCGlobalConfig.floatingBroadcastScopeAll),
Divider(height: 1.w, color: const Color(0xffeeeeee)),
_buildScopeOption(SCGlobalConfig.floatingBroadcastScopeRoom),
Divider(height: 1.w, color: const Color(0xffeeeeee)),
_buildScopeOption(SCGlobalConfig.floatingBroadcastScopeOff),
Container(height: 6.w, color: const Color(0xfff5f5f5)),
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => SmartDialog.dismiss(tag: _scopePickerTag),
child: Container(
height: 48.w,
alignment: Alignment.center,
child: text(
SCAppLocalizations.of(context)!.cancel,
textColor: Colors.black45,
fontSize: 13.sp,
),
),
),
],
),
),
);
},
);
}
Widget _buildScopeOption(String scope) {
final selected =
SCGlobalConfig.normalizeFloatingBroadcastScope(_selectedScope) ==
SCGlobalConfig.normalizeFloatingBroadcastScope(scope);
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => _selectScope(scope),
child: Container(
height: 48.w,
padding: EdgeInsets.symmetric(horizontal: 18.w),
child: Row(
children: [
Expanded(
child: Center(
child: text(
_scopeTitle(context, scope),
textColor: Colors.black87,
fontSize: 13.sp,
),
),
),
SizedBox(
width: 18.w,
child:
selected
? Icon(
Icons.check,
size: 16.w,
color: const Color(0xff18F2B1),
)
: null,
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
Image.asset(
SCGlobalConfig.businessLogicStrategy.getSettingsPageBackgroundImage(),
width: ScreenUtil().screenWidth,
height: ScreenUtil().screenHeight,
fit: BoxFit.fill,
),
Scaffold(
backgroundColor: Colors.transparent,
resizeToAvoidBottomInset: false,
appBar: SocialChatStandardAppBar(
title: SCAppLocalizations.of(context)!.broadcast,
actions: [],
),
body: SafeArea(
top: false,
child: Column(
children: [
Container(
padding: EdgeInsets.symmetric(vertical: 12.w),
margin: EdgeInsets.symmetric(vertical: 8.w, horizontal: 15.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12),
color:
SCGlobalConfig.businessLogicStrategy
.getSettingsPageContainerBackgroundColor(),
border: Border.all(
color:
SCGlobalConfig.businessLogicStrategy
.getSettingsPageContainerBorderColor(),
width: 1.w,
),
),
child: SCDebounceWidget(
onTap: _showScopePicker,
child: Row(
children: [
SizedBox(width: 18.w),
Expanded(
child: text(
SCAppLocalizations.of(context)!.broadcastDisplay,
textColor:
SCGlobalConfig.businessLogicStrategy
.getSettingsPagePrimaryTextColor(),
fontSize: 13.sp,
),
),
text(
_scopeTitle(context, _selectedScope),
textColor:
SCGlobalConfig.businessLogicStrategy
.getSettingsPageSecondaryTextColor(),
fontSize: 12.sp,
maxWidth: 120.w,
textAlign: TextAlign.end,
),
SizedBox(width: 6.w),
Icon(
SCGlobalConfig.lang == "ar"
? Icons.keyboard_arrow_left
: Icons.keyboard_arrow_right,
size: 15.w,
color:
SCGlobalConfig.businessLogicStrategy
.getSettingsPageIconColor(),
),
SizedBox(width: 18.w),
],
),
),
),
],
),
),
),
],
);
}
}