1.2.6
This commit is contained in:
parent
fd445ccdaa
commit
36ba0f3573
@ -502,7 +502,7 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 7;
|
CURRENT_PROJECT_VERSION = 8;
|
||||||
DEVELOPMENT_TEAM = S9X2AJ2US9;
|
DEVELOPMENT_TEAM = S9X2AJ2US9;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -511,7 +511,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.5;
|
MARKETING_VERSION = 1.2.6;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -693,7 +693,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 7;
|
CURRENT_PROJECT_VERSION = 8;
|
||||||
DEVELOPMENT_TEAM = F33K8VUZ62;
|
DEVELOPMENT_TEAM = F33K8VUZ62;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -702,7 +702,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.5;
|
MARKETING_VERSION = 1.2.6;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -722,7 +722,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 7;
|
CURRENT_PROJECT_VERSION = 8;
|
||||||
DEVELOPMENT_TEAM = F33K8VUZ62;
|
DEVELOPMENT_TEAM = F33K8VUZ62;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -731,7 +731,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.5;
|
MARKETING_VERSION = 1.2.6;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|||||||
@ -272,8 +272,7 @@ class _RoomFollowPageState
|
|||||||
Provider.of<RtcProvider>(context, listen: false).joinVoiceRoomSession(
|
Provider.of<RtcProvider>(context, listen: false).joinVoiceRoomSession(
|
||||||
context,
|
context,
|
||||||
roomRes.roomProfile?.id ?? "",
|
roomRes.roomProfile?.id ?? "",
|
||||||
previewSeatCount:
|
previewData: RoomEntryPreviewData.fromFollowRoom(roomRes),
|
||||||
roomRes.roomProfile?.extValues?.roomSetting?.mikeSize?.toInt(),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@ -272,8 +272,7 @@ class _SCRoomHistoryPageState
|
|||||||
Provider.of<RtcProvider>(context, listen: false).joinVoiceRoomSession(
|
Provider.of<RtcProvider>(context, listen: false).joinVoiceRoomSession(
|
||||||
context,
|
context,
|
||||||
roomRes.roomProfile?.id ?? "",
|
roomRes.roomProfile?.id ?? "",
|
||||||
previewSeatCount:
|
previewData: RoomEntryPreviewData.fromFollowRoom(roomRes),
|
||||||
roomRes.roomProfile?.extValues?.roomSetting?.mikeSize?.toInt(),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@ -238,23 +238,26 @@ class _HomeMinePageState extends State<SCHomeMinePage>
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
String roomId =
|
final roomManager = Provider.of<SocialChatRoomManager>(
|
||||||
Provider.of<SocialChatRoomManager>(
|
context,
|
||||||
context,
|
listen: false,
|
||||||
listen: false,
|
);
|
||||||
).myRoom?.id ??
|
final myRoom = roomManager.myRoom;
|
||||||
"";
|
final roomId = myRoom?.id ?? "";
|
||||||
Provider.of<RealTimeCommunicationManager>(
|
Provider.of<RealTimeCommunicationManager>(
|
||||||
context,
|
context,
|
||||||
listen: false,
|
listen: false,
|
||||||
).joinVoiceRoomSession(
|
).joinVoiceRoomSession(
|
||||||
context,
|
context,
|
||||||
roomId,
|
roomId,
|
||||||
previewSeatCount:
|
previewData:
|
||||||
Provider.of<SocialChatRoomManager>(
|
myRoom == null
|
||||||
context,
|
? null
|
||||||
listen: false,
|
: RoomEntryPreviewData.fromMyRoom(
|
||||||
).myRoom?.setting?.mikeSize?.toInt(),
|
myRoom,
|
||||||
|
ownerProfile:
|
||||||
|
AccountStorage().getCurrentUser()?.userProfile,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import '../../../../shared/business_logic/models/res/follow_room_res.dart';
|
|||||||
import '../../../../shared/business_logic/models/res/room_res.dart';
|
import '../../../../shared/business_logic/models/res/room_res.dart';
|
||||||
import '../../../../services/audio/rtc_manager.dart';
|
import '../../../../services/audio/rtc_manager.dart';
|
||||||
import '../../../../services/general/sc_app_general_manager.dart';
|
import '../../../../services/general/sc_app_general_manager.dart';
|
||||||
|
import '../../../../services/home/home_room_preload_manager.dart';
|
||||||
import '../../../../ui_kit/components/sc_compontent.dart';
|
import '../../../../ui_kit/components/sc_compontent.dart';
|
||||||
import '../../../../ui_kit/components/text/sc_text.dart';
|
import '../../../../ui_kit/components/text/sc_text.dart';
|
||||||
import '../../../../ui_kit/widgets/room/room_live_audio_indicator.dart';
|
import '../../../../ui_kit/widgets/room/room_live_audio_indicator.dart';
|
||||||
@ -122,7 +123,7 @@ class _HomePartyPageState extends State<SCHomePartyPage>
|
|||||||
enablePullUp: false,
|
enablePullUp: false,
|
||||||
controller: _refreshController,
|
controller: _refreshController,
|
||||||
onRefresh: () {
|
onRefresh: () {
|
||||||
loadData();
|
loadData(forceRefresh: true);
|
||||||
},
|
},
|
||||||
onLoading: () {},
|
onLoading: () {},
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
@ -968,20 +969,20 @@ class _HomePartyPageState extends State<SCHomePartyPage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadData() {
|
loadData({bool forceRefresh = false}) {
|
||||||
final generalManager = Provider.of<SCAppGeneralManager>(
|
final generalManager = Provider.of<SCAppGeneralManager>(
|
||||||
context,
|
context,
|
||||||
listen: false,
|
listen: false,
|
||||||
);
|
);
|
||||||
setState(() {
|
setState(() {
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
_isBannerLoading =
|
_isBannerLoading =
|
||||||
generalManager.exploreBanners.isEmpty &&
|
generalManager.exploreBanners.isEmpty &&
|
||||||
generalManager.homeBanners.isEmpty;
|
generalManager.homeBanners.isEmpty;
|
||||||
_isLeaderboardLoading = generalManager.appLeaderResult == null;
|
_isLeaderboardLoading = generalManager.appLeaderResult == null;
|
||||||
});
|
});
|
||||||
SCChatRoomRepository()
|
SCHomeRoomPreloadManager.instance
|
||||||
.discovery(allRegion: true)
|
.loadPartyRooms(forceRefresh: forceRefresh)
|
||||||
.then((values) {
|
.then((values) {
|
||||||
rooms = _mergeLatestRoomsWithCurrentCounters(values);
|
rooms = _mergeLatestRoomsWithCurrentCounters(values);
|
||||||
isLoading = false;
|
isLoading = false;
|
||||||
@ -1020,7 +1021,9 @@ class _HomePartyPageState extends State<SCHomePartyPage>
|
|||||||
|
|
||||||
_buildItem(SocialChatRoomRes res, int index) {
|
_buildItem(SocialChatRoomRes res, int index) {
|
||||||
final rankBorderAsset =
|
final rankBorderAsset =
|
||||||
index < _topRankBorderAssets.length ? _topRankBorderAssets[index] : null;
|
index < _topRankBorderAssets.length
|
||||||
|
? _topRankBorderAssets[index]
|
||||||
|
: null;
|
||||||
final rankBorderOverflow = 12.w;
|
final rankBorderOverflow = 12.w;
|
||||||
final rankInfoHorizontalInset = rankBorderAsset != null ? 10.w : 0.w;
|
final rankInfoHorizontalInset = rankBorderAsset != null ? 10.w : 0.w;
|
||||||
final rankInfoBottomInset = rankBorderAsset != null ? 9.w : 0.w;
|
final rankInfoBottomInset = rankBorderAsset != null ? 9.w : 0.w;
|
||||||
@ -1177,7 +1180,7 @@ class _HomePartyPageState extends State<SCHomePartyPage>
|
|||||||
Provider.of<RtcProvider>(context, listen: false).joinVoiceRoomSession(
|
Provider.of<RtcProvider>(context, listen: false).joinVoiceRoomSession(
|
||||||
context,
|
context,
|
||||||
res.id ?? "",
|
res.id ?? "",
|
||||||
previewSeatCount: res.extValues?.roomSetting?.mikeSize?.toInt(),
|
previewData: RoomEntryPreviewData.fromSocialChatRoom(res),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@ -591,6 +591,24 @@ class _RoomEditPageState extends State<RoomEditPage> {
|
|||||||
rtcProvider?.currenRoom?.roomProfile?.roomProfile?.id ??
|
rtcProvider?.currenRoom?.roomProfile?.roomProfile?.id ??
|
||||||
"",
|
"",
|
||||||
clearRoomData: true,
|
clearRoomData: true,
|
||||||
|
previewData: RoomEntryPreviewData(
|
||||||
|
roomId:
|
||||||
|
mergedRoomInfo.id ??
|
||||||
|
rtcProvider?.currenRoom?.roomProfile?.roomProfile?.id,
|
||||||
|
roomAccount:
|
||||||
|
rtcProvider?.currenRoom?.roomProfile?.roomProfile?.roomAccount,
|
||||||
|
userId: rtcProvider?.currenRoom?.roomProfile?.roomProfile?.userId,
|
||||||
|
roomCover: mergedRoomInfo.roomCover,
|
||||||
|
roomName: mergedRoomInfo.roomName ?? submittedRoomName,
|
||||||
|
roomDesc: mergedRoomInfo.roomDesc ?? submittedRoomDesc,
|
||||||
|
roomSetting: rtcProvider?.currenRoom?.roomProfile?.roomSetting,
|
||||||
|
ownerProfile: rtcProvider?.currenRoom?.roomProfile?.userProfile,
|
||||||
|
roomAdminCount:
|
||||||
|
rtcProvider?.currenRoom?.roomProfile?.roomCounter?.adminCount,
|
||||||
|
roomMemberCount:
|
||||||
|
rtcProvider?.currenRoom?.roomProfile?.roomCounter?.memberCount,
|
||||||
|
entrantsRole: rtcProvider?.currenRoom?.entrants?.roles,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
SCLoadingManager.hide();
|
SCLoadingManager.hide();
|
||||||
|
|||||||
@ -65,6 +65,8 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
|
|||||||
final Map<String, _LuckyGiftComboSession> _luckyGiftComboSessions =
|
final Map<String, _LuckyGiftComboSession> _luckyGiftComboSessions =
|
||||||
<String, _LuckyGiftComboSession>{};
|
<String, _LuckyGiftComboSession>{};
|
||||||
int _shownRoomStartupFailureToken = 0;
|
int _shownRoomStartupFailureToken = 0;
|
||||||
|
RtcProvider? _rtcProvider;
|
||||||
|
bool _roomProviderRebuildScheduled = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
@ -90,11 +92,20 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
|
|||||||
@override
|
@override
|
||||||
void didChangeDependencies() {
|
void didChangeDependencies() {
|
||||||
super.didChangeDependencies();
|
super.didChangeDependencies();
|
||||||
|
final rtcProvider = context.read<RtcProvider>();
|
||||||
|
if (!identical(_rtcProvider, rtcProvider)) {
|
||||||
|
_rtcProvider?.removeListener(_handleRoomProviderChanged);
|
||||||
|
_rtcProvider = rtcProvider;
|
||||||
|
rtcProvider.addListener(_handleRoomProviderChanged);
|
||||||
|
}
|
||||||
_ensureRoomVisualEffectsEnabled();
|
_ensureRoomVisualEffectsEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_rtcProvider?.removeListener(_handleRoomProviderChanged);
|
||||||
|
_rtcProvider = null;
|
||||||
|
_roomProviderRebuildScheduled = false;
|
||||||
_suspendRoomVisualEffects();
|
_suspendRoomVisualEffects();
|
||||||
_tabController.removeListener(_handleTabChange);
|
_tabController.removeListener(_handleTabChange);
|
||||||
_tabController.dispose(); // 释放资源
|
_tabController.dispose(); // 释放资源
|
||||||
@ -109,6 +120,20 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
|
|||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _handleRoomProviderChanged() {
|
||||||
|
if (!mounted || _roomProviderRebuildScheduled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_roomProviderRebuildScheduled = true;
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
_roomProviderRebuildScheduled = false;
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setState(() {});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void _enableRoomVisualEffects() {
|
void _enableRoomVisualEffects() {
|
||||||
Provider.of<RtcProvider>(
|
Provider.of<RtcProvider>(
|
||||||
context,
|
context,
|
||||||
|
|||||||
@ -20,6 +20,9 @@ class VoiceRoomRoute implements SCIRouterProvider {
|
|||||||
static String roomBackgroundPreview = '/room/background/preview';
|
static String roomBackgroundPreview = '/room/background/preview';
|
||||||
static String roomBackgroundUpload = '/room/background/upload';
|
static String roomBackgroundUpload = '/room/background/upload';
|
||||||
static String roomMusic = '/room/music';
|
static String roomMusic = '/room/music';
|
||||||
|
static int _voiceRoomRouteDepth = 0;
|
||||||
|
|
||||||
|
static bool get isVoiceRoomOpen => _voiceRoomRouteDepth > 0;
|
||||||
|
|
||||||
static Route<T> _buildRoute<T>(Widget page, {RouteSettings? settings}) {
|
static Route<T> _buildRoute<T>(Widget page, {RouteSettings? settings}) {
|
||||||
if (Platform.isIOS) {
|
if (Platform.isIOS) {
|
||||||
@ -54,14 +57,26 @@ class VoiceRoomRoute implements SCIRouterProvider {
|
|||||||
bool rootNavigator = false,
|
bool rootNavigator = false,
|
||||||
}) {
|
}) {
|
||||||
final navigator = Navigator.of(context, rootNavigator: rootNavigator);
|
final navigator = Navigator.of(context, rootNavigator: rootNavigator);
|
||||||
|
if (!replace && isVoiceRoomOpen) {
|
||||||
|
debugPrint('[RoomRoute] skip duplicate voice room route');
|
||||||
|
return Future<T?>.value();
|
||||||
|
}
|
||||||
final route = _buildRoute<T>(
|
final route = _buildRoute<T>(
|
||||||
const VoiceRoomPage(),
|
const VoiceRoomPage(),
|
||||||
settings: RouteSettings(name: voiceRoom),
|
settings: RouteSettings(name: voiceRoom),
|
||||||
);
|
);
|
||||||
|
_voiceRoomRouteDepth = replace ? 1 : _voiceRoomRouteDepth + 1;
|
||||||
|
Future<T?> routeFuture;
|
||||||
if (replace) {
|
if (replace) {
|
||||||
return navigator.pushReplacement<T, T>(route);
|
routeFuture = navigator.pushReplacement<T, T>(route);
|
||||||
|
} else {
|
||||||
|
routeFuture = navigator.push<T>(route);
|
||||||
}
|
}
|
||||||
return navigator.push<T>(route);
|
return routeFuture.whenComplete(() {
|
||||||
|
if (_voiceRoomRouteDepth > 0) {
|
||||||
|
_voiceRoomRouteDepth -= 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<T?> openRoomEdit<T>(
|
static Future<T?> openRoomEdit<T>(
|
||||||
|
|||||||
@ -434,13 +434,11 @@ class _SearchRoomListState extends State<SearchRoomList> {
|
|||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (context != null) {
|
Provider.of<RtcProvider>(context, listen: false).joinVoiceRoomSession(
|
||||||
Provider.of<RtcProvider>(context, listen: false).joinVoiceRoomSession(
|
context,
|
||||||
context,
|
e.id ?? "",
|
||||||
e.id ?? "",
|
previewData: RoomEntryPreviewData.fromSocialChatRoom(e),
|
||||||
previewSeatCount: e.extValues?.roomSetting?.mikeSize?.toInt(),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: Alignment.bottomCenter,
|
alignment: Alignment.bottomCenter,
|
||||||
@ -544,9 +542,9 @@ class _SearchRoomListState extends State<SearchRoomList> {
|
|||||||
width: 20.w,
|
width: 20.w,
|
||||||
height: 20.w,
|
height: 20.w,
|
||||||
),
|
),
|
||||||
(e.extValues?.roomSetting?.password?.isEmpty ?? false)
|
(e.extValues?.roomSetting?.password?.isEmpty ?? false)
|
||||||
? SizedBox(width: 3.w)
|
? SizedBox(width: 3.w)
|
||||||
: Container(height: 10.w),
|
: Container(height: 10.w),
|
||||||
(e.extValues?.roomSetting?.password?.isEmpty ?? false)
|
(e.extValues?.roomSetting?.password?.isEmpty ?? false)
|
||||||
? text(
|
? text(
|
||||||
e.displayMemberCount,
|
e.displayMemberCount,
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
|
|||||||
import 'package:yumi/shared/business_logic/models/res/login_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/login_res.dart';
|
||||||
import 'package:yumi/app/routes/sc_routes.dart';
|
import 'package:yumi/app/routes/sc_routes.dart';
|
||||||
import 'package:yumi/app/routes/sc_fluro_navigator.dart';
|
import 'package:yumi/app/routes/sc_fluro_navigator.dart';
|
||||||
|
import 'package:yumi/services/home/home_room_preload_manager.dart';
|
||||||
import 'package:yumi/shared/data_sources/sources/local/file_cache_manager.dart';
|
import 'package:yumi/shared/data_sources/sources/local/file_cache_manager.dart';
|
||||||
import 'package:yumi/ui_kit/components/sc_compontent.dart';
|
import 'package:yumi/ui_kit/components/sc_compontent.dart';
|
||||||
|
|
||||||
@ -95,6 +96,7 @@ class _SplashPageState extends State<SplashPage> {
|
|||||||
_selectedVariant = _pickSplashVariant();
|
_selectedVariant = _pickSplashVariant();
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
unawaited(FileCacheManager.getInstance().getFilePath());
|
unawaited(FileCacheManager.getInstance().getFilePath());
|
||||||
|
SCHomeRoomPreloadManager.instance.preloadInitialHomeRooms();
|
||||||
unawaited(WeeklyStarSplashCache.refreshCacheInBackground());
|
unawaited(WeeklyStarSplashCache.refreshCacheInBackground());
|
||||||
unawaited(LastWeeklyCPSplashCache.refreshCacheInBackground());
|
unawaited(LastWeeklyCPSplashCache.refreshCacheInBackground());
|
||||||
});
|
});
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import 'package:yumi/app_localizations.dart';
|
|||||||
import 'package:yumi/modules/index/main_route.dart';
|
import 'package:yumi/modules/index/main_route.dart';
|
||||||
import 'package:yumi/modules/store/store_route.dart';
|
import 'package:yumi/modules/store/store_route.dart';
|
||||||
import 'package:yumi/modules/user/settings/settings_route.dart';
|
import 'package:yumi/modules/user/settings/settings_route.dart';
|
||||||
import 'package:yumi/modules/user/task/task_route.dart';
|
|
||||||
import 'package:yumi/modules/user/vip/vip_route.dart';
|
import 'package:yumi/modules/user/vip/vip_route.dart';
|
||||||
import 'package:yumi/modules/wallet/wallet_route.dart';
|
import 'package:yumi/modules/wallet/wallet_route.dart';
|
||||||
import 'package:yumi/services/auth/user_profile_manager.dart';
|
import 'package:yumi/services/auth/user_profile_manager.dart';
|
||||||
@ -114,6 +113,14 @@ class _MePage2State extends State<MePage2> {
|
|||||||
return repository.vipStatus();
|
return repository.vipStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _refreshAfterVipReturn(SocialChatUserProfileManager profileManager) {
|
||||||
|
debugPrint('[VIP][MeEntry] refresh user data after vip page return');
|
||||||
|
profileManager.fetchUserProfileData(loadGuardCount: false);
|
||||||
|
profileManager.balance();
|
||||||
|
_loadCounter();
|
||||||
|
_loadVipStatus();
|
||||||
|
}
|
||||||
|
|
||||||
void _openInviteActivity() {
|
void _openInviteActivity() {
|
||||||
final inviteActivityUrl = _appendToken(_inviteActivityUrl);
|
final inviteActivityUrl = _appendToken(_inviteActivityUrl);
|
||||||
if (inviteActivityUrl.isEmpty) return;
|
if (inviteActivityUrl.isEmpty) return;
|
||||||
@ -287,12 +294,6 @@ class _MePage2State extends State<MePage2> {
|
|||||||
Widget _buildEntryRow() {
|
Widget _buildEntryRow() {
|
||||||
return Row(
|
return Row(
|
||||||
children: [
|
children: [
|
||||||
_buildEntryItem(
|
|
||||||
title: SCAppLocalizations.of(context)!.task,
|
|
||||||
iconPath: 'sc_images/index/sc_icon_task.png',
|
|
||||||
onTap: () => SCNavigatorUtils.push(context, TaskRoute.task),
|
|
||||||
),
|
|
||||||
SizedBox(width: 10.w),
|
|
||||||
_buildEntryItem(
|
_buildEntryItem(
|
||||||
title: SCAppLocalizations.of(context)!.store,
|
title: SCAppLocalizations.of(context)!.store,
|
||||||
iconPath: 'sc_images/index/sc_icon_shop.png',
|
iconPath: 'sc_images/index/sc_icon_shop.png',
|
||||||
@ -304,12 +305,6 @@ class _MePage2State extends State<MePage2> {
|
|||||||
iconPath: 'sc_images/index/sc_icon_bag.png',
|
iconPath: 'sc_images/index/sc_icon_bag.png',
|
||||||
onTap: () => SCNavigatorUtils.push(context, StoreRoute.bags),
|
onTap: () => SCNavigatorUtils.push(context, StoreRoute.bags),
|
||||||
),
|
),
|
||||||
SizedBox(width: 10.w),
|
|
||||||
_buildEntryItem(
|
|
||||||
title: SCAppLocalizations.of(context)!.level,
|
|
||||||
iconPath: 'sc_images/index/sc_icon_level.png',
|
|
||||||
onTap: () => SCNavigatorUtils.push(context, SCMainRoute.levelList),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -408,7 +403,7 @@ class _MePage2State extends State<MePage2> {
|
|||||||
onTap: () async {
|
onTap: () async {
|
||||||
await SCNavigatorUtils.push(context, VipRoute.detail);
|
await SCNavigatorUtils.push(context, VipRoute.detail);
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
_loadVipStatus();
|
_refreshAfterVipReturn(profileManager);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Container(
|
child: Container(
|
||||||
|
|||||||
@ -27,6 +27,10 @@ import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
|
|||||||
import 'package:yumi/shared/business_logic/models/res/join_room_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/join_room_res.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/login_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/login_res.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/mic_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/mic_res.dart';
|
||||||
|
import 'package:yumi/shared/business_logic/models/res/follow_room_res.dart'
|
||||||
|
as follow_room;
|
||||||
|
import 'package:yumi/shared/business_logic/models/res/my_room_res.dart'
|
||||||
|
as my_room;
|
||||||
import 'package:yumi/shared/business_logic/models/res/room_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/room_res.dart';
|
||||||
import 'package:yumi/modules/room/voice_room_route.dart';
|
import 'package:yumi/modules/room/voice_room_route.dart';
|
||||||
import 'package:yumi/ui_kit/widgets/room/empty_mai_select.dart';
|
import 'package:yumi/ui_kit/widgets/room/empty_mai_select.dart';
|
||||||
@ -76,8 +80,178 @@ class _RoomStartupAsyncResult<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _AgoraJoinCanceled implements Exception {
|
||||||
|
const _AgoraJoinCanceled(this.reason);
|
||||||
|
|
||||||
|
final String reason;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => reason;
|
||||||
|
}
|
||||||
|
|
||||||
enum _PendingRoomStartupSeatActionType { clickSeat, goUpMic }
|
enum _PendingRoomStartupSeatActionType { clickSeat, goUpMic }
|
||||||
|
|
||||||
|
class RoomEntryPreviewData {
|
||||||
|
const RoomEntryPreviewData({
|
||||||
|
this.roomId,
|
||||||
|
this.roomAccount,
|
||||||
|
this.userId,
|
||||||
|
this.roomCover,
|
||||||
|
this.roomName,
|
||||||
|
this.roomDesc,
|
||||||
|
this.event,
|
||||||
|
this.sysOrigin,
|
||||||
|
this.countryCode,
|
||||||
|
this.countryName,
|
||||||
|
this.nationalFlag,
|
||||||
|
this.langCode,
|
||||||
|
this.del,
|
||||||
|
this.createTime,
|
||||||
|
this.updateTime,
|
||||||
|
this.activeTime,
|
||||||
|
this.roomSetting,
|
||||||
|
this.ownerProfile,
|
||||||
|
this.roomAdminCount,
|
||||||
|
this.roomMemberCount,
|
||||||
|
this.entrantsRole,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory RoomEntryPreviewData.fromSocialChatRoom(SocialChatRoomRes room) {
|
||||||
|
return RoomEntryPreviewData(
|
||||||
|
roomId: room.id,
|
||||||
|
roomAccount: room.roomAccount,
|
||||||
|
userId: room.userId,
|
||||||
|
roomCover: room.roomCover,
|
||||||
|
roomName: room.roomName,
|
||||||
|
roomDesc: room.roomDesc,
|
||||||
|
event: room.event,
|
||||||
|
sysOrigin: room.sysOrigin,
|
||||||
|
countryCode: room.countryCode,
|
||||||
|
countryName: room.countryName,
|
||||||
|
nationalFlag: room.nationalFlag,
|
||||||
|
roomSetting: room.extValues?.roomSetting,
|
||||||
|
ownerProfile: room.userProfile,
|
||||||
|
roomAdminCount: room.roomCounter?.adminCount,
|
||||||
|
roomMemberCount: room.roomCounter?.memberCount,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory RoomEntryPreviewData.fromFollowRoom(follow_room.FollowRoomRes room) {
|
||||||
|
final roomProfile = room.roomProfile;
|
||||||
|
return RoomEntryPreviewData(
|
||||||
|
roomId: roomProfile?.id ?? room.id,
|
||||||
|
roomAccount: roomProfile?.roomAccount,
|
||||||
|
userId: roomProfile?.userId,
|
||||||
|
roomCover: roomProfile?.roomCover,
|
||||||
|
roomName: roomProfile?.roomName,
|
||||||
|
roomDesc: roomProfile?.roomDesc,
|
||||||
|
event: roomProfile?.event,
|
||||||
|
sysOrigin: roomProfile?.sysOrigin,
|
||||||
|
countryCode: roomProfile?.countryCode,
|
||||||
|
countryName: roomProfile?.countryName,
|
||||||
|
nationalFlag: roomProfile?.nationalFlag,
|
||||||
|
roomSetting: roomProfile?.extValues?.roomSetting,
|
||||||
|
ownerProfile: roomProfile?.userProfile,
|
||||||
|
roomAdminCount: roomProfile?.roomCounter?.adminCount,
|
||||||
|
roomMemberCount: roomProfile?.roomCounter?.memberCount,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory RoomEntryPreviewData.fromMyRoom(
|
||||||
|
my_room.MyRoomRes room, {
|
||||||
|
SocialChatUserProfile? ownerProfile,
|
||||||
|
}) {
|
||||||
|
return RoomEntryPreviewData(
|
||||||
|
roomId: room.id,
|
||||||
|
roomAccount: room.roomAccount,
|
||||||
|
userId: room.userId,
|
||||||
|
roomCover: room.roomCover,
|
||||||
|
roomName: room.roomName,
|
||||||
|
roomDesc: room.roomDesc,
|
||||||
|
event: room.event,
|
||||||
|
sysOrigin: room.sysOrigin,
|
||||||
|
countryCode: room.countryCode,
|
||||||
|
countryName: room.countryName,
|
||||||
|
nationalFlag: room.nationalFlag,
|
||||||
|
langCode: room.langCode,
|
||||||
|
del: room.del,
|
||||||
|
createTime: room.createTime,
|
||||||
|
updateTime: room.updateTime,
|
||||||
|
activeTime: room.activeTime,
|
||||||
|
roomSetting: room.setting,
|
||||||
|
ownerProfile: ownerProfile,
|
||||||
|
roomAdminCount: room.counter?.adminCount,
|
||||||
|
roomMemberCount: room.counter?.memberCount,
|
||||||
|
entrantsRole: SCRoomRolesType.HOMEOWNER.name,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final String? roomId;
|
||||||
|
final String? roomAccount;
|
||||||
|
final String? userId;
|
||||||
|
final String? roomCover;
|
||||||
|
final String? roomName;
|
||||||
|
final String? roomDesc;
|
||||||
|
final String? event;
|
||||||
|
final String? sysOrigin;
|
||||||
|
final String? countryCode;
|
||||||
|
final String? countryName;
|
||||||
|
final String? nationalFlag;
|
||||||
|
final String? langCode;
|
||||||
|
final bool? del;
|
||||||
|
final num? createTime;
|
||||||
|
final num? updateTime;
|
||||||
|
final num? activeTime;
|
||||||
|
final RoomSetting? roomSetting;
|
||||||
|
final SocialChatUserProfile? ownerProfile;
|
||||||
|
final num? roomAdminCount;
|
||||||
|
final num? roomMemberCount;
|
||||||
|
final String? entrantsRole;
|
||||||
|
|
||||||
|
int? get seatCount => roomSetting?.mikeSize?.toInt();
|
||||||
|
|
||||||
|
JoinRoomRes toJoinRoomRes({String? fallbackRoomId}) {
|
||||||
|
final resolvedRoomId =
|
||||||
|
(roomId ?? "").trim().isNotEmpty ? roomId : fallbackRoomId;
|
||||||
|
return JoinRoomRes(
|
||||||
|
entrants:
|
||||||
|
(entrantsRole ?? "").trim().isNotEmpty
|
||||||
|
? Entrants(roles: entrantsRole)
|
||||||
|
: null,
|
||||||
|
roomProfile: RoomProfile(
|
||||||
|
regionCode: countryCode,
|
||||||
|
roomCounter:
|
||||||
|
roomAdminCount != null || roomMemberCount != null
|
||||||
|
? RoomCounter(
|
||||||
|
adminCount: roomAdminCount,
|
||||||
|
memberCount: roomMemberCount,
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
roomProfile: RoomProfile2(
|
||||||
|
activeTime: activeTime,
|
||||||
|
countryCode: countryCode,
|
||||||
|
countryName: countryName,
|
||||||
|
createTime: createTime,
|
||||||
|
del: del,
|
||||||
|
event: event,
|
||||||
|
id: resolvedRoomId,
|
||||||
|
langCode: langCode,
|
||||||
|
nationalFlag: nationalFlag,
|
||||||
|
roomAccount: roomAccount,
|
||||||
|
roomCover: roomCover,
|
||||||
|
roomDesc: roomDesc,
|
||||||
|
roomName: roomName,
|
||||||
|
sysOrigin: sysOrigin,
|
||||||
|
updateTime: updateTime,
|
||||||
|
userId: userId,
|
||||||
|
),
|
||||||
|
roomSetting: roomSetting,
|
||||||
|
userProfile: ownerProfile,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _PendingRoomStartupSeatAction {
|
class _PendingRoomStartupSeatAction {
|
||||||
const _PendingRoomStartupSeatAction.clickSeat({
|
const _PendingRoomStartupSeatAction.clickSeat({
|
||||||
required this.index,
|
required this.index,
|
||||||
@ -122,20 +296,24 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
bool _isHandlingAgoraRoomFailure = false;
|
bool _isHandlingAgoraRoomFailure = false;
|
||||||
bool _agoraJoined = false;
|
bool _agoraJoined = false;
|
||||||
bool _agoraRoleIsBroadcaster = false;
|
bool _agoraRoleIsBroadcaster = false;
|
||||||
|
String? _agoraJoinedChannelId;
|
||||||
bool _agoraAudioConfigured = false;
|
bool _agoraAudioConfigured = false;
|
||||||
RoomStartupStatus _roomStartupStatus = RoomStartupStatus.idle;
|
RoomStartupStatus _roomStartupStatus = RoomStartupStatus.idle;
|
||||||
RoomStartupFailureType _roomStartupFailureType = RoomStartupFailureType.none;
|
RoomStartupFailureType _roomStartupFailureType = RoomStartupFailureType.none;
|
||||||
int _roomStartupFailureToken = 0;
|
int _roomStartupFailureToken = 0;
|
||||||
int _roomEntryRequestSerial = 0;
|
int _roomEntryRequestSerial = 0;
|
||||||
int? _previewRoomSeatCount;
|
int? _previewRoomSeatCount;
|
||||||
|
bool _currentRoomIsEntryPreview = false;
|
||||||
bool _isHandlingRoomStartupFailure = false;
|
bool _isHandlingRoomStartupFailure = false;
|
||||||
Timer? _micListPollingTimer;
|
Timer? _micListPollingTimer;
|
||||||
Timer? _onlineUsersPollingTimer;
|
Timer? _onlineUsersPollingTimer;
|
||||||
Timer? _joinAgoraTimeoutTimer;
|
Timer? _joinAgoraTimeoutTimer;
|
||||||
Timer? _agoraDisconnectedCleanupTimer;
|
Timer? _agoraDisconnectedCleanupTimer;
|
||||||
|
Timer? _roomEntryEffectTimer;
|
||||||
Completer<void>? _joinAgoraCompleter;
|
Completer<void>? _joinAgoraCompleter;
|
||||||
Future<RtcEngine>? _rtcEngineInitTask;
|
Future<RtcEngine>? _rtcEngineInitTask;
|
||||||
Future<void>? _rtcEnginePrewarmTask;
|
Future<void>? _rtcEnginePrewarmTask;
|
||||||
|
Future<void>? _pendingRoomSwitchAgoraLeaveTask;
|
||||||
String? _joiningChannelId;
|
String? _joiningChannelId;
|
||||||
bool _isRefreshingMicList = false;
|
bool _isRefreshingMicList = false;
|
||||||
bool _isRefreshingOnlineUsers = false;
|
bool _isRefreshingOnlineUsers = false;
|
||||||
@ -247,6 +425,10 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
if (_roomVisualEffectsEnabled == enabled) {
|
if (_roomVisualEffectsEnabled == enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!enabled) {
|
||||||
|
_roomEntryEffectTimer?.cancel();
|
||||||
|
_roomEntryEffectTimer = null;
|
||||||
|
}
|
||||||
_roomVisualEffectsEnabled = enabled;
|
_roomVisualEffectsEnabled = enabled;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
@ -273,6 +455,9 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _setRoomStartupFailed(RoomStartupFailureType failureType) {
|
void _setRoomStartupFailed(RoomStartupFailureType failureType) {
|
||||||
|
if (_roomStartupStatus != RoomStartupStatus.loading) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_stopRoomStatePolling();
|
_stopRoomStatePolling();
|
||||||
_isHandlingRoomStartupFailure = false;
|
_isHandlingRoomStartupFailure = false;
|
||||||
_roomStartupFailureType = failureType;
|
_roomStartupFailureType = failureType;
|
||||||
@ -825,10 +1010,11 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _resetAgoraTracking({bool clearJoiningChannel = true}) {
|
void _resetAgoraTracking({bool clearJoiningChannel = true}) {
|
||||||
_cancelAgoraJoinWaiter();
|
_cancelAgoraJoinWaiter(const _AgoraJoinCanceled('Agora join canceled'));
|
||||||
_cancelAgoraDisconnectedCleanup();
|
_cancelAgoraDisconnectedCleanup();
|
||||||
_agoraJoined = false;
|
_agoraJoined = false;
|
||||||
_agoraRoleIsBroadcaster = false;
|
_agoraRoleIsBroadcaster = false;
|
||||||
|
_agoraJoinedChannelId = null;
|
||||||
if (clearJoiningChannel) {
|
if (clearJoiningChannel) {
|
||||||
_joiningChannelId = null;
|
_joiningChannelId = null;
|
||||||
}
|
}
|
||||||
@ -1138,7 +1324,24 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _cleanupAgoraRoomState({bool clearMicSeats = false}) async {
|
Future<void> _cleanupAgoraRoomState({
|
||||||
|
bool clearMicSeats = false,
|
||||||
|
String? onlyIfJoinedChannelId,
|
||||||
|
}) async {
|
||||||
|
final expectedChannelId = (onlyIfJoinedChannelId ?? "").trim();
|
||||||
|
if (expectedChannelId.isNotEmpty) {
|
||||||
|
final joinedChannelId = (_agoraJoinedChannelId ?? "").trim();
|
||||||
|
final currentRoomId =
|
||||||
|
(currenRoom?.roomProfile?.roomProfile?.id ?? "").trim();
|
||||||
|
if (joinedChannelId.isNotEmpty && joinedChannelId != expectedChannelId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (joinedChannelId.isEmpty &&
|
||||||
|
currentRoomId.isNotEmpty &&
|
||||||
|
currentRoomId != expectedChannelId) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
_resetAgoraTracking();
|
_resetAgoraTracking();
|
||||||
try {
|
try {
|
||||||
await engine?.leaveChannel();
|
await engine?.leaveChannel();
|
||||||
@ -1261,7 +1464,16 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_cancelAgoraJoinWaiter();
|
final pendingRoomSwitchLeaveTask = _pendingRoomSwitchAgoraLeaveTask;
|
||||||
|
if (pendingRoomSwitchLeaveTask != null) {
|
||||||
|
try {
|
||||||
|
await pendingRoomSwitchLeaveTask;
|
||||||
|
} catch (error) {
|
||||||
|
debugPrint('[Agora] pending room switch leave failed: $error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_cancelAgoraJoinWaiter(const _AgoraJoinCanceled('Agora join superseded'));
|
||||||
_cancelAgoraDisconnectedCleanup();
|
_cancelAgoraDisconnectedCleanup();
|
||||||
_joiningChannelId = channelId;
|
_joiningChannelId = channelId;
|
||||||
_agoraJoined = false;
|
_agoraJoined = false;
|
||||||
@ -1303,6 +1515,13 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
_syncSelfMicRuntimeState();
|
_syncSelfMicRuntimeState();
|
||||||
rtcEngine.muteAllRemoteAudioStreams(roomIsMute);
|
rtcEngine.muteAllRemoteAudioStreams(roomIsMute);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
if (e is _AgoraJoinCanceled) {
|
||||||
|
debugPrint('[Agora] join canceled: $e');
|
||||||
|
if (throwOnError) {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
await _handleAgoraJoinFailed(e, exitRoom: !throwOnError);
|
await _handleAgoraJoinFailed(e, exitRoom: !throwOnError);
|
||||||
if (throwOnError) {
|
if (throwOnError) {
|
||||||
rethrow;
|
rethrow;
|
||||||
@ -1475,6 +1694,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
_agoraJoined = true;
|
_agoraJoined = true;
|
||||||
_agoraRoleIsBroadcaster = false;
|
_agoraRoleIsBroadcaster = false;
|
||||||
|
_agoraJoinedChannelId = joinedChannelId.trim();
|
||||||
_cancelAgoraDisconnectedCleanup();
|
_cancelAgoraDisconnectedCleanup();
|
||||||
_joinAgoraTimeoutTimer?.cancel();
|
_joinAgoraTimeoutTimer?.cancel();
|
||||||
_joinAgoraTimeoutTimer = null;
|
_joinAgoraTimeoutTimer = null;
|
||||||
@ -1533,6 +1753,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
reason ==
|
reason ==
|
||||||
ConnectionChangedReasonType.connectionChangedRejoinSuccess) {
|
ConnectionChangedReasonType.connectionChangedRejoinSuccess) {
|
||||||
_agoraJoined = true;
|
_agoraJoined = true;
|
||||||
|
_agoraJoinedChannelId = connection.channelId?.trim();
|
||||||
_cancelAgoraDisconnectedCleanup();
|
_cancelAgoraDisconnectedCleanup();
|
||||||
_resyncHeartbeatFromAgoraState();
|
_resyncHeartbeatFromAgoraState();
|
||||||
return;
|
return;
|
||||||
@ -1771,6 +1992,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
bool needOpenRedenvelope = false,
|
bool needOpenRedenvelope = false,
|
||||||
String redPackId = "",
|
String redPackId = "",
|
||||||
int? previewSeatCount,
|
int? previewSeatCount,
|
||||||
|
RoomEntryPreviewData? previewData,
|
||||||
}) async {
|
}) async {
|
||||||
int nextTime = DateTime.now().millisecondsSinceEpoch;
|
int nextTime = DateTime.now().millisecondsSinceEpoch;
|
||||||
if (nextTime - startTime < 1000) {
|
if (nextTime - startTime < 1000) {
|
||||||
@ -1787,6 +2009,16 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
throw ArgumentError('Microphone permission is denied.');
|
throw ArgumentError('Microphone permission is denied.');
|
||||||
}
|
}
|
||||||
if (roomId == currenRoom?.roomProfile?.roomProfile?.id) {
|
if (roomId == currenRoom?.roomProfile?.roomProfile?.id) {
|
||||||
|
if (_currentRoomIsEntryPreview ||
|
||||||
|
_roomStartupStatus == RoomStartupStatus.loading) {
|
||||||
|
SCFloatIchart().remove();
|
||||||
|
if (!context.mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
VoiceRoomRoute.openVoiceRoom(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
///最小化进入房间,或者进入的是同一个房间
|
///最小化进入房间,或者进入的是同一个房间
|
||||||
final loaded = await loadRoomInfo(
|
final loaded = await loadRoomInfo(
|
||||||
currenRoom?.roomProfile?.roomProfile?.id ?? "",
|
currenRoom?.roomProfile?.roomProfile?.id ?? "",
|
||||||
@ -1811,7 +2043,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
} else {
|
} else {
|
||||||
SCFloatIchart().remove();
|
SCFloatIchart().remove();
|
||||||
if (currenRoom != null) {
|
if (currenRoom != null) {
|
||||||
await exitCurrentVoiceRoomSession(false, deferRemoteCleanup: false);
|
_switchAwayFromCurrentRoomForNewEntry();
|
||||||
}
|
}
|
||||||
if (!context.mounted) {
|
if (!context.mounted) {
|
||||||
return;
|
return;
|
||||||
@ -1823,7 +2055,11 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
_setRoomStartupLoading();
|
_setRoomStartupLoading();
|
||||||
setRoomVisualEffectsEnabled(true);
|
setRoomVisualEffectsEnabled(true);
|
||||||
_setPreviewRoomSeatCount(previewSeatCount, notify: false);
|
_applyRoomEntryPreview(
|
||||||
|
roomId,
|
||||||
|
previewData: previewData,
|
||||||
|
previewSeatCount: previewSeatCount,
|
||||||
|
);
|
||||||
VoiceRoomRoute.openVoiceRoom(context);
|
VoiceRoomRoute.openVoiceRoom(context);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
final entryRequestSerial = ++_roomEntryRequestSerial;
|
final entryRequestSerial = ++_roomEntryRequestSerial;
|
||||||
@ -1858,9 +2094,11 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
currenRoom = enteredRoom;
|
currenRoom = enteredRoom;
|
||||||
|
_currentRoomIsEntryPreview = false;
|
||||||
_previewRoomSeatCount = null;
|
_previewRoomSeatCount = null;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
await initializeRoomSession(
|
await initializeRoomSession(
|
||||||
|
entryRequestSerial: entryRequestSerial,
|
||||||
needOpenRedenvelope: needOpenRedenvelope,
|
needOpenRedenvelope: needOpenRedenvelope,
|
||||||
redPackId: redPackId,
|
redPackId: redPackId,
|
||||||
shouldOpenRoomPage: false,
|
shouldOpenRoomPage: false,
|
||||||
@ -1879,6 +2117,17 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
_roomStartupStatus == RoomStartupStatus.loading;
|
_roomStartupStatus == RoomStartupStatus.loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _isCurrentRoomEntrySession(int entryRequestSerial, String roomId) {
|
||||||
|
return entryRequestSerial == _roomEntryRequestSerial &&
|
||||||
|
roomId.isNotEmpty &&
|
||||||
|
currenRoom?.roomProfile?.roomProfile?.id == roomId;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isActiveRoomStartup(int entryRequestSerial, String roomId) {
|
||||||
|
return _isActiveRoomEntryRequest(entryRequestSerial) &&
|
||||||
|
_isCurrentRoomEntrySession(entryRequestSerial, roomId);
|
||||||
|
}
|
||||||
|
|
||||||
void _setPreviewRoomSeatCount(int? seatCount, {bool notify = true}) {
|
void _setPreviewRoomSeatCount(int? seatCount, {bool notify = true}) {
|
||||||
final normalizedSeatCount = _normalizePreviewRoomSeatCount(seatCount);
|
final normalizedSeatCount = _normalizePreviewRoomSeatCount(seatCount);
|
||||||
if (_previewRoomSeatCount == normalizedSeatCount) {
|
if (_previewRoomSeatCount == normalizedSeatCount) {
|
||||||
@ -1902,11 +2151,31 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _applyRoomEntryPreview(
|
||||||
|
String roomId, {
|
||||||
|
RoomEntryPreviewData? previewData,
|
||||||
|
int? previewSeatCount,
|
||||||
|
}) {
|
||||||
|
final resolvedPreviewSeatCount = previewData?.seatCount ?? previewSeatCount;
|
||||||
|
_setPreviewRoomSeatCount(resolvedPreviewSeatCount, notify: false);
|
||||||
|
if (previewData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
currenRoom = previewData.toJoinRoomRes(fallbackRoomId: roomId);
|
||||||
|
_currentRoomIsEntryPreview = true;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _cleanupStaleEnteredRoom(JoinRoomRes enteredRoom) async {
|
Future<void> _cleanupStaleEnteredRoom(JoinRoomRes enteredRoom) async {
|
||||||
final staleRoomId = enteredRoom.roomProfile?.roomProfile?.id ?? "";
|
final staleRoomId = enteredRoom.roomProfile?.roomProfile?.id ?? "";
|
||||||
if (staleRoomId.isEmpty) {
|
if (staleRoomId.isEmpty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (_isCurrentRoomId(staleRoomId)) {
|
||||||
|
debugPrint(
|
||||||
|
'[RoomStartup] skip stale entry cleanup: room $staleRoomId is active again',
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
await _retryExitNetworkRequest('quit stale entered room $staleRoomId', () {
|
await _retryExitNetworkRequest('quit stale entered room $staleRoomId', () {
|
||||||
return SCAccountRepository().quitRoom(staleRoomId).then((didQuit) {
|
return SCAccountRepository().quitRoom(staleRoomId).then((didQuit) {
|
||||||
if (!didQuit) {
|
if (!didQuit) {
|
||||||
@ -1918,12 +2187,17 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
|
|
||||||
///初始化房间相关
|
///初始化房间相关
|
||||||
Future<void> initializeRoomSession({
|
Future<void> initializeRoomSession({
|
||||||
|
required int entryRequestSerial,
|
||||||
bool needOpenRedenvelope = false,
|
bool needOpenRedenvelope = false,
|
||||||
String? redPackId,
|
String? redPackId,
|
||||||
bool shouldOpenRoomPage = true,
|
bool shouldOpenRoomPage = true,
|
||||||
}) async {
|
}) async {
|
||||||
_disableMicListRefreshForCurrentSession = false;
|
_disableMicListRefreshForCurrentSession = false;
|
||||||
_disableOnlineUsersRefreshForCurrentSession = false;
|
_disableOnlineUsersRefreshForCurrentSession = false;
|
||||||
|
final startupRoomId = currenRoom?.roomProfile?.roomProfile?.id ?? "";
|
||||||
|
if (!_isActiveRoomStartup(entryRequestSerial, startupRoomId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if ((currenRoom?.roomProfile?.roomProfile?.event ==
|
if ((currenRoom?.roomProfile?.roomProfile?.event ==
|
||||||
SCRoomInfoEventType.WAITING_CONFIRMED.name ||
|
SCRoomInfoEventType.WAITING_CONFIRMED.name ||
|
||||||
currenRoom?.roomProfile?.roomProfile?.event ==
|
currenRoom?.roomProfile?.roomProfile?.event ==
|
||||||
@ -1938,26 +2212,39 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
if (currenRoom?.roomProfile?.roomProfile?.id !=
|
if (currenRoom?.roomProfile?.roomProfile?.id !=
|
||||||
AccountStorage().getCurrentUser()?.userProfile?.id) {
|
AccountStorage().getCurrentUser()?.userProfile?.id) {
|
||||||
SCChatRoomRepository()
|
final followRoomId = startupRoomId;
|
||||||
.isFollowRoom(currenRoom?.roomProfile?.roomProfile?.id ?? "")
|
SCChatRoomRepository().isFollowRoom(followRoomId).then((value) {
|
||||||
.then((value) {
|
if (!_isActiveRoomStartup(entryRequestSerial, followRoomId)) {
|
||||||
isFollowRoomRes = value;
|
return;
|
||||||
notifyListeners();
|
}
|
||||||
});
|
isFollowRoomRes = value;
|
||||||
|
notifyListeners();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
_setRoomStartupLoading();
|
_setRoomStartupLoading();
|
||||||
setRoomVisualEffectsEnabled(true);
|
setRoomVisualEffectsEnabled(true);
|
||||||
if (shouldOpenRoomPage) {
|
if (shouldOpenRoomPage) {
|
||||||
VoiceRoomRoute.openVoiceRoom(context!);
|
VoiceRoomRoute.openVoiceRoom(context!);
|
||||||
}
|
}
|
||||||
unawaited(_bootstrapEnteredVoiceRoomSession());
|
unawaited(
|
||||||
|
_bootstrapEnteredVoiceRoomSession(
|
||||||
|
entryRequestSerial: entryRequestSerial,
|
||||||
|
roomId: startupRoomId,
|
||||||
|
groupId: currenRoom?.roomProfile?.roomProfile?.roomAccount ?? "",
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _bootstrapEnteredVoiceRoomSession() async {
|
Future<void> _bootstrapEnteredVoiceRoomSession({
|
||||||
|
required int entryRequestSerial,
|
||||||
|
required String roomId,
|
||||||
|
required String groupId,
|
||||||
|
}) async {
|
||||||
var failureType = RoomStartupFailureType.im;
|
var failureType = RoomStartupFailureType.im;
|
||||||
|
if (!_isActiveRoomStartup(entryRequestSerial, roomId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
final roomId = currenRoom?.roomProfile?.roomProfile?.id ?? "";
|
|
||||||
final groupId = currenRoom?.roomProfile?.roomProfile?.roomAccount ?? "";
|
|
||||||
final joinGroupFuture = rtmProvider?.joinRoomGroup(groupId, "");
|
final joinGroupFuture = rtmProvider?.joinRoomGroup(groupId, "");
|
||||||
final rtcTokenFuture = _captureStartupFuture(
|
final rtcTokenFuture = _captureStartupFuture(
|
||||||
_fetchRtcTokenForCurrentRoom(isPublisher: false),
|
_fetchRtcTokenForCurrentRoom(isPublisher: false),
|
||||||
@ -1965,6 +2252,9 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
final microphoneListFuture = retrieveMicrophoneList();
|
final microphoneListFuture = retrieveMicrophoneList();
|
||||||
final onlineUsersFuture = fetchOnlineUsersList();
|
final onlineUsersFuture = fetchOnlineUsersList();
|
||||||
final joinResult = await joinGroupFuture;
|
final joinResult = await joinGroupFuture;
|
||||||
|
if (!_isActiveRoomStartup(entryRequestSerial, roomId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (joinResult == null || joinResult.code != 0) {
|
if (joinResult == null || joinResult.code != 0) {
|
||||||
debugPrint(
|
debugPrint(
|
||||||
'[RoomStartup] join IM group failed code=${joinResult?.code} desc=${joinResult?.desc}',
|
'[RoomStartup] join IM group failed code=${joinResult?.code} desc=${joinResult?.desc}',
|
||||||
@ -1986,16 +2276,36 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await Future.wait([microphoneListFuture, onlineUsersFuture]);
|
await Future.wait([microphoneListFuture, onlineUsersFuture]);
|
||||||
|
if (!_isActiveRoomStartup(entryRequestSerial, roomId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_startRoomStatePolling();
|
_startRoomStatePolling();
|
||||||
Provider.of<SocialChatRoomManager>(
|
final currentContext = context;
|
||||||
context!,
|
if (currentContext != null && currentContext.mounted) {
|
||||||
listen: false,
|
Provider.of<SocialChatRoomManager>(
|
||||||
).fetchContributionLevelData(roomId);
|
currentContext,
|
||||||
|
listen: false,
|
||||||
|
).fetchContributionLevelData(roomId);
|
||||||
|
}
|
||||||
|
|
||||||
failureType = RoomStartupFailureType.rtc;
|
failureType = RoomStartupFailureType.rtc;
|
||||||
final rtcToken = (await rtcTokenFuture).requireValue();
|
final rtcTokenResult = await rtcTokenFuture;
|
||||||
|
if (!_isActiveRoomStartup(entryRequestSerial, roomId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final rtcToken = rtcTokenResult.requireValue();
|
||||||
await joinAgoraVoiceChannel(throwOnError: true, rtcToken: rtcToken);
|
await joinAgoraVoiceChannel(throwOnError: true, rtcToken: rtcToken);
|
||||||
|
if (!_isActiveRoomStartup(entryRequestSerial, roomId)) {
|
||||||
|
await _cleanupAgoraRoomState(
|
||||||
|
clearMicSeats: currenRoom == null,
|
||||||
|
onlyIfJoinedChannelId: roomId,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
await _bootstrapRoomHeartbeatState();
|
await _bootstrapRoomHeartbeatState();
|
||||||
|
if (!_isActiveRoomStartup(entryRequestSerial, roomId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_setRoomStartupReady();
|
_setRoomStartupReady();
|
||||||
|
|
||||||
Msg joinMsg = Msg(
|
Msg joinMsg = Msg(
|
||||||
@ -2006,30 +2316,46 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
type: SCRoomMsgType.joinRoom,
|
type: SCRoomMsgType.joinRoom,
|
||||||
);
|
);
|
||||||
rtmProvider?.dispatchMessage(joinMsg, addLocal: true);
|
rtmProvider?.dispatchMessage(joinMsg, addLocal: true);
|
||||||
_playRoomEntryEffects(joinMsg);
|
_playRoomEntryEffects(
|
||||||
|
joinMsg,
|
||||||
|
entryRequestSerial: entryRequestSerial,
|
||||||
|
roomId: roomId,
|
||||||
|
);
|
||||||
_loadRoomSecondaryData();
|
_loadRoomSecondaryData();
|
||||||
} catch (error, stackTrace) {
|
} catch (error, stackTrace) {
|
||||||
|
if (!_isActiveRoomStartup(entryRequestSerial, roomId)) {
|
||||||
|
debugPrint('[RoomStartup] ignore canceled bootstrap failure: $error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
debugPrint('[RoomStartup] bootstrap failed: $error\n$stackTrace');
|
debugPrint('[RoomStartup] bootstrap failed: $error\n$stackTrace');
|
||||||
_setRoomStartupFailed(failureType);
|
_setRoomStartupFailed(failureType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _playRoomEntryEffects(Msg joinMsg) {
|
void _playRoomEntryEffects(
|
||||||
|
Msg joinMsg, {
|
||||||
|
required int entryRequestSerial,
|
||||||
|
required String roomId,
|
||||||
|
}) {
|
||||||
if (SCGlobalConfig.isEntryVehicleAnimation) {
|
if (SCGlobalConfig.isEntryVehicleAnimation) {
|
||||||
if (AccountStorage().getCurrentUser()?.userProfile?.getMountains() !=
|
final sourceUrl =
|
||||||
null &&
|
AccountStorage()
|
||||||
shouldShowRoomVisualEffects) {
|
.getCurrentUser()
|
||||||
Future.delayed(Duration(milliseconds: 550), () {
|
?.userProfile
|
||||||
SCGiftVapSvgaManager().play(
|
?.getMountains()
|
||||||
AccountStorage()
|
?.sourceUrl ??
|
||||||
.getCurrentUser()
|
"";
|
||||||
?.userProfile
|
if (sourceUrl.isNotEmpty &&
|
||||||
?.getMountains()
|
shouldShowRoomVisualEffects &&
|
||||||
?.sourceUrl ??
|
_isCurrentRoomEntrySession(entryRequestSerial, roomId)) {
|
||||||
"",
|
_roomEntryEffectTimer?.cancel();
|
||||||
priority: 100,
|
_roomEntryEffectTimer = Timer(const Duration(milliseconds: 550), () {
|
||||||
type: 1,
|
_roomEntryEffectTimer = null;
|
||||||
);
|
if (!shouldShowRoomVisualEffects ||
|
||||||
|
!_isCurrentRoomEntrySession(entryRequestSerial, roomId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SCGiftVapSvgaManager().play(sourceUrl, priority: 100, type: 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2193,6 +2519,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
_stopRoomStatePolling();
|
_stopRoomStatePolling();
|
||||||
final groupId = currenRoom?.roomProfile?.roomProfile?.roomAccount ?? "";
|
final groupId = currenRoom?.roomProfile?.roomProfile?.roomAccount ?? "";
|
||||||
final roomId = currenRoom?.roomProfile?.roomProfile?.id ?? "";
|
final roomId = currenRoom?.roomProfile?.roomProfile?.id ?? "";
|
||||||
|
final isPreviewOnlyExit = _currentRoomIsEntryPreview;
|
||||||
final exitRtmProvider = rtmProvider;
|
final exitRtmProvider = rtmProvider;
|
||||||
final navigationContext = context;
|
final navigationContext = context;
|
||||||
try {
|
try {
|
||||||
@ -2218,8 +2545,8 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
final agoraLeaveTask = _leaveAgoraRoomForExit();
|
final agoraLeaveTask = _leaveAgoraRoomForExit();
|
||||||
final remoteCleanupTask = _cleanupExitedRoomRemotely(
|
final remoteCleanupTask = _cleanupExitedRoomRemotely(
|
||||||
exitRtmProvider: exitRtmProvider,
|
exitRtmProvider: exitRtmProvider,
|
||||||
groupId: groupId,
|
groupId: isPreviewOnlyExit ? "" : groupId,
|
||||||
roomId: roomId,
|
roomId: isPreviewOnlyExit ? "" : roomId,
|
||||||
shouldSendOnlineHeartbeat: !isLogout,
|
shouldSendOnlineHeartbeat: !isLogout,
|
||||||
);
|
);
|
||||||
if (deferRemoteCleanup) {
|
if (deferRemoteCleanup) {
|
||||||
@ -2231,6 +2558,44 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _switchAwayFromCurrentRoomForNewEntry() {
|
||||||
|
_stopRoomStatePolling();
|
||||||
|
final groupId = currenRoom?.roomProfile?.roomProfile?.roomAccount ?? "";
|
||||||
|
final roomId = currenRoom?.roomProfile?.roomProfile?.id ?? "";
|
||||||
|
final isPreviewOnlyExit = _currentRoomIsEntryPreview;
|
||||||
|
final exitRtmProvider = rtmProvider;
|
||||||
|
try {
|
||||||
|
exitRtmProvider?.msgAllListener = null;
|
||||||
|
exitRtmProvider?.msgChatListener = null;
|
||||||
|
exitRtmProvider?.msgGiftListener = null;
|
||||||
|
SCGiftVapSvgaManager().stopPlayback();
|
||||||
|
setRoomVisualEffectsEnabled(false);
|
||||||
|
SCHeartbeatUtils.cancelTimer();
|
||||||
|
exitRtmProvider?.cleanRoomData();
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('rtc切换房间本地清理出错: $e');
|
||||||
|
}
|
||||||
|
|
||||||
|
_clearData();
|
||||||
|
final agoraLeaveTask = _leaveAgoraRoomForExit();
|
||||||
|
_pendingRoomSwitchAgoraLeaveTask = agoraLeaveTask;
|
||||||
|
unawaited(
|
||||||
|
agoraLeaveTask.whenComplete(() {
|
||||||
|
if (identical(_pendingRoomSwitchAgoraLeaveTask, agoraLeaveTask)) {
|
||||||
|
_pendingRoomSwitchAgoraLeaveTask = null;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
unawaited(
|
||||||
|
_cleanupExitedRoomRemotely(
|
||||||
|
exitRtmProvider: exitRtmProvider,
|
||||||
|
groupId: isPreviewOnlyExit ? "" : groupId,
|
||||||
|
roomId: isPreviewOnlyExit ? "" : roomId,
|
||||||
|
shouldSendOnlineHeartbeat: false,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _cleanupExitedRoomRemotely({
|
Future<void> _cleanupExitedRoomRemotely({
|
||||||
required RtmProvider? exitRtmProvider,
|
required RtmProvider? exitRtmProvider,
|
||||||
required String groupId,
|
required String groupId,
|
||||||
@ -2348,6 +2713,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
}
|
}
|
||||||
_isHandlingRoomStartupFailure = true;
|
_isHandlingRoomStartupFailure = true;
|
||||||
final failedRoom = currenRoom;
|
final failedRoom = currenRoom;
|
||||||
|
final isPreviewOnlyFailure = _currentRoomIsEntryPreview;
|
||||||
final groupId = failedRoom?.roomProfile?.roomProfile?.roomAccount ?? "";
|
final groupId = failedRoom?.roomProfile?.roomProfile?.roomAccount ?? "";
|
||||||
final roomId = failedRoom?.roomProfile?.roomProfile?.id ?? "";
|
final roomId = failedRoom?.roomProfile?.roomProfile?.id ?? "";
|
||||||
final navigatorContext = navigationContext ?? context;
|
final navigatorContext = navigationContext ?? context;
|
||||||
@ -2359,12 +2725,12 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
SCHeartbeatUtils.cancelTimer();
|
SCHeartbeatUtils.cancelTimer();
|
||||||
SCHeartbeatUtils.cancelAnchorTimer();
|
SCHeartbeatUtils.cancelAnchorTimer();
|
||||||
rtmProvider?.cleanRoomData();
|
rtmProvider?.cleanRoomData();
|
||||||
if (groupId.isNotEmpty) {
|
if (!isPreviewOnlyFailure && groupId.isNotEmpty) {
|
||||||
await rtmProvider?.quitGroup(groupId);
|
await rtmProvider?.quitGroup(groupId);
|
||||||
}
|
}
|
||||||
await _cleanupAgoraRoomState(clearMicSeats: true);
|
await _cleanupAgoraRoomState(clearMicSeats: true);
|
||||||
await Future.delayed(const Duration(milliseconds: 100));
|
await Future.delayed(const Duration(milliseconds: 100));
|
||||||
if (roomId.isNotEmpty) {
|
if (!isPreviewOnlyFailure && roomId.isNotEmpty) {
|
||||||
await SCAccountRepository().quitRoom(roomId);
|
await SCAccountRepository().quitRoom(roomId);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -2382,6 +2748,8 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
///清空列表数据
|
///清空列表数据
|
||||||
void _clearData() {
|
void _clearData() {
|
||||||
_roomEntryRequestSerial += 1;
|
_roomEntryRequestSerial += 1;
|
||||||
|
_roomEntryEffectTimer?.cancel();
|
||||||
|
_roomEntryEffectTimer = null;
|
||||||
_previewRoomSeatCount = null;
|
_previewRoomSeatCount = null;
|
||||||
_finishRoomStartupSeatLoading(executePendingAction: false);
|
_finishRoomStartupSeatLoading(executePendingAction: false);
|
||||||
_resetSelfMicGoUpFailureState();
|
_resetSelfMicGoUpFailureState();
|
||||||
@ -2394,6 +2762,7 @@ class RealTimeCommunicationManager extends ChangeNotifier {
|
|||||||
_isSelfMicActionInFlight = false;
|
_isSelfMicActionInFlight = false;
|
||||||
_roomStartupStatus = RoomStartupStatus.idle;
|
_roomStartupStatus = RoomStartupStatus.idle;
|
||||||
_roomStartupFailureType = RoomStartupFailureType.none;
|
_roomStartupFailureType = RoomStartupFailureType.none;
|
||||||
|
_currentRoomIsEntryPreview = false;
|
||||||
_isHandlingRoomStartupFailure = false;
|
_isHandlingRoomStartupFailure = false;
|
||||||
_isHandlingAgoraRoomFailure = false;
|
_isHandlingAgoraRoomFailure = false;
|
||||||
_pendingMicListRefresh = false;
|
_pendingMicListRefresh = false;
|
||||||
|
|||||||
65
lib/services/home/home_room_preload_manager.dart
Normal file
65
lib/services/home/home_room_preload_manager.dart
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:yumi/shared/business_logic/models/res/room_res.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';
|
||||||
|
|
||||||
|
class SCHomeRoomPreloadManager {
|
||||||
|
SCHomeRoomPreloadManager._();
|
||||||
|
|
||||||
|
static final SCHomeRoomPreloadManager instance = SCHomeRoomPreloadManager._();
|
||||||
|
|
||||||
|
static const Duration _partyRoomCacheTtl = Duration(seconds: 30);
|
||||||
|
|
||||||
|
Future<List<SocialChatRoomRes>>? _partyRoomsFuture;
|
||||||
|
List<SocialChatRoomRes>? _partyRooms;
|
||||||
|
DateTime? _partyRoomsLoadedAt;
|
||||||
|
|
||||||
|
void preloadInitialHomeRooms() {
|
||||||
|
final token = AccountStorage().getToken();
|
||||||
|
if (AccountStorage().getCurrentUser() == null || token.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
unawaited(
|
||||||
|
loadPartyRooms().catchError((error, stackTrace) {
|
||||||
|
debugPrint('[HomePreload] party rooms preload failed: $error');
|
||||||
|
return <SocialChatRoomRes>[];
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<List<SocialChatRoomRes>> loadPartyRooms({bool forceRefresh = false}) {
|
||||||
|
if (!forceRefresh && _hasFreshPartyRoomCache) {
|
||||||
|
return Future.value(List<SocialChatRoomRes>.from(_partyRooms!));
|
||||||
|
}
|
||||||
|
if (!forceRefresh) {
|
||||||
|
final pendingFuture = _partyRoomsFuture;
|
||||||
|
if (pendingFuture != null) {
|
||||||
|
return pendingFuture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final future = SCChatRoomRepository()
|
||||||
|
.discovery(allRegion: true)
|
||||||
|
.then((rooms) {
|
||||||
|
_partyRooms = List<SocialChatRoomRes>.from(rooms);
|
||||||
|
_partyRoomsLoadedAt = DateTime.now();
|
||||||
|
return List<SocialChatRoomRes>.from(rooms);
|
||||||
|
})
|
||||||
|
.whenComplete(() {
|
||||||
|
_partyRoomsFuture = null;
|
||||||
|
});
|
||||||
|
_partyRoomsFuture = future;
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get _hasFreshPartyRoomCache {
|
||||||
|
final rooms = _partyRooms;
|
||||||
|
final loadedAt = _partyRoomsLoadedAt;
|
||||||
|
if (rooms == null || loadedAt == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return DateTime.now().difference(loadedAt) < _partyRoomCacheTtl;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
import 'package:yumi/app_localizations.dart';
|
import 'package:yumi/app_localizations.dart';
|
||||||
@ -6,8 +8,14 @@ import 'package:yumi/ui_kit/components/text/sc_text.dart';
|
|||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:yumi/app/routes/sc_routes.dart';
|
import 'package:yumi/app/routes/sc_routes.dart';
|
||||||
import 'package:yumi/app/routes/sc_fluro_navigator.dart';
|
import 'package:yumi/app/routes/sc_fluro_navigator.dart';
|
||||||
|
import 'package:yumi/services/audio/rtm_manager.dart';
|
||||||
import 'package:yumi/services/gift/gift_animation_manager.dart';
|
import 'package:yumi/services/gift/gift_animation_manager.dart';
|
||||||
|
import 'package:yumi/services/music/room_music_manager.dart';
|
||||||
import 'package:yumi/services/audio/rtc_manager.dart';
|
import 'package:yumi/services/audio/rtc_manager.dart';
|
||||||
|
import 'package:yumi/shared/data_sources/sources/local/floating_screen_manager.dart';
|
||||||
|
import 'package:yumi/shared/tools/sc_gift_vap_svga_manager.dart';
|
||||||
|
import 'package:yumi/shared/tools/sc_room_effect_scheduler.dart';
|
||||||
|
import 'package:yumi/ui_kit/widgets/room/anim/room_entrance_widget.dart';
|
||||||
|
|
||||||
import '../../components/sc_float_ichart.dart';
|
import '../../components/sc_float_ichart.dart';
|
||||||
|
|
||||||
@ -54,15 +62,34 @@ class _ExitMinRoomPageState extends State<ExitMinRoomPage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () async {
|
||||||
|
final rtcProvider = context.read<RtcProvider>();
|
||||||
|
if (rtcProvider.roomStartupStatus ==
|
||||||
|
RoomStartupStatus.loading ||
|
||||||
|
rtcProvider.roomStartupStatus == RoomStartupStatus.failed) {
|
||||||
|
SCNavigatorUtils.goBack(context);
|
||||||
|
await rtcProvider.exitCurrentVoiceRoomSession(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
final giftAnimationManager =
|
final giftAnimationManager =
|
||||||
context.read<GiftAnimationManager>();
|
context.read<GiftAnimationManager>();
|
||||||
|
final rtmProvider = context.read<RtmProvider>();
|
||||||
|
rtcProvider.setRoomVisualEffectsEnabled(false);
|
||||||
|
rtmProvider.msgFloatingGiftListener = null;
|
||||||
|
rtmProvider.msgLuckyGiftRewardTickerListener = null;
|
||||||
|
RoomEntranceHelper.clearQueue();
|
||||||
|
OverlayManager().removeRoom();
|
||||||
|
SCRoomEffectScheduler().clearDeferredTasks(
|
||||||
|
reason: 'room_minimize',
|
||||||
|
);
|
||||||
|
SCGiftVapSvgaManager().stopPlayback();
|
||||||
|
unawaited(context.read<RoomMusicManager>().stopForRoomExit());
|
||||||
|
giftAnimationManager.cleanupAnimationResources();
|
||||||
SCFloatIchart().show();
|
SCFloatIchart().show();
|
||||||
SCNavigatorUtils.popUntil(
|
SCNavigatorUtils.popUntil(
|
||||||
context,
|
context,
|
||||||
ModalRoute.withName(SCRoutes.home),
|
ModalRoute.withName(SCRoutes.home),
|
||||||
);
|
);
|
||||||
giftAnimationManager.cleanupAnimationResources();
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
SCDebounceWidget(
|
SCDebounceWidget(
|
||||||
|
|||||||
@ -38,7 +38,7 @@ class _RoomMenuDialogState extends State<RoomMenuDialog> {
|
|||||||
static const int _menuReport = 5;
|
static const int _menuReport = 5;
|
||||||
static const int _menuBackground = 6;
|
static const int _menuBackground = 6;
|
||||||
static const int _menuMusic = 7;
|
static const int _menuMusic = 7;
|
||||||
static bool get _showBackgroundFeature => true;
|
static bool get _showBackgroundFeature => false;
|
||||||
|
|
||||||
List<RoomMenu> items2 = [];
|
List<RoomMenu> items2 = [];
|
||||||
|
|
||||||
|
|||||||
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.2.5+7
|
version: 1.2.6+8
|
||||||
|
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user