@@ -167,12 +167,14 @@ export default function MainPhotos({ initialDirectories, initialFiles, initialPa
@@ -186,7 +188,7 @@ export default function MainPhotos({ initialDirectories, initialFiles, initialPa
setNewFilter({ status: 'unread' })}
+ type='button'
>
Show only unread
@@ -183,6 +184,7 @@ export default function Articles({ initialArticles }: ArticlesProps) {
filter.value.status === 'all' ? 'font-semibold' : ''
}`}
onClick={() => setNewFilter({ status: 'all' })}
+ type='button'
>
Show all
diff --git a/islands/news/Feeds.tsx b/islands/news/Feeds.tsx
index 39e4efd..2c57eee 100644
--- a/islands/news/Feeds.tsx
+++ b/islands/news/Feeds.tsx
@@ -252,12 +252,14 @@ export default function Feeds({ initialFeeds }: FeedsProps) {
diff --git a/islands/notes/Note.tsx b/islands/notes/Note.tsx
index b4e7f96..3d5fce8 100644
--- a/islands/notes/Note.tsx
+++ b/islands/notes/Note.tsx
@@ -68,7 +68,7 @@ export default function Note({ fileName, currentPath, contents }: NoteProps) {
return (
-
+
/
{decodeURIComponent(fileName)}
diff --git a/lib/data/files.ts b/lib/data/files.ts
index d68ef54..12c8977 100644
--- a/lib/data/files.ts
+++ b/lib/data/files.ts
@@ -192,6 +192,15 @@ export async function createFile(
const rootPath = join(getFilesRootPath(), userId, path);
try {
+ // Ensure the directory exist, if being requested
+ try {
+ await Deno.stat(rootPath);
+ } catch (error) {
+ if ((error as Error).toString().includes('NotFound')) {
+ await Deno.mkdir(rootPath, { recursive: true });
+ }
+ }
+
if (typeof contents === 'string') {
await Deno.writeTextFile(join(rootPath, name), contents, { append: false, createNew: true });
} else {
diff --git a/routes/api/files/upload.tsx b/routes/api/files/upload.tsx
index 7e81c5c..b953cb4 100644
--- a/routes/api/files/upload.tsx
+++ b/routes/api/files/upload.tsx
@@ -1,13 +1,14 @@
import { Handlers } from 'fresh/server.ts';
-import { DirectoryFile, FreshContextState } from '/lib/types.ts';
-import { createFile, getFiles } from '/lib/data/files.ts';
+import { Directory, DirectoryFile, FreshContextState } from '/lib/types.ts';
+import { createFile, getDirectories, getFiles } from '/lib/data/files.ts';
interface Data {}
export interface ResponseBody {
success: boolean;
newFiles: DirectoryFile[];
+ newDirectories: Directory[];
}
export const handler: Handlers = {
@@ -18,13 +19,14 @@ export const handler: Handlers = {
const requestBody = await request.clone().formData();
+ const pathInView = requestBody.get('path_in_view') as string;
const parentPath = requestBody.get('parent_path') as string;
const name = requestBody.get('name') as string;
const contents = requestBody.get('contents') as File | string;
if (
- !parentPath || !name.trim() || !contents || !parentPath.startsWith('/') ||
- parentPath.includes('../')
+ !parentPath || !pathInView || !name.trim() || !contents || !parentPath.startsWith('/') ||
+ parentPath.includes('../') || !pathInView.startsWith('/') || pathInView.includes('../')
) {
return new Response('Bad Request', { status: 400 });
}
@@ -33,9 +35,10 @@ export const handler: Handlers = {
const createdFile = await createFile(context.state.user.id, parentPath, name.trim(), fileContents);
- const newFiles = await getFiles(context.state.user.id, parentPath);
+ const newFiles = await getFiles(context.state.user.id, pathInView);
+ const newDirectories = await getDirectories(context.state.user.id, pathInView);
- const responseBody: ResponseBody = { success: createdFile, newFiles };
+ const responseBody: ResponseBody = { success: createdFile, newFiles, newDirectories };
return new Response(JSON.stringify(responseBody));
},