Fix terminal status and content scrolling
This commit is contained in:
@@ -138,6 +138,7 @@ public final class MainActivity extends Activity {
|
|||||||
private LinearLayout projectList;
|
private LinearLayout projectList;
|
||||||
private LinearLayout sessionGroupList;
|
private LinearLayout sessionGroupList;
|
||||||
private TextView terminalText;
|
private TextView terminalText;
|
||||||
|
private TextView terminalStatusLineText;
|
||||||
private TextView terminalMetaText;
|
private TextView terminalMetaText;
|
||||||
private TextView terminalConnectionText;
|
private TextView terminalConnectionText;
|
||||||
private ScrollView terminalScroll;
|
private ScrollView terminalScroll;
|
||||||
@@ -167,8 +168,6 @@ public final class MainActivity extends Activity {
|
|||||||
private final Set<String> serverCountFailures = new HashSet<>();
|
private final Set<String> serverCountFailures = new HashSet<>();
|
||||||
private TerminalScreenBuffer terminalScreen = new TerminalScreenBuffer(DEFAULT_TERMINAL_COLS, DEFAULT_TERMINAL_ROWS);
|
private TerminalScreenBuffer terminalScreen = new TerminalScreenBuffer(DEFAULT_TERMINAL_COLS, DEFAULT_TERMINAL_ROWS);
|
||||||
private final StringBuilder queuedTerminalInput = new StringBuilder();
|
private final StringBuilder queuedTerminalInput = new StringBuilder();
|
||||||
private final Set<String> terminalExpandedBlocks = new HashSet<>();
|
|
||||||
private final Set<String> terminalExpandedMessages = new HashSet<>();
|
|
||||||
private final List<ConversationMessage> terminalConversationMessages = new ArrayList<>();
|
private final List<ConversationMessage> terminalConversationMessages = new ArrayList<>();
|
||||||
private boolean terminalConnected;
|
private boolean terminalConnected;
|
||||||
private boolean terminalConnecting;
|
private boolean terminalConnecting;
|
||||||
@@ -1861,8 +1860,6 @@ public final class MainActivity extends Activity {
|
|||||||
terminalFollowOutput = true;
|
terminalFollowOutput = true;
|
||||||
terminalKeyPage = 0;
|
terminalKeyPage = 0;
|
||||||
terminalHistoryOffset = 0;
|
terminalHistoryOffset = 0;
|
||||||
terminalExpandedBlocks.clear();
|
|
||||||
terminalExpandedMessages.clear();
|
|
||||||
terminalConversationMessages.clear();
|
terminalConversationMessages.clear();
|
||||||
terminalLiveStatusText = null;
|
terminalLiveStatusText = null;
|
||||||
terminalLiveOutputText = null;
|
terminalLiveOutputText = null;
|
||||||
@@ -1913,6 +1910,20 @@ public final class MainActivity extends Activity {
|
|||||||
0,
|
0,
|
||||||
1
|
1
|
||||||
));
|
));
|
||||||
|
terminalStatusLineText = new TextView(this);
|
||||||
|
terminalStatusLineText.setTextColor(COLOR_TEXT);
|
||||||
|
terminalStatusLineText.setTextSize(terminalFontSizeSp);
|
||||||
|
terminalStatusLineText.setTypeface(terminalTypeface());
|
||||||
|
terminalStatusLineText.setIncludeFontPadding(false);
|
||||||
|
terminalStatusLineText.setSingleLine(true);
|
||||||
|
terminalStatusLineText.setGravity(Gravity.CENTER_VERTICAL | Gravity.START);
|
||||||
|
terminalStatusLineText.setHorizontallyScrolling(true);
|
||||||
|
terminalStatusLineText.setPadding(dp(2), 0, dp(2), 0);
|
||||||
|
terminalStatusLineText.setBackgroundColor(terminalBackgroundColor());
|
||||||
|
root.addView(terminalStatusLineText, new LinearLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
dp(22)
|
||||||
|
));
|
||||||
terminalAccessoryBar = createAccessoryBar();
|
terminalAccessoryBar = createAccessoryBar();
|
||||||
root.addView(terminalAccessoryBar, new LinearLayout.LayoutParams(
|
root.addView(terminalAccessoryBar, new LinearLayout.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
@@ -2252,28 +2263,16 @@ public final class MainActivity extends Activity {
|
|||||||
private View conversationToolGroup(List<ConversationMessage> tools) {
|
private View conversationToolGroup(List<ConversationMessage> tools) {
|
||||||
LinearLayout group = new LinearLayout(this);
|
LinearLayout group = new LinearLayout(this);
|
||||||
group.setOrientation(LinearLayout.VERTICAL);
|
group.setOrientation(LinearLayout.VERTICAL);
|
||||||
String firstId = tools.isEmpty() ? "empty" : tools.get(0).messageId;
|
|
||||||
String lastId = tools.isEmpty() ? "empty" : tools.get(tools.size() - 1).messageId;
|
|
||||||
String groupKey = "tools:" + firstId + ":" + lastId;
|
|
||||||
boolean expanded = terminalExpandedMessages.contains(groupKey);
|
|
||||||
String firstTitle = tools.isEmpty() ? "Tool activity" : conversationToolTitle(tools.get(0));
|
String firstTitle = tools.isEmpty() ? "Tool activity" : conversationToolTitle(tools.get(0));
|
||||||
TextView summary = new TextView(this);
|
TextView summary = new TextView(this);
|
||||||
summary.setText((expanded ? "▼ " : "▶ ") + tools.size() + " tool "
|
summary.setText(tools.size() + " tool "
|
||||||
+ (tools.size() == 1 ? "activity" : "activities") + " · " + compactLabel(firstTitle, 44));
|
+ (tools.size() == 1 ? "activity" : "activities") + " · " + compactLabel(firstTitle, 44));
|
||||||
summary.setTextColor(COLOR_ACCENT_WARM);
|
summary.setTextColor(COLOR_ACCENT_WARM);
|
||||||
summary.setTextSize(10);
|
summary.setTextSize(10);
|
||||||
summary.setTypeface(Typeface.MONOSPACE, Typeface.BOLD);
|
summary.setTypeface(Typeface.MONOSPACE, Typeface.BOLD);
|
||||||
summary.setPadding(dp(10), dp(6), dp(10), dp(6));
|
summary.setPadding(dp(10), dp(6), dp(10), dp(6));
|
||||||
summary.setOnClickListener(view -> {
|
|
||||||
if (!terminalExpandedMessages.add(groupKey)) {
|
|
||||||
terminalExpandedMessages.remove(groupKey);
|
|
||||||
}
|
|
||||||
renderTerminalConversation();
|
|
||||||
});
|
|
||||||
summary.setContentDescription((expanded ? "Collapse " : "Expand ") + tools.size() + " tool activities");
|
|
||||||
group.addView(summary, matchWrap());
|
group.addView(summary, matchWrap());
|
||||||
|
|
||||||
if (expanded) {
|
|
||||||
for (ConversationMessage message : tools) {
|
for (ConversationMessage message : tools) {
|
||||||
LinearLayout detail = new LinearLayout(this);
|
LinearLayout detail = new LinearLayout(this);
|
||||||
detail.setOrientation(LinearLayout.VERTICAL);
|
detail.setOrientation(LinearLayout.VERTICAL);
|
||||||
@@ -2286,7 +2285,6 @@ public final class MainActivity extends Activity {
|
|||||||
detail.addView(conversationContent(message, true), matchWrap());
|
detail.addView(conversationContent(message, true), matchWrap());
|
||||||
group.addView(detail, matchWrap());
|
group.addView(detail, matchWrap());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
@@ -2379,14 +2377,8 @@ public final class MainActivity extends Activity {
|
|||||||
: connected ? "● live" : "● " + defaultValue(socket, "connecting"));
|
: connected ? "● live" : "● " + defaultValue(socket, "connecting"));
|
||||||
terminalLiveStatusText.setTextColor(terminalHistoryOffset > 0 ? COLOR_ACCENT_WARM : connected ? COLOR_SUCCESS
|
terminalLiveStatusText.setTextColor(terminalHistoryOffset > 0 ? COLOR_ACCENT_WARM : connected ? COLOR_SUCCESS
|
||||||
: socket.contains("error") || socket.contains("disconnected") ? COLOR_DANGER : COLOR_ACCENT_WARM);
|
: socket.contains("error") || socket.contains("disconnected") ? COLOR_DANGER : COLOR_ACCENT_WARM);
|
||||||
terminalLiveOutputText.setMovementMethod(LinkMovementMethod.getInstance());
|
terminalLiveOutputText.setMovementMethod(null);
|
||||||
terminalLiveOutputText.setHighlightColor(Color.TRANSPARENT);
|
terminalLiveOutputText.setText(terminalScreen.renderBody());
|
||||||
terminalLiveOutputText.setText(terminalScreen.renderFocused(terminalExpandedBlocks, key -> {
|
|
||||||
if (!terminalExpandedBlocks.add(key)) {
|
|
||||||
terminalExpandedBlocks.remove(key);
|
|
||||||
}
|
|
||||||
renderTerminalNow();
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTerminalMeta() {
|
private void updateTerminalMeta() {
|
||||||
@@ -2608,9 +2600,7 @@ public final class MainActivity extends Activity {
|
|||||||
|
|
||||||
private void clearTerminalHistory() {
|
private void clearTerminalHistory() {
|
||||||
terminalScreen.clear();
|
terminalScreen.clear();
|
||||||
if (terminalText != null) {
|
renderTerminalNow();
|
||||||
terminalText.setText("");
|
|
||||||
}
|
|
||||||
if (terminalSocket != null) {
|
if (terminalSocket != null) {
|
||||||
terminalSocket.clearHistory();
|
terminalSocket.clearHistory();
|
||||||
}
|
}
|
||||||
@@ -3060,6 +3050,11 @@ public final class MainActivity extends Activity {
|
|||||||
terminalLiveOutputText.setLineSpacing(0, terminalLineHeight);
|
terminalLiveOutputText.setLineSpacing(0, terminalLineHeight);
|
||||||
terminalLiveOutputText.setBackgroundColor(terminalBackgroundColor());
|
terminalLiveOutputText.setBackgroundColor(terminalBackgroundColor());
|
||||||
}
|
}
|
||||||
|
if (terminalStatusLineText != null) {
|
||||||
|
terminalStatusLineText.setTextSize(terminalFontSizeSp);
|
||||||
|
terminalStatusLineText.setTypeface(typeface);
|
||||||
|
terminalStatusLineText.setBackgroundColor(terminalBackgroundColor());
|
||||||
|
}
|
||||||
if (terminalScroll != null) {
|
if (terminalScroll != null) {
|
||||||
terminalScroll.setBackgroundColor(terminalBackgroundColor());
|
terminalScroll.setBackgroundColor(terminalBackgroundColor());
|
||||||
}
|
}
|
||||||
@@ -4236,18 +4231,10 @@ public final class MainActivity extends Activity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lastTerminalRenderMs = System.currentTimeMillis();
|
lastTerminalRenderMs = System.currentTimeMillis();
|
||||||
if (terminalViewMode == TERMINAL_VIEW_CHAT) {
|
|
||||||
terminalText.setMovementMethod(LinkMovementMethod.getInstance());
|
|
||||||
terminalText.setHighlightColor(Color.TRANSPARENT);
|
|
||||||
terminalText.setText(terminalScreen.renderFocused(terminalExpandedBlocks, key -> {
|
|
||||||
if (!terminalExpandedBlocks.add(key)) {
|
|
||||||
terminalExpandedBlocks.remove(key);
|
|
||||||
}
|
|
||||||
renderTerminalNow();
|
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
terminalText.setMovementMethod(null);
|
terminalText.setMovementMethod(null);
|
||||||
terminalText.setText(terminalScreen.render());
|
terminalText.setText(terminalScreen.renderBody());
|
||||||
|
if (terminalStatusLineText != null) {
|
||||||
|
terminalStatusLineText.setText(terminalScreen.renderStatusLine());
|
||||||
}
|
}
|
||||||
updateTerminalLivePanel();
|
updateTerminalLivePanel();
|
||||||
if (terminalFollowOutput) {
|
if (terminalFollowOutput) {
|
||||||
|
|||||||
@@ -120,10 +120,22 @@ final class TerminalScreenBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CharSequence render() {
|
CharSequence render() {
|
||||||
|
return renderRows(0, rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
CharSequence renderBody() {
|
||||||
|
return renderRows(0, Math.max(0, rows - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
CharSequence renderStatusLine() {
|
||||||
|
return renderRows(Math.max(0, rows - 1), rows);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CharSequence renderRows(int startRow, int endRow) {
|
||||||
SpannableStringBuilder output = new SpannableStringBuilder();
|
SpannableStringBuilder output = new SpannableStringBuilder();
|
||||||
for (int row = 0; row < rows; row++) {
|
for (int row = startRow; row < endRow; row++) {
|
||||||
appendRow(output, row);
|
appendRow(output, row);
|
||||||
if (row + 1 < rows) {
|
if (row + 1 < endRow) {
|
||||||
output.append('\n');
|
output.append('\n');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user