refact: android audio input, voice call (#8037)

Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
fufesou
2024-05-14 09:20:27 +08:00
committed by GitHub
parent d70b0cdd4f
commit 0500bf070e
51 changed files with 610 additions and 148 deletions

View File

@@ -8,6 +8,7 @@ import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/mobile/widgets/gesture_help.dart';
import 'package:flutter_hbb/models/chat_model.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart';
import 'package:provider/provider.dart';
import 'package:wakelock_plus/wakelock_plus.dart';
@@ -79,7 +80,7 @@ class _RemotePageState extends State<RemotePage> {
initSharedStates(widget.id);
gFFI.chatModel
.changeCurrentKey(MessageKey(widget.id, ChatModel.clientModeID));
gFFI.chatModel.voiceCallStatus.value = VoiceCallStatus.notStarted;
_blockableOverlayState.applyFfi(gFFI);
}
@@ -102,6 +103,11 @@ class _RemotePageState extends State<RemotePage> {
}
await keyboardSubscription.cancel();
removeSharedStates(widget.id);
if (isAndroid) {
// Only one client is considered here for now.
// TODO: take into account the case where there are multiple clients
gFFI.invokeMethod("on_voice_call_closed");
}
}
// to-do: It should be better to use transparent color instead of the bgColor.
@@ -369,9 +375,7 @@ class _RemotePageState extends State<RemotePage> {
onPressed: () {
clientClose(sessionId, gFFI.dialogManager);
},
)
] +
<Widget>[
),
IconButton(
color: Colors.white,
icon: Icon(Icons.tv),
@@ -416,11 +420,9 @@ class _RemotePageState extends State<RemotePage> {
IconButton(
color: Colors.white,
icon: Icon(Icons.message),
onPressed: () {
gFFI.chatModel.changeCurrentKey(MessageKey(
widget.id, ChatModel.clientModeID));
gFFI.chatModel.toggleChatOverlay();
},
onPressed: () => isAndroid
? showChatOptions(widget.id)
: onPressedTextChat(widget.id),
)
]) +
[
@@ -538,6 +540,82 @@ class _RemotePageState extends State<RemotePage> {
}();
}
onPressedTextChat(String id) {
gFFI.chatModel.changeCurrentKey(MessageKey(id, ChatModel.clientModeID));
gFFI.chatModel.toggleChatOverlay();
}
showChatOptions(String id) async {
onPressVoiceCall() => bind.sessionRequestVoiceCall(sessionId: sessionId);
onPressEndVoiceCall() => bind.sessionCloseVoiceCall(sessionId: sessionId);
makeTextMenu(String label, String svg, VoidCallback onPressed,
{ColorFilter? colorFilter, TextStyle? labelStyle}) =>
TTextMenu(
child: Text(translate(label), style: labelStyle),
trailingIcon: Transform.scale(
scale: (isDesktop || isWebDesktop) ? 0.8 : 1,
child: IconButton(
onPressed: onPressed,
icon: SvgPicture.asset(
svg,
colorFilter: colorFilter ??
ColorFilter.mode(MyTheme.accent, BlendMode.srcIn),
),
),
),
onPressed: onPressed,
);
final isInVoice = [
VoiceCallStatus.waitingForResponse,
VoiceCallStatus.connected
].contains(gFFI.chatModel.voiceCallStatus.value);
final menus = [
makeTextMenu(
'Text chat', 'assets/chat.svg', () => onPressedTextChat(widget.id)),
isInVoice
? makeTextMenu(
'End voice call', 'assets/call_wait.svg', onPressEndVoiceCall,
colorFilter: ColorFilter.mode(Colors.redAccent, BlendMode.srcIn),
labelStyle: TextStyle(color: Colors.redAccent))
: makeTextMenu(
'Voice call', 'assets/call_wait.svg', onPressVoiceCall),
];
getChild(TTextMenu menu) {
if (menu.trailingIcon != null) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
menu.child,
menu.trailingIcon!,
]);
} else {
return menu.child;
}
}
final menuItems = menus
.asMap()
.entries
.map((e) => PopupMenuItem<int>(child: getChild(e.value), value: e.key))
.toList();
Future.delayed(Duration.zero, () async {
final size = MediaQuery.of(context).size;
final x = 120.0;
final y = size.height;
var index = await showMenu(
context: context,
position: RelativeRect.fromLTRB(x, y, x, y),
items: menuItems,
elevation: 8,
);
if (index != null && index < menus.length) {
menus[index].onPressed.call();
}
});
}
/// aka changeTouchMode
BottomAppBar getGestureHelp() {
return BottomAppBar(