mirror of
https://github.com/khairul169/code-share.git
synced 2026-10-24 11:53:58 +07:00
feat: initial editor files, add toast
This commit is contained in:
@@ -4,6 +4,8 @@ import trpcServer from "~/server/api/trpc/trpc";
|
||||
|
||||
export const data = async (ctx: PageContext) => {
|
||||
const trpc = await trpcServer(ctx);
|
||||
const searchParams = ctx.urlParsed.search;
|
||||
const filesParam = searchParams.files ? searchParams.files.split(",") : null;
|
||||
|
||||
const project = await trpc.project.getById(ctx.routeParams?.slug!);
|
||||
if (!project) {
|
||||
@@ -11,14 +13,16 @@ export const data = async (ctx: PageContext) => {
|
||||
}
|
||||
|
||||
const files = await trpc.file.getAll({ projectId: project.id });
|
||||
const pinnedFiles = files.filter((i) => i.isPinned);
|
||||
const initialFiles = files.filter((i) =>
|
||||
filesParam != null ? filesParam.includes(i.path) : i.isPinned
|
||||
);
|
||||
|
||||
return {
|
||||
title: project.title,
|
||||
description: `Check ${project.title} on CodeShare!`,
|
||||
project,
|
||||
files,
|
||||
pinnedFiles,
|
||||
initialFiles,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ const ConsoleLogger = () => {
|
||||
const logs = useConsoleLogs();
|
||||
|
||||
return (
|
||||
<div className="h-full flex flex-col bg-[#242424] border-t border-t-gray-600">
|
||||
<div className="h-full flex flex-col bg-[#242424] border-t border-gray-700">
|
||||
<p className="py-2 px-3 uppercase text-xs">Console</p>
|
||||
<ErrorBoundary>
|
||||
<div className="overflow-y-auto flex-1">
|
||||
|
||||
@@ -20,21 +20,21 @@ import StatusBar from "./status-bar";
|
||||
import { FiTerminal } from "react-icons/fi";
|
||||
|
||||
const Editor = () => {
|
||||
const { project, pinnedFiles } = useData<Data>();
|
||||
const { project, initialFiles } = useData<Data>();
|
||||
const trpcUtils = trpc.useUtils();
|
||||
const projectCtx = useProjectContext();
|
||||
const [breakpoint] = useBreakpoint();
|
||||
|
||||
const [curTabIdx, setCurTabIdx] = useState(0);
|
||||
const [curOpenFiles, setOpenFiles] = useState<number[]>(
|
||||
pinnedFiles.map((i) => i.id)
|
||||
initialFiles.map((i) => i.id)
|
||||
);
|
||||
|
||||
const openedFilesData = trpc.file.getAll.useQuery(
|
||||
{ projectId: project.id, id: curOpenFiles },
|
||||
{ enabled: curOpenFiles.length > 0, initialData: pinnedFiles }
|
||||
{ enabled: curOpenFiles.length > 0, initialData: initialFiles }
|
||||
);
|
||||
const [openedFiles, setOpenedFiles] = useState<any[]>(pinnedFiles);
|
||||
const [openedFiles, setOpenedFiles] = useState<any[]>(initialFiles);
|
||||
|
||||
const deleteFile = trpc.file.delete.useMutation({
|
||||
onSuccess: (file) => {
|
||||
@@ -49,11 +49,11 @@ const Editor = () => {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (!pinnedFiles?.length || curOpenFiles.length > 0) {
|
||||
if (!initialFiles?.length || curOpenFiles.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
pinnedFiles.forEach((file) => {
|
||||
initialFiles.forEach((file) => {
|
||||
onOpenFile(file.id, false);
|
||||
});
|
||||
|
||||
@@ -61,7 +61,7 @@ const Editor = () => {
|
||||
setOpenFiles([]);
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [pinnedFiles]);
|
||||
}, [initialFiles]);
|
||||
|
||||
useEffect(() => {
|
||||
if (openedFilesData.data) {
|
||||
@@ -170,7 +170,7 @@ const Editor = () => {
|
||||
collapsedSize={0}
|
||||
/>
|
||||
|
||||
<ResizableHandle className="bg-slate-900" />
|
||||
<ResizableHandle className="w-0" />
|
||||
|
||||
<ResizablePanel defaultSize={{ sm: 100, md: 75 }}>
|
||||
<ResizablePanelGroup autoSaveId="code-editor" direction="vertical">
|
||||
@@ -185,7 +185,7 @@ const Editor = () => {
|
||||
|
||||
{breakpoint >= 2 ? (
|
||||
<>
|
||||
<ResizableHandle />
|
||||
<ResizableHandle className="!h-0" />
|
||||
|
||||
<ResizablePanel
|
||||
defaultSize={{ sm: 0, md: 20 }}
|
||||
|
||||
@@ -19,9 +19,8 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
DropdownMenuSeparator,
|
||||
} from "~/components/ui/dropdown-menu";
|
||||
import { cn, getPreviewUrl } from "~/lib/utils";
|
||||
import { cn, getPreviewUrl, getUrl, copy } from "~/lib/utils";
|
||||
import FileIcon from "~/components/ui/file-icon";
|
||||
import copy from "copy-to-clipboard";
|
||||
import { useData } from "~/renderer/hooks";
|
||||
import Spinner from "~/components/ui/spinner";
|
||||
import { Data } from "../+data";
|
||||
@@ -197,6 +196,13 @@ const FileItem = ({ file, createFileDlg }: FileItemProps) => {
|
||||
Open in new tab
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
copy(getUrl(project.slug + `?files=${file.path}`))
|
||||
}
|
||||
>
|
||||
Share
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
return updateFile.mutate({
|
||||
|
||||
@@ -11,8 +11,8 @@ type Props = {
|
||||
};
|
||||
|
||||
const FileViewer = ({ id }: Props) => {
|
||||
const { pinnedFiles } = useData<Data>();
|
||||
const initialData = pinnedFiles.find((i) => i.id === id);
|
||||
const { initialFiles } = useData<Data>();
|
||||
const initialData = initialFiles.find((i) => i.id === id);
|
||||
|
||||
const { data, isLoading, refetch } = trpc.file.getById.useQuery(id, {
|
||||
initialData,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from "react";
|
||||
import { FiSidebar, FiSmartphone, FiUser } from "react-icons/fi";
|
||||
import { FiArrowLeft, FiSidebar, FiSmartphone, FiUser } from "react-icons/fi";
|
||||
import { useStore } from "zustand";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { cn } from "~/lib/utils";
|
||||
@@ -22,24 +22,30 @@ const StatusBar = ({ className }: React.ComponentProps<"div">) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"h-10 flex items-center gap-1 pl-2 pr-3 w-full bg-slate-900 md:bg-[#242424] border-b md:border-b-0 md:border-t border-slate-900 md:border-black/30",
|
||||
"h-10 flex items-center gap-1 pl-2 pr-3 w-full bg-slate-800 md:bg-[#242424] md:border-t border-slate-900 md:border-black/30",
|
||||
className
|
||||
)}
|
||||
>
|
||||
<ActionButton
|
||||
title="Toggle Sidebar"
|
||||
title="Toggle Sidebar (CTRL+B)"
|
||||
icon={FiSidebar}
|
||||
className={sidebarExpanded ? "text-white" : ""}
|
||||
onClick={() => sidebarStore.getState().toggle()}
|
||||
/>
|
||||
<ActionButton
|
||||
title="Toggle Preview Window"
|
||||
title="Toggle Preview Window (CTRL+P)"
|
||||
icon={FiSmartphone}
|
||||
className={previewExpanded ? "text-white" : ""}
|
||||
onClick={() => previewStore.getState().toggle()}
|
||||
/>
|
||||
|
||||
<div className="flex-1"></div>
|
||||
<ActionButton
|
||||
title="Return to Home"
|
||||
href="/"
|
||||
icon={FiArrowLeft}
|
||||
size="lg"
|
||||
/>
|
||||
<Button
|
||||
href={user ? "/user" : "/auth/login?return=" + urlPathname}
|
||||
className="h-full p-0 gap-2 text-xs"
|
||||
|
||||
Reference in New Issue
Block a user