feat: cm interface

This commit is contained in:
Kingtous
2023-02-07 16:11:55 +08:00
parent 5e21a81a5c
commit 2943d2d0cc
12 changed files with 143 additions and 44 deletions

View File

@@ -521,6 +521,38 @@ class _CmControlPanel extends StatelessWidget {
return Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Offstage(
offstage: !client.inVoiceCall,
child: buildButton(context,
color: Colors.purple,
onClick: () => closeVoiceCall(),
icon: Icon(Icons.reply, color: Colors.white),
text: "Stop voice call",
textColor: Colors.white),
),
Offstage(
offstage: !client.incomingVoiceCall,
child: Row(
children: [
Expanded(
child: buildButton(context,
color: MyTheme.accent,
onClick: () => handleVoiceCall(true),
icon: Icon(Icons.phone, color: Colors.white),
text: "Accept",
textColor: Colors.white),
),
Expanded(
child: buildButton(context,
color: Colors.red,
onClick: () => handleVoiceCall(false),
icon: Icon(Icons.phone, color: Colors.white),
text: "Deny",
textColor: Colors.white),
)
],
),
),
Offstage(
offstage: !client.fromSwitch,
child: buildButton(context,
@@ -626,7 +658,7 @@ class _CmControlPanel extends StatelessWidget {
.marginSymmetric(horizontal: showElevation ? 0 : bigMargin);
}
buildButton(
Widget buildButton(
BuildContext context, {
required Color? color,
required Function() onClick,
@@ -692,6 +724,14 @@ class _CmControlPanel extends StatelessWidget {
void handleSwitchBack(BuildContext context) {
bind.cmSwitchBack(connId: client.id);
}
void handleVoiceCall(bool accept) {
bind.cmHandleIncomingVoiceCall(id: client.id, accept: accept);
}
void closeVoiceCall() {
bind.cmCloseVoiceCall(id: client.id);
}
}
void checkClickTime(int id, Function() callback) async {

View File

@@ -713,19 +713,27 @@ class _RemoteMenubarState extends State<RemoteMenubar> {
() {
switch (widget.ffi.chatModel.voiceCallStatus.value) {
case VoiceCallStatus.waitingForResponse:
return SvgPicture.asset(
"assets/voice_call_waiting.svg",
color: _MenubarTheme.commonColor,
width: Theme.of(context).iconTheme.size ?? 24.0,
height: Theme.of(context).iconTheme.size ?? 24.0,
);
break;
return IconButton(
onPressed: () {
widget.ffi.chatModel.closeVoiceCall(widget.id);
},
icon: SvgPicture.asset(
"assets/voice_call_waiting.svg",
color: Colors.red,
width: Theme.of(context).iconTheme.size ?? 24.0,
height: Theme.of(context).iconTheme.size ?? 24.0,
));
case VoiceCallStatus.connected:
return SvgPicture.asset(
"assets/voice_call.svg",
color: Colors.red,
width: Theme.of(context).iconTheme.size ?? 24.0,
height: Theme.of(context).iconTheme.size ?? 24.0,
return IconButton(
onPressed: () {
widget.ffi.chatModel.closeVoiceCall(widget.id);
},
icon: SvgPicture.asset(
"assets/voice_call.svg",
color: Colors.red,
width: Theme.of(context).iconTheme.size ?? 24.0,
height: Theme.of(context).iconTheme.size ?? 24.0,
),
);
default:
return const Offstage();

View File

@@ -316,6 +316,10 @@ class ChatModel with ChangeNotifier {
_voiceCallStatus.value = VoiceCallStatus.incoming;
}
}
void closeVoiceCall(String id) {
bind.sessionCloseVoiceCall(id: id);
}
}
enum VoiceCallStatus {

View File

@@ -216,6 +216,8 @@ class FfiModel with ChangeNotifier {
} else if (name == "on_voice_call_incoming") {
// Voice call is requested by the peer.
parent.target?.chatModel.onVoiceCallIncoming();
} else if (name == "update_voice_call_state") {
parent.target?.serverModel.updateVoiceCallState(evt);
} else {
debugPrint("Unknown event name: $name");
}

View File

@@ -579,6 +579,20 @@ class ServerModel with ChangeNotifier {
notifyListeners();
}
}
void updateVoiceCallState(Map<String, dynamic> evt) {
try {
final client = Client.fromJson(jsonDecode(evt["client"]));
final index = _clients.indexWhere((element) => element.id == client.id);
if (index != -1) {
_clients[index].inVoiceCall = evt['in_voice_call'];
_clients[index].incomingVoiceCall = evt['incoming_voice_call'];
notifyListeners();
}
} catch (e) {
debugPrint("updateVoiceCallState failed: $e");
}
}
}
enum ClientType {
@@ -602,6 +616,8 @@ class Client {
bool recording = false;
bool disconnected = false;
bool fromSwitch = false;
bool inVoiceCall = false;
bool incomingVoiceCall = false;
RxBool hasUnreadChatMessage = false.obs;
@@ -623,6 +639,8 @@ class Client {
recording = json['recording'];
disconnected = json['disconnected'];
fromSwitch = json['from_switch'];
inVoiceCall = json['in_voice_call'];
incomingVoiceCall = json['incoming_voice_call'];
}
Map<String, dynamic> toJson() {