@mjasano/devtunnel 1.4.0 → 1.5.0
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/.claude/settings.local.json +2 -1
- package/CHANGELOG.md +13 -0
- package/package.json +1 -1
- package/public/app.js +10 -0
- package/public/index.html +3 -0
- package/public/login.html +32 -0
- package/public/styles.css +359 -4
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.5.0] - 2026-01-02
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Mobile-responsive UI with touch-friendly design
|
|
12
|
+
- Sidebar close button for mobile devices
|
|
13
|
+
- Full-width sidebar on small screens (480px and below)
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Improved touch targets (minimum 44px for buttons/tabs)
|
|
17
|
+
- Dynamic terminal height using flex layout
|
|
18
|
+
- Input font-size set to 16px to prevent iOS auto-zoom
|
|
19
|
+
- Smoother sidebar slide animation with overlay
|
|
20
|
+
|
|
8
21
|
## [1.4.0] - 2026-01-02
|
|
9
22
|
|
|
10
23
|
### Added
|
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -712,6 +712,16 @@ function toggleSection(section) {
|
|
|
712
712
|
content.style.display = content.style.display === 'none' ? 'block' : 'none';
|
|
713
713
|
}
|
|
714
714
|
|
|
715
|
+
// Mobile sidebar toggle
|
|
716
|
+
function toggleMobileSidebar() {
|
|
717
|
+
const sidebar = document.querySelector('.sidebar');
|
|
718
|
+
const overlay = document.getElementById('sidebar-overlay');
|
|
719
|
+
sidebar.classList.toggle('open');
|
|
720
|
+
overlay.classList.toggle('show');
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
window.toggleMobileSidebar = toggleMobileSidebar;
|
|
724
|
+
|
|
715
725
|
window.copyUrl = copyUrl;
|
|
716
726
|
window.stopTunnel = stopTunnel;
|
|
717
727
|
window.createNewSession = createNewSession;
|
package/public/index.html
CHANGED
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
<span id="status-text">Connecting...</span>
|
|
28
28
|
</div>
|
|
29
29
|
<button class="btn-logout" id="logout-btn" style="display: none;" onclick="logout()">Logout</button>
|
|
30
|
+
<button class="mobile-sidebar-toggle" id="sidebar-toggle" onclick="toggleMobileSidebar()">☰</button>
|
|
30
31
|
</div>
|
|
31
32
|
</div>
|
|
32
33
|
|
|
@@ -42,6 +43,7 @@
|
|
|
42
43
|
</div>
|
|
43
44
|
</div>
|
|
44
45
|
|
|
46
|
+
<div class="sidebar-overlay" id="sidebar-overlay" onclick="toggleMobileSidebar()"></div>
|
|
45
47
|
<div class="main-container">
|
|
46
48
|
<div id="terminal-container">
|
|
47
49
|
<div class="terminal-tabs" id="terminal-tabs">
|
|
@@ -63,6 +65,7 @@
|
|
|
63
65
|
</div>
|
|
64
66
|
|
|
65
67
|
<div class="sidebar">
|
|
68
|
+
<button class="sidebar-close" onclick="toggleMobileSidebar()">×</button>
|
|
66
69
|
<!-- Files Section -->
|
|
67
70
|
<div class="sidebar-section">
|
|
68
71
|
<div class="sidebar-header" onclick="toggleSection('files')">
|
package/public/login.html
CHANGED
|
@@ -141,6 +141,38 @@
|
|
|
141
141
|
@keyframes spin {
|
|
142
142
|
to { transform: rotate(360deg); }
|
|
143
143
|
}
|
|
144
|
+
|
|
145
|
+
@media (max-width: 480px) {
|
|
146
|
+
.login-container {
|
|
147
|
+
margin: 16px;
|
|
148
|
+
padding: 24px;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.logo {
|
|
152
|
+
width: 48px;
|
|
153
|
+
height: 48px;
|
|
154
|
+
margin-bottom: 16px;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
h1 {
|
|
158
|
+
font-size: 20px;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.subtitle {
|
|
162
|
+
font-size: 13px;
|
|
163
|
+
margin-bottom: 24px;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.form-group input {
|
|
167
|
+
padding: 14px 12px;
|
|
168
|
+
font-size: 18px;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.btn {
|
|
172
|
+
padding: 14px 24px;
|
|
173
|
+
font-size: 16px;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
144
176
|
</style>
|
|
145
177
|
</head>
|
|
146
178
|
<body>
|
package/public/styles.css
CHANGED
|
@@ -143,6 +143,7 @@ body {
|
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
.sidebar {
|
|
146
|
+
position: relative;
|
|
146
147
|
width: 320px;
|
|
147
148
|
background-color: #161b22;
|
|
148
149
|
border-left: 1px solid #30363d;
|
|
@@ -839,19 +840,373 @@ body {
|
|
|
839
840
|
}
|
|
840
841
|
}
|
|
841
842
|
|
|
843
|
+
/* Mobile Toggle Button */
|
|
844
|
+
.mobile-sidebar-toggle {
|
|
845
|
+
display: none;
|
|
846
|
+
width: 44px;
|
|
847
|
+
height: 44px;
|
|
848
|
+
background-color: #21262d;
|
|
849
|
+
border: 1px solid #30363d;
|
|
850
|
+
border-radius: 6px;
|
|
851
|
+
color: #8b949e;
|
|
852
|
+
font-size: 20px;
|
|
853
|
+
cursor: pointer;
|
|
854
|
+
align-items: center;
|
|
855
|
+
justify-content: center;
|
|
856
|
+
-webkit-tap-highlight-color: transparent;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
.mobile-sidebar-toggle:hover,
|
|
860
|
+
.mobile-sidebar-toggle:active {
|
|
861
|
+
background-color: #30363d;
|
|
862
|
+
color: #c9d1d9;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
/* Mobile Sidebar Close */
|
|
866
|
+
.sidebar-close {
|
|
867
|
+
display: none;
|
|
868
|
+
position: absolute;
|
|
869
|
+
top: 12px;
|
|
870
|
+
right: 12px;
|
|
871
|
+
width: 32px;
|
|
872
|
+
height: 32px;
|
|
873
|
+
background-color: transparent;
|
|
874
|
+
border: none;
|
|
875
|
+
border-radius: 6px;
|
|
876
|
+
color: #8b949e;
|
|
877
|
+
font-size: 20px;
|
|
878
|
+
cursor: pointer;
|
|
879
|
+
align-items: center;
|
|
880
|
+
justify-content: center;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
.sidebar-close:hover {
|
|
884
|
+
background-color: #21262d;
|
|
885
|
+
color: #c9d1d9;
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
/* Mobile Styles */
|
|
842
889
|
@media (max-width: 768px) {
|
|
890
|
+
.header {
|
|
891
|
+
padding: 10px 12px;
|
|
892
|
+
min-height: 56px;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
.header h1 {
|
|
896
|
+
font-size: 16px;
|
|
897
|
+
gap: 8px;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
.header h1 .logo {
|
|
901
|
+
width: 24px;
|
|
902
|
+
height: 24px;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
.header-right {
|
|
906
|
+
gap: 10px;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
.system-info {
|
|
910
|
+
display: none;
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
.session-indicator {
|
|
914
|
+
display: none !important;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
.status {
|
|
918
|
+
gap: 6px;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
.status span {
|
|
922
|
+
display: none;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
.status-dot {
|
|
926
|
+
width: 10px;
|
|
927
|
+
height: 10px;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
.btn-logout {
|
|
931
|
+
padding: 8px 12px;
|
|
932
|
+
font-size: 12px;
|
|
933
|
+
min-height: 36px;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
.mobile-sidebar-toggle {
|
|
937
|
+
display: flex;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
.tab-bar {
|
|
941
|
+
padding: 0;
|
|
942
|
+
overflow-x: auto;
|
|
943
|
+
-webkit-overflow-scrolling: touch;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
.tab {
|
|
947
|
+
flex: 1;
|
|
948
|
+
padding: 12px 16px;
|
|
949
|
+
font-size: 13px;
|
|
950
|
+
justify-content: center;
|
|
951
|
+
min-height: 44px;
|
|
952
|
+
}
|
|
953
|
+
|
|
843
954
|
.main-container {
|
|
844
955
|
flex-direction: column;
|
|
956
|
+
position: relative;
|
|
957
|
+
flex: 1;
|
|
958
|
+
overflow: hidden;
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
#terminal-container {
|
|
962
|
+
padding: 4px;
|
|
963
|
+
flex: 1;
|
|
964
|
+
display: flex;
|
|
965
|
+
flex-direction: column;
|
|
966
|
+
overflow: hidden;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
#terminal-container #terminal {
|
|
970
|
+
flex: 1;
|
|
971
|
+
min-height: 0;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
#editor-container {
|
|
975
|
+
flex: 1;
|
|
976
|
+
overflow: hidden;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
.terminal-tabs {
|
|
980
|
+
min-height: 40px;
|
|
981
|
+
flex-shrink: 0;
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
.terminal-tab {
|
|
985
|
+
padding: 10px 14px;
|
|
986
|
+
font-size: 12px;
|
|
987
|
+
min-height: 40px;
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
.terminal-tab-new {
|
|
991
|
+
width: 36px;
|
|
992
|
+
height: 36px;
|
|
993
|
+
font-size: 18px;
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
.terminal-tab-close {
|
|
997
|
+
width: 20px;
|
|
998
|
+
height: 20px;
|
|
999
|
+
font-size: 16px;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
.editor-tabs {
|
|
1003
|
+
min-height: 40px;
|
|
1004
|
+
overflow-x: auto;
|
|
1005
|
+
-webkit-overflow-scrolling: touch;
|
|
1006
|
+
flex-shrink: 0;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
.editor-tab {
|
|
1010
|
+
padding: 10px 14px;
|
|
1011
|
+
font-size: 12px;
|
|
1012
|
+
min-height: 40px;
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
.editor-tab-close {
|
|
1016
|
+
width: 20px;
|
|
1017
|
+
height: 20px;
|
|
1018
|
+
font-size: 16px;
|
|
845
1019
|
}
|
|
846
1020
|
|
|
1021
|
+
/* Sidebar as overlay on mobile */
|
|
847
1022
|
.sidebar {
|
|
1023
|
+
position: fixed;
|
|
1024
|
+
top: 0;
|
|
1025
|
+
right: -100%;
|
|
1026
|
+
width: 85%;
|
|
1027
|
+
max-width: 320px;
|
|
1028
|
+
height: 100%;
|
|
1029
|
+
height: 100dvh;
|
|
1030
|
+
border-left: 1px solid #30363d;
|
|
1031
|
+
transition: right 0.25s ease-out;
|
|
1032
|
+
z-index: 100;
|
|
1033
|
+
overflow-y: auto;
|
|
1034
|
+
-webkit-overflow-scrolling: touch;
|
|
1035
|
+
padding-top: 50px;
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
.sidebar.open {
|
|
1039
|
+
right: 0;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
.sidebar-close {
|
|
1043
|
+
display: flex;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
.sidebar-overlay {
|
|
1047
|
+
display: none;
|
|
1048
|
+
position: fixed;
|
|
1049
|
+
top: 0;
|
|
1050
|
+
left: 0;
|
|
1051
|
+
right: 0;
|
|
1052
|
+
bottom: 0;
|
|
1053
|
+
background-color: rgba(0, 0, 0, 0.6);
|
|
1054
|
+
z-index: 99;
|
|
1055
|
+
opacity: 0;
|
|
1056
|
+
transition: opacity 0.25s ease-out;
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1059
|
+
.sidebar-overlay.show {
|
|
1060
|
+
display: block;
|
|
1061
|
+
opacity: 1;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
.sidebar-header {
|
|
1065
|
+
padding: 14px 16px;
|
|
1066
|
+
min-height: 48px;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
.sidebar-content {
|
|
1070
|
+
max-height: none;
|
|
1071
|
+
padding: 8px 12px;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
#files-content {
|
|
1075
|
+
max-height: 40vh !important;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
.tunnel-form {
|
|
1079
|
+
padding: 12px;
|
|
1080
|
+
flex-direction: column;
|
|
1081
|
+
gap: 10px;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
.tunnel-form input {
|
|
1085
|
+
width: 100%;
|
|
1086
|
+
padding: 12px;
|
|
1087
|
+
font-size: 16px;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
.tunnel-form .btn {
|
|
848
1091
|
width: 100%;
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
border-top: 1px solid #30363d;
|
|
1092
|
+
padding: 12px;
|
|
1093
|
+
min-height: 44px;
|
|
852
1094
|
}
|
|
853
1095
|
|
|
854
1096
|
.toast {
|
|
855
|
-
right:
|
|
1097
|
+
right: 12px;
|
|
1098
|
+
left: 12px;
|
|
1099
|
+
bottom: 12px;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
.reconnect-box {
|
|
1103
|
+
margin: 20px;
|
|
1104
|
+
padding: 24px;
|
|
1105
|
+
width: calc(100% - 40px);
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
.reconnect-btn {
|
|
1109
|
+
padding: 14px 24px;
|
|
1110
|
+
min-height: 48px;
|
|
1111
|
+
width: 100%;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
.breadcrumb {
|
|
1115
|
+
padding: 10px 12px;
|
|
1116
|
+
font-size: 12px;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
.breadcrumb-item {
|
|
1120
|
+
padding: 4px 8px;
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
.file-search {
|
|
1124
|
+
padding: 10px 12px;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
.file-search input {
|
|
1128
|
+
padding: 10px 12px;
|
|
1129
|
+
font-size: 16px;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
.file-item {
|
|
1133
|
+
padding: 10px 12px;
|
|
1134
|
+
min-height: 44px;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
.item-card {
|
|
1138
|
+
padding: 12px;
|
|
1139
|
+
}
|
|
1140
|
+
|
|
1141
|
+
.item-url {
|
|
1142
|
+
flex-direction: column;
|
|
1143
|
+
gap: 8px;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
.item-url input {
|
|
1147
|
+
width: 100%;
|
|
1148
|
+
padding: 10px;
|
|
1149
|
+
font-size: 13px;
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
.btn-copy {
|
|
1153
|
+
width: 100%;
|
|
1154
|
+
text-align: center;
|
|
1155
|
+
padding: 10px;
|
|
1156
|
+
min-height: 40px;
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
.context-menu {
|
|
1160
|
+
min-width: 160px;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
.context-menu-item {
|
|
1164
|
+
padding: 12px 16px;
|
|
1165
|
+
min-height: 44px;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
.modal {
|
|
1169
|
+
width: calc(100% - 32px);
|
|
1170
|
+
margin: 16px;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
.modal input {
|
|
1174
|
+
padding: 12px;
|
|
1175
|
+
font-size: 16px;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
.modal-actions .btn {
|
|
1179
|
+
padding: 10px 16px;
|
|
1180
|
+
min-height: 40px;
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
/* Small mobile */
|
|
1185
|
+
@media (max-width: 480px) {
|
|
1186
|
+
.header h1 span {
|
|
1187
|
+
display: none;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
.header h1 .logo {
|
|
1191
|
+
width: 28px;
|
|
1192
|
+
height: 28px;
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
.btn-logout {
|
|
1196
|
+
padding: 6px 10px;
|
|
1197
|
+
font-size: 11px;
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
.tab-icon {
|
|
1201
|
+
display: none;
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
.tab {
|
|
1205
|
+
font-size: 12px;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
.sidebar {
|
|
1209
|
+
width: 100%;
|
|
1210
|
+
max-width: none;
|
|
856
1211
|
}
|
|
857
1212
|
}
|