Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 12 additions & 82 deletions PolyPilot/Components/ExpandedSessionView.razor
Original file line number Diff line number Diff line change
Expand Up @@ -497,28 +497,9 @@
$"<span style=\"font-size:11px;color:#6c7086;background:rgba(255,255,255,0.05);padding:2px 8px;border-radius:3px;white-space:nowrap;margin-left:8px\">{EscapeHtml(s.Source)}</span></div>" +
desc + "</div>";
}));
var jsHtml = EscapeForJs(rows);
var headerHtml = EscapeForJs("<div style=\"padding:8px 14px;font-size:13px;color:#6c7086;border-bottom:1px solid #313244;font-weight:600\">Available Skills</div>");
await JS.InvokeVoidAsync("eval", $@"
(function(){{
var old = document.getElementById('skills-popup-overlay');
if(old) old.remove();
var trigger = document.querySelector('[data-trigger=""skills""]');
var rect = trigger ? trigger.getBoundingClientRect() : {{left:20,bottom:60}};
var ov = document.createElement('div');
ov.id = 'skills-popup-overlay';
ov.style.cssText = 'position:fixed;inset:0;z-index:9998;background:rgba(0,0,0,0.3)';
ov.onclick = function(){{ ov.remove(); }};
var popup = document.createElement('div');
var left = Math.max(8, Math.min(rect.left, window.innerWidth - 368));
var bottom = window.innerHeight - rect.top + 8;
popup.style.cssText = 'position:fixed;bottom:'+bottom+'px;left:'+left+'px;z-index:9999;background:#1e1e2e;border:1px solid #45475a;border-radius:10px;padding:6px 0;min-width:240px;max-width:360px;max-height:50vh;overflow-y:auto;box-shadow:0 -4px 20px rgba(0,0,0,0.5)';
popup.innerHTML = '{headerHtml}{jsHtml}';
popup.onclick = function(e){{ e.stopPropagation(); }};
ov.appendChild(popup);
document.body.appendChild(ov);
}})()
");
await JS.InvokeVoidAsync("showPopup", "[data-trigger=\"skills\"]",
"<div style=\"padding:8px 14px;font-size:13px;color:#6c7086;border-bottom:1px solid #313244;font-weight:600\">Available Skills</div>",
rows);
}

private async Task ShowAgentsPopup()
Expand All @@ -534,28 +515,9 @@
$"<span style=\"font-size:11px;color:#6c7086;background:rgba(255,255,255,0.05);padding:2px 8px;border-radius:3px;white-space:nowrap;margin-left:8px\">{EscapeHtml(a.Source)}</span></div>" +
desc + "</div>";
}));
var jsHtml = EscapeForJs(rows);
var headerHtml = EscapeForJs("<div style=\"padding:8px 14px;font-size:13px;color:#6c7086;border-bottom:1px solid #313244;font-weight:600\">Available Agents</div>");
await JS.InvokeVoidAsync("eval", $@"
(function(){{
var old = document.getElementById('skills-popup-overlay');
if(old) old.remove();
var trigger = document.querySelector('[data-trigger=""agents""]');
var rect = trigger ? trigger.getBoundingClientRect() : {{left:20,bottom:60}};
var ov = document.createElement('div');
ov.id = 'skills-popup-overlay';
ov.style.cssText = 'position:fixed;inset:0;z-index:9998;background:rgba(0,0,0,0.3)';
ov.onclick = function(){{ ov.remove(); }};
var popup = document.createElement('div');
var left = Math.max(8, Math.min(rect.left, window.innerWidth - 368));
var bottom = window.innerHeight - rect.top + 8;
popup.style.cssText = 'position:fixed;bottom:'+bottom+'px;left:'+left+'px;z-index:9999;background:#1e1e2e;border:1px solid #45475a;border-radius:10px;padding:6px 0;min-width:240px;max-width:360px;max-height:50vh;overflow-y:auto;box-shadow:0 -4px 20px rgba(0,0,0,0.5)';
popup.innerHTML = '{headerHtml}{jsHtml}';
popup.onclick = function(e){{ e.stopPropagation(); }};
ov.appendChild(popup);
document.body.appendChild(ov);
}})()
");
await JS.InvokeVoidAsync("showPopup", "[data-trigger=\"agents\"]",
"<div style=\"padding:8px 14px;font-size:13px;color:#6c7086;border-bottom:1px solid #313244;font-weight:600\">Available Agents</div>",
rows);
}

private async Task ShowPromptsPopup()
Expand All @@ -571,53 +533,21 @@
$"<span style=\"font-size:11px;color:#6c7086;background:rgba(255,255,255,0.05);padding:2px 8px;border-radius:3px;white-space:nowrap;margin-left:8px\">{EscapeHtml(p.SourceLabel)}</span></div>" +
desc + "</div>";
}));
var jsHtml = EscapeForJs(rows);
var headerHtml = EscapeForJs("<div style=\"padding:8px 14px;font-size:13px;color:#6c7086;border-bottom:1px solid #313244;font-weight:600\">Available Prompts (click to use)</div>");
await JS.InvokeVoidAsync("eval", $@"
(function(){{
var old = document.getElementById('skills-popup-overlay');
if(old) old.remove();
var trigger = document.querySelector('[data-trigger=""prompts""]');
var rect = trigger ? trigger.getBoundingClientRect() : {{left:20,bottom:60}};
var ov = document.createElement('div');
ov.id = 'skills-popup-overlay';
ov.style.cssText = 'position:fixed;inset:0;z-index:9998;background:rgba(0,0,0,0.3)';
ov.onclick = function(){{ ov.remove(); }};
var popup = document.createElement('div');
var left = Math.max(8, Math.min(rect.left, window.innerWidth - 368));
var bottom = window.innerHeight - rect.top + 8;
popup.style.cssText = 'position:fixed;bottom:'+bottom+'px;left:'+left+'px;z-index:9999;background:#1e1e2e;border:1px solid #45475a;border-radius:10px;padding:6px 0;min-width:240px;max-width:360px;max-height:50vh;overflow-y:auto;box-shadow:0 -4px 20px rgba(0,0,0,0.5)';
popup.innerHTML = '{headerHtml}{jsHtml}';
popup.onclick = function(e){{
var row = e.target.closest('.prompt-row');
if(row){{
var name = row.getAttribute('data-prompt');
ov.remove();
var inputEl = document.querySelector('[data-session=""{EscapeForJs(Session.Name)}""] textarea');
if(inputEl){{
inputEl.value = '/prompt use ' + name;
inputEl.dispatchEvent(new Event('input'));
}}
}}
}};
ov.appendChild(popup);
document.body.appendChild(ov);
}})()
");
await JS.InvokeVoidAsync("showPromptsPopup", "[data-trigger=\"prompts\"]",
"<div style=\"padding:8px 14px;font-size:13px;color:#6c7086;border-bottom:1px solid #313244;font-weight:600\">Available Prompts (click to use)</div>",
rows,
Session.Name);
}

private static string EscapeHtml(string s) =>
s.Replace("&", "&amp;").Replace("<", "&lt;").Replace(">", "&gt;").Replace("\"", "&quot;");

private async Task InsertReflectCommand()
{
var inputId = EscapeForJs("input-" + Session.Name.Replace(" ", "-"));
await JS.InvokeVoidAsync("eval", $"var el = document.getElementById('{inputId}'); if(el){{ el.value = '/reflect '; el.focus(); }}");
var inputId = "input-" + Session.Name.Replace(" ", "-");
await JS.InvokeVoidAsync("focusAndSetValue", inputId, "/reflect ");
}

private static string EscapeForJs(string s) =>
s.Replace("\\", "\\\\").Replace("'", "\\'").Replace("\n", " ").Replace("\r", "");

private static string TruncateDesc(string desc)
{
desc = desc.Trim();
Expand Down
27 changes: 3 additions & 24 deletions PolyPilot/Components/Layout/MainLayout.razor
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
UiTheme.SolarizedLight => "solarized-light",
_ => ""
};
await JS.InvokeVoidAsync("eval", $"document.documentElement.setAttribute('data-theme', '{dataTheme}')");
await JS.InvokeVoidAsync("setThemeAttribute", dataTheme);

// Load saved font size and navigate to last page
var uiState = CopilotService.LoadUiState();
Expand Down Expand Up @@ -83,33 +83,12 @@

private async Task ApplyFontSize()
{
await JS.InvokeVoidAsync("eval", $"document.documentElement.style.setProperty('--app-font-size', '{fontSize}px')");
await JS.InvokeVoidAsync("setAppFontSize", fontSize);
}

private async Task StartResize(MouseEventArgs e)
{
await JS.InvokeVoidAsync("eval", $@"
(function() {{
var sidebar = document.querySelector('.sidebar.desktop-only');
if (!sidebar) return;
var startX = {e.ClientX};
var startW = sidebar.offsetWidth;
function onMove(e) {{
var w = Math.min(Math.max(startW + e.clientX - startX, 200), 600);
sidebar.style.width = w + 'px';
}}
function onUp() {{
document.removeEventListener('mousemove', onMove);
document.removeEventListener('mouseup', onUp);
document.body.style.userSelect = '';
document.body.style.cursor = '';
}}
document.body.style.userSelect = 'none';
document.body.style.cursor = 'col-resize';
document.addEventListener('mousemove', onMove);
document.addEventListener('mouseup', onUp);
}})();
");
await JS.InvokeVoidAsync("startSidebarResize", e.ClientX);
}

private void ToggleFlyout()
Expand Down
21 changes: 4 additions & 17 deletions PolyPilot/Components/Layout/SessionSidebar.razor
Original file line number Diff line number Diff line change
Expand Up @@ -794,14 +794,7 @@ else
if (firstRender)
{
// Set up Enter key handler via JS to avoid Blazor round-trips on every keystroke
await JS.InvokeVoidAsync("eval", @"
document.getElementById('sessionNameInput')?.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
document.querySelector('.new-session button')?.click();
}
});
");
await JS.InvokeVoidAsync("wireSessionNameInputEnter");
}
}

Expand Down Expand Up @@ -1008,10 +1001,7 @@ else
StateHasChanged();
// Focus the input after render
await Task.Yield();
await JS.InvokeVoidAsync("eval", @"
var el = document.getElementById('renameInput');
if (el) { el.focus(); el.select(); }
");
await JS.InvokeVoidAsync("focusAndSelect", "renameInput");
}

private async Task CommitRename()
Expand Down Expand Up @@ -1044,10 +1034,7 @@ else
renamingGroupId = groupId;
StateHasChanged();
await Task.Yield();
await JS.InvokeVoidAsync("eval", @"
var el = document.getElementById('groupRenameInput');
if (el) { el.focus(); el.select(); }
");
await JS.InvokeVoidAsync("focusAndSelect", "groupRenameInput");
}

private async Task CommitGroupRename(string groupId)
Expand All @@ -1072,7 +1059,7 @@ else
CopilotService.SetActiveSession(null);
CopilotService.SaveUiState("/");
currentPage = "/";
try { await JS.InvokeVoidAsync("eval", "window.__dashRef?.invokeMethodAsync('JsCollapseToGrid')"); } catch { }
try { await JS.InvokeVoidAsync("collapseToGrid"); } catch { }
Nav.NavigateTo("/");
}

Expand Down
Loading