Skip to content

Commit

Permalink
Merge pull request #7 from LinumLabs/feature/mm/loading-image-grid-start
Browse files Browse the repository at this point in the history
Feature/mm/loading image grid start
  • Loading branch information
Rocco Russo authored Dec 21, 2021
2 parents c87148f + 8336923 commit 820d5a6
Show file tree
Hide file tree
Showing 23 changed files with 316 additions and 32 deletions.
4 changes: 4 additions & 0 deletions assets/gear-icon-72a7cf.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion components/ContentHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import HamburgerIcon from 'assets/icons/hamburger.svg';
import UnionIcon from 'assets/icons/union.svg';
import Dropdown from 'components/Dropdown';
import usePods from 'hooks/usePods';
import { useRouter } from 'next/router';

const ContentHeader = () => {
const { pods } = usePods();
const router = useRouter();
const { slug = '/' } = router.query;

return (
<div className="my-6 flex justify-between">
Expand All @@ -15,7 +18,7 @@ const ContentHeader = () => {
<FolderIcon />
</Dropdown>
<span className="text-xl font-semibold text-purple">
Pod 2 / Folder 111
{slug[0]} {slug[1] && `/ ${slug[1]}`}
</span>
</div>

Expand Down
34 changes: 34 additions & 0 deletions components/DirsGrid/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { PodDir } from 'contexts/Dirs';
import Link from 'next/link';

interface Props {
pod: string;
dirs: PodDir[];
}

const DirsGrid = ({ pod, dirs }: Props) => {
return (
<div className="flex flex-wrap my-6">
{dirs &&
dirs.map((dir, key: number) => (
<div key={key} className="text-purple">
<Link href={`/pods/${pod}/${dir.name}`}>
<a className="inline-block w-72 h-72 mr-12 rounded-lg bg-gray"></a>
</Link>
<footer className="px-2 py-3">
<div>
<strong>{dir.name}</strong>
</div>
<div>
{new Intl.DateTimeFormat('en-GB', {
dateStyle: 'long',
}).format(Number(dir.creation_time) * 1000)}
</div>
</footer>
</div>
))}
</div>
);
};

export default DirsGrid;
13 changes: 8 additions & 5 deletions components/Dropdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import useOnClickOutside from 'use-onclickoutside';

export interface DropdownItem {
title: string;
href?: string;
slug?: string;
}

type Props = {
Expand Down Expand Up @@ -44,13 +44,16 @@ const Dropdown = ({
{children}
</Button>
{show && (
<div className="absolute top-full left-0 right-0 min-w-min whitespace-nowrap mt-1 py-3 bg-white rounded-md border-blue border">
<div className="z-10 absolute top-full left-0 right-0 min-w-min whitespace-nowrap mt-1 py-3 bg-white rounded-md border-blue border">
<ul>
{options.map((option: DropdownItem, ix: number) => (
<li key={`${ix}${option.title}`}>
{option.href ? (
<Link href={option.href}>
<a className="block py-1 px-6 hover:bg-indigo-300">
{option.slug ? (
<Link href={option.slug}>
<a
className="block py-1 px-6 hover:bg-indigo-300"
onClick={() => setShow(false)}
>
{option.title}
</a>
</Link>
Expand Down
4 changes: 4 additions & 0 deletions components/ImageGrid/ImageGrid.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.imageGridItem {
height: 180px;
padding: 6px;
}
27 changes: 27 additions & 0 deletions components/ImageGrid/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import classes from './ImageGrid.module.scss';

interface Props {
images: string[];
className?: string;
}

const ImageGrid = ({ images }: Props) => {
return (
<div className={classes.content}>
<div className="flex flex-wrap">
{images && !!images.length
? images.map((file, key: number) => (
<img
className={classes.imageGridItem}
src={file}
key={String(key) + file}
alt={String(key)}
/>
))
: 'No photos'}
</div>
</div>
);
};

export default ImageGrid;
12 changes: 11 additions & 1 deletion components/Sidebar/Sidebar.module.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
.root {
// display: flex;
@apply absolute;
@apply left-0;
@apply top-0;
@apply z-0;
@apply w-48;
@apply lg:w-72;
@apply px-6;
@apply py-20;
@apply bg-white;
@apply shadow-xl;
@apply min-h-full;
}

.list {
Expand Down
4 changes: 1 addition & 3 deletions components/Sidebar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ const Sidebar = () => {
const { slug = '/' } = router.query;

return (
<aside
className={`fixed left-0 top-0 bottom-0 z-0 w-48 lg:w-72 px-6 pt-20 bg-white shadow-xl ${classes.root}`}
>
<aside className={classes.root}>
<header className="font-semibold text-2xl text-purple my-6">
Your Pods
</header>
Expand Down
11 changes: 11 additions & 0 deletions components/Spinner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import GearIcon from 'assets/gear-icon-72a7cf.svg';

const Spinner = () => {
return (
<div className="inline-block animate-spin-slow">
<GearIcon />
</div>
);
};

export default Spinner;
2 changes: 1 addition & 1 deletion components/Topbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Topbar = () => {

return (
<header
className={`fixed flex top-0 left-0 right-0 z-10 h-20 bg-gray ${classes.root}`}
className={`fixed flex top-0 left-0 right-0 z-10 h-20 bg-blue ${classes.root}`}
>
<div className="w-72 pl-5">
<Link href="/">
Expand Down
20 changes: 20 additions & 0 deletions contexts/Dirs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { createContext, Dispatch, SetStateAction } from 'react';

export type PodDir = {
access_time: string;
content_type: string;
creation_time: string;
modification_time: string;
name: string;
};

export interface DirsContextProps {
dirs: PodDir[];
setDirs: Dispatch<SetStateAction<PodDir[]>>;
}

export const DirsContext = createContext<DirsContextProps>(
{} as DirsContextProps
);

export default DirsContext.Provider;
22 changes: 22 additions & 0 deletions contexts/Files.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { createContext, Dispatch, SetStateAction } from 'react';

export type PodFile = {
access_time: string;
block_size: string;
content_type: string;
creation_time: string;
modification_time: string;
name: string;
size: string;
};

export interface FilesContextProps {
files: string[];
setFiles: Dispatch<SetStateAction<string[]>>;
}

export const FilesContext = createContext<FilesContextProps>(
{} as FilesContextProps
);

export default FilesContext.Provider;
3 changes: 3 additions & 0 deletions helpers/urlPath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function urlPath(path: string): string {
return path.replace(/&/g, '/');
}
6 changes: 6 additions & 0 deletions hooks/useDirs.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { DirsContext } from 'contexts/Dirs';
import { useContext } from 'react';

const useDirs = () => useContext(DirsContext);

export default useDirs;
101 changes: 96 additions & 5 deletions hooks/useFairOs.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable no-useless-catch */
// import qs from 'qs';
import axios from 'axios';
import { PodDir } from 'contexts/Dirs';
import { PodItem } from 'contexts/Pods';
import { PodFile } from 'contexts/Files';
import useUser from 'hooks/useUser';
import { Dispatch, SetStateAction, useState } from 'react';

interface Payload {
username?: string;
Expand All @@ -20,7 +23,14 @@ const host = process.env.NEXT_PUBLIC_FAIROSHOST;

const podNameDefault = 'Home';

export interface DownloadFilesPayload {
podName: string;
directory: string;
files: any;
}

const useFairOs = () => {
const [abortList, setAbortList] = useState<AbortController[]>([]);
const { user } = useUser();

const login = async (payload: Payload) => {
Expand Down Expand Up @@ -126,7 +136,18 @@ const useFairOs = () => {
withCredentials: true,
});

return response;
const filteredResponse: { dirs: PodDir[]; files: PodFile[] } = {
dirs: response.data.dirs,
files: [],
};

// filter out non-images
response?.data?.files?.forEach((file: PodFile) => {
if (file.content_type.search('image/') !== -1)
filteredResponse.files.push(file);
});

return filteredResponse;
} catch (error) {
throw error;
}
Expand All @@ -142,11 +163,15 @@ const useFairOs = () => {
},
withCredentials: true,
});

return response;
};

const openPod = async (podName: string) => {
abortList.forEach((controller) => {
controller.abort();
});
setAbortList([]);

try {
const openPod = await axios({
baseURL: host,
Expand Down Expand Up @@ -176,22 +201,86 @@ const useFairOs = () => {
const podsWithHref: PodItem[] = [];

data.pod_name.forEach((pod: string) => {
if (pod.toLowerCase() === 'home') {
if (pod === 'Home') {
podsWithHref.push({
title: pod,
slug: '/',
});
} else {
podsWithHref.push({
title: pod,
slug: `/pods/${pod.toLowerCase()}`,
slug: `/pods/${pod}`,
});
}
});

return podsWithHref;
};

const downloadFilePreview = async (
filename: string,
directory: string,
podName: string
) => {
const controller = new AbortController();
let writePath = '';

if (directory === 'root') {
writePath = '/';
} else {
writePath = '/' + directory + '/';
}

const formData = new FormData();

formData.append('pod_name', podName);
formData.append('file_path', writePath + filename);

setAbortList((list) => {
return [...list, controller];
});

try {
const downloadFile = await axios.post(host + 'file/download', formData, {
data: formData,
responseType: 'blob',
withCredentials: true,
signal: controller.signal,
});

return downloadFile.data;
} catch (err) {
return err;
}
};

const downloadAllFiles = (
payload: DownloadFilesPayload,
setFiles: Dispatch<SetStateAction<string[]>>,
callback: () => void
) => {
const { files, directory, podName } = payload;

if (files !== null && files !== undefined) {
files.map(async (entry: any) => {
const url = window.URL.createObjectURL(
await downloadFilePreview(entry.name, directory, podName)
);

// Incremental loading
setFiles((list) => {
return [...list, url];
});
});

callback && callback();

return files;
}

return null;
};

return {
login,
logout,
Expand All @@ -200,6 +289,8 @@ const useFairOs = () => {
getPods,
getPodsWithHref,
openPod,
downloadFilePreview,
downloadAllFiles,
};
};

Expand Down
6 changes: 6 additions & 0 deletions hooks/useFiles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { FilesContext } from 'contexts/Files';
import { useContext } from 'react';

const useFiles = () => useContext(FilesContext);

export default useFiles;
Loading

0 comments on commit 820d5a6

Please sign in to comment.