Add sessions page status panel
Some checks failed
Gitea Android APK / build (push) Failing after 0s
Gitea Smoke / smoke (push) Successful in 0s

This commit is contained in:
Codex 2026-07-06 13:12:01 +00:00
parent 1585d9ee07
commit c683f135e3
2 changed files with 36 additions and 3 deletions

View File

@ -12,6 +12,7 @@ APIs directly:
- one-tap probe for the preset Tailscale APIs, showing health/version and
session counts
- native tmux session list
- Sessions page with current API/server and loaded session count
- create, rename, send command, split pane, select pane, kill pane, pin, mute,
and kill session through HTTP API
- open one live terminal viewer through `/ws/terminal`

View File

@ -81,6 +81,7 @@ public final class MainActivity extends Activity {
private EditText urlField;
private ProgressBar progressBar;
private TextView statusText;
private TextView sessionSummaryText;
private TextView terminalText;
private ScrollView terminalScroll;
private EditText inputField;
@ -190,11 +191,14 @@ public final class MainActivity extends Activity {
));
ScrollView scroll = new ScrollView(this);
LinearLayout content = pageContent();
content.addView(sessionSummaryBlock());
content.addView(sectionTitle("Tmux sessions"));
LinearLayout list = new LinearLayout(this);
list.setOrientation(LinearLayout.VERTICAL);
list.setPadding(dp(8), dp(8), dp(8), dp(8));
list.setTag("session-list");
scroll.addView(list);
content.addView(list);
scroll.addView(content);
root.addView(scroll, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
0,
@ -206,6 +210,15 @@ public final class MainActivity extends Activity {
));
}
private View sessionSummaryBlock() {
View block = infoBlock(
"Active API",
"Server: " + getServerUrl() + "\nSessions: loading"
);
sessionSummaryText = findBodyText(block);
return block;
}
private void renderToolsScreen() {
closeTerminalSocket();
activeSessionName = null;
@ -547,6 +560,17 @@ public final class MainActivity extends Activity {
return block;
}
private TextView findBodyText(View block) {
if (!(block instanceof LinearLayout)) {
return null;
}
LinearLayout layout = (LinearLayout) block;
if (layout.getChildCount() < 2 || !(layout.getChildAt(1) instanceof TextView)) {
return null;
}
return (TextView) layout.getChildAt(1);
}
private LinearLayout actionPanel(Button... buttons) {
LinearLayout panel = new LinearLayout(this);
panel.setOrientation(LinearLayout.VERTICAL);
@ -602,7 +626,12 @@ public final class MainActivity extends Activity {
List<SessionSummary> sessions = api.getSessions();
runOnUiThread(() -> renderSessionList(sessions));
} catch (Exception error) {
runOnUiThread(() -> showMessage("Session load failed: " + error.getMessage()));
runOnUiThread(() -> {
if (sessionSummaryText != null) {
sessionSummaryText.setText("Server: " + getServerUrl() + "\nSessions: failed - " + error.getMessage());
}
showMessage("Session load failed: " + error.getMessage());
});
} finally {
runOnUiThread(() -> progressBar.setVisibility(View.GONE));
}
@ -623,6 +652,9 @@ public final class MainActivity extends Activity {
for (SessionSummary session : sessions) {
list.addView(sessionRow(session), matchWrap());
}
if (sessionSummaryText != null) {
sessionSummaryText.setText("Server: " + getServerUrl() + "\nSessions: " + sessions.size());
}
setStatus("Loaded " + sessions.size() + " sessions");
}