Skip to content
Merged
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
1 change: 1 addition & 0 deletions changelog.d/276-sidebar-gear.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Own Bot rows in the wide sidebar show the same hover/focus gear as friends' Bots, opening Edit Bot ([#276](https://github.com/ThinkFlowLab/FlyBot/issues/276)).
7 changes: 4 additions & 3 deletions core/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -5928,11 +5928,12 @@ function BotRow({ bot, roster, actions, useSessions, useSessionStatus, useSessio
) : null,
unreadMark
);
const settings = wide && bot.remote ? (0, import_react9.createElement)("button", {
const settingsLabel = bot.remote ? t("Bot settings") : t("Edit Bot");
const settings = wide ? (0, import_react9.createElement)("button", {
type: "button",
className: "bt-row-settings",
"aria-label": t("Bot settings"),
title: t("Bot settings"),
"aria-label": settingsLabel,
title: settingsLabel,
onClick: (event) => {
event.stopPropagation();
actions.openSettings("bots", id);
Expand Down
6 changes: 4 additions & 2 deletions core/src/client/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,10 @@ function BotRow({ bot, roster, actions, useSessions, useSessionStatus, useSessio
h('span', { className: 'bt-row-name' }, h('span', { className: 'bt-row-title' }, shown), bot.remote ? h(RemoteMark, { remote: bot.remote }) : null, pinned ? h(PinMark) : null),
awayLine ? h('span', { className: 'bt-row-preview' }, awayLine) : preview ? h('span', { className: 'bt-row-preview' }, preview) : null) : null,
unreadMark)
const settings = wide && bot.remote ? h('button', {
type: 'button', className: 'bt-row-settings', 'aria-label': t('Bot settings'), title: t('Bot settings'),
// Hover/focus gear on every wide row (#276/#173): own Bots and friends' Bots alike.
const settingsLabel = bot.remote ? t('Bot settings') : t('Edit Bot')
const settings = wide ? h('button', {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Register own Bot rows once with the glide animator

With motion enabled, when activity reorders the wide sidebar, useListGlide animates every matching [data-bot-id]. Enabling settings for own Bots sends them through the wrapper at line 96, which has the same ID as the inner row button at line 82, so the parent and child both receive the translation and their transforms compound; the row starts twice the measured distance away while its gear starts at the correct old position. Keep the glide ID on only one element for each wide own-Bot entry.

Useful? React with 👍 / 👎.

type: 'button', className: 'bt-row-settings', 'aria-label': settingsLabel, title: settingsLabel,
onClick: (event) => { event.stopPropagation(); actions.openSettings('bots', id) },
}, h(GearIcon)) : null
if (settings) return h('div', { className: 'bt-row-wrap', 'data-bot-id': id }, row, settings)
Expand Down
3 changes: 3 additions & 0 deletions core/test/looks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ test('Bot settings is the only settings entry; nothing is called Team settings',
assert.match(text('remote-bot-settings.js'), /focus\?\.\(\{ preventScroll: true \}\)/)
assert.match(text('sidebar.js'), /\.bt-tree-item>\.bt-row-wrap\{flex:1 1 auto;width:auto;min-width:0\}/)
assert.match(text('sidebar.js'), /bt-row-settings/)
// #276: gear is on every wide Bot row (own and friends'), not only remotes.
assert.match(text('sidebar.js'), /const settings = wide \? h\('button'/)
assert.doesNotMatch(text('sidebar.js'), /wide && bot\.remote \? h\('button'/)
assert.match(text('header.js'), /setAttribute\('aria-label', composerLabel\)/)
assert.match(text('settings.js'), /filter\(bot => !bot\.remote\)/)
// #276: only the user's own Bots are offered as a Main Bot, in both selects.
Expand Down
2 changes: 1 addition & 1 deletion docs/subsystems/core-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ The overlay (`flybot-slots.js` `FlyBotApprovals`) is the fallback, not a second
- The "@" reader is shared with the host (`core/src/shared/mentions.js`, bundled into `core/client.js`). #287 added `unmatchedMentions` there (the `@` words that name nobody, used by the host for the face-room hint); `mentionSpans` and what the bubbles draw are unchanged.
- A friend's Bot settings surface is not the local editor (#160): no rename, avatar editor, model, folder, instructions, Main Bot, Hide, Duplicate, or Delete. The details gear and context menu say **Bot settings**. The menu is Mark as Unread, Bot settings, and Copy conversation ID. Per-friend **Auto-send** and **Remove this Bot** stay on that page (`flybot.bot.details`); Remove closes the overlay so a stale local editor cannot appear. The Bots settings list is local Bots only.
- A friend's Bot details overview is that compact panel: handle plus `FlyBotDetails` (Auto-send and a muted Remove link), no Browser tab, no Usage / model / folder. Opening the gear uses `remote-bot-settings` (`RemoteBotSettingsSheet`): a bottom sheet on narrow viewports and a centered card from 520px up, with the scrim behind the dialog (`z-index` stacking like `bt-settings` / `bt-mem`) so the sheet stays clickable through enter/leave animations. The surrounding DSH settings-shell chrome (back/title) is not redesigned (#166). The sheet takes focus when it opens (`tabIndex -1`, `preventScroll`), closes on Escape from its own `onKeyDown` as well as `useEscape`, and gives focus back without scrolling; in the tree a friend's `.bt-row-wrap` (row plus gear) shrinks like a plain row (`.bt-tree-item>.bt-row-wrap`), so the gear never overflows the sidebar and focusing it cannot scroll it sideways (#274).
- A listed friend's Bot row in wide sidebar mode is a `bt-row-wrap`: the session `bt-row` and a sibling gear (`bt-row-settings`) that opens Bot settings — not a button inside the row (#166).
- Every listed Bot row in wide sidebar mode is a `bt-row-wrap`: the session `bt-row` and a sibling gear (`bt-row-settings`, hover/focus) that opens Edit Bot for an own Bot or Bot settings for a friend's (#166, #276).
- `HeaderPill` sets the composer placeholder CSS var and mirrors the localized **Message {name}** string on `[data-composer-input]`'s `aria-label`; cleanup restores the prior label when the header unmounts or the session changes (#166).

### Face-room held bubble and overview
Expand Down
13 changes: 9 additions & 4 deletions patches/ds-bot/0003-flybot-api-client.patch
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ diff --git a/src/client/sidebar.js b/src/client/sidebar.js
import { showsDshRow } from './dsh-offer.js'

// -------------------------------------------------------------------------
@@ -37,56 +37,88 @@ const workKeys = text => (text === '' ? [] : text.split(',').map((key) => {
@@ -37,56 +37,90 @@ const workKeys = text => (text === '' ? [] : text.split(',').map((key) => {
}))
const workLine = (lead, tool, more) => h(Shimmer, null, `${lead} · ${workPhrase(tool)}…${more > 0 ? ` +${more}` : ''}`)

Expand Down Expand Up @@ -1042,8 +1042,10 @@ diff --git a/src/client/sidebar.js b/src/client/sidebar.js
awayLine ? h('span', { className: 'bt-row-preview' }, awayLine) : preview ? h('span', { className: 'bt-row-preview' }, preview) : null) : null,
- wide && unread && !active ? h('span', { className: 'bt-unread', 'aria-hidden': true }) : null)
+ unreadMark)
+ const settings = wide && bot.remote ? h('button', {
+ type: 'button', className: 'bt-row-settings', 'aria-label': t('Bot settings'), title: t('Bot settings'),
+ // Hover/focus gear on every wide row (#276/#173): own Bots and friends' Bots alike.
+ const settingsLabel = bot.remote ? t('Bot settings') : t('Edit Bot')
+ const settings = wide ? h('button', {
+ type: 'button', className: 'bt-row-settings', 'aria-label': settingsLabel, title: settingsLabel,
+ onClick: (event) => { event.stopPropagation(); actions.openSettings('bots', id) },
+ }, h(GearIcon)) : null
+ if (settings) return h('div', { className: 'bt-row-wrap', 'data-bot-id': id }, row, settings)
Expand Down Expand Up @@ -1596,7 +1598,7 @@ diff --git a/test/create-bot.test.js b/test/create-bot.test.js
diff --git a/test/looks.test.js b/test/looks.test.js
--- a/test/looks.test.js
+++ b/test/looks.test.js
@@ -40,7 +40,24 @@ test('Bot settings is the only settings entry; nothing is called Team settings',
@@ -40,7 +40,27 @@ test('Bot settings is the only settings entry; nothing is called Team settings',
assert.match(text('palette.js'), /title: t\('Bot settings'\), run: \(\) => actions\.openSettings\('general'\)/)
// One Bot's own entries open that Bot, so they read Edit Bot instead.
assert.match(text('context-menu.js'), /\[t\('Edit Bot'\), GearIcon, \(\) => actions\.openSettings\('bots', bot\.id\)\]/)
Expand All @@ -1613,6 +1615,9 @@ diff --git a/test/looks.test.js b/test/looks.test.js
+ assert.match(text('remote-bot-settings.js'), /focus\?\.\(\{ preventScroll: true \}\)/)
+ assert.match(text('sidebar.js'), /\.bt-tree-item>\.bt-row-wrap\{flex:1 1 auto;width:auto;min-width:0\}/)
+ assert.match(text('sidebar.js'), /bt-row-settings/)
+ // #276: gear is on every wide Bot row (own and friends'), not only remotes.
+ assert.match(text('sidebar.js'), /const settings = wide \? h\('button'/)
+ assert.doesNotMatch(text('sidebar.js'), /wide && bot\.remote \? h\('button'/)
+ assert.match(text('header.js'), /setAttribute\('aria-label', composerLabel\)/)
+ assert.match(text('settings.js'), /filter\(bot => !bot\.remote\)/)
+ // #276: only the user's own Bots are offered as a Main Bot, in both selects.
Expand Down
9 changes: 5 additions & 4 deletions patches/ds-bot/0008-client-bundle.patch
Original file line number Diff line number Diff line change
Expand Up @@ -3644,7 +3644,7 @@ diff --git a/client.js b/client.js
"button",
{
type: "button",
@@ -4802,21 +4802,65 @@ function BotRow({ bot, roster, actions, useSessions, useSessionStatus, useSessio
@@ -4802,21 +4802,66 @@ function BotRow({ bot, roster, actions, useSessions, useSessionStatus, useSessio
onClick: () => actions.openSession(id),
onContextMenu
},
Expand All @@ -3664,11 +3664,12 @@ diff --git a/client.js b/client.js
- wide && unread && !active ? (0, import_react8.createElement)("span", { className: "bt-unread", "aria-hidden": true }) : null
+ unreadMark
+ );
+ const settings = wide && bot.remote ? (0, import_react9.createElement)("button", {
+ const settingsLabel = bot.remote ? t("Bot settings") : t("Edit Bot");
+ const settings = wide ? (0, import_react9.createElement)("button", {
+ type: "button",
+ className: "bt-row-settings",
+ "aria-label": t("Bot settings"),
+ title: t("Bot settings"),
+ "aria-label": settingsLabel,
+ title: settingsLabel,
+ onClick: (event) => {
+ event.stopPropagation();
+ actions.openSettings("bots", id);
Expand Down
Loading