basic file opening

This commit is contained in:
Djeeberjr 2021-07-28 12:49:35 +02:00
parent b08a527199
commit 67cbf7ab28
10 changed files with 196 additions and 3 deletions

3
src/App.module.scss Normal file
View File

@ -0,0 +1,3 @@
.imageOpener{
width: 90%;
}

View File

View File

@ -1,5 +1,4 @@
import React from "react"
import "./App.scss"
import FileBrowser from "./components/FileBrowser"
const App: React.FC = () => {

View File

@ -3,9 +3,12 @@ import { useState } from "react"
import { useOpenDirQuery } from "../generated/graphql"
import Breadcrum from "./Breadcrum"
import FileBrowserElement from "./FileBrowserElement"
import FileOpen from "./FileOpen"
const FileBrowser: React.FC = () => {
const [path,setPath] = useState("/")
const [openFileId, setOpenFileId] = useState("")
const [showFile, setShowFile] = useState(false)
const { data } = useOpenDirQuery({
variables:{
@ -31,18 +34,25 @@ const FileBrowser: React.FC = () => {
{ data?.directorys.map(v => (<FileBrowserElement
key={v?.id}
dir={v}
onClick={(data)=>{
setPath(data.id)
onClick={(dir)=>{
setPath(dir.id)
}}
/>))}
{ data?.files.map(v => (<FileBrowserElement
key={v?.id}
file={v}
onClick={(file)=>{
setOpenFileId(file.id)
setShowFile(true)
}}
/>))}
</tbody>
</table>
</div>
{<FileOpen id={openFileId} show={showFile} onCloseClick={()=>{
setShowFile(false)
}} />}
</div>
)
}

View File

@ -0,0 +1,69 @@
import React from "react"
import PropTypes from "prop-types"
import { useGetFileQuery } from "../generated/graphql"
import ImageOpener from "./ImageOpener"
import TextOpener from "./TextOpener"
interface Props {
id: string
show: boolean
onCloseClick?: ()=>void
}
const FileOpen: React.FC<Props> = (props) => {
const { data } = useGetFileQuery({
variables:{
id: props.id
}
})
let opener = <div>TODO</div>
if(data?.file != null){
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
if (data.file.contentType?.startsWith("image/")){
opener = <ImageOpener file={data?.file} />
}else if (data.file.contentType?.startsWith("text/")){
opener = <TextOpener file={data.file} />
}else{
// Get Opener bases on file extension
const ext = data.file.name?.split(".").pop()
switch (ext) {
case "png":
case "jpg":
case "jpeg":
case "gif":
// TODO: more ext
opener = <ImageOpener file={data.file} />
break
case "txt":
case "md":
opener = <TextOpener file={data.file} />
break
default:
opener = <ImageOpener file={data?.file} />
break
}
}
}
return (
<div className={`modal modal-sm ${props.show ? "active":""}`}>
<a className="modal-overlay" onClick={()=>{
props.onCloseClick?.()
}}></a>
<div className="modal-container">
{opener}
</div>
</div>
)
}
FileOpen.propTypes = {
id: PropTypes.string.isRequired,
show: PropTypes.bool.isRequired,
onCloseClick: PropTypes.func
}
export default FileOpen

View File

@ -0,0 +1,23 @@
import React from "react"
import PropTypes from "prop-types"
import { File } from "../generated/graphql"
import genDownloadLink from "../functions/genDownloadLink"
import style from "./../App.module.scss"
interface Props {
file: File
}
const ImageOpener: React.FC<Props> = (props) => {
return (
<div className={style.imageOpener}>
<img className="img-responsive img-fit-cover" src={genDownloadLink(props.file.id)}/>
</div>
)
}
ImageOpener.propTypes = {
file: PropTypes.any.isRequired
}
export default ImageOpener

View File

@ -0,0 +1,23 @@
import React from "react"
import PropTypes from "prop-types"
import { File } from "../generated/graphql"
interface Props {
file: File
}
const TextOpener: React.FC<Props> = (props) => {
return (
<div>
<textarea>
{props.file.name}
</textarea>
</div>
)
}
TextOpener.propTypes = {
file: PropTypes.any.isRequired,
}
export default TextOpener

View File

@ -0,0 +1,5 @@
function genDownloadLink(id:string): string {
return `/api/file?id=${encodeURIComponent(id)}`
}
export default genDownloadLink

View File

@ -58,6 +58,19 @@ export type RootQueryFilesArgs = {
path: Scalars["String"];
};
export type GetFileQueryVariables = Exact<{
id: Scalars["ID"];
}>;
export type GetFileQuery = (
{ __typename?: "RootQuery" }
& { file?: Maybe<(
{ __typename?: "File" }
& Pick<File, "id" | "name" | "size" | "contentType" | "etag">
)> }
);
export type OpenDirQueryVariables = Exact<{
path: Scalars["String"];
}>;
@ -75,6 +88,45 @@ export type OpenDirQuery = (
);
export const GetFileDocument = gql`
query getFile($id: ID!) {
file(id: $id) {
id
name
size
contentType
etag
}
}
`
/**
* __useGetFileQuery__
*
* To run a query within a React component, call `useGetFileQuery` and pass it any options that fit your needs.
* When your component renders, `useGetFileQuery` returns an object from Apollo Client that contains loading, error, and data properties
* you can use to render your UI.
*
* @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
*
* @example
* const { data, loading, error } = useGetFileQuery({
* variables: {
* id: // value for 'id'
* },
* });
*/
export function useGetFileQuery(baseOptions: Apollo.QueryHookOptions<GetFileQuery, GetFileQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useQuery<GetFileQuery, GetFileQueryVariables>(GetFileDocument, options)
}
export function useGetFileLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<GetFileQuery, GetFileQueryVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useLazyQuery<GetFileQuery, GetFileQueryVariables>(GetFileDocument, options)
}
export type GetFileQueryHookResult = ReturnType<typeof useGetFileQuery>;
export type GetFileLazyQueryHookResult = ReturnType<typeof useGetFileLazyQuery>;
export type GetFileQueryResult = Apollo.QueryResult<GetFileQuery, GetFileQueryVariables>;
export const OpenDirDocument = gql`
query openDir($path: String!) {
files(path: $path) {

View File

@ -0,0 +1,9 @@
query getFile($id: ID!){
file(id: $id){
id
name
size
contentType
etag
}
}