fix: debug, terminal web (#12375)
Signed-off-by: fufesou <linlong1266@gmail.com>
This commit is contained in:
@@ -551,7 +551,7 @@ abstract class BasePeerCard extends StatelessWidget {
|
|||||||
MenuEntryBase<String> _terminalAction(BuildContext context) {
|
MenuEntryBase<String> _terminalAction(BuildContext context) {
|
||||||
return _connectCommonAction(
|
return _connectCommonAction(
|
||||||
context,
|
context,
|
||||||
translate('Terminal'),
|
'${translate('Terminal')} (beta)',
|
||||||
isTerminal: true,
|
isTerminal: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -560,7 +560,7 @@ abstract class BasePeerCard extends StatelessWidget {
|
|||||||
MenuEntryBase<String> _terminalRunAsAdminAction(BuildContext context) {
|
MenuEntryBase<String> _terminalRunAsAdminAction(BuildContext context) {
|
||||||
return _connectCommonAction(
|
return _connectCommonAction(
|
||||||
context,
|
context,
|
||||||
translate('Terminal (Run as administrator)'),
|
'${translate('Terminal (Run as administrator)')} (beta)',
|
||||||
isTerminalRunAsAdmin: true,
|
isTerminalRunAsAdmin: true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ List<TTextMenu> toolbarControls(BuildContext context, String id, FFI ffi) {
|
|||||||
);
|
);
|
||||||
v.add(
|
v.add(
|
||||||
TTextMenu(
|
TTextMenu(
|
||||||
child: Text(translate('Terminal')),
|
child: Text('${translate('Terminal')} (beta)'),
|
||||||
onPressed: () => connectWithToken(isTerminal: true)),
|
onPressed: () => connectWithToken(isTerminal: true)),
|
||||||
);
|
);
|
||||||
v.add(
|
v.add(
|
||||||
|
|||||||
@@ -563,7 +563,7 @@ class _ConnectionPageState extends State<ConnectionPage>
|
|||||||
() => onConnect(isViewCamera: true)
|
() => onConnect(isViewCamera: true)
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'Terminal',
|
'${translate('Terminal')} (beta)',
|
||||||
() => onConnect(isTerminal: true)
|
() => onConnect(isTerminal: true)
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
SettingsTile.switchTile(
|
SettingsTile.switchTile(
|
||||||
title: Text('${translate('Adaptive bitrate')} (beta)'),
|
title: Text(translate('Adaptive bitrate')),
|
||||||
initialValue: _enableAbr,
|
initialValue: _enableAbr,
|
||||||
onToggle: isOptionFixed(kOptionEnableAbr)
|
onToggle: isOptionFixed(kOptionEnableAbr)
|
||||||
? null
|
? null
|
||||||
@@ -540,7 +540,7 @@ class _SettingsState extends State<SettingsPage> with WidgetsBindingObserver {
|
|||||||
enhancementsTiles.add(SettingsTile.switchTile(
|
enhancementsTiles.add(SettingsTile.switchTile(
|
||||||
initialValue: _enableStartOnBoot,
|
initialValue: _enableStartOnBoot,
|
||||||
title: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
title: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||||
Text("${translate('Start on boot')} (beta)"),
|
Text(translate('Start on boot')),
|
||||||
Text(
|
Text(
|
||||||
'* ${translate('Start the screen sharing service on boot, requires special permissions')}',
|
'* ${translate('Start the screen sharing service on boot, requires special permissions')}',
|
||||||
style: Theme.of(context).textTheme.bodySmall),
|
style: Theme.of(context).textTheme.bodySmall),
|
||||||
|
|||||||
@@ -3214,7 +3214,7 @@ class FFI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void routeTerminalResponse(Map<String, dynamic> evt) {
|
void routeTerminalResponse(Map<String, dynamic> evt) {
|
||||||
final int terminalId = evt['terminal_id'] ?? 0;
|
final int terminalId = TerminalModel.getTerminalIdFromEvt(evt);
|
||||||
|
|
||||||
// Route to specific terminal model if it exists
|
// Route to specific terminal model if it exists
|
||||||
final model = _terminalModels[terminalId];
|
final model = _terminalModels[terminalId];
|
||||||
|
|||||||
@@ -165,9 +165,58 @@ class TerminalModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int getTerminalIdFromEvt(Map<String, dynamic> evt) {
|
||||||
|
if (evt.containsKey('terminal_id')) {
|
||||||
|
final v = evt['terminal_id'];
|
||||||
|
if (v is int) {
|
||||||
|
// Desktop and mobile send terminal_id as an int
|
||||||
|
return v;
|
||||||
|
} else if (v is String) {
|
||||||
|
// Web sends terminal_id as a string
|
||||||
|
final parsed = int.tryParse(v);
|
||||||
|
if (parsed != null) {
|
||||||
|
return parsed;
|
||||||
|
} else {
|
||||||
|
debugPrint(
|
||||||
|
'[TerminalModel] Failed to parse terminal_id as integer: $v. Expected a numeric string.');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Unexpected type, log and handle gracefully
|
||||||
|
debugPrint(
|
||||||
|
'[TerminalModel] Unexpected terminal_id type: ${v.runtimeType}, value: $v. Expected int or String.');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
debugPrint('[TerminalModel] Event does not contain terminal_id');
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool getSuccessFromEvt(Map<String, dynamic> evt) {
|
||||||
|
if (evt.containsKey('success')) {
|
||||||
|
final v = evt['success'];
|
||||||
|
if (v is bool) {
|
||||||
|
// Desktop and mobile
|
||||||
|
return v;
|
||||||
|
} else if (v is String) {
|
||||||
|
// Web
|
||||||
|
return v.toLowerCase() == 'true';
|
||||||
|
} else {
|
||||||
|
// Unexpected type, log and handle gracefully
|
||||||
|
debugPrint(
|
||||||
|
'[TerminalModel] Unexpected success type: ${v.runtimeType}, value: $v. Expected bool or String.');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
debugPrint('[TerminalModel] Event does not contain success');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void handleTerminalResponse(Map<String, dynamic> evt) {
|
void handleTerminalResponse(Map<String, dynamic> evt) {
|
||||||
final String? type = evt['type'];
|
final String? type = evt['type'];
|
||||||
final int evtTerminalId = evt['terminal_id'] ?? 0;
|
final int evtTerminalId = getTerminalIdFromEvt(evt);
|
||||||
|
|
||||||
// Only handle events for this terminal
|
// Only handle events for this terminal
|
||||||
if (evtTerminalId != terminalId) {
|
if (evtTerminalId != terminalId) {
|
||||||
@@ -193,7 +242,7 @@ class TerminalModel with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _handleTerminalOpened(Map<String, dynamic> evt) {
|
void _handleTerminalOpened(Map<String, dynamic> evt) {
|
||||||
final bool success = evt['success'] ?? false;
|
final bool success = getSuccessFromEvt(evt);
|
||||||
final String message = evt['message'] ?? '';
|
final String message = evt['message'] ?? '';
|
||||||
final String? serviceId = evt['service_id'];
|
final String? serviceId = evt['service_id'];
|
||||||
|
|
||||||
|
|||||||
@@ -908,8 +908,18 @@ class RustdeskImpl {
|
|||||||
return js.context.callMethod('getByName', ['option:local', key]);
|
return js.context.callMethod('getByName', ['option:local', key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do not return the real environment variables.
|
||||||
|
// Use the global variable as the environment variable in web.
|
||||||
String mainGetEnv({required String key, dynamic hint}) {
|
String mainGetEnv({required String key, dynamic hint}) {
|
||||||
throw UnimplementedError("mainGetEnv");
|
return js.context.callMethod('getByName', ['envvar', key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use the global variable as the environment variable in web.
|
||||||
|
void mainSetEnv({required String key, String? value, dynamic hint}) {
|
||||||
|
js.context.callMethod('setByName', [
|
||||||
|
'envvar',
|
||||||
|
jsonEncode({'name': key, 'value': value})
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> mainSetLocalOption(
|
Future<void> mainSetLocalOption(
|
||||||
@@ -1960,9 +1970,7 @@ class RustdeskImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> sessionCloseTerminal(
|
Future<void> sessionCloseTerminal(
|
||||||
{required UuidValue sessionId,
|
{required UuidValue sessionId, required int terminalId, dynamic hint}) {
|
||||||
required int terminalId,
|
|
||||||
dynamic hint}) {
|
|
||||||
return Future(() => js.context.callMethod('setByName', [
|
return Future(() => js.context.callMethod('setByName', [
|
||||||
'close_terminal',
|
'close_terminal',
|
||||||
jsonEncode({
|
jsonEncode({
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ fn get_or_create_service(
|
|||||||
// Ensure cleanup task is running
|
// Ensure cleanup task is running
|
||||||
ensure_cleanup_task();
|
ensure_cleanup_task();
|
||||||
|
|
||||||
service.lock().unwrap().reset_status();
|
service.lock().unwrap().reset_status(is_persistent);
|
||||||
|
|
||||||
Ok(service)
|
Ok(service)
|
||||||
}
|
}
|
||||||
@@ -600,7 +600,8 @@ impl PersistentTerminalService {
|
|||||||
!self.sessions.is_empty()
|
!self.sessions.is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_status(&mut self) {
|
fn reset_status(&mut self, is_persistent: bool) {
|
||||||
|
self.is_persistent = is_persistent;
|
||||||
self.needs_session_sync = true;
|
self.needs_session_sync = true;
|
||||||
for session in self.sessions.values() {
|
for session in self.sessions.values() {
|
||||||
let mut session = session.lock().unwrap();
|
let mut session = session.lock().unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user