| null>(null)
+
+ useEffect(
+ () => () => {
+ if (zoomInterval.current) {
+ clearInterval(zoomInterval.current)
+ console.log("clearInterval")
+ zoomInterval.current = null
+ }
+ },
+ [],
+ )
+
+ function startZooming(delta: number) {
+ setZoomLevel((zoom) => zoom + delta)
+ zoomInterval.current = setInterval(() => {
+ setZoomLevel((zoom) => zoom + delta)
+ }, 100)
+ }
+
+ function stopZooming() {
+ if (zoomInterval.current) {
+ clearInterval(zoomInterval.current)
+ zoomInterval.current = null
+ }
+ }
+
+ return (
+
+
+
+
+
+ )
+}
+
+function ResetZoomButton() {
+ const [zoomLevel, setZoomLevel] = useAtom(zoomLevelAtom)
+
+ if (zoomLevel === 1) {
+ return null
+ }
+
+ return (
+
+ )
+}
+
+function ImagePreview({
+ fileUrl,
+ file,
+}: {
+ fileUrl: string
+ file: Doc<"files">
+}) {
+ const zoomLevel = useAtomValue(zoomLevelAtom)
+ return (
+
+ )
+}
diff --git a/packages/web/src/components/ui/dialog.tsx b/packages/web/src/components/ui/dialog.tsx
index 6cb123b..ba114f5 100644
--- a/packages/web/src/components/ui/dialog.tsx
+++ b/packages/web/src/components/ui/dialog.tsx
@@ -1,141 +1,144 @@
-import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { XIcon } from "lucide-react"
+import type * as React from "react"
import { cn } from "@/lib/utils"
function Dialog({
- ...props
+ ...props
}: React.ComponentProps) {
- return
+ return
}
function DialogTrigger({
- ...props
+ ...props
}: React.ComponentProps) {
- return
+ return
}
function DialogPortal({
- ...props
+ ...props
}: React.ComponentProps) {
- return
+ return
}
function DialogClose({
- ...props
+ ...props
}: React.ComponentProps) {
- return
+ return
}
function DialogOverlay({
- className,
- ...props
+ className,
+ ...props
}: React.ComponentProps) {
- return (
-
- )
+ return (
+
+ )
}
function DialogContent({
- className,
- children,
- showCloseButton = true,
- ...props
+ className,
+ children,
+ showCloseButton = true,
+ ...props
}: React.ComponentProps & {
- showCloseButton?: boolean
+ showCloseButton?: boolean
}) {
- return (
-
-
-
- {children}
- {showCloseButton && (
-
-
- Close
-
- )}
-
-
- )
+ return (
+
+
+
+ {children}
+ {showCloseButton && (
+
+
+ Close
+
+ )}
+
+
+ )
}
function DialogHeader({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- )
+ return (
+
+ )
}
function DialogFooter({ className, ...props }: React.ComponentProps<"div">) {
- return (
-
- )
+ return (
+
+ )
}
function DialogTitle({
- className,
- ...props
+ className,
+ ...props
}: React.ComponentProps) {
- return (
-
- )
+ return (
+
+ )
}
function DialogDescription({
- className,
- ...props
+ className,
+ ...props
}: React.ComponentProps) {
- return (
-
- )
+ return (
+
+ )
}
export {
- Dialog,
- DialogClose,
- DialogContent,
- DialogDescription,
- DialogFooter,
- DialogHeader,
- DialogOverlay,
- DialogPortal,
- DialogTitle,
- DialogTrigger,
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogOverlay,
+ DialogPortal,
+ DialogTitle,
+ DialogTrigger,
}
diff --git a/packages/web/src/directories/directory-page/context.ts b/packages/web/src/directories/directory-page/context.ts
index 86edb1e..2a65743 100644
--- a/packages/web/src/directories/directory-page/context.ts
+++ b/packages/web/src/directories/directory-page/context.ts
@@ -3,6 +3,7 @@ import type { DirectoryItem } from "@fileone/convex/model/directories"
import { createContext } from "react"
type DirectoryPageContextType = {
+ rootDirectory: Doc<"directories">
directory: Doc<"directories">
directoryContent: DirectoryItem[]
}
diff --git a/packages/web/src/directories/directory-page/directory-content-table.tsx b/packages/web/src/directories/directory-page/directory-content-table.tsx
index 1dfe4c4..e6554aa 100644
--- a/packages/web/src/directories/directory-page/directory-content-table.tsx
+++ b/packages/web/src/directories/directory-page/directory-content-table.tsx
@@ -41,6 +41,7 @@ import {
contextMenuTargeItemAtom,
itemBeingRenamedAtom,
newItemKindAtom,
+ openedFileAtom,
optimisticDeletedItemsAtom,
} from "./state"
@@ -83,7 +84,7 @@ const columns: ColumnDef[] = [
cell: ({ row }) => {
switch (row.original.kind) {
case "file":
- return
+ return
case "directory":
return
}
@@ -413,11 +414,20 @@ function DirectoryNameCell({ directory }: { directory: Doc<"directories"> }) {
)
}
-function FileNameCell({ initialName }: { initialName: string }) {
+function FileNameCell({ file }: { file: Doc<"files"> }) {
+ const setOpenedFile = useSetAtom(openedFileAtom)
return (
- {initialName}
+
)
}
diff --git a/packages/web/src/directories/directory-page/directory-page.tsx b/packages/web/src/directories/directory-page/directory-page.tsx
index 446b72a..fa2a114 100644
--- a/packages/web/src/directories/directory-page/directory-page.tsx
+++ b/packages/web/src/directories/directory-page/directory-page.tsx
@@ -3,7 +3,7 @@ import { baseName, splitPath } from "@fileone/path"
import { useMutation } from "@tanstack/react-query"
import { Link } from "@tanstack/react-router"
import { useMutation as useConvexMutation } from "convex/react"
-import { useSetAtom } from "jotai"
+import { useAtom, useSetAtom } from "jotai"
import {
ChevronDownIcon,
Loader2Icon,
@@ -12,6 +12,7 @@ import {
} from "lucide-react"
import { type ChangeEvent, Fragment, useContext, useRef } from "react"
import { toast } from "sonner"
+import { ImagePreviewDialog } from "@/components/image-preview-dialog"
import {
DropdownMenu,
DropdownMenuContent,
@@ -32,7 +33,7 @@ import { Button } from "../../components/ui/button"
import { DirectoryPageContext } from "./context"
import { DirectoryContentTable } from "./directory-content-table"
import { RenameFileDialog } from "./rename-file-dialog"
-import { newItemKindAtom } from "./state"
+import { newItemKindAtom, openedFileAtom } from "./state"
export function DirectoryPage() {
const { directory } = useContext(DirectoryPageContext)
@@ -49,6 +50,7 @@ export function DirectoryPage() {
+
>
)
}
@@ -184,3 +186,25 @@ function NewDirectoryItemDropdown() {
)
}
+
+function PreviewDialog() {
+ const [openedFile, setOpenedFile] = useAtom(openedFileAtom)
+
+ if (!openedFile) return null
+
+ console.log("openedFile", openedFile)
+
+ switch (openedFile.mimeType) {
+ case "image/jpeg":
+ case "image/png":
+ case "image/gif":
+ return (
+ setOpenedFile(null)}
+ />
+ )
+ default:
+ return null
+ }
+}
diff --git a/packages/web/src/directories/directory-page/state.ts b/packages/web/src/directories/directory-page/state.ts
index 68720c4..dfde8ed 100644
--- a/packages/web/src/directories/directory-page/state.ts
+++ b/packages/web/src/directories/directory-page/state.ts
@@ -1,4 +1,4 @@
-import type { Id } from "@fileone/convex/_generated/dataModel"
+import type { Doc, Id } from "@fileone/convex/_generated/dataModel"
import type {
DirectoryItem,
DirectoryItemKind,
@@ -20,3 +20,5 @@ export const itemBeingRenamedAtom = atom<{
originalItem: DirectoryItem
name: string
} | null>(null)
+
+export const openedFileAtom = atom | null>(null)