diff --git a/client/components/app/index.tsx b/client/components/app/index.tsx index 8504e8f4..3e68a12e 100644 --- a/client/components/app/index.tsx +++ b/client/components/app/index.tsx @@ -26,7 +26,7 @@ const App = ({ accents_6: 'var(--darker-gray)', accents_7: 'var(--darkest-gray)', accents_8: 'var(--darkest-gray)', - border: 'var(--light-gray)', + border: 'var(--lightest-gray)', }, expressiveness: { dropdownBoxShadow: '0 0 0 1px var(--light-gray)', diff --git a/client/components/file-tree/file-tree.module.css b/client/components/file-tree/file-tree.module.css new file mode 100644 index 00000000..09d7f77f --- /dev/null +++ b/client/components/file-tree/file-tree.module.css @@ -0,0 +1,99 @@ +.fileTreeWrapper { + display: block; + position: absolute; + left: 0; + height: 100%; +} + +.fileTreeWrapper h5 { + text-align: center; +} + +.fileTree { + list-style: none; + width: 100%; +} + +.fileTree li { + transition: var(--transition); + border-radius: var(--radius); + padding: var(--gap-half) 0; + margin: 0; +} + +.fileTree li:hover { + background: var(--lighter-gray); +} + +.fileTree li .fileTreeIcon { + display: inline-block; + padding-right: var(--gap-half); + padding-left: var(--gap-half); +} + +.fileTree li .fileTreeTitle { + font-size: 1.1rem; +} + +.fileTree li::before { + content: ""; + padding: 0; + margin: 0; +} + +.card { + top: 0; + overflow-y: scroll; + overflow-x: hidden; + position: fixed; +} + +.cardContent { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: var(--gap-half); + padding-top: 200px; +} + +@media screen and (max-width: 82rem) { + .fileTreeWrapper { + position: relative; + width: 100%; + height: auto; + margin-top: var(--gap); + } + + .card { + position: relative; + padding: 0; + } + + .cardContent { + margin: var(--gap); + padding: 0; + } + + .fileTree { + width: 100%; + } + + .fileTree li { + padding: 0.5rem 0; + } + + .fileTree li .fileTreeIcon { + margin-right: var(--gap-half); + } + + .fileTree li .fileTreeTitle { + font-size: 1.2rem; + } + + .fileTree li::before { + content: ""; + padding: 0; + margin: 0; + } +} diff --git a/client/components/file-tree/index.tsx b/client/components/file-tree/index.tsx new file mode 100644 index 00000000..ebd905dd --- /dev/null +++ b/client/components/file-tree/index.tsx @@ -0,0 +1,61 @@ +import { File } from "@lib/types" +import { Card, Link, Text } from '@geist-ui/core' +import FileIcon from '@geist-ui/icons/fileText' +import CodeIcon from '@geist-ui/icons/fileLambda' +import styles from './file-tree.module.css' +import ShiftBy from "@components/shift-by" +import { useEffect, useState } from "react" +import { codeFileExtensions } from "@lib/constants" + +type Item = File & { + icon: JSX.Element +} + +const FileTree = ({ + files +}: { + files: File[] +}) => { + const [items, setItems] = useState([]) + useEffect(() => { + const newItems = files.map(file => { + const extension = file.title.split('.').pop() + if (codeFileExtensions.includes(extension || '')) { + return { + ...file, + icon: + } + } else { + return { + ...file, + icon: + } + } + }) + setItems(newItems) + }, [files]) + + // a list of files with an icon and a title + return ( +
+ +
+ Files +
    + {items.map(({ id, title, icon }) => ( +
  • + + + {icon} + {title} + +
  • + ))} +
+
+
+
+ ) +} + +export default FileTree \ No newline at end of file diff --git a/client/components/new-post/drag-and-drop/index.tsx b/client/components/new-post/drag-and-drop/index.tsx index a20ca0e1..75ac7aaa 100644 --- a/client/components/new-post/drag-and-drop/index.tsx +++ b/client/components/new-post/drag-and-drop/index.tsx @@ -4,103 +4,8 @@ import { useDropzone } from 'react-dropzone' import styles from './drag-and-drop.module.css' import type { Document } from '@lib/types' import generateUUID from '@lib/generate-uuid' -const allowedFileTypes = [ - 'application/json', - 'application/x-javascript', - 'application/xhtml+xml', - 'application/xml', - 'text/xml', - 'text/plain', - 'text/html', - 'text/csv', - 'text/tab-separated-values', - 'text/x-c', - 'text/x-c++', - 'text/x-csharp', - 'text/x-java', - 'text/x-javascript', - 'text/x-php', - 'text/x-python', - 'text/x-ruby', - 'text/x-scala', - 'text/x-swift', - 'text/x-typescript', - 'text/x-vb', - 'text/x-vbscript', - 'text/x-yaml', - 'text/x-c++', - 'text/x-c#', - 'text/mathml', - 'text/x-markdown', - 'text/markdown', -] +import { allowedFileTypes, allowedFileNames, allowedFileExtensions } from '@lib/constants' -const allowedFileNames = [ - 'Makefile', - 'README', - 'Dockerfile', - 'Jenkinsfile', - 'LICENSE', - '.env', - '.gitignore', - '.gitattributes', - '.env.example', - '.env.development', - '.env.production', - '.env.test', - '.env.staging', - '.env.development.local', - 'yarn.lock', - '.bash', - '.bashrc', - '.bash_profile', - '.bash_logout', - '.profile', - '.fish_prompt', - '.zshrc', - '.zsh', - '.zprofile', -] - -const allowedFileExtensions = [ - 'json', - 'js', - 'jsx', - 'ts', - 'tsx', - 'c', - 'cpp', - 'c++', - 'c#', - 'java', - 'php', - 'py', - 'rb', - 'scala', - 'swift', - 'vb', - 'vbscript', - 'yaml', - 'less', - 'stylus', - 'styl', - 'sass', - 'scss', - 'lock', - 'md', - 'markdown', - 'txt', - 'html', - 'htm', - 'css', - 'csv', - 'log', - 'sql', - 'xml', - 'webmanifest', - 'vue', - 'vuex', -] function FileDropzone({ setDocs }: { setDocs: ((docs: Document[]) => void) }) { const { palette } = useTheme() diff --git a/client/components/post-page/index.tsx b/client/components/post-page/index.tsx index ca79e581..8816264a 100644 --- a/client/components/post-page/index.tsx +++ b/client/components/post-page/index.tsx @@ -10,6 +10,7 @@ import { Page, Button, Text, Badge, Tooltip, Spacer } from "@geist-ui/core" import ShiftBy from "@components/shift-by" import { useMemo, useState } from "react" import timeAgo from "@lib/time-ago" +import FileTree from "@components/file-tree" type Props = { post: Post @@ -61,6 +62,7 @@ const PostPage = ({ post }: Props) => { Download as ZIP archive + {post.files.length > 1 && } {post.files.map(({ id, content, title }: File) => (