Skip to content
Open
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
34 changes: 15 additions & 19 deletions frontend/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,15 @@ import {
isEditableTarget,
type ActionId,
} from "@/lib/keyboardShortcuts";

const OPEN_FILE_EXTENSIONS = ["md", "markdown", "txt", "html", "htm", "pdf", "docx"];
const CONVERTIBLE_EXTENSIONS = new Set(["html", "htm", "pdf", "docx"]);
const SUPPORTED_FILE_EXTENSIONS = new Set(OPEN_FILE_EXTENSIONS);

function fileExtension(name: string) {
return name.split(".").pop()?.toLowerCase() ?? "";
}

function isSupportedFile(name: string) {
return SUPPORTED_FILE_EXTENSIONS.has(fileExtension(name));
}
import {
isSupportedFile,
needsConversion,
MARKITDOWN_EXTENSIONS,
NATIVE_CONVERTIBLE_EXTENSIONS,
OPEN_FILE_ACCEPT,
OPEN_FILE_EXTENSIONS,
PLAIN_TEXT_EXTENSIONS,
} from "@/lib/supportedFormats";

function convertedMarkdownLabel(name: string) {
const withoutExtension = name.replace(/\.[^/.]+$/, "");
Expand Down Expand Up @@ -233,8 +230,9 @@ export default function HomePage() {
multiple: false,
filters: [
{ name: "Supported documents", extensions: OPEN_FILE_EXTENSIONS },
{ name: "Markdown", extensions: ["md", "markdown", "txt"] },
{ name: "Convertible documents", extensions: ["html", "htm", "pdf", "docx"] },
{ name: "Markdown", extensions: [...PLAIN_TEXT_EXTENSIONS] },
{ name: "Convertible documents", extensions: NATIVE_CONVERTIBLE_EXTENSIONS },
{ name: "Universal import (MarkItDown)", extensions: MARKITDOWN_EXTENSIONS },
],
});
if (!selected) return;
Expand All @@ -261,8 +259,7 @@ export default function HomePage() {
const file = e.target.files?.[0];
if (!file) return;
try {
const ext = fileExtension(file.name);
if (CONVERTIBLE_EXTENSIONS.has(ext)) {
if (needsConversion(file.name)) {
const content_base64 = arrayBufferToBase64(await file.arrayBuffer());
const { markdown } = await Files.convertToMarkdown({
filename: file.name,
Expand Down Expand Up @@ -804,8 +801,7 @@ export default function HomePage() {
for (const file of files) {
if (!isSupportedFile(file.name)) continue;

const ext = fileExtension(file.name);
if (CONVERTIBLE_EXTENSIONS.has(ext)) {
if (needsConversion(file.name)) {
try {
const content_base64 = arrayBufferToBase64(await file.arrayBuffer());
const { markdown } = await Files.convertToMarkdown({
Expand Down Expand Up @@ -843,7 +839,7 @@ export default function HomePage() {
<input
ref={fileInputRef}
type="file"
accept=".md,.markdown,.txt,.html,.htm,.pdf,.docx"
accept={OPEN_FILE_ACCEPT}
className="hidden"
onChange={handleFileInputChange}
/>
Expand Down
11 changes: 2 additions & 9 deletions frontend/src/hooks/useEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import { useState, useCallback, useRef } from "react";
import { Files, Markdown, Export, type ExportPayload, type WordCountResult } from "@/lib/api";
import { needsConversion } from "@/lib/supportedFormats";

export type Tab = {
id: string;
Expand All @@ -20,12 +21,6 @@ export type Tab = {
dirty: boolean;
};

const CONVERTIBLE_EXTENSIONS = new Set(["pdf", "html", "htm", "docx"]);

function fileExtension(name: string) {
return name.split(".").pop()?.toLowerCase() ?? "";
}

function convertedMarkdownLabel(name: string) {
const baseName = name.split(/[/\\]/).pop() ?? name;
const withoutExtension = baseName.replace(/\.[^/.]+$/, "");
Expand Down Expand Up @@ -104,9 +99,7 @@ export function useEditor() {
// ── file ops ───────────────────────────────────────────────────────────────
const openFile = useCallback(
async (filePath: string) => {
const ext = fileExtension(filePath);

if (CONVERTIBLE_EXTENSIONS.has(ext)) {
if (needsConversion(filePath)) {
try {
const { markdown } = await Files.convertToMarkdown({ path: filePath });
const label = convertedMarkdownLabel(filePath);
Expand Down
56 changes: 56 additions & 0 deletions frontend/src/lib/supportedFormats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* File extensions accepted for open/import, matching backend/routers/files.py.
*/

export const PLAIN_TEXT_EXTENSIONS = new Set(["md", "markdown", "txt"]);

export const NATIVE_CONVERTIBLE_EXTENSIONS = ["html", "htm", "pdf", "docx"];

export const MARKITDOWN_EXTENSIONS = [
"pptx",
"ppt",
"xlsx",
"xls",
"csv",
"epub",
"xml",
"zip",
"wav",
"mp3",
"jpg",
"jpeg",
"png",
"gif",
"bmp",
"tiff",
"tif",
"msg",
"ipynb",
];

export const OPEN_FILE_EXTENSIONS = [
...PLAIN_TEXT_EXTENSIONS,
...NATIVE_CONVERTIBLE_EXTENSIONS,
...MARKITDOWN_EXTENSIONS,
];

export const SUPPORTED_FILE_EXTENSIONS = new Set(OPEN_FILE_EXTENSIONS);

export const OPEN_FILE_ACCEPT = OPEN_FILE_EXTENSIONS.map((ext) => `.${ext}`).join(",");

export function fileExtension(name: string) {
return name.split(".").pop()?.toLowerCase() ?? "";
}

export function isPlainTextFile(name: string) {
return PLAIN_TEXT_EXTENSIONS.has(fileExtension(name));
}

export function isSupportedFile(name: string) {
return SUPPORTED_FILE_EXTENSIONS.has(fileExtension(name));
}

export function needsConversion(name: string) {
const ext = fileExtension(name);
return SUPPORTED_FILE_EXTENSIONS.has(ext) && !PLAIN_TEXT_EXTENSIONS.has(ext);
}