termites 1.0.10 → 1.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/server.js +34 -14
package/package.json
CHANGED
package/server.js
CHANGED
|
@@ -966,7 +966,14 @@ class TermitesServer {
|
|
|
966
966
|
if (mod) {
|
|
967
967
|
modifiers[mod] = !modifiers[mod];
|
|
968
968
|
btn.classList.toggle('active', modifiers[mod]);
|
|
969
|
-
|
|
969
|
+
// Set timeout to auto-reset Ctrl after 10 seconds (for IME users)
|
|
970
|
+
if (mod === 'ctrl' && modifiers.ctrl) {
|
|
971
|
+
if (window.ctrlTimeout) clearTimeout(window.ctrlTimeout);
|
|
972
|
+
window.ctrlTimeout = setTimeout(() => {
|
|
973
|
+
modifiers.ctrl = false;
|
|
974
|
+
btn.classList.remove('active');
|
|
975
|
+
}, 10000);
|
|
976
|
+
}
|
|
970
977
|
// Don't focus terminal when toggling modifier, keep keyboard open
|
|
971
978
|
return;
|
|
972
979
|
}
|
|
@@ -995,6 +1002,7 @@ class TermitesServer {
|
|
|
995
1002
|
// Reset modifiers after use
|
|
996
1003
|
modifiers.ctrl = false;
|
|
997
1004
|
modifiers.alt = false;
|
|
1005
|
+
if (window.ctrlTimeout) { clearTimeout(window.ctrlTimeout); window.ctrlTimeout = null; }
|
|
998
1006
|
toolbar.querySelectorAll('.mod-btn').forEach(b => b.classList.remove('active'));
|
|
999
1007
|
}
|
|
1000
1008
|
// Only focus terminal for non-modifier buttons
|
|
@@ -1057,20 +1065,23 @@ class TermitesServer {
|
|
|
1057
1065
|
term.loadAddon(fitAddon);
|
|
1058
1066
|
term.open(document.getElementById('terminal-container'));
|
|
1059
1067
|
fitAddon.fit();
|
|
1068
|
+
let ctrlTimeout = null;
|
|
1060
1069
|
term.onData(data => {
|
|
1061
1070
|
if (ws?.readyState === WebSocket.OPEN && selectedClientId) {
|
|
1062
1071
|
let sendData = data;
|
|
1063
|
-
console.log('Input received:', data, 'Ctrl active:', modifiers.ctrl);
|
|
1064
1072
|
// Apply Ctrl modifier to keyboard input
|
|
1065
|
-
if (modifiers.ctrl
|
|
1066
|
-
|
|
1073
|
+
if (modifiers.ctrl) {
|
|
1074
|
+
// Handle single character or IME input
|
|
1075
|
+
const char = data.length >= 1 ? data[0] : '';
|
|
1076
|
+
const code = char.toUpperCase().charCodeAt(0);
|
|
1067
1077
|
if (code >= 65 && code <= 90) { // A-Z
|
|
1068
1078
|
sendData = String.fromCharCode(code - 64);
|
|
1069
|
-
console.log('Sending Ctrl+' +
|
|
1079
|
+
console.log('Sending Ctrl+' + char.toUpperCase());
|
|
1080
|
+
// Reset Ctrl after successful use
|
|
1081
|
+
modifiers.ctrl = false;
|
|
1082
|
+
if (ctrlTimeout) { clearTimeout(ctrlTimeout); ctrlTimeout = null; }
|
|
1083
|
+
document.querySelectorAll('.mod-btn[data-mod="ctrl"]').forEach(b => b.classList.remove('active'));
|
|
1070
1084
|
}
|
|
1071
|
-
// Reset Ctrl after use
|
|
1072
|
-
modifiers.ctrl = false;
|
|
1073
|
-
document.querySelectorAll('.mod-btn').forEach(b => b.classList.remove('active'));
|
|
1074
1085
|
}
|
|
1075
1086
|
ws.send(JSON.stringify({ type: 'input', clientId: selectedClientId, text: sendData }));
|
|
1076
1087
|
term.scrollToBottom();
|
|
@@ -1085,17 +1096,24 @@ class TermitesServer {
|
|
|
1085
1096
|
}));
|
|
1086
1097
|
}
|
|
1087
1098
|
}
|
|
1099
|
+
function isMobileDevice() {
|
|
1100
|
+
return 'ontouchstart' in window || navigator.maxTouchPoints > 0 ||
|
|
1101
|
+
/Mobile|Android|iPhone|iPad|iPod|webOS|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
|
|
1102
|
+
}
|
|
1088
1103
|
function handleViewportResize() {
|
|
1089
|
-
//
|
|
1090
|
-
if (window.visualViewport) {
|
|
1104
|
+
// Only adjust body height on mobile devices (handles keyboard popup)
|
|
1105
|
+
if (isMobileDevice() && window.visualViewport) {
|
|
1091
1106
|
const vh = window.visualViewport.height;
|
|
1092
1107
|
document.body.style.height = vh + 'px';
|
|
1093
1108
|
// Scroll viewport to top to prevent offset issues
|
|
1094
1109
|
window.scrollTo(0, 0);
|
|
1110
|
+
} else {
|
|
1111
|
+
// On desktop, use full viewport height
|
|
1112
|
+
document.body.style.height = '';
|
|
1095
1113
|
}
|
|
1096
1114
|
handleResize();
|
|
1097
1115
|
}
|
|
1098
|
-
window.addEventListener('resize',
|
|
1116
|
+
window.addEventListener('resize', handleViewportResize);
|
|
1099
1117
|
window.addEventListener('orientationchange', () => {
|
|
1100
1118
|
// Delay fit after orientation change to let browser settle
|
|
1101
1119
|
setTimeout(handleViewportResize, 100);
|
|
@@ -1103,10 +1121,12 @@ class TermitesServer {
|
|
|
1103
1121
|
// Also handle visual viewport changes (mobile keyboard show/hide)
|
|
1104
1122
|
if (window.visualViewport) {
|
|
1105
1123
|
window.visualViewport.addEventListener('resize', handleViewportResize);
|
|
1106
|
-
window.visualViewport.addEventListener('scroll', () =>
|
|
1107
|
-
|
|
1108
|
-
|
|
1124
|
+
window.visualViewport.addEventListener('scroll', () => {
|
|
1125
|
+
if (isMobileDevice()) window.scrollTo(0, 0);
|
|
1126
|
+
});
|
|
1109
1127
|
}
|
|
1128
|
+
// Initial adjustment
|
|
1129
|
+
handleViewportResize();
|
|
1110
1130
|
connect();
|
|
1111
1131
|
applyTheme(currentTheme);
|
|
1112
1132
|
}
|