fix(mobile-next): 按 B-91 收口 Android 通话视觉打回项
呼出/通话中按钮、计时器、底色、60s 未接与进出场动效对齐视觉规范。 Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
Cursor
multica-agent
parent
714794f7fe
commit
9bde926c81
@@ -10,6 +10,7 @@ import 'package:just_audio/just_audio.dart';
|
||||
import 'package:openim_common/openim_common.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'package:vibration/vibration.dart';
|
||||
|
||||
import '../openim_live.dart';
|
||||
|
||||
@@ -53,12 +54,11 @@ mixin OpenIMLive {
|
||||
|
||||
final _ring = 'assets/audio/live_ring.wav';
|
||||
final _audioPlayer = AudioPlayer(
|
||||
// Handle audio_session events ourselves for the purpose of this demo.
|
||||
handleInterruptions: false,
|
||||
// androidApplyAudioAttributes: false,
|
||||
// handleAudioSessionActivation: false,
|
||||
);
|
||||
|
||||
Timer? _incomingVibrateTimer;
|
||||
|
||||
bool get isBusy => OpenIMLiveClient().isBusy;
|
||||
|
||||
onCloseLive() {
|
||||
@@ -94,7 +94,7 @@ mixin OpenIMLive {
|
||||
(event) async {
|
||||
_beCalledEvent = null;
|
||||
if (event.state == CallState.beCalled) {
|
||||
_playSound();
|
||||
_playSound(vibrate: true);
|
||||
final mediaType = event.data.invitation!.mediaType;
|
||||
final sessionType = event.data.invitation!.sessionType;
|
||||
final callType = mediaType == 'audio' ? CallType.audio : CallType.video;
|
||||
@@ -135,6 +135,7 @@ mixin OpenIMLive {
|
||||
onError: onError,
|
||||
onRoomDisconnected: () => onRoomDisconnected(event.data),
|
||||
onStartCalling: onLiveConnected,
|
||||
onInviteTimeout: () => _onInviteTimeout(event.data),
|
||||
onClose: () {
|
||||
_stopSound();
|
||||
onLiveSessionClosed();
|
||||
@@ -195,7 +196,7 @@ mixin OpenIMLive {
|
||||
inviterUserID: inviterUserID,
|
||||
inviteeUserIDList: inviteeUserIDList,
|
||||
roomID: roomID ?? groupID ?? const Uuid().v4(),
|
||||
timeout: 30,
|
||||
timeout: Styles.callInviteTimeout.inSeconds,
|
||||
mediaType: mediaType,
|
||||
sessionType: sessionType,
|
||||
platformID: IMUtils.getPlatform(),
|
||||
@@ -233,6 +234,7 @@ mixin OpenIMLive {
|
||||
},
|
||||
onError: onError,
|
||||
onRoomDisconnected: () => onRoomDisconnected(signal),
|
||||
onInviteTimeout: () => _onInviteTimeout(signal),
|
||||
onClose: () {
|
||||
_stopSound();
|
||||
onLiveSessionClosed();
|
||||
@@ -242,7 +244,6 @@ mixin OpenIMLive {
|
||||
|
||||
onError(error, stack) {
|
||||
Logger.print('onError=====> $error $stack');
|
||||
OpenIMLiveClient().close();
|
||||
_stopSound();
|
||||
if (error is PlatformException) {
|
||||
if (int.parse(error.code) == SDKErrorCode.hasBeenBlocked) {
|
||||
@@ -250,7 +251,7 @@ mixin OpenIMLive {
|
||||
return;
|
||||
}
|
||||
}
|
||||
IMViews.showToast(StrRes.networkError);
|
||||
IMViews.showToast(StrRes.callNetworkInterrupted);
|
||||
}
|
||||
|
||||
onRoomDisconnected(SignalingInfo signalingInfo) {}
|
||||
@@ -332,12 +333,20 @@ mixin OpenIMLive {
|
||||
OpenIM.iMManager.messageManager.sendMessage(
|
||||
message: message,
|
||||
offlinePushInfo: OfflinePushInfo(),
|
||||
userID: signaling.invitation!.inviterUserID,
|
||||
userID: signaling.invitation!.inviterUserID == OpenIM.iMManager.userID
|
||||
? signaling.invitation!.inviteeUserIDList!.first
|
||||
: signaling.invitation!.inviterUserID,
|
||||
isOnlineOnly: true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<void> _onInviteTimeout(SignalingInfo signaling) async {
|
||||
_stopSound();
|
||||
insertSignalingMessageSubject.add(CallEvent(CallState.timeout, signaling));
|
||||
await onTimeoutCancelled(signaling);
|
||||
}
|
||||
|
||||
onTapHangup(SignalingInfo signaling, int duration, bool isPositive) async {
|
||||
if (isPositive) {
|
||||
final data = {'customType': CustomMessageType.callingHungup, 'data': signaling.invitation!.toJson()};
|
||||
@@ -388,16 +397,44 @@ mixin OpenIMLive {
|
||||
return list;
|
||||
}
|
||||
|
||||
void _playSound() async {
|
||||
void _playSound({bool vibrate = false}) async {
|
||||
if (!_audioPlayer.playerState.playing) {
|
||||
_audioPlayer.setAsset(_ring, package: 'openim_common');
|
||||
_audioPlayer.setLoopMode(LoopMode.one);
|
||||
_audioPlayer.setVolume(1.0);
|
||||
_audioPlayer.play();
|
||||
}
|
||||
if (vibrate) {
|
||||
_startIncomingVibrate();
|
||||
}
|
||||
}
|
||||
|
||||
void _startIncomingVibrate() {
|
||||
_stopIncomingVibrate();
|
||||
_pulseVibrate();
|
||||
_incomingVibrateTimer = Timer.periodic(Styles.callVibrate, (_) => _pulseVibrate());
|
||||
}
|
||||
|
||||
void _stopIncomingVibrate() {
|
||||
_incomingVibrateTimer?.cancel();
|
||||
_incomingVibrateTimer = null;
|
||||
try {
|
||||
Vibration.cancel();
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
Future<void> _pulseVibrate() async {
|
||||
try {
|
||||
if (await Vibration.hasVibrator() == true) {
|
||||
await Vibration.vibrate(duration: 200);
|
||||
return;
|
||||
}
|
||||
} catch (_) {}
|
||||
HapticFeedback.vibrate();
|
||||
}
|
||||
|
||||
void _stopSound() async {
|
||||
_stopIncomingVibrate();
|
||||
if (_audioPlayer.playerState.playing) {
|
||||
_audioPlayer.stop();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user