import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:yumi/app/constants/sc_global_config.dart'; import 'package:yumi/app/routes/sc_fluro_navigator.dart'; import 'package:yumi/app_localizations.dart'; import 'package:yumi/ui_kit/theme/socialchat_theme.dart'; import 'package:yumi/ui_kit/widgets/room/room_bottom_widget.dart'; import 'package:yumi/ui_kit/widgets/room/room_head_widget.dart'; import 'package:yumi/ui_kit/widgets/room/room_online_user_widget.dart'; class RoomBackgroundPreviewPage extends StatelessWidget { const RoomBackgroundPreviewPage({super.key, this.backgroundPath}); final String? backgroundPath; @override Widget build(BuildContext context) { final bottomPadding = MediaQuery.of(context).padding.bottom; final localizations = SCAppLocalizations.of(context)!; return Scaffold( backgroundColor: Colors.black, body: Stack( children: [ Positioned.fill(child: _PreviewBackground(path: backgroundPath)), Positioned.fill(child: _PreviewRoomLayer()), Positioned( left: 24.w, right: 24.w, bottom: 148.w + bottomPadding, child: _PreviewPrimaryButton( text: localizations.endPreview, onTap: () => SCNavigatorUtils.goBackWithParams(context, true), ), ), Positioned( left: 24.w, right: 24.w, bottom: 90.w + bottomPadding, child: _PreviewSecondaryButton( text: localizations.selectAgain, onTap: () => SCNavigatorUtils.goBackWithParams(context, false), ), ), ], ), ); } } class _PreviewBackground extends StatelessWidget { const _PreviewBackground({this.path}); final String? path; @override Widget build(BuildContext context) { final value = (path ?? "").trim(); if (value.startsWith("http://") || value.startsWith("https://")) { return Image.network( value, fit: BoxFit.cover, errorBuilder: (_, __, ___) => const _DefaultPreviewBackground(), ); } if (value.startsWith("assets/") || value.startsWith("sc_images/")) { return Image.asset( value, fit: BoxFit.cover, errorBuilder: (_, __, ___) => const _DefaultPreviewBackground(), ); } if (value.isNotEmpty) { final file = File(value); if (file.existsSync()) { return Image.file( file, fit: BoxFit.cover, errorBuilder: (_, __, ___) => const _DefaultPreviewBackground(), ); } } return const _DefaultPreviewBackground(); } } class _DefaultPreviewBackground extends StatelessWidget { const _DefaultPreviewBackground(); @override Widget build(BuildContext context) { return Image.asset( SCGlobalConfig.businessLogicStrategy.getVoiceRoomDefaultBackgroundImage(), fit: BoxFit.cover, ); } } class _PreviewRoomLayer extends StatelessWidget { @override Widget build(BuildContext context) { return Column( children: [ SizedBox(height: ScreenUtil().setWidth(42)), IgnorePointer(child: RoomHeadWidget()), SizedBox(height: 5.w), const IgnorePointer(child: RoomOnlineUserWidget()), const IgnorePointer(child: _PreviewSeat10()), Expanded(child: _PreviewChatArea()), const IgnorePointer(child: RoomBottomWidget()), ], ); } } class _PreviewSeat10 extends StatelessWidget { const _PreviewSeat10(); @override Widget build(BuildContext context) { return Container( margin: EdgeInsets.only(top: 3.w, left: 10.w, right: 10.w), child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: List.generate( 5, (index) => Expanded( child: _PreviewSeatItem(index: index, locked: index == 1), ), ), ), Row( children: List.generate(5, (index) { final seatIndex = index + 5; return Expanded( child: _PreviewSeatItem( index: seatIndex, locked: seatIndex == 6, ), ); }), ), ], ), ); } } class _PreviewSeatItem extends StatelessWidget { const _PreviewSeatItem({required this.index, required this.locked}); final int index; final bool locked; @override Widget build(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, children: [ SizedBox( width: 55.w, height: 55.w, child: Image.asset( locked ? "sc_images/room/sc_icon_seat_lock.png" : "sc_images/room/sc_icon_seat_open.png", width: 52.w, height: 52.w, ), ), SizedBox( height: 16.w, child: Center( child: Text( "NO.${index + 1}", style: TextStyle( color: Colors.white, fontSize: 10.sp, fontWeight: FontWeight.w600, ), ), ), ), ], ); } } class _PreviewChatArea extends StatefulWidget { @override State<_PreviewChatArea> createState() => _PreviewChatAreaState(); } class _PreviewChatAreaState extends State<_PreviewChatArea> { int _selectedTabIndex = 0; void _selectTab(int index) { if (_selectedTabIndex == index) { return; } setState(() { _selectedTabIndex = index; }); } @override Widget build(BuildContext context) { return Stack( children: [ Positioned( left: 0, right: 0, top: 0, child: _PreviewChatTabs( selectedIndex: _selectedTabIndex, onTap: _selectTab, ), ), Positioned( left: 24.w, right: 24.w, bottom: 166.w, child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ _PreviewChatBubble(text: "Hello My Friends!"), SizedBox(height: 12.w), _PreviewGiftBubble(), ], ), ), ], ); } } class _PreviewChatTabs extends StatelessWidget { const _PreviewChatTabs({required this.selectedIndex, required this.onTap}); final int selectedIndex; final ValueChanged onTap; @override Widget build(BuildContext context) { return SizedBox( height: 32.w, child: ListView.builder( scrollDirection: Axis.horizontal, padding: EdgeInsets.symmetric(horizontal: 8.w), itemCount: 3, itemBuilder: (context, index) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () => onTap(index), child: Padding( padding: EdgeInsets.symmetric(horizontal: 8.w), child: Center( child: Image.asset( _assetFor(index, selectedIndex == index), height: 26.w, fit: BoxFit.contain, ), ), ), ); }, ), ); } String _assetFor(int index, bool selected) { switch (index) { case 0: return selected ? "sc_images/room/sc_icon_room_chat_tab_all_selected.png" : "sc_images/room/sc_icon_room_chat_tab_all_unselected.png"; case 1: return selected ? "sc_images/room/sc_icon_room_chat_tab_chat_selected.png" : "sc_images/room/sc_icon_room_chat_tab_chat_unselected.png"; case 2: default: return selected ? "sc_images/room/sc_icon_room_chat_tab_gift_selected.png" : "sc_images/room/sc_icon_room_chat_tab_gift_unselected.png"; } } } class _PreviewChatBubble extends StatelessWidget { const _PreviewChatBubble({required this.text}); final String text; @override Widget build(BuildContext context) { return Container( constraints: BoxConstraints(maxWidth: 276.w), padding: EdgeInsets.symmetric(horizontal: 14.w, vertical: 10.w), decoration: BoxDecoration( color: Colors.black.withValues(alpha: 0.42), borderRadius: BorderRadius.circular(10.w), ), child: Text( text, style: TextStyle( color: Colors.white, fontSize: 13.sp, fontWeight: FontWeight.w700, ), ), ); } } class _PreviewGiftBubble extends StatelessWidget { @override Widget build(BuildContext context) { return Container( constraints: BoxConstraints(maxWidth: 300.w), padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 10.w), decoration: BoxDecoration( color: Colors.black.withValues(alpha: 0.44), borderRadius: BorderRadius.circular(10.w), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Flexible( child: Text( "Send To User Name2", maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( color: Colors.white, fontSize: 13.sp, fontWeight: FontWeight.w700, ), ), ), SizedBox(width: 10.w), ClipOval( child: Image.asset( "sc_images/general/sc_icon_avar_defalt.png", width: 32.w, height: 32.w, fit: BoxFit.cover, ), ), SizedBox(width: 6.w), Text( "*1", style: TextStyle( color: Colors.white, fontSize: 12.sp, fontWeight: FontWeight.w800, ), ), ], ), ); } } class _PreviewPrimaryButton extends StatelessWidget { const _PreviewPrimaryButton({required this.text, required this.onTap}); final String text; final VoidCallback onTap; @override Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: onTap, child: Container( height: 48.w, alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(999.w), gradient: LinearGradient( colors: [SocialChatTheme.primaryLight, const Color(0xff8BF2D0)], ), ), child: Text( text, style: TextStyle( color: const Color(0xff0B2823), fontSize: 18.sp, fontWeight: FontWeight.w700, ), ), ), ); } } class _PreviewSecondaryButton extends StatelessWidget { const _PreviewSecondaryButton({required this.text, required this.onTap}); final String text; final VoidCallback onTap; @override Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: onTap, child: Container( height: 48.w, alignment: Alignment.center, decoration: BoxDecoration( color: const Color(0xff06372F).withValues(alpha: 0.9), borderRadius: BorderRadius.circular(999.w), border: Border.all(color: SocialChatTheme.primaryLight, width: 1.w), ), child: Text( text, style: TextStyle( color: Colors.white, fontSize: 18.sp, fontWeight: FontWeight.w700, ), ), ), ); } }