persist cm chat page if chat unanswered

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages
2022-10-08 20:15:02 +08:00
parent c4c13bfbeb
commit ca9ca19fa7
32 changed files with 259 additions and 125 deletions

View File

@@ -158,40 +158,26 @@ class ConnectionManagerState extends State<ConnectionManager> {
),
);
}
Widget buildTab(Client client) {
return Tab(
child: Row(
children: [
SizedBox(
width: 80,
child: Text(
client.name,
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,
)),
],
),
);
}
}
Widget buildConnectionCard(Client client) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
key: ValueKey(client.id),
children: [
_CmHeader(client: client),
client.isFileTransfer ? Offstage() : _PrivilegeBoard(client: client),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: _CmControlPanel(client: client),
))
],
).paddingSymmetric(vertical: 8.0, horizontal: 8.0);
return Consumer<ServerModel>(
builder: (context, value, child) => Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
key: ValueKey(client.id),
children: [
_CmHeader(client: client),
client.isFileTransfer || client.disconnected
? Offstage()
: _PrivilegeBoard(client: client),
Expanded(
child: Align(
alignment: Alignment.bottomCenter,
child: _CmControlPanel(client: client),
))
],
).paddingSymmetric(vertical: 8.0, horizontal: 8.0));
}
class _AppIcon extends StatelessWidget {
@@ -249,7 +235,7 @@ class _CmHeaderState extends State<_CmHeader>
void initState() {
super.initState();
_timer = Timer.periodic(Duration(seconds: 1), (_) {
_time.value = _time.value + 1;
if (!client.disconnected) _time.value = _time.value + 1;
});
}
@@ -303,7 +289,10 @@ class _CmHeaderState extends State<_CmHeader>
FittedBox(
child: Row(
children: [
Text(translate("Connected")).marginOnly(right: 8.0),
Text(client.disconnected
? translate("Disconnected")
: translate("Connected"))
.marginOnly(right: 8.0),
Obx(() => Text(
formatDurationToTime(Duration(seconds: _time.value))))
],
@@ -311,15 +300,14 @@ class _CmHeaderState extends State<_CmHeader>
],
),
),
Consumer<ServerModel>(
builder: (_, model, child) => Offstage(
offstage: !client.authorized || client.isFileTransfer,
child: IconButton(
onPressed: () => checkClickTime(client.id,
() => gFFI.chatModel.toggleCMChatPage(client.id)),
icon: Icon(Icons.message_outlined),
),
))
Offstage(
offstage: !client.authorized || client.isFileTransfer,
child: IconButton(
onPressed: () => checkClickTime(
client.id, () => gFFI.chatModel.toggleCMChatPage(client.id)),
icon: Icon(Icons.message_outlined),
),
)
],
);
}
@@ -435,11 +423,11 @@ class _CmControlPanel extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Consumer<ServerModel>(builder: (_, model, child) {
return client.authorized
? buildAuthorized(context)
: buildUnAuthorized(context);
});
return client.authorized
? client.disconnected
? buildDisconnected(context)
: buildAuthorized(context)
: buildUnAuthorized(context);
}
buildAuthorized(BuildContext context) {
@@ -468,6 +456,31 @@ class _CmControlPanel extends StatelessWidget {
);
}
buildDisconnected(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Ink(
width: 200,
height: 40,
decoration: BoxDecoration(
color: MyTheme.accent, borderRadius: BorderRadius.circular(10)),
child: InkWell(
onTap: () => handleClose(context),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
translate("Close"),
style: TextStyle(color: Colors.white),
),
],
)),
)
],
);
}
buildUnAuthorized(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
@@ -527,6 +540,13 @@ class _CmControlPanel extends StatelessWidget {
final model = Provider.of<ServerModel>(context, listen: false);
model.sendLoginResponse(client, true);
}
void handleClose(BuildContext context) async {
await bind.cmRemoveDisconnectedConnection(connId: client.id);
if (await bind.cmGetClientsLength() == 0) {
windowManager.close();
}
}
}
void checkClickTime(int id, Function() callback) async {

View File

@@ -376,29 +376,29 @@ class ServerModel with ChangeNotifier {
} else {
_clients[index].authorized = true;
}
tabController.add(
TabInfo(
key: client.id.toString(),
label: client.name,
closable: false,
page: Desktop.buildConnectionCard(client)),
authorized: true);
scrollToBottom();
notifyListeners();
} else {
if (_clients.any((c) => c.id == client.id)) {
return;
}
_clients.add(client);
tabController.add(TabInfo(
key: client.id.toString(),
label: client.name,
closable: false,
page: Desktop.buildConnectionCard(client)));
scrollToBottom();
notifyListeners();
if (isAndroid) showLoginDialog(client);
}
tabController.add(
TabInfo(
key: client.id.toString(),
label: client.name,
closable: false,
page: Desktop.buildConnectionCard(client)),
authorized: client.authorized);
// remove disconnected
final index_disconnected = _clients
.indexWhere((c) => c.disconnected && c.peerId == client.peerId);
if (index_disconnected >= 0) {
_clients.removeAt(index_disconnected);
tabController.remove(index_disconnected);
}
scrollToBottom();
notifyListeners();
if (isAndroid && !client.authorized) showLoginDialog(client);
} catch (e) {
debugPrint("Failed to call loginRequest,error:$e");
}
@@ -477,38 +477,19 @@ class ServerModel with ChangeNotifier {
}
}
void onClientAuthorized(Map<String, dynamic> evt) {
try {
final client = Client.fromJson(jsonDecode(evt['client']));
parent.target?.dialogManager.dismissByTag(getLoginDialogTag(client.id));
final index = _clients.indexWhere((c) => c.id == client.id);
if (index < 0) {
_clients.add(client);
} else {
_clients[index].authorized = true;
}
tabController.add(
TabInfo(
key: client.id.toString(),
label: client.name,
closable: false,
page: Desktop.buildConnectionCard(client)),
authorized: true);
scrollToBottom();
notifyListeners();
} catch (e) {
debugPrint("onClientAuthorized:$e");
}
}
void onClientRemove(Map<String, dynamic> evt) {
try {
final id = int.parse(evt['id'] as String);
final close = (evt['close'] as String) == 'true';
if (_clients.any((c) => c.id == id)) {
final index = _clients.indexWhere((client) => client.id == id);
if (index >= 0) {
_clients.removeAt(index);
tabController.remove(index);
if (close) {
_clients.removeAt(index);
tabController.remove(index);
} else {
_clients[index].disconnected = true;
}
}
parent.target?.dialogManager.dismissByTag(getLoginDialogTag(id));
parent.target?.invokeMethod("cancel_notification", id);
@@ -545,6 +526,7 @@ class Client {
bool file = false;
bool restart = false;
bool recording = false;
bool disconnected = false;
Client(this.id, this.authorized, this.isFileTransfer, this.name, this.peerId,
this.keyboard, this.clipboard, this.audio);
@@ -561,18 +543,20 @@ class Client {
file = json['file'];
restart = json['restart'];
recording = json['recording'];
disconnected = json['disconnected'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['is_start'] = this.authorized;
data['is_file_transfer'] = this.isFileTransfer;
data['name'] = this.name;
data['peer_id'] = this.peerId;
data['keyboard'] = this.keyboard;
data['clipboard'] = this.clipboard;
data['audio'] = this.audio;
data['id'] = id;
data['is_start'] = authorized;
data['is_file_transfer'] = isFileTransfer;
data['name'] = name;
data['peer_id'] = peerId;
data['keyboard'] = keyboard;
data['clipboard'] = clipboard;
data['audio'] = audio;
data['disconnected'] = disconnected;
return data;
}
}