Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc. changes related to media grid, figcaption handling, demo login layout #249

Merged
merged 2 commits into from
Feb 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const nextConfig = {
ignoreBuildErrors: true,
},
images: {
domains: ["images.unsplash.com"],
domains: ["images.unsplash.com", "res.cloudinary.com"],
},
gaTrackingId: "UA-120251616-1",
basePath,
Expand Down
44 changes: 0 additions & 44 deletions src/components/MediaItem.tsx

This file was deleted.

8 changes: 8 additions & 0 deletions src/components/NoSsr.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import dynamic from "next/dynamic";
import React from "react";

const NoSsr = (props) => <React.Fragment>{props.children}</React.Fragment>;

export default dynamic(() => Promise.resolve(NoSsr), {
ssr: false,
});
53 changes: 21 additions & 32 deletions src/components/file-explorer/InfiniteScrollList.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import InfiniteScroll from "react-infinite-scroll-component";
import React from "react";
import styled from "styled-components";
import { LoadingOutlined } from "@ant-design/icons";

interface IInfiniteScrollListProps {
Expand All @@ -15,38 +14,28 @@ const InfiniteScrollList = ({
loadMore,
}: IInfiniteScrollListProps) => {
return (
<Container>
<InfiniteScroll
height={400}
dataLength={data.length}
next={loadMore}
hasMore={data.length < count}
loader={<LoadingOutlined spin style={{ padding: 40 }} />}
>
<div className="image-grid">{data}</div>
</InfiniteScroll>
</Container>
<>
<div className="grid">
<InfiniteScroll
height={400}
dataLength={data.length}
next={loadMore}
hasMore={data.length < count}
loader={<LoadingOutlined spin style={{ padding: 40 }} />}
>
<div className="image-grid">{data}</div>
</InfiniteScroll>
</div>
<style jsx>{`
.image-grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
/* grid-auto-rows: minmax(50px, auto); */
}
`}</style>
</>
);
};

export default InfiniteScrollList;

const Container = styled.div`
.image-grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
grid-auto-rows: minmax(50px, auto);

.image-item:nth-child(5n) {
grid-column-end: span 2;
}

img {
display: flex;
width: 100%;
height: 100%;
object-fit: cover;
}
}
`;
59 changes: 24 additions & 35 deletions src/components/file-explorer/MediaItem.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from "react";
import styled from "styled-components";

import { Media } from "@/__generated__/__types__";

Expand All @@ -18,41 +17,31 @@ const MediaItem: React.FC<IProps> = ({
onMediaSelected(media);
};

const classes = isSelected ? " selected" : "";
const classes = isSelected ? "item selected" : "item";
return (
<Container data-testid="media-item" className={classes} onClick={onSelect}>
<div className="post-thumbnail">
<img src={media.url} />
</div>
<div className="post-body with-border">
<div className="post-header hide">
<div className="post-meta">
{/* Placeholder for something cool. maybe*/}
</div>
</div>
<div className="post-content">
<div className="post-name">{media.name}</div>
</div>
</div>
</Container>
<div data-testid="media-item" className={classes} onClick={onSelect}>
<img src={media.url} />

<style jsx>{`
img {
display: flex;
width: 100%;
object-fit: cover;
}
.item {
align-items: center;
display: flex;
background: rgba(var(--color-border), 0.5);
padding: 10px;
}
.item.selected {
background: rgba(var(--accent), 0.5);
}
/* .item:nth-child(5n) {
grid-column-end: span 2;
} */
`}</style>
</div>
);
};
export default MediaItem;

const Container = styled.article`
.post-thumbnail {
height: 150px;
img {
object-fit: cover;
width: 100%;
height: 100%;
}
}
border: 2px solid transparent;
&.selected {
border: 2px solid var(--color-base);
}
.post-name {
font-size: x-small;
}
`;
5 changes: 3 additions & 2 deletions src/components/file-explorer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useRef, useState } from "react";
import { uploadFile } from "@/shared/utils";
import { MediaProvider } from "src/shared/types";
import { TypeMediaInsert } from "letterpad-editor";
import NoSsr from "../NoSsr";

interface IProps {
isVisible: boolean;
Expand Down Expand Up @@ -89,7 +90,7 @@ const FileExplorer = ({
const hasSelectedImages = Object.keys(selectedUrls).length > 0;
if (!isVisible) return null;
return (
<>
<NoSsr>
<Modal
centered
className="file-explorer"
Expand Down Expand Up @@ -153,7 +154,7 @@ const FileExplorer = ({
}
}
`}</style>
</>
</NoSsr>
);
};

Expand Down
79 changes: 79 additions & 0 deletions src/components/grid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import Image from "next/image";
import { useEffect, useRef, useState } from "react";

export const Grid = ({ images, actions, onClick }) => {
const ref = useRef<HTMLDivElement>(null);
const [width, setWidth] = useState(200);

useEffect(() => {
handleResize();
}, [ref.current]);

useEffect(() => {
window.addEventListener("resize", handleResize);

return () => {
window.removeEventListener("resize", handleResize);
};
}, []);

const handleResize = () => {
if (ref.current) {
const node = ref.current.firstChild;
if (node) {
//@ts-ignore
setWidth(node.clientWidth);
}
}
};

return (
<>
<div className="grid" ref={ref}>
{images.map((image, index) => {
image = getDimensions({ ...image }, width - 20);
return (
<div className="image-item">
<Image
{...image}
src={image.url}
loading="lazy"
alt="kkkk"
onClick={() => onClick && onClick(index)}
/>
{actions && actions(index)}
</div>
);
})}
</div>
<style jsx>{`
.grid {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-rows: minmax(50px, auto);
}
.image-item {
display: flex;
align-items: center;
justify-content: space-evenly;
background: rgb(var(--content-bg));
flex-direction: column;
}
`}</style>
</>
);
};

function getDimensions(image, availableWidth: number) {
const aspectRatio = image.width / image.height;
image.width = availableWidth;
image.height = availableWidth / aspectRatio;

while (image.height > availableWidth) {
image.width -= 1;
image.height -= 1;
}

return image;
}
2 changes: 1 addition & 1 deletion src/components/login/views/LoginForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export const LoginForm = ({
<Row
justify="center"
align="middle"
style={{ paddingLeft: 10, height: "calc(100% - 60px)" }}
style={{ paddingLeft: 10, height: "calc(100% - 70px)" }}
>
<Form
name="basic"
Expand Down
23 changes: 18 additions & 5 deletions src/components/login/views/LoginFormDemo.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Button, message, Row } from "antd";
import { Button, message } from "antd";
import { useCallback } from "react";
import { doLogin } from "../actions";
import { key } from "../constants";
Expand All @@ -17,14 +17,27 @@ export const LoginFormDemo = ({ isVisible }: { isVisible: boolean }) => {
if (!isVisible) return null;
return (
<>
<Row justify="space-between" align="middle" style={{ paddingLeft: 10 }}>
You are logging into a demo account. Few features will be disabled.
<div
className="container"
style={{ paddingLeft: 10, height: "calc(100% - 70px)" }}
>
<span>
You are logging into a demo account. Few features will be disabled.
</span>
<br />
<br />
<Button onClick={loginAction} data-testid="btn-login">
<Button onClick={loginAction} type="primary" data-testid="btn-login">
Enter Now
</Button>
</Row>
</div>
<style jsx global>{`
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
`}</style>
</>
);
};
2 changes: 1 addition & 1 deletion src/components/post/components/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const insertImageInEditor = (editor: Editor["editor"], images: any) => {
newNode.innerHTML = `
<figure>
<img src="${image.src}" alt="${image.caption}">
<figcaption>${image.caption}</figcaption>
<figcaption contenteditable>${image.caption}</figcaption>
</figure>
`;
range.insertNode(newNode);
Expand Down
18 changes: 18 additions & 0 deletions src/components/post/components/tinymce/tinymce.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,24 @@ const LpEditor: React.FC<Props> = ({ text }) => {
onMediaBrowse && onMediaBrowse();
},
});
editor.on("keydown", function (e) {
// move cursor to next element when hitting enter on figcaption
if (e.key == "Enter") {
const tag = editorRef.current?.selection.getNode().tagName;
if (tag === "FIGCAPTION") {
const range = new Range();
const nextEle =
editorRef.current?.selection.getNode().parentElement
?.parentElement?.nextElementSibling;
if (nextEle) {
range.setStart(nextEle, 0);
range.setEnd(nextEle, 0);
editorRef.current?.selection.setRng(range, true);
}
}
e.preventDefault();
}
});
},
entity_encoding: "raw",
}}
Expand Down
Loading