personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'hopper-vc6iumln-chat-bar-response-above'

Refined chat bar response panel: CSS class toggle transition
instead of display:none, smooth max-height expansion, separator
element, and repositioned dismiss button with updated styling.

Conflicts resolved by taking the feature branch versions of
convey/static/app.css and convey/templates/app.html, as the
feature branch is the refined iteration of the same work that
was partially landed in 50532ca5.

+65 -45
+34 -20
convey/static/app.css
··· 995 995 transform: translateX(-50%); 996 996 width: 80%; 997 997 z-index: var(--z-bars); 998 - display: flex; 999 998 min-height: var(--app-bar-height); 999 + padding: 0; 1000 + display: flex; 1000 1001 flex-direction: column; 1001 - align-items: center; 1002 1002 border-radius: 12px; 1003 1003 border: 1px solid var(--facet-border, #e0e0e0); 1004 1004 box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12); ··· 1031 1031 border-radius: 12px; 1032 1032 } 1033 1033 1034 - .chat-bar-input-row { 1035 - display: flex; 1036 - flex-direction: row; 1037 - align-items: center; 1038 - gap: 12px; 1039 - width: 100%; 1034 + /* Response panel (above input row) */ 1035 + .chat-bar-response-panel { 1036 + max-height: 0; 1037 + overflow: hidden; 1040 1038 padding: 0 16px; 1041 - min-height: var(--app-bar-height); 1039 + position: relative; 1040 + z-index: 1; 1041 + transition: max-height 0.2s ease, padding 0.2s ease; 1042 1042 } 1043 1043 1044 - .chat-bar-response-panel { 1045 - position: relative; 1046 - padding: 12px 16px; 1047 - padding-right: 36px; 1048 - border-bottom: 1px solid var(--facet-border, #e0e0e0); 1049 - width: 100%; 1044 + .chat-bar-response-panel.chat-bar-panel-open { 1045 + max-height: 200px; 1046 + padding: 12px 16px 0; 1047 + } 1048 + 1049 + .chat-bar-separator { 1050 + height: 1px; 1051 + background: var(--facet-border, #e0e0e0); 1052 + margin: 12px -16px 0; 1050 1053 } 1051 1054 1052 1055 .chat-bar-dismiss { ··· 1060 1063 color: #999; 1061 1064 font-size: 14px; 1062 1065 cursor: pointer; 1066 + border-radius: 4px; 1063 1067 display: flex; 1064 1068 align-items: center; 1065 1069 justify-content: center; 1066 - border-radius: 50%; 1067 - z-index: 1; 1070 + z-index: 2; 1068 1071 } 1069 1072 1070 1073 .chat-bar-dismiss:hover { 1071 - background: rgba(0, 0, 0, 0.05); 1074 + background: rgba(0, 0, 0, 0.06); 1072 1075 color: #666; 1076 + } 1077 + 1078 + /* Input row */ 1079 + .chat-bar-input-row { 1080 + display: flex; 1081 + flex-direction: row; 1082 + align-items: center; 1083 + gap: 12px; 1084 + padding: 0 16px; 1085 + min-height: var(--app-bar-height); 1073 1086 } 1074 1087 1075 1088 /* Chat Bar Elements */ ··· 1144 1157 1145 1158 .chat-bar-response { 1146 1159 font-size: 13px; 1160 + line-height: 1.5; 1147 1161 color: #666; 1162 + max-height: 5em; 1148 1163 overflow: hidden; 1149 - max-height: 5em; 1150 - line-height: 1.4; 1164 + padding-right: 28px; 1151 1165 position: relative; 1152 1166 z-index: 1; 1153 1167 }
+31 -25
convey/templates/app.html
··· 68 68 69 69 <!-- Chat Bar (universal) --> 70 70 <div class="app-bar"> 71 - <div class="chat-bar-response-panel" style="display: none;"> 71 + <div class="chat-bar-response-panel"> 72 72 <div class="chat-bar-thinking" style="display: none;"> 73 73 <span class="chat-bar-thinking-dot"></span> 74 74 Thinking… 75 75 </div> 76 76 <div class="chat-bar-response" style="display: none;"></div> 77 77 <button class="chat-bar-dismiss" style="display: none;" title="Dismiss">✕</button> 78 + <div class="chat-bar-separator"></div> 78 79 </div> 79 80 <div class="chat-bar-input-row"> 80 81 <form id="chatInputForm" style="display: contents;"> ··· 104 105 const isChatApp = window.location.pathname.startsWith('/app/chat'); 105 106 const STORAGE_KEY = 'solstone:chatBarState'; 106 107 107 - if (!chatBarInput || !chatBarForm) return; 108 - 109 - // --- Panel visibility helpers --- 110 108 function showPanel() { 111 - if (chatBarPanel) chatBarPanel.style.display = ''; 109 + if (chatBarPanel) chatBarPanel.classList.add('chat-bar-panel-open'); 112 110 } 113 111 function hidePanel() { 114 - if (chatBarPanel) chatBarPanel.style.display = 'none'; 115 - if (chatBarThinking) chatBarThinking.style.display = 'none'; 116 - if (chatBarResponse) chatBarResponse.style.display = 'none'; 117 - if (chatBarDismiss) chatBarDismiss.style.display = 'none'; 112 + if (chatBarPanel) chatBarPanel.classList.remove('chat-bar-panel-open'); 118 113 } 119 114 120 - // --- Dismiss button --- 121 - if (chatBarDismiss) { 122 - chatBarDismiss.addEventListener('click', () => { 123 - hidePanel(); 124 - }); 125 - } 115 + if (!chatBarInput || !chatBarForm) return; 126 116 127 117 // --- Auto-resize textarea --- 128 118 chatBarInput.addEventListener('input', () => { ··· 152 142 } 153 143 } catch {} 154 144 145 + // --- Dismiss response panel --- 146 + if (chatBarDismiss) { 147 + chatBarDismiss.addEventListener('click', () => { 148 + hidePanel(); 149 + if (chatBarThinking) chatBarThinking.style.display = 'none'; 150 + if (chatBarResponse) chatBarResponse.style.display = 'none'; 151 + chatBarDismiss.style.display = 'none'; 152 + }); 153 + } 154 + 155 155 // --- Non-chat app: triage submit --- 156 156 if (!isChatApp) { 157 157 // Enter to submit, shift+enter for newline ··· 174 174 chatBarSend.style.display = 'none'; 175 175 } 176 176 chatBarInput.disabled = true; 177 - if (chatBarThinking) chatBarThinking.style.display = ''; 178 - if (chatBarResponse) chatBarResponse.style.display = 'none'; 179 - if (chatBarDismiss) chatBarDismiss.style.display = 'none'; 177 + if (chatBarThinking) { 178 + chatBarThinking.style.display = ''; 179 + } 180 + if (chatBarResponse) { 181 + chatBarResponse.style.display = 'none'; 182 + } 183 + if (chatBarDismiss) { 184 + chatBarDismiss.style.display = 'none'; 185 + } 180 186 showPanel(); 181 187 182 188 try { ··· 195 201 const data = await r.json(); 196 202 if (chatBarResponse) { 197 203 chatBarResponse.textContent = data.response || ''; 198 - if (data.response) { 199 - chatBarResponse.style.display = ''; 200 - if (chatBarDismiss) chatBarDismiss.style.display = ''; 201 - } else { 202 - chatBarResponse.style.display = 'none'; 203 - hidePanel(); 204 - } 204 + chatBarResponse.style.display = data.response ? '' : 'none'; 205 + } 206 + if (data.response && chatBarDismiss) { 207 + chatBarDismiss.style.display = ''; 208 + } 209 + if (!data.response) { 210 + hidePanel(); 205 211 } 206 212 207 213 // Save to localStorage