mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
feat: add mobile suggestion button and force-focus parameter
- Add "Suggest" button to mobile diff controls with three-column layout - Replace focusInput's onMobile param with force param for explicit control - Scope diff mobile button styles to prevent conflicts - Enable focus on chat input when suggestion button clicked
This commit is contained in:
parent
f74286f3c8
commit
afaa530f8b
6 changed files with 39 additions and 17 deletions
|
|
@ -115,9 +115,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
export function focusInput(onMobile: boolean = false) {
|
||||
// don't focus on mobile, it's annoying
|
||||
if (onMobile || !Platform.isMobile) {
|
||||
export function focusInput(force: boolean = false) {
|
||||
// Generally don't focus on mobile, it's annoying
|
||||
if (force || !Platform.isMobile) {
|
||||
tick().then(() => {
|
||||
textareaElement?.focus();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -43,8 +43,8 @@
|
|||
|
||||
let currentThought: string | null = null;
|
||||
|
||||
export function focusInput() {
|
||||
chatInput?.focusInput();
|
||||
export function focusInput(force: boolean = false) {
|
||||
chatInput?.focusInput(force);
|
||||
}
|
||||
|
||||
export function resetChatArea() {
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@
|
|||
|
||||
.diff-view-mobile .diff-mobile-controls {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: var(--size-4-2);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
|
|
@ -128,7 +128,7 @@
|
|||
z-index: 10;
|
||||
}
|
||||
|
||||
.diff-mobile-button {
|
||||
.diff-mobile-controls .diff-mobile-button {
|
||||
min-height: 44px;
|
||||
font-size: var(--font-ui-medium);
|
||||
font-weight: var(--font-semibold);
|
||||
|
|
@ -138,7 +138,7 @@
|
|||
color: var(--text-on-accent);
|
||||
}
|
||||
|
||||
.diff-mobile-accept {
|
||||
.diff-mobile-controls .diff-mobile-accept {
|
||||
background-color: color-mix(
|
||||
in srgb,
|
||||
var(--color-green) 75%,
|
||||
|
|
@ -146,11 +146,19 @@
|
|||
);
|
||||
}
|
||||
|
||||
.diff-mobile-accept:active {
|
||||
.diff-mobile-controls .diff-mobile-accept:active {
|
||||
background-color: var(--color-green);
|
||||
}
|
||||
|
||||
.diff-mobile-reject {
|
||||
.diff-mobile-controls .diff-mobile-suggest {
|
||||
background-color: var(--interactive-accent);
|
||||
}
|
||||
|
||||
.diff-mobile-controls .diff-mobile-suggest:active {
|
||||
background-color: var(--interactive-accent-hover);
|
||||
}
|
||||
|
||||
.diff-mobile-controls .diff-mobile-reject {
|
||||
background-color: color-mix(
|
||||
in srgb,
|
||||
var(--color-red) 75%,
|
||||
|
|
@ -158,7 +166,7 @@
|
|||
);
|
||||
}
|
||||
|
||||
.diff-mobile-reject:active {
|
||||
.diff-mobile-controls .diff-mobile-reject:active {
|
||||
background-color: var(--color-red);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { Resolve } from "Services/DependencyService";
|
|||
import type { EventService } from "Services/EventService";
|
||||
import type { DiffService } from "Services/DiffService";
|
||||
import { Services } from "Services/Services";
|
||||
import { VIEW_TYPE_MAIN } from "./MainView";
|
||||
import { VIEW_TYPE_MAIN, type MainView } from "./MainView";
|
||||
import { tick } from "svelte";
|
||||
|
||||
export const VIEW_TYPE_DIFF = 'vaultkeeper-ai-diff-view';
|
||||
|
|
@ -115,6 +115,12 @@ export class DiffView extends ItemView {
|
|||
});
|
||||
acceptButton.setAttribute('aria-label', 'Accept changes');
|
||||
|
||||
const suggestButton = container.createEl('button', {
|
||||
cls: 'diff-mobile-button diff-mobile-suggest',
|
||||
text: 'Suggest'
|
||||
});
|
||||
suggestButton.setAttribute('aria-label', 'Make a suggestion');
|
||||
|
||||
const rejectButton = container.createEl('button', {
|
||||
cls: 'diff-mobile-button diff-mobile-reject',
|
||||
text: 'Reject'
|
||||
|
|
@ -126,6 +132,10 @@ export class DiffView extends ItemView {
|
|||
await this.refocusMainView();
|
||||
});
|
||||
|
||||
this.registerDomEvent(suggestButton, 'click', async () => {
|
||||
await this.refocusMainView(true);
|
||||
});
|
||||
|
||||
this.registerDomEvent(rejectButton, 'click', async () => {
|
||||
this.diffService.onReject();
|
||||
await this.refocusMainView();
|
||||
|
|
@ -134,7 +144,7 @@ export class DiffView extends ItemView {
|
|||
return container;
|
||||
}
|
||||
|
||||
private async refocusMainView(): Promise<void> {
|
||||
private async refocusMainView(focusChatInput: boolean = false): Promise<void> {
|
||||
await tick().then(async () => {
|
||||
const { workspace } = this.app;
|
||||
const leaves = workspace.getLeavesOfType(VIEW_TYPE_MAIN);
|
||||
|
|
@ -142,6 +152,10 @@ export class DiffView extends ItemView {
|
|||
if (leaves.length > 0) {
|
||||
await workspace.revealLeaf(leaves[0]);
|
||||
workspace.setActiveLeaf(leaves[0], { focus: true });
|
||||
|
||||
if (focusChatInput) {
|
||||
(leaves[0].view as MainView).input?.focusInput(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { Services } from 'Services/Services';
|
|||
export const VIEW_TYPE_MAIN = 'vaultkeeper-ai-main-view';
|
||||
|
||||
interface ChatWindowComponent {
|
||||
focusInput: () => void;
|
||||
focusInput: (force?: boolean) => void;
|
||||
resetChatArea: () => void;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ if (typeof HTMLElement !== 'undefined') {
|
|||
options?: string | DomElementInfo,
|
||||
callback?: (el: HTMLElementTagNameMap[K]) => void
|
||||
): HTMLElementTagNameMap[K] {
|
||||
const el = document.createElement(tag);
|
||||
const el = document.createElement(tag) as HTMLElementTagNameMap[K];
|
||||
applyElementInfo(el, options);
|
||||
if (this instanceof HTMLElement && el.parentNode !== this) {
|
||||
this.appendChild(el);
|
||||
|
|
@ -101,9 +101,9 @@ if (typeof HTMLElement !== 'undefined') {
|
|||
return el;
|
||||
}
|
||||
|
||||
HTMLElement.prototype.createEl = function(tag: string, options?: string | DomElementInfo, callback?: (el: HTMLElement) => void) {
|
||||
HTMLElement.prototype.createEl = function(this: HTMLElement, tag: string, options?: string | DomElementInfo, callback?: (el: HTMLElement) => void) {
|
||||
return createElImpl.call(this, tag as keyof HTMLElementTagNameMap, options, callback as any);
|
||||
};
|
||||
} as HTMLElement['createEl'];
|
||||
HTMLElement.prototype.createDiv = function(options?: string | DomElementInfo, callback?: (el: HTMLDivElement) => void) {
|
||||
return this.createEl('div', options, callback as any);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue