diff --git a/README.md b/README.md index a85e547..91a98b8 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ APIs directly: - open one live terminal viewer through `/ws/terminal` - native `/ws/events` listener for session invalidation and hook notifications - selectable GitHub or Gitea update manifest source -- native API action center for health, server status, timeline, preferences, +- native Tools page for health, server status, timeline, preferences, kanban projects, group messages, hook events, image file/URL upload, image preview info, and native image preview display - mobile soft-key row for tmux-oriented input, including tmux prefix, detach, @@ -177,10 +177,10 @@ In the app: - If Android sends you to the unknown-app install permission screen, return to the app after allowing it; the app continues installing the already downloaded APK without another update check or download. -- Open `More` -> `Open APK download` to download the current public APK in a +- Open the `Update` page and tap `APK` to download the current public APK in a browser. -- Open the `Update` page or `More` -> `Permissions / update status` to see the - installed version, selected update source, APK URL, install permission state, - and a `Check update` button. +- Open the `Update` page and tap `Details` to see the installed version, + selected update source, APK URL, install permission state, and a `Check + update` button. - Open the `About` page to see the app version, package name, API/protocol summary, and update policy. diff --git a/app/src/main/java/com/neatstudio/tmuxandroid/MainActivity.java b/app/src/main/java/com/neatstudio/tmuxandroid/MainActivity.java index 33a6c4c..0528724 100644 --- a/app/src/main/java/com/neatstudio/tmuxandroid/MainActivity.java +++ b/app/src/main/java/com/neatstudio/tmuxandroid/MainActivity.java @@ -228,7 +228,8 @@ public final class MainActivity extends Activity { content.addView(actionPanel( actionButton("Health", view -> showRaw("Health", () -> api.health())), actionButton("Probe Tailscale", view -> probeServerProfiles()), - actionButton("Status", view -> showRaw("Server status", () -> api.serverStatus())) + actionButton("Status", view -> showRaw("Server status", () -> api.serverStatus())), + actionButton("Preferences", view -> showRaw("Preferences", () -> api.preferences())) )); content.addView(sectionTitle("Sessions")); content.addView(actionPanel( @@ -240,9 +241,11 @@ public final class MainActivity extends Activity { content.addView(actionPanel( actionButton("Projects", view -> showRaw("Kanban projects", () -> api.kanbanProjects())), actionButton("New project", view -> promptCreateKanbanProject()), - actionButton("Messages", view -> promptGroupMessages()) + actionButton("Delete project", view -> promptDeleteKanbanProject()), + actionButton("Remove session", view -> promptRemoveKanbanSession()) )); content.addView(actionPanel( + actionButton("Messages", view -> promptGroupMessages()), actionButton("Send message", view -> promptSendGroupMessage()), actionButton("Scan message", view -> promptScanGroupMessage()), actionButton("Post hook", view -> promptPostHookEvent()) @@ -251,6 +254,7 @@ public final class MainActivity extends Activity { content.addView(actionPanel( actionButton("Upload file", view -> promptUploadImageFile()), actionButton("Upload URL", view -> promptUploadImageUrl()), + actionButton("Preview info", view -> promptImagePreviewInfo()), actionButton("Preview", view -> promptOpenImagePreview()) )); scroll.addView(content); @@ -398,16 +402,38 @@ public final class MainActivity extends Activity { actionRow.setOrientation(LinearLayout.HORIZONTAL); actionRow.setGravity(Gravity.CENTER_VERTICAL); actionRow.setPadding(0, dp(6), 0, 0); - actionRow.addView(toolbarButton("New", view -> promptCreateSession())); - actionRow.addView(toolbarButton("Refresh", view -> refreshSessions())); - actionRow.addView(toolbarButton("Update", view -> updateManager.check(true))); - actionRow.addView(toolbarButton("More", view -> showMainActions())); + addContextActions(actionRow); toolbar.addView(urlRow, matchWrap()); - toolbar.addView(actionRow, matchWrap()); + if (actionRow.getChildCount() > 0) { + toolbar.addView(actionRow, matchWrap()); + } return toolbar; } + private void addContextActions(LinearLayout actionRow) { + if (PAGE_SESSIONS.equals(activeMainPage)) { + actionRow.addView(toolbarButton("New", view -> promptCreateSession())); + actionRow.addView(toolbarButton("Refresh", view -> refreshSessions())); + actionRow.addView(toolbarButton("Probe", view -> probeServerProfiles())); + return; + } + if (PAGE_TOOLS.equals(activeMainPage)) { + actionRow.addView(toolbarButton("Health", view -> showRaw("Health", () -> api.health()))); + actionRow.addView(toolbarButton("Probe", view -> probeServerProfiles())); + return; + } + if (PAGE_UPDATE.equals(activeMainPage)) { + actionRow.addView(toolbarButton("Check now", view -> updateManager.check(true))); + actionRow.addView(toolbarButton("Source", view -> showUpdateSourcePicker())); + return; + } + if (PAGE_ABOUT.equals(activeMainPage)) { + actionRow.addView(toolbarButton("Release", view -> openExternalUrl(BuildConfig.DEFAULT_RELEASE_PAGE_URL))); + actionRow.addView(toolbarButton("Permissions", view -> showPermissionsAndUpdateStatus())); + } + } + private HorizontalScrollView createServerProfileBar() { HorizontalScrollView scroller = new HorizontalScrollView(this); scroller.setHorizontalScrollBarEnabled(false); @@ -750,112 +776,6 @@ public final class MainActivity extends Activity { return bar; } - private void showMainActions() { - String[] items = { - "Health", - "Probe Tailscale APIs", - "Server status", - "Timeline", - "Preferences", - "All session details", - "Pane details", - "Kanban projects", - "Create kanban project", - "Delete kanban project", - "Remove kanban session", - "Group messages", - "Send group message", - "Scan group message", - "Post hook event", - "Upload image file", - "Upload image URL", - "Image preview info", - "Open image preview", - "Open APK download", - "Update source", - "Permissions / update status", - "About" - }; - new AlertDialog.Builder(this) - .setTitle("Native API actions") - .setItems(items, (dialog, which) -> { - switch (which) { - case 0: - showRaw("Health", () -> api.health()); - break; - case 1: - probeServerProfiles(); - break; - case 2: - showRaw("Server status", () -> api.serverStatus()); - break; - case 3: - showRaw("Timeline", () -> api.timeline(50)); - break; - case 4: - showRaw("Preferences", () -> api.preferences()); - break; - case 5: - showRaw("All session details", () -> api.sessionsAll()); - break; - case 6: - showRaw("Pane details", () -> api.sessionsPanes()); - break; - case 7: - showRaw("Kanban projects", () -> api.kanbanProjects()); - break; - case 8: - promptCreateKanbanProject(); - break; - case 9: - promptDeleteKanbanProject(); - break; - case 10: - promptRemoveKanbanSession(); - break; - case 11: - promptGroupMessages(); - break; - case 12: - promptSendGroupMessage(); - break; - case 13: - promptScanGroupMessage(); - break; - case 14: - promptPostHookEvent(); - break; - case 15: - promptUploadImageFile(); - break; - case 16: - promptUploadImageUrl(); - break; - case 17: - promptImagePreviewInfo(); - break; - case 18: - promptOpenImagePreview(); - break; - case 19: - openExternalUrl(BuildConfig.DEFAULT_APK_URL); - break; - case 20: - showUpdateSourcePicker(); - break; - case 21: - showPermissionsAndUpdateStatus(); - break; - case 22: - renderAboutScreen(); - break; - default: - break; - } - }) - .show(); - } - private void showSessionActions(String sessionName) { String[] items = { "Status", diff --git a/docs/android-client-notes.md b/docs/android-client-notes.md index 3190bf4..7c89cd4 100644 --- a/docs/android-client-notes.md +++ b/docs/android-client-notes.md @@ -79,7 +79,7 @@ Implemented now: - bottom shortcut bar for `Esc`, `Tab`, `Ctrl+C`, `Ctrl+V`, arrows, page keys, tmux prefix actions, and paste - shortcut delivery through the terminal WebSocket `input` message -- native action center for health, server status, timeline, preferences, kanban +- native Tools page for health, server status, timeline, preferences, kanban projects, group messages, hook events, image file/URL upload, image preview metadata, and native image preview display - GitHub Actions APK build