yumi-flutter/lib/modules/room/background/room_background_apply_service.dart
2026-05-07 10:06:02 +08:00

119 lines
4.1 KiB
Dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
import 'package:yumi/app/constants/sc_room_msg_type.dart';
import 'package:yumi/modules/room/background/room_background_history.dart';
import 'package:yumi/services/audio/rtc_manager.dart';
import 'package:yumi/services/audio/rtm_manager.dart';
import 'package:yumi/services/room/rc_room_manager.dart';
import 'package:yumi/shared/data_sources/sources/repositories/sc_general_repository_imp.dart';
import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
import 'package:yumi/ui_kit/widgets/room/room_msg_item.dart';
class RoomBackgroundApplyService {
static Future<String> apply(BuildContext context, String sourcePath) async {
final normalizedSource = sourcePath.trim();
if (normalizedSource.isEmpty) {
throw StateError("Room background source is empty");
}
final rtcProvider = context.read<RtcProvider>();
final rtmProvider = context.read<RtmProvider>();
final roomManager = context.read<SocialChatRoomManager>();
final roomProfile = rtcProvider.currenRoom?.roomProfile?.roomProfile;
final roomId = (roomProfile?.id ?? "").trim();
final roomAccount = (roomProfile?.roomAccount ?? "").trim();
if (roomId.isEmpty) {
throw StateError("Room id is empty");
}
final uploadedUrl =
_isNetworkImage(normalizedSource)
? normalizedSource
: await _uploadSource(normalizedSource);
if (uploadedUrl.trim().isEmpty) {
throw StateError("Uploaded background URL is empty");
}
debugPrint(
"[Room Background Apply] source=$normalizedSource uploadedUrl=$uploadedUrl",
);
final roomInfo = await SCAccountRepository().updateRoomBackground(
roomId,
uploadedUrl,
);
final roomBackground = _preferNonEmpty(
roomInfo.roomBackground,
uploadedUrl,
);
rtcProvider.updateCurrentRoomBasicInfo(roomBackground: roomBackground);
roomManager.updateMyRoomInfo(
roomInfo.copyWith(
id: roomInfo.id ?? roomId,
roomBackground: roomBackground,
),
);
if (roomAccount.isNotEmpty) {
rtmProvider.dispatchMessage(
Msg(
groupId: roomAccount,
msg: roomInfo.id ?? roomId,
type: SCRoomMsgType.roomSettingUpdate,
),
addLocal: false,
);
}
await RoomBackgroundHistory.add(roomBackground);
return roomBackground;
}
static bool _isNetworkImage(String value) {
return value.startsWith("http://") || value.startsWith("https://");
}
static Future<String> _uploadSource(String sourcePath) async {
final sourceFile =
_isAssetPath(sourcePath)
? await _copyAssetToTemporaryFile(sourcePath)
: File(sourcePath);
if (!sourceFile.existsSync()) {
throw StateError("Room background source file does not exist");
}
debugPrint(
"[Room Background Upload] upload local file path=${sourceFile.path} size=${sourceFile.lengthSync()}",
);
final uploadedUrl = await SCGeneralRepositoryImp().upload(sourceFile);
debugPrint("[Room Background Upload] upload success url=$uploadedUrl");
return uploadedUrl;
}
static bool _isAssetPath(String value) {
return value.startsWith("assets/") || value.startsWith("sc_images/");
}
static Future<File> _copyAssetToTemporaryFile(String assetPath) async {
final bytes = await rootBundle.load(assetPath);
final directory = await getTemporaryDirectory();
final fileName = assetPath.split("/").last;
final file = File("${directory.path}/room_background_$fileName");
await file.writeAsBytes(
bytes.buffer.asUint8List(bytes.offsetInBytes, bytes.lengthInBytes),
flush: true,
);
debugPrint(
"[Room Background Upload] copied asset=$assetPath to temp=${file.path} size=${file.lengthSync()}",
);
return file;
}
static String _preferNonEmpty(String? primary, String fallback) {
if ((primary ?? "").trim().isNotEmpty) {
return primary!.trim();
}
return fallback.trim();
}
}