Add share target, prompt templates, command palette and session organisation

- PWA share target: shared text/links start a new chat or go into a
  recent session (chooser dialog)
- Prompt templates (personal + global for admins) with {{placeholders}}
  that are asked for on insert; managed under Settings → Templates
- Ctrl/Cmd+K command palette; Alt+N new session, Alt+Up/Down switch
  sessions, Ctrl+, settings
- Sessions can be pinned, archived and filed into folders; the list can
  be grouped by date or by project, groups are collapsible
- Fix: the "What's new" dialog was never shown to signed-in users

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Richard ZinkandClaude Opus 5.5 committed 2026-11-09 05:27:45 +01:00
1 parent b5de531d2e
commit 428e2df40a
25 files changed
+1106 -33

No files matched your search

+264
View File
@@ -148,12 +148,97 @@ textarea:focus {
padding: 4px 8px;
}
.session-group {
display: flex;
align-items: center;
gap: 5px;
width: 100%;
border: none;
background: transparent;
text-align: left;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--muted);
padding: 10px 8px 4px;
}
button.session-group:hover {
color: var(--fg2);
}
.session-group .grow {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.session-group .count {
text-transform: none;
letter-spacing: 0;
}
.session-view {
display: flex;
justify-content: flex-end;
padding: 0 0 2px;
}
.session-view button {
display: inline-flex;
align-items: center;
font-size: 11.5px;
color: var(--muted);
gap: 5px;
}
.session-row {
position: relative;
}
.session-row .session-item {
padding-right: 30px;
}
.session-more {
position: absolute;
top: 6px;
right: 4px;
padding: 2px 4px;
opacity: 0;
color: var(--muted);
}
.session-row:hover .session-more,
.session-row.menu-open .session-more,
.session-more:focus-visible {
opacity: 1;
}
@media (pointer: coarse) {
.session-more {
opacity: 1;
}
}
.session-menu {
position: absolute;
right: 4px;
top: 30px;
z-index: 20;
min-width: 200px;
background: var(--bg1);
border: 1px solid var(--bg3);
border-radius: 8px;
box-shadow: var(--shadow);
padding: 4px;
display: flex;
flex-direction: column;
}
.session-menu button {
display: flex;
align-items: center;
gap: 8px;
border: none;
background: transparent;
text-align: left;
padding: 7px 8px;
border-radius: 5px;
font-size: 13px;
}
.session-menu button:hover {
background: var(--bg2);
}
.session-item {
display: block;
width: 100%;
@@ -3096,3 +3181,182 @@ button.danger-solid {
font-size: 13px;
color: var(--fg2);
}
/* --- share target ------------------------------------------------------------- */
.share-target textarea {
width: 100%;
resize: vertical;
margin-bottom: 10px;
}
.share-new {
width: 100%;
justify-content: center;
}
.share-sep {
margin: 14px 0 6px;
font-size: 12px;
color: var(--muted);
}
.share-list {
display: flex;
flex-direction: column;
gap: 4px;
}
.share-list button {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 2px;
text-align: left;
background: var(--bg2);
}
.share-list button:hover:not(:disabled) {
background: var(--bg3);
}
.share-title {
font-weight: 600;
color: var(--fg1);
}
.share-meta {
font-size: 12px;
color: var(--muted);
}
/* --- prompt templates ---------------------------------------------------------- */
.tpl-picker {
width: min(560px, 100%);
}
.tpl-list {
display: flex;
flex-direction: column;
gap: 4px;
margin-top: 10px;
max-height: 50vh;
overflow-y: auto;
}
.tpl-list button {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 2px;
text-align: left;
background: var(--bg2);
}
.tpl-list button.active {
background: var(--bg3);
}
.tpl-name {
display: flex;
gap: 6px;
align-items: center;
font-weight: 600;
color: var(--fg1);
}
.tpl-preview {
font-size: 12px;
color: var(--muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
}
.tpl-field {
display: flex;
flex-direction: column;
gap: 4px;
margin-bottom: 10px;
}
.tpl-field span {
font-size: 13px;
font-weight: 600;
}
.tpl-field textarea,
.tpl-edit textarea {
width: 100%;
resize: vertical;
}
.tpl-edit {
display: flex;
flex-direction: column;
gap: 6px;
padding: 10px 0;
border-bottom: 1px solid var(--bg2);
}
.tpl-ph {
display: flex;
gap: 4px;
flex-wrap: wrap;
}
/* --- command palette ----------------------------------------------------------- */
.palette-backdrop {
align-items: flex-start;
padding-top: 12vh;
}
.palette {
width: min(600px, 100%);
padding: 10px;
display: flex;
flex-direction: column;
gap: 8px;
max-height: 70vh;
}
.palette > input {
width: 100%;
font-size: 15px;
padding: 10px 12px;
}
.palette-list {
display: flex;
flex-direction: column;
gap: 2px;
overflow-y: auto;
min-height: 0;
}
.palette-list button {
display: flex;
align-items: center;
gap: 10px;
text-align: left;
background: transparent;
border-color: transparent;
}
.palette-list button.active {
background: var(--bg2);
}
.palette-label {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: var(--fg1);
}
.palette-hint {
font-size: 12px;
color: var(--muted);
white-space: nowrap;
}
.palette kbd {
font: 11px var(--mono, monospace);
padding: 1px 5px;
border-radius: 4px;
border: 1px solid var(--bg3);
background: var(--bg0);
color: var(--fg2);
margin-right: 2px;
}
.palette-foot {
display: flex;
flex-wrap: wrap;
gap: 12px;
font-size: 11px;
color: var(--muted);
padding: 4px 4px 0;
border-top: 1px solid var(--bg2);
}
@media (pointer: coarse) {
.palette-foot {
display: none;
}
}