mirror of
https://github.com/stackblitz-labs/bolt.diy
synced 2025-06-23 02:16:08 +00:00
Merge pull request #14 from vgcman16/codex/fix-errors-or-bugs
Fix lint errors and type issues
This commit is contained in:
commit
407f60d74c
@ -288,8 +288,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
const handleFileUpload = () => {
|
||||
const input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
input.accept =
|
||||
'image/*,.pdf,.docx,.txt,.md,.js,.ts,.tsx,.html,.css,.json';
|
||||
input.accept = 'image/*,.pdf,.docx,.txt,.md,.js,.ts,.tsx,.html,.css,.json';
|
||||
|
||||
input.onchange = async (e) => {
|
||||
const file = (e.target as HTMLInputElement).files?.[0];
|
||||
@ -297,6 +296,7 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
if (file) {
|
||||
if (file.type.startsWith('image/')) {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = (ev) => {
|
||||
const base64Image = ev.target?.result as string;
|
||||
setUploadedFiles?.([...uploadedFiles, file]);
|
||||
@ -326,11 +326,16 @@ export const BaseChat = React.forwardRef<HTMLDivElement, BaseChatProps>(
|
||||
for (const item of items) {
|
||||
if (item.kind === 'file') {
|
||||
const file = item.getAsFile();
|
||||
if (!file) continue;
|
||||
|
||||
if (!file) {
|
||||
continue;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
if (file.type.startsWith('image/')) {
|
||||
const reader = new FileReader();
|
||||
|
||||
reader.onload = (ev) => {
|
||||
const base64Image = ev.target?.result as string;
|
||||
setUploadedFiles?.([...uploadedFiles, file]);
|
||||
|
@ -449,6 +449,7 @@ function FileContextMenu({
|
||||
}
|
||||
|
||||
const success = workbenchStore.targetFile(fullPath);
|
||||
|
||||
if (success) {
|
||||
toast.success(`File targeted`);
|
||||
}
|
||||
@ -465,6 +466,7 @@ function FileContextMenu({
|
||||
}
|
||||
|
||||
const success = workbenchStore.unTargetFile(fullPath);
|
||||
|
||||
if (success) {
|
||||
toast.success(`File un-targeted`);
|
||||
}
|
||||
@ -761,9 +763,7 @@ function File({
|
||||
title={'File is locked'}
|
||||
/>
|
||||
)}
|
||||
{isTargeted && (
|
||||
<span className="shrink-0 i-ph:crosshair text-green-500 scale-80" title="Targeted file" />
|
||||
)}
|
||||
{isTargeted && <span className="shrink-0 i-ph:crosshair text-green-500 scale-80" title="Targeted file" />}
|
||||
{unsavedChanges && <span className="i-ph:circle-fill scale-68 shrink-0 text-orange-500" />}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -47,6 +47,7 @@ export function usePromptEnhancer() {
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
_input = '';
|
||||
|
||||
let _error;
|
||||
|
||||
try {
|
||||
|
@ -12,6 +12,7 @@ function getChatSet(chatId: string, create = false): Set<string> | undefined {
|
||||
if (create && !targetedFilesMap.has(chatId)) {
|
||||
targetedFilesMap.set(chatId, new Set());
|
||||
}
|
||||
|
||||
return targetedFilesMap.get(chatId);
|
||||
}
|
||||
|
||||
@ -19,17 +20,22 @@ function initializeCache(): TargetedFile[] {
|
||||
if (targetedFilesCache !== null) {
|
||||
return targetedFilesCache;
|
||||
}
|
||||
|
||||
try {
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
const json = localStorage.getItem(TARGETED_FILES_KEY);
|
||||
|
||||
if (json) {
|
||||
const items = JSON.parse(json) as TargetedFile[];
|
||||
targetedFilesCache = items;
|
||||
rebuildLookup(items);
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
|
||||
targetedFilesCache = [];
|
||||
|
||||
return [];
|
||||
} catch {
|
||||
targetedFilesCache = [];
|
||||
@ -39,12 +45,15 @@ function initializeCache(): TargetedFile[] {
|
||||
|
||||
function rebuildLookup(items: TargetedFile[]): void {
|
||||
targetedFilesMap.clear();
|
||||
|
||||
for (const item of items) {
|
||||
let set = targetedFilesMap.get(item.chatId);
|
||||
|
||||
if (!set) {
|
||||
set = new Set();
|
||||
targetedFilesMap.set(item.chatId, set);
|
||||
}
|
||||
|
||||
set.add(item.path);
|
||||
}
|
||||
}
|
||||
@ -52,6 +61,7 @@ function rebuildLookup(items: TargetedFile[]): void {
|
||||
export function saveTargetedFiles(items: TargetedFile[]): void {
|
||||
targetedFilesCache = [...items];
|
||||
rebuildLookup(items);
|
||||
|
||||
try {
|
||||
if (typeof localStorage !== 'undefined') {
|
||||
localStorage.setItem(TARGETED_FILES_KEY, JSON.stringify(items));
|
||||
@ -67,6 +77,7 @@ export function addTargetedFile(chatId: string, path: string): void {
|
||||
const files = getTargetedFiles();
|
||||
const set = getChatSet(chatId, true)!;
|
||||
set.add(path);
|
||||
|
||||
const filtered = files.filter((f) => !(f.chatId === chatId && f.path === path));
|
||||
filtered.push({ chatId, path });
|
||||
saveTargetedFiles(filtered);
|
||||
@ -75,20 +86,28 @@ export function addTargetedFile(chatId: string, path: string): void {
|
||||
export function removeTargetedFile(chatId: string, path: string): void {
|
||||
const files = getTargetedFiles();
|
||||
const set = getChatSet(chatId);
|
||||
if (set) set.delete(path);
|
||||
|
||||
if (set) {
|
||||
set.delete(path);
|
||||
}
|
||||
|
||||
const filtered = files.filter((f) => !(f.chatId === chatId && f.path === path));
|
||||
saveTargetedFiles(filtered);
|
||||
}
|
||||
|
||||
export function isFileTargeted(chatId: string, path: string): boolean {
|
||||
initializeCache();
|
||||
|
||||
const set = getChatSet(chatId);
|
||||
|
||||
return set ? set.has(path) : false;
|
||||
}
|
||||
|
||||
export function getTargetedFilesForChat(chatId: string): string[] {
|
||||
initializeCache();
|
||||
|
||||
const set = getChatSet(chatId);
|
||||
|
||||
return set ? Array.from(set) : [];
|
||||
}
|
||||
|
||||
|
@ -20,11 +20,7 @@ import {
|
||||
migrateLegacyLocks,
|
||||
clearCache,
|
||||
} from '~/lib/persistence/lockedFiles';
|
||||
import {
|
||||
getTargetedFilesForChat,
|
||||
addTargetedFile,
|
||||
removeTargetedFile,
|
||||
} from '~/lib/persistence/targetedFiles';
|
||||
import { getTargetedFilesForChat, addTargetedFile, removeTargetedFile } from '~/lib/persistence/targetedFiles';
|
||||
import { getCurrentChatId } from '~/utils/fileLocks';
|
||||
|
||||
const logger = createScopedLogger('FilesStore');
|
||||
@ -101,6 +97,7 @@ export class FilesStore {
|
||||
|
||||
// Load locked files from localStorage
|
||||
this.#loadLockedFiles();
|
||||
|
||||
// Load targeted files from localStorage
|
||||
this.#loadTargetedFiles();
|
||||
|
||||
@ -377,6 +374,7 @@ export class FilesStore {
|
||||
|
||||
this.files.setKey(filePath, { ...file, isTargeted: true });
|
||||
addTargetedFile(currentChatId, filePath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -394,6 +392,7 @@ export class FilesStore {
|
||||
|
||||
this.files.setKey(filePath, { ...file, isTargeted: false });
|
||||
removeTargetedFile(currentChatId, filePath);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -7,10 +7,7 @@ import { Header } from '~/components/header/Header';
|
||||
import BackgroundRays from '~/components/ui/BackgroundRays';
|
||||
|
||||
export const meta: MetaFunction = () => {
|
||||
return [
|
||||
{ title: 'Bolt' },
|
||||
{ name: 'description', content: 'Talk with Bolt, an AI assistant from StackBlitz' },
|
||||
];
|
||||
return [{ title: 'Bolt' }, { name: 'description', content: 'Talk with Bolt, an AI assistant from StackBlitz' }];
|
||||
};
|
||||
|
||||
export async function loader(args: LoaderFunctionArgs) {
|
||||
|
@ -8,9 +8,11 @@ import { escapeBoltTags } from './projectCommands';
|
||||
*/
|
||||
function extractFileKey(url: string): string {
|
||||
const match = url.match(/file\/(\w+)/);
|
||||
|
||||
if (!match) {
|
||||
throw new Error('Invalid Figma URL');
|
||||
}
|
||||
|
||||
return match[1];
|
||||
}
|
||||
|
||||
@ -26,8 +28,9 @@ function collectFrames(node: any, frames: any[]) {
|
||||
if (node.type === 'FRAME') {
|
||||
frames.push(node);
|
||||
}
|
||||
|
||||
if (Array.isArray(node.children)) {
|
||||
node.children.forEach((child) => collectFrames(child, frames));
|
||||
node.children.forEach((child: any) => collectFrames(child, frames));
|
||||
}
|
||||
}
|
||||
|
||||
@ -35,6 +38,7 @@ function figmaFramesToComponents(frames: any[]): GeneratedComponent[] {
|
||||
return frames.map((frame) => {
|
||||
const name = frame.name.replace(/[^a-zA-Z0-9]/g, '') || 'Component';
|
||||
const code = `export function ${name}() {\n return <div>${frame.name}</div>;\n}`;
|
||||
|
||||
return { name, code };
|
||||
});
|
||||
}
|
||||
@ -42,10 +46,7 @@ function figmaFramesToComponents(frames: any[]): GeneratedComponent[] {
|
||||
/**
|
||||
* Create chat messages from a Figma design
|
||||
*/
|
||||
export async function createChatFromFigma(
|
||||
figmaUrl: string,
|
||||
token: string,
|
||||
): Promise<Message[]> {
|
||||
export async function createChatFromFigma(figmaUrl: string, token: string): Promise<Message[]> {
|
||||
const fileKey = extractFileKey(figmaUrl);
|
||||
const res = await fetch(`https://api.figma.com/v1/files/${fileKey}`, {
|
||||
headers: { 'X-Figma-Token': token },
|
||||
@ -55,14 +56,14 @@ export async function createChatFromFigma(
|
||||
throw new Error(`Failed to fetch Figma file: ${res.status}`);
|
||||
}
|
||||
|
||||
const data = await res.json();
|
||||
const data = (await res.json()) as { document: unknown };
|
||||
const frames: any[] = [];
|
||||
collectFrames(data.document, frames);
|
||||
collectFrames((data as any).document, frames);
|
||||
|
||||
const components = figmaFramesToComponents(frames);
|
||||
const componentActions = components
|
||||
.map(
|
||||
(c) =>
|
||||
`<boltAction type="file" filePath="app/components/${c.name}.tsx">${escapeBoltTags(c.code)}</boltAction>`,
|
||||
(c) => `<boltAction type="file" filePath="app/components/${c.name}.tsx">${escapeBoltTags(c.code)}</boltAction>`,
|
||||
)
|
||||
.join('\n');
|
||||
|
||||
|
@ -9,21 +9,23 @@ export async function extractTextFromFile(file: File): Promise<string> {
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
|
||||
const texts: string[] = [];
|
||||
|
||||
for (let i = 1; i <= pdf.numPages; i++) {
|
||||
const page = await pdf.getPage(i);
|
||||
const content = await page.getTextContent();
|
||||
texts.push(content.items.map((item: any) => item.str).join(' '));
|
||||
}
|
||||
|
||||
return texts.join('\n');
|
||||
}
|
||||
|
||||
if (
|
||||
file.type ===
|
||||
'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
|
||||
file.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
|
||||
file.name.toLowerCase().endsWith('.docx')
|
||||
) {
|
||||
const arrayBuffer = await file.arrayBuffer();
|
||||
const result = await mammoth.extractRawText({ arrayBuffer });
|
||||
|
||||
return result.value;
|
||||
}
|
||||
|
||||
|
@ -120,10 +120,7 @@ ${files[filePath].content}
|
||||
`;
|
||||
};
|
||||
|
||||
export const uploadedFilesToArtifacts = (
|
||||
files: { [path: string]: string },
|
||||
id: string,
|
||||
): string => {
|
||||
export const uploadedFilesToArtifacts = (files: { [path: string]: string }, id: string): string => {
|
||||
return `
|
||||
<boltArtifact id="${id}" title="Uploaded Files">
|
||||
${Object.keys(files)
|
||||
|
Loading…
Reference in New Issue
Block a user