mirror of
https://github.com/andy-stack/vaultkeeper-ai.git
synced 2026-07-22 06:42:03 +00:00
fix: improve mobile UI layout and interaction handling
- Add mobile-specific height constraints for input buttons - Fix message alignment to left for better readability - Change click to mousedown for better mobile responsiveness - Adjust top bar grid columns for mobile layout - Update view type identifier to 'ai-agent-main-view' - Standardize quote style to double quotes across config files
This commit is contained in:
parent
a0afcdd0d0
commit
4dcce63bce
9 changed files with 85 additions and 53 deletions
|
|
@ -228,6 +228,7 @@
|
|||
|
||||
.message-container {
|
||||
display: flex;
|
||||
text-align: left;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
|
@ -270,6 +271,7 @@
|
|||
}
|
||||
|
||||
.streaming-content {
|
||||
justify-content: left;
|
||||
min-height: 1em; /* Ensure the element exists for binding */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -347,6 +347,10 @@
|
|||
transition-duration: 0.5s;
|
||||
}
|
||||
|
||||
:global(.is-mobile) #user-instruction-button {
|
||||
max-height: 2rem;
|
||||
}
|
||||
|
||||
#user-instruction-button.instruction-active {
|
||||
box-shadow: 0px 0px 4px 1px var(--color-accent);
|
||||
}
|
||||
|
|
@ -374,6 +378,10 @@
|
|||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
:global(.is-mobile) #input-field {
|
||||
align-content: end;
|
||||
}
|
||||
|
||||
#input-field:focus {
|
||||
border-color: var(--color-accent);
|
||||
box-shadow: 0px 0px 4px 1px var(--color-accent);
|
||||
|
|
@ -416,6 +424,10 @@
|
|||
transition-duration: 0.5s;
|
||||
}
|
||||
|
||||
:global(.is-mobile) #edit-mode-button {
|
||||
max-height: 2rem;
|
||||
}
|
||||
|
||||
#submit-button {
|
||||
grid-row: 3;
|
||||
grid-column: 8;
|
||||
|
|
@ -427,6 +439,10 @@
|
|||
background-color: var(--interactive-accent);
|
||||
}
|
||||
|
||||
:global(.is-mobile) #submit-button {
|
||||
max-height: 2rem;
|
||||
}
|
||||
|
||||
#submit-button:not(:disabled):hover {
|
||||
cursor: pointer;
|
||||
background-color: var(--interactive-accent-hover);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<script lang="ts">
|
||||
import { basename } from 'path-browserify';
|
||||
import type { ISearchState, SearchStateStore } from 'Stores/SearchStateStore';
|
||||
import { tick } from 'svelte';
|
||||
import { setIcon } from 'obsidian';
|
||||
import { SearchTrigger } from 'Enums/SearchTrigger';
|
||||
import { Resolve } from 'Services/DependencyService';
|
||||
import { Services } from 'Services/Services';
|
||||
import { basename } from "path-browserify";
|
||||
import type { ISearchState, SearchStateStore } from "Stores/SearchStateStore";
|
||||
import { tick } from "svelte";
|
||||
import { setIcon } from "obsidian";
|
||||
import { SearchTrigger } from "Enums/SearchTrigger";
|
||||
import { Resolve } from "Services/DependencyService";
|
||||
import { Services } from "Services/Services";
|
||||
|
||||
export let searchState: ISearchState;
|
||||
export let onResultAccept: () => void;
|
||||
|
|
@ -35,13 +35,13 @@
|
|||
function getIconName(trigger: SearchTrigger | null): string {
|
||||
switch(trigger) {
|
||||
case SearchTrigger.File:
|
||||
return 'file-text';
|
||||
return "file-text";
|
||||
case SearchTrigger.Folder:
|
||||
return 'folder';
|
||||
return "folder";
|
||||
case SearchTrigger.Tag:
|
||||
return 'tag';
|
||||
return "tag";
|
||||
default:
|
||||
return 'file-text';
|
||||
return "file-text";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -58,9 +58,9 @@
|
|||
const selectedIndex = searchState.results.indexOf(searchState.selectedResult);
|
||||
if (selectedIndex !== -1 && resultElements[selectedIndex]) {
|
||||
resultElements[selectedIndex]?.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'nearest',
|
||||
inline: 'nearest'
|
||||
behavior: "smooth",
|
||||
block: "nearest",
|
||||
inline: "nearest"
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -78,7 +78,7 @@
|
|||
bind:this={resultElements[index]}
|
||||
style:background-color={searchResult === searchState.selectedResult ? "var(--interactive-accent)" : "transparent"}
|
||||
on:mouseenter={() => searchStateStore.setSelectedResult(index)}
|
||||
on:click={onResultAccept}
|
||||
on:mousedown={onResultAccept}
|
||||
on:keydown={() => {}}>
|
||||
<div class="input-search-result-icon" bind:this={iconElements[index]}></div>
|
||||
<div class="input-search-result-title">{basename(searchResult)}</div>
|
||||
|
|
@ -145,4 +145,8 @@
|
|||
font-size: var(--font-smallest);
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
:global(.is-mobile) .input-search-result-container[aria-selected="true"] {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -142,6 +142,10 @@
|
|||
border-radius: var(--radius-m);
|
||||
}
|
||||
|
||||
:global(.is-mobile) .top-bar-content {
|
||||
grid-template-columns: var(--size-4-1) auto auto auto auto auto auto 1fr 0fr auto var(--size-4-1);
|
||||
}
|
||||
|
||||
.top-bar-divider {
|
||||
width: var(--divider-width);
|
||||
height: auto;
|
||||
|
|
@ -149,6 +153,10 @@
|
|||
margin: var(--size-4-2) var(--size-4-3);
|
||||
}
|
||||
|
||||
:global(.is-mobile) .top-bar-divider {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#new-conversation-button {
|
||||
grid-row: 1;
|
||||
grid-column: 2;
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@
|
|||
style:background-color={selectedInstruction === index ? "var(--interactive-accent)" : "transparent"}
|
||||
bind:this={instructionsElements[index]}
|
||||
on:mouseenter={() => selectedInstruction = index}
|
||||
on:click={handleInstructionSelect}
|
||||
on:mousedown={handleInstructionSelect}
|
||||
on:keydown={() => {}}>
|
||||
<div class="user-instruction-title">{basename(userInstruction)}</div>
|
||||
{#if userInstruction !== basename(userInstruction)}
|
||||
|
|
@ -236,4 +236,8 @@
|
|||
#user-instruction-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
:global(.is-mobile) .user-instruction-container[aria-selected="true"] {
|
||||
background-color: transparent !important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -6,7 +6,7 @@ import type { StatusBarService } from 'Services/StatusBarService';
|
|||
import { Resolve } from 'Services/DependencyService';
|
||||
import { Services } from 'Services/Services';
|
||||
|
||||
export const VIEW_TYPE_MAIN = 'main-view';
|
||||
export const VIEW_TYPE_MAIN = 'ai-agent-main-view';
|
||||
|
||||
export class MainView extends ItemView {
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ import esbuild from "esbuild";
|
|||
import process from "process";
|
||||
import builtins from "builtin-modules";
|
||||
import { copyFileSync, mkdirSync, existsSync, readdirSync, statSync } from "fs";
|
||||
import path, { join } from "path";
|
||||
|
||||
import esbuildSvelte from 'esbuild-svelte';
|
||||
import { sveltePreprocess } from 'svelte-preprocess';
|
||||
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
/* Main View Customization */
|
||||
/* ============================== */
|
||||
|
||||
.workspace-leaf-content[data-type="main-view"] {
|
||||
.workspace-leaf-content[data-type="ai-agent-main-view"] {
|
||||
background-color: var(--background-secondary);
|
||||
}
|
||||
|
||||
.workspace-leaf-content[data-type="main-view"] .view-content {
|
||||
.workspace-leaf-content[data-type="ai-agent-main-view"] .view-content {
|
||||
align-self: center;
|
||||
max-width: 1000px;
|
||||
background-color: var(--background-secondary);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { defineConfig } from 'vitest/config';
|
||||
import * as path from 'path-browserify';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { defineConfig } from "vitest/config";
|
||||
import * as path from "path-browserify";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
|
|
@ -8,50 +8,50 @@ export default defineConfig({
|
|||
plugins: [],
|
||||
resolve: {
|
||||
alias: {
|
||||
'obsidian': path.resolve(__dirname, '__mocks__/obsidian.ts'),
|
||||
"obsidian": path.resolve(__dirname, "__mocks__/obsidian.ts"),
|
||||
// Support TypeScript path mapping from tsconfig
|
||||
'Helpers': path.resolve(__dirname, 'Helpers'),
|
||||
'Enums': path.resolve(__dirname, 'Enums'),
|
||||
'Services': path.resolve(__dirname, 'Services'),
|
||||
'Conversations': path.resolve(__dirname, 'Conversations'),
|
||||
'AIClasses': path.resolve(__dirname, 'AIClasses'),
|
||||
'Components': path.resolve(__dirname, 'Components'),
|
||||
'Stores': path.resolve(__dirname, 'Stores'),
|
||||
'Views': path.resolve(__dirname, 'Views'),
|
||||
'Modals': path.resolve(__dirname, 'Modals')
|
||||
"Helpers": path.resolve(__dirname, "Helpers"),
|
||||
"Enums": path.resolve(__dirname, "Enums"),
|
||||
"Services": path.resolve(__dirname, "Services"),
|
||||
"Conversations": path.resolve(__dirname, "Conversations"),
|
||||
"AIClasses": path.resolve(__dirname, "AIClasses"),
|
||||
"Components": path.resolve(__dirname, "Components"),
|
||||
"Stores": path.resolve(__dirname, "Stores"),
|
||||
"Views": path.resolve(__dirname, "Views"),
|
||||
"Modals": path.resolve(__dirname, "Modals")
|
||||
}
|
||||
},
|
||||
test: {
|
||||
// Use happy-dom for faster DOM simulation
|
||||
environment: 'happy-dom',
|
||||
environment: "happy-dom",
|
||||
|
||||
// Test file patterns
|
||||
include: ['__tests__/**/*.{test,spec}.{js,ts}'],
|
||||
include: ["__tests__/**/*.{test,spec}.{js,ts}"],
|
||||
|
||||
// Setup files to run before each test file
|
||||
setupFiles: ['__tests__/setup.ts'],
|
||||
setupFiles: ["__tests__/setup.ts"],
|
||||
|
||||
// Coverage configuration
|
||||
coverage: {
|
||||
provider: 'v8',
|
||||
reporter: ['text', 'json', 'html'],
|
||||
provider: "v8",
|
||||
reporter: ["text", "json", "html"],
|
||||
include: [
|
||||
'Services/**/*.ts',
|
||||
'AIClasses/**/*.ts',
|
||||
'Helpers/**/*.ts',
|
||||
'Conversations/**/*.ts',
|
||||
'Components/**/*.svelte',
|
||||
'Enums/**/*.ts',
|
||||
'Stores/**/*.ts'
|
||||
"Services/**/*.ts",
|
||||
"AIClasses/**/*.ts",
|
||||
"Helpers/**/*.ts",
|
||||
"Conversations/**/*.ts",
|
||||
"Components/**/*.svelte",
|
||||
"Enums/**/*.ts",
|
||||
"Stores/**/*.ts"
|
||||
],
|
||||
exclude: [
|
||||
'**/*.test.ts',
|
||||
'**/*.spec.ts',
|
||||
'node_modules/**',
|
||||
'__tests__/**',
|
||||
'main.ts',
|
||||
'Views/**',
|
||||
'Modals/**'
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.ts",
|
||||
"node_modules/**",
|
||||
"__tests__/**",
|
||||
"main.ts",
|
||||
"Views/**",
|
||||
"Modals/**"
|
||||
],
|
||||
thresholds: {
|
||||
lines: 70,
|
||||
|
|
|
|||
Loading…
Reference in a new issue