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
15 changes: 15 additions & 0 deletions apps/desktop/bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@blocknote/core": "^0.25.0",
"@blocknote/mantine": "^0.25.0",
"@blocknote/react": "^0.25.0",
"@dnd-kit/react": "0.5.0",
"@excalidraw/excalidraw": "0.18.1",
"@hugeicons/core-free-icons": "^4.3.0",
"@hugeicons/react": "^1.1.10",
Expand Down
45 changes: 20 additions & 25 deletions apps/desktop/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,10 @@ import { dirtyKey, isDirty as isFileDirty, markDirty } from "./files/dirty";
import { synchronizeLspRuntimePolicy } from "./lsp/runtimePolicy";
import { configurePluginLanguageServers } from "./lsp/client";
import { quickQuotaProviderFor, quickQuotaSummary } from "./usage/quickQuota";
import type { SessionConfig } from "./session/config";
import {
transitionProviderModelSelection,
type SessionConfig,
} from "./session/config";
import {
SESSION_MODES,
executionPolicyChangeDisabled,
Expand Down Expand Up @@ -1401,17 +1404,6 @@ export default function App() {
const [activeFile, setActiveFile] = useState<string | null>(null);
const [fileReveal, setFileReveal] = useState<FileRevealTarget | null>(null);
const fileRevealRequestRef = useRef(0);
// Composer geometry: how tall the document area may grow before it scrolls, and whether it has
// taken over the whole column for long-form authoring. The persisted value is the default; each
// pane then remembers its own height in-session (see composerHByPane) so resizing one tiled
// composer never drags the others with it.
const [composerH, setComposerH] = usePersistedNumber(
"codetwo.composerHeight",
190,
);
const [composerHByPane, setComposerHByPane] = useState<Record<string, number>>(
{},
);
const [dockWidth, setDockWidth] = usePersistedNumber(
"codetwo.dockWidth",
440,
Expand Down Expand Up @@ -2651,11 +2643,6 @@ export default function App() {
const focusedDefaultModel = defaultModel;
const focusedConfigOptions = configOptions;
const focusedSessionUsage = sessionUsage;
// Composer height: the persisted value is each pane's default; resizing the focused pane also
// persists it so new panes inherit the latest preference.
const focusedComposerHeight = composerH;
const persistComposerHeight = setComposerH;

const activeWorktreeState = useMemo(() => {
const stored =
sessions.find((session) => session.id === activeSession) ??
Expand Down Expand Up @@ -7299,6 +7286,22 @@ export default function App() {
setDefaultModel(null);
}
},
onProviderModel: (nextProvider, nextModel) => {
transitionProviderModelSelection({
hasActiveSession: activeSessionRef.current !== null,
createSession,
apply: () => {
providerPinned.current = true;
setProvider(nextProvider);
setModels(
providers.find((candidate) => candidate.id === nextProvider)?.models ?? [],
);
setCurrentModel(nextModel);
setDefaultModel(null);
setConfigOptions([]);
},
});
},
onReloadProviders: () => {
void refreshProviders().catch(() => {});
},
Expand Down Expand Up @@ -7947,12 +7950,6 @@ export default function App() {
// Usage is polled only for the focused session; a background pane hides its cost
// segment rather than borrow the focused figures.
const sessionUsage = paneFocused ? focusedSessionUsage : null;
// Each pane keeps its own composer height so a resize stays local to that tile.
const composerH = composerHByPane[paneId] ?? focusedComposerHeight;
const setComposerH = (h: number) => {
setComposerHByPane((prev) => ({ ...prev, [paneId]: h }));
if (paneFocused) persistComposerHeight(h);
};
const activeInteractionCapabilities = activeSession
? interactionCapabilities[activeSession] ?? null
: null;
Expand Down Expand Up @@ -8325,8 +8322,6 @@ export default function App() {
}}
docMode={docMode}
onDocMode={toggleDocMode}
height={composerH}
onHeight={setComposerH}
boundsRef={mainRef}
models={activeSession === null
? providers.find((candidate) => candidate.id === provider)?.models ?? []
Expand Down
31 changes: 31 additions & 0 deletions apps/desktop/src/components/ui/drag-drop.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { ComponentProps } from "react";
import {
DragDropProvider as DndKitProvider,
useDroppable,
type DragEndEvent,
type DragOverEvent,
type DragStartEvent,
type UseDroppableInput,
} from "@dnd-kit/react";
import {
useSortable,
type UseSortableInput,
} from "@dnd-kit/react/sortable";

/** Shared boundary for the desktop's mature drag-and-drop interaction library. */
function DragDropRoot(props: ComponentProps<typeof DndKitProvider>) {
return <DndKitProvider {...props} />;
}

export {
DragDropRoot,
useDroppable as useDragDropZone,
useSortable as useDragDropSortable,
};
export type {
DragEndEvent,
DragOverEvent,
DragStartEvent,
UseDroppableInput,
UseSortableInput,
};
3 changes: 1 addition & 2 deletions apps/desktop/src/environment/EnvironmentPopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,7 @@ export function EnvironmentPopover({
/>

<PopoverContent
align="end"
alignOffset={-36}
align="start"
sideOffset={16}
className="max-h-(--available-height) overflow-y-auto p-2"
initialFocus={false}
Expand Down
2 changes: 0 additions & 2 deletions apps/desktop/src/i18n/strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,6 @@ export const en = {
"composer.runEmpty": "Write a prompt first",
"composer.loadingSession": "Wait for this session to finish loading",
"composer.toSend": "{key} to send",
"composer.grip": "Drag to resize · double-click for full page",
"composer.cliNotFound": "CLI not found",
"checkout.title": "Checkout",
"checkout.choose": "Choose where the next session runs",
Expand Down Expand Up @@ -3406,7 +3405,6 @@ export const zhCN: Record<StringKey, string> = {
"composer.runEmpty": "先写点什么",
"composer.loadingSession": "请等待会话加载完成",
"composer.toSend": "{key} 发送",
"composer.grip": "拖动调整高度 · 双击整页",
"composer.cliNotFound": "未找到 CLI",
"checkout.title": "检出位置",
"checkout.choose": "选择下一个会话的运行位置",
Expand Down
Loading