diff --git a/package.json b/package.json index b797b5e7..bc2d9cc2 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,8 @@ "@rtk-query/codegen-openapi": "^1.0.0-alpha.1", "@svgr/webpack": "^6.2.1", "@tippyjs/react": "^4.2.6", + "@toast-ui/editor": "^3.1.3", + "@toast-ui/editor-plugin-code-syntax-highlight": "^3.0.0", "@toast-ui/react-editor": "^3.1.3", "@udecode/plate": "^10.4.2", "animate.css": "^4.1.1", @@ -37,6 +39,7 @@ "html-webpack-plugin": "^5.5.0", "linkify-it": "^3.0.3", "localforage": "^1.10.0", + "masonry-layout": "^4.2.2", "mini-css-extract-plugin": "^2.6.0", "react": "^17.0.2", "react-dev-utils": "^12.0.0", @@ -49,6 +52,7 @@ "react-icons": "^4.3.1", "react-linkify": "^1.0.0-alpha", "react-markdown": "^8.0.1", + "react-pdf": "^5.7.1", "react-redux": "^7.2.6", "react-refresh": "^0.11.0", "react-router-dom": "6", diff --git a/src/assets/icons/arrow.down.svg b/src/assets/icons/arrow.down.svg new file mode 100644 index 00000000..3d50acd0 --- /dev/null +++ b/src/assets/icons/arrow.down.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icons/check.sign.svg b/src/assets/icons/check.sign.svg new file mode 100644 index 00000000..bf14a8ec --- /dev/null +++ b/src/assets/icons/check.sign.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/common/component/FileBox/index.js b/src/common/component/FileBox/index.js index 97379a6e..4a68e840 100644 --- a/src/common/component/FileBox/index.js +++ b/src/common/component/FileBox/index.js @@ -9,6 +9,7 @@ import { ImagePreview, PdfPreview, CodePreview, + DocPreview, } from "./preview"; import { getFileIcon, formatBytes } from "../../utils"; import IconDownload from "../../../assets/icons/download.svg"; @@ -40,9 +41,9 @@ const renderPreview = (data) => { case checks.code.test(_type): preview = ; break; - // case checks.doc.test(_type): - // icon = ; - // break; + case checks.doc.test(_type): + preview = ; + break; case checks.audio.test(_type): preview = ; break; @@ -70,8 +71,14 @@ export default function FileBox({ const icon = getFileIcon(file_type, name); if (!content || !fromUser || !name) return null; console.log("file content", content, name, flex); + const previewContent = renderPreview({ file_type, content, name }); + const withPreview = preview && previewContent; return ( - +
{icon}
@@ -88,11 +95,7 @@ export default function FileBox({
- {preview && ( -
- {renderPreview({ file_type, content, name })} -
- )} + {withPreview &&
{previewContent}
} ); } diff --git a/src/common/component/FileBox/preview/Code.js b/src/common/component/FileBox/preview/Code.js index afa65105..837f32f1 100644 --- a/src/common/component/FileBox/preview/Code.js +++ b/src/common/component/FileBox/preview/Code.js @@ -8,6 +8,8 @@ const Styled = styled.div` overflow: scroll; white-space: pre-wrap; word-break: break-all; + background-color: #000; + color: #eee; `; export default function Code({ url = "" }) { const [content, setContent] = useState(""); diff --git a/src/common/component/FileBox/preview/Doc.js b/src/common/component/FileBox/preview/Doc.js new file mode 100644 index 00000000..88bb3349 --- /dev/null +++ b/src/common/component/FileBox/preview/Doc.js @@ -0,0 +1,26 @@ +import { useState, useEffect } from "react"; +import styled from "styled-components"; +const Styled = styled.div` + background-color: #fff; + height: 218px; + padding: 15px 15px 0 15px; + line-height: 1.4; + overflow: scroll; + white-space: pre-wrap; + word-break: break-all; +`; +export default function Doc({ url = "" }) { + const [content, setContent] = useState(""); + useEffect(() => { + const getContent = async (url) => { + if (!url) return; + const resp = await fetch(url); + const txt = await resp.text(); + setContent(txt); + }; + getContent(url); + }, [url]); + if (!content) return null; + + return {content}; +} diff --git a/src/common/component/FileBox/preview/Pdf.js b/src/common/component/FileBox/preview/Pdf.js index c10cc05b..a16098bc 100644 --- a/src/common/component/FileBox/preview/Pdf.js +++ b/src/common/component/FileBox/preview/Pdf.js @@ -2,7 +2,8 @@ import { useState } from "react"; import styled from "styled-components"; import { Document, Page } from "react-pdf"; const Styled = styled.div` - height: 218px; + padding: 8px; + /* height: 218px; */ overflow: hidden; img { width: 100%; diff --git a/src/common/component/FileBox/preview/index.js b/src/common/component/FileBox/preview/index.js index deb5f0e7..b3798e34 100644 --- a/src/common/component/FileBox/preview/index.js +++ b/src/common/component/FileBox/preview/index.js @@ -3,5 +3,13 @@ import AudioPreview from "./Audio"; import ImagePreview from "./Image"; import PdfPreview from "./Pdf"; import CodePreview from "./Code"; +import DocPreview from "./Doc"; -export { VideoPreview, AudioPreview, ImagePreview, PdfPreview, CodePreview }; +export { + VideoPreview, + AudioPreview, + ImagePreview, + PdfPreview, + CodePreview, + DocPreview, +}; diff --git a/src/common/component/FileBox/styled.js b/src/common/component/FileBox/styled.js index e1791065..d3010dd8 100644 --- a/src/common/component/FileBox/styled.js +++ b/src/common/component/FileBox/styled.js @@ -5,12 +5,19 @@ const Styled = styled.div` box-sizing: border-box; border-radius: 6px; width: 370px; - max-height: 281px; - height: fit-content; - overflow: hidden; + height: 66px; + /* height: fit-content; */ + * { + user-select: text; + } &.flex { width: 100%; } + &.preview { + position: relative; + overflow: hidden; + height: 281px; + } .basic { padding: 8px; display: flex; @@ -26,11 +33,14 @@ const Styled = styled.div` flex-direction: column; gap: 4px; width: 100%; + overflow: hidden; .name { font-weight: 600; font-size: 14px; line-height: 20px; color: #1c1c1e; + white-space: nowrap; + text-overflow: ellipsis; } .details { font-weight: 400; @@ -49,6 +59,8 @@ const Styled = styled.div` } } .preview { + overflow: hidden; + /* todo */ } `; diff --git a/src/common/hook/useFilteredChannels.js b/src/common/hook/useFilteredChannels.js new file mode 100644 index 00000000..88014b0b --- /dev/null +++ b/src/common/hook/useFilteredChannels.js @@ -0,0 +1,28 @@ +import { useState, useEffect } from "react"; +import { useSelector } from "react-redux"; +export default function useFilteredChannels() { + const [input, setInput] = useState(""); + const channels = useSelector((store) => Object.values(store.channels.byId)); + const [filteredChannels, setfilteredChannels] = useState([]); + useEffect(() => { + if (!input) { + setfilteredChannels(channels); + } else { + let str = ["", ...input.toLowerCase(), ""].join(".*"); + let reg = new RegExp(str); + setfilteredChannels( + channels.filter((c) => { + return reg.test(c.name.toLowerCase()); + }) + ); + } + }, [input]); + const updateInput = (val) => { + setInput(val); + }; + return { + input, + channels: filteredChannels, + updateInput, + }; +} diff --git a/src/routes/home/ServerDropList.js b/src/routes/home/ServerDropList.js index b6a46ecd..3d8c1556 100644 --- a/src/routes/home/ServerDropList.js +++ b/src/routes/home/ServerDropList.js @@ -4,15 +4,12 @@ import styled from "styled-components"; const StyledWrapper = styled.div` min-height: 56px; - padding: 0 20px; - padding-right: 5px; display: flex; justify-content: space-between; align-items: center; - box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.1); - &.expand { + /* &.expand { padding-right: 16px; - } + } */ .server { display: flex; align-items: center; diff --git a/src/routes/home/styled.js b/src/routes/home/styled.js index 069d653c..ae3e1157 100644 --- a/src/routes/home/styled.js +++ b/src/routes/home/styled.js @@ -9,6 +9,7 @@ const StyledWrapper = styled.div` display: flex; flex-direction: column; &.left { + align-items: center; position: relative; background: #e5e7eb; width: 64px; @@ -21,7 +22,7 @@ const StyledWrapper = styled.div` margin: 8px 16px; } &.expand { - width: 180px; + width: 140px; } } &.right { diff --git a/src/routes/resources/Filter.js b/src/routes/resources/Filter.js deleted file mode 100644 index e1e1672d..00000000 --- a/src/routes/resources/Filter.js +++ /dev/null @@ -1,18 +0,0 @@ -// import React from "react"; -import styled from "styled-components"; -const Styled = styled.div` - /* padding: 20px 0; */ - display: flex; - align-items: center; - gap: 8px; - .filter { - } -`; - -export default function Filter() { - return ( - -
filter item
-
- ); -} diff --git a/src/routes/resources/Filter/Channel.js b/src/routes/resources/Filter/Channel.js new file mode 100644 index 00000000..812b1307 --- /dev/null +++ b/src/routes/resources/Filter/Channel.js @@ -0,0 +1,87 @@ +// import React from 'react' +// import { useSelector } from "react-redux"; +import styled from "styled-components"; +import CheckSign from "../../../assets/icons/check.sign.svg"; +import ChannelIcon from "../../../common/component/ChannelIcon"; +import Search from "../Search"; +import useFilteredChannels from "../../../common/hook/useFilteredChannels"; +const Styled = styled.div` + padding: 0 4px 4px 4px; + background: #ffffff; + max-height: 400px; + overflow: auto; + box-shadow: 0px 24px 48px -12px rgba(16, 24, 40, 0.18); + border-radius: 8px; + display: flex; + flex-direction: column; + align-items: flex-start; + position: relative; + > .search { + z-index: 1; + background-color: #fff; + position: sticky; + top: 0; + input { + z-index: 2; + } + } + > .list { + width: 100%; + display: flex; + flex-direction: column; + gap: 16px; + padding: 8px; + .channel { + position: relative; + cursor: pointer; + display: flex; + align-items: center; + gap: 8px; + .name { + color: #616161; + font-weight: 600; + font-size: 14px; + line-height: 20px; + } + .check { + position: absolute; + right: 0; + top: 50%; + transform: translateY(-50%); + } + } + } +`; +export default function Channel({ select = "", updateFilter }) { + const { input, updateInput, channels } = useFilteredChannels(); + const handleClick = (gid) => { + updateFilter({ channel: gid }); + }; + return ( + +
+ +
+
    +
  • + + Any Channel + {!select && } +
  • + {channels.map(({ gid, is_public, name }) => { + return ( +
  • + + {name} + {select == gid && } +
  • + ); + })} +
+
+ ); +} diff --git a/src/routes/resources/Filter/From.js b/src/routes/resources/Filter/From.js new file mode 100644 index 00000000..695d591b --- /dev/null +++ b/src/routes/resources/Filter/From.js @@ -0,0 +1,89 @@ +// import React from 'react' +import { useSelector } from "react-redux"; +import styled from "styled-components"; +import Search from "../Search"; +import CheckSign from "../../../assets/icons/check.sign.svg"; + +import Contact from "../../../common/component/Contact"; +import useFilteredUsers from "../../../common/hook/useFilteredUsers"; +const Styled = styled.div` + padding: 0 4px 4px 4px; + background: #ffffff; + max-height: 230px; + overflow: auto; + box-shadow: 0px 24px 48px -12px rgba(16, 24, 40, 0.18); + border-radius: 8px; + display: flex; + flex-direction: column; + align-items: flex-start; + position: relative; + > .search { + z-index: 1; + background-color: #fff; + position: sticky; + top: 0; + input { + z-index: 2; + } + } + > .list { + width: 100%; + display: flex; + flex-direction: column; + .contact { + position: relative; + cursor: pointer; + &.none { + padding: 10px; + font-weight: 600; + font-size: 14px; + line-height: 20px; + color: #616161; + } + .check { + position: absolute; + right: 6px; + top: 50%; + transform: translateY(-50%); + } + } + } +`; +export default function From({ select = "", updateFilter }) { + const { input, updateInput, contacts } = useFilteredUsers(); + // const contacts=useSelector(store=>store.contacts); + + // const uid=contacts.ids; + // const dataMap=contacts.byId; + const handleClick = (uid) => { + updateFilter({ from: uid }); + }; + return ( + +
+ +
+
    +
  • + Anyone + {!select && } +
  • + {contacts.map(({ uid }) => { + return ( +
  • + + {select == uid && } +
  • + ); + })} +
+
+ ); +} diff --git a/src/routes/resources/Filter/Type.js b/src/routes/resources/Filter/Type.js new file mode 100644 index 00000000..bbc871da --- /dev/null +++ b/src/routes/resources/Filter/Type.js @@ -0,0 +1,111 @@ +// import React from 'react' +import { useSelector } from "react-redux"; +import styled from "styled-components"; +import IconPdf from "../../../assets/icons/file.pdf.svg"; +import IconAudio from "../../../assets/icons/file.audio.svg"; +import IconVideo from "../../../assets/icons/file.video.svg"; +import IconUnkown from "../../../assets/icons/file.unkown.svg"; +import IconDoc from "../../../assets/icons/file.doc.svg"; +import IconCode from "../../../assets/icons/file.code.svg"; +import IconImage from "../../../assets/icons/file.image.svg"; +import CheckSign from "../../../assets/icons/check.sign.svg"; + +const Styled = styled.div` + padding: 12px; + background: #ffffff; + min-width: 200px; + /* max-height: 230px; */ + overflow: auto; + box-shadow: 0px 24px 48px -12px rgba(16, 24, 40, 0.18); + border-radius: 8px; + display: flex; + flex-direction: column; + align-items: flex-start; + position: relative; + > .list { + width: 100%; + display: flex; + flex-direction: column; + gap: 16px; + .type { + position: relative; + cursor: pointer; + display: flex; + align-items: center; + gap: 8px; + color: #616161; + .icon { + width: 15px; + height: auto; + } + .check { + position: absolute; + right: 0; + top: 50%; + transform: translateY(-50%); + } + } + } +`; +export const FileTypes = { + doc: { + title: "Documents", + icon: , + }, + pdf: { + title: "PDFs", + icon: , + }, + image: { + title: "Images", + icon: , + }, + audio: { + title: "Audio", + icon: , + }, + video: { + title: "Videos", + icon: , + }, + code: { + title: "Code Snippets", + icon: , + }, + unkown: { + title: "Unkown Files", + icon: , + }, +}; +export default function Type({ select = "", updateFilter }) { + // const { input, updateInput, contacts } = useFilteredUsers(); + // const contacts=useSelector(store=>store.contacts); + + // const uid=contacts.ids; + // const dataMap=contacts.byId; + const handleClick = (uid) => { + updateFilter({ type: uid }); + }; + return ( + +
    +
  • + Any Type + {!select && } +
  • + {Object.entries(FileTypes).map(([type, { title, icon }]) => { + return ( +
  • + {icon} {title} + {select == type && } +
  • + ); + })} +
+
+ ); +} diff --git a/src/routes/resources/Filter/index.js b/src/routes/resources/Filter/index.js new file mode 100644 index 00000000..7b68b95c --- /dev/null +++ b/src/routes/resources/Filter/index.js @@ -0,0 +1,103 @@ +// import React from "react"; +import styled from "styled-components"; +import Tippy from "@tippyjs/react"; +import { useSelector } from "react-redux"; +import { FileTypes } from "./Type"; +import Avatar from "../../../common/component/Avatar"; +import FilterFrom from "./From"; +import FilterChannel from "./Channel"; +import FilterType from "./Type"; +import ArrowDown from "../../../assets/icons/arrow.down.svg"; +const Styled = styled.div` + /* padding: 20px 0; */ + display: flex; + align-items: center; + gap: 8px; + .filter { + cursor: pointer; + display: flex; + align-items: center; + gap: 8px; + border: 1px solid #d0d5dd; + box-sizing: border-box; + box-shadow: 0px 1px 2px rgba(16, 24, 40, 0.05); + border-radius: var(--br); + padding: 7px 12px; + font-weight: 500; + font-size: 12px; + line-height: 18px; + &.selected { + border: none; + color: #fff; + background-color: #22ccee; + .arrow path { + stroke: #fff; + } + } + .avatar { + width: 16px; + height: 16px; + border-radius: 50%; + } + } +`; + +export default function Filter({ filter, updateFilter }) { + const { contactMap, channelMap } = useSelector((store) => { + return { contactMap: store.contacts.byId, channelMap: store.channels.byId }; + }); + console.log("maps", contactMap, filter); + const { from, channel, type } = filter; + return ( + + + } + > +
+ {from && ( + + )} + From {from && contactMap[from].name} + +
+
+ + } + > +
+ + {channel ? `In ${channelMap[channel].name}` : `Channel`} + + +
+
+ + } + > +
+ {type ? FileTypes[type].title : "Type"} + +
+
+
+ ); +} diff --git a/src/routes/resources/Search.js b/src/routes/resources/Search.js index 7196ad1d..2100430f 100644 --- a/src/routes/resources/Search.js +++ b/src/routes/resources/Search.js @@ -1,8 +1,44 @@ // import React from "react"; import styled from "styled-components"; +import iconSearch from "../../assets/icons/search.svg?url"; const Styled = styled.div` + width: 100%; padding: 6px 16px; + box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.1); + &.embed { + padding: 6px 8px; + box-shadow: none; + } + .search { + outline: none; + background-color: rgba(0, 0, 0, 0.08); + border-radius: 25px; + padding: 10px 8px 10px 36px; + color: #a1a1aa; + font-weight: 400; + font-size: 14px; + line-height: 20px; + background-image: url(${iconSearch}); + background-repeat: no-repeat; + background-position: 8px center; + } `; -export default function Search() { - return s; +export default function Search({ + value = "", + updateSearchValue = null, + embed = false, +}) { + const handleChange = (evt) => { + updateSearchValue(evt.target.value); + }; + return ( + + + + ); } diff --git a/src/routes/resources/index.js b/src/routes/resources/index.js index aa8067b6..f222d6e5 100644 --- a/src/routes/resources/index.js +++ b/src/routes/resources/index.js @@ -1,13 +1,16 @@ import { useState, useEffect, useRef } from "react"; import Styled from "./styled"; import { useSelector } from "react-redux"; +import Masonry from "masonry-layout"; // import waterfall from "waterfall.js/src/waterfall"; import View, { Views } from "./View"; import Search from "./Search"; import Filter from "./Filter"; import FileBox from "../../common/component/FileBox"; +let msnry = null; export default function ResourceManagement() { const listContainerRef = useRef(null); + const [filter, setFilter] = useState({}); const [view, setView] = useState(Views.item); const { fileMessages, message } = useSelector((store) => { return { message: store.message, fileMessages: store.fileMessage }; @@ -16,13 +19,29 @@ export default function ResourceManagement() { const toggleView = () => { setView((prev) => (prev == Views.item ? Views.grid : Views.item)); }; - // useEffect(() => { - // if (view == Views.grid && listContainerRef) { - // const wtf = waterfall(listContainerRef.current); - // console.log("wtf", wtf); - // waterfall - // } - // }, [view]); + const updateFilter = (data) => { + setFilter((prev) => { + return { ...prev, ...data }; + }); + }; + useEffect(() => { + if (view == Views.grid && listContainerRef) { + msnry = new Masonry(listContainerRef.current, { + // options + itemSelector: ".file_box", + // columnWidth: 200 + }); + } else { + if (msnry) { + msnry.destroy(); + } + } + // return ()=>{ + // if(msnry){ + // msnry.destory() + // } + // } + }, [view]); console.log("files", fileMessages); return ( @@ -30,7 +49,7 @@ export default function ResourceManagement() {
- +
diff --git a/src/routes/resources/styled.js b/src/routes/resources/styled.js index a3c2e19e..3f4512c0 100644 --- a/src/routes/resources/styled.js +++ b/src/routes/resources/styled.js @@ -5,27 +5,33 @@ const Styled = styled.div` display: flex; flex-direction: column; align-items: flex-start; - padding: 0 16px; + .opts { - padding: 20px 0; + padding: 20px 16px; display: flex; justify-content: space-between; width: 100%; } - .list { + > .list { + padding: 0 16px; height: 100%; overflow-y: scroll; width: 100%; - gap: 8px; + + display: flex; &.item { - display: flex; + gap: 8px; flex-direction: column; /* align-items: flex-start; */ } &.grid { - display: grid; - grid-template-columns: repeat(4, 1fr); - grid-template-rows: auto; + flex-direction: row; + flex-wrap: wrap; + > .file_box { + flex-direction: column; + margin-right: 8px; + margin-bottom: 8px; + } } } `; diff --git a/yarn.lock b/yarn.lock index 47044e38..8a21b23b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2066,6 +2066,13 @@ dependencies: tippy.js "^6.3.1" +"@toast-ui/editor-plugin-code-syntax-highlight@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@toast-ui/editor-plugin-code-syntax-highlight/-/editor-plugin-code-syntax-highlight-3.0.0.tgz#a82a7b75f12386280be7efdc7c6f5bf5b48744f3" + integrity sha512-62XB3IcFgvRxVZzj2kTeQao0xACotv/mD6jScSDkWac2V0jkCsTh0kZRG4TSW5bGdKvx4xz3YjFm7gWgw1I/Aw== + dependencies: + prismjs "^1.23.0" + "@toast-ui/editor@^3.1.3": version "3.1.3" resolved "https://registry.yarnpkg.com/@toast-ui/editor/-/editor-3.1.3.tgz#12f15dab1fc9c1db336683f51208f8ba8017abb9" @@ -4349,6 +4356,11 @@ dequal@^2.0.0: resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d" integrity sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug== +desandro-matches-selector@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/desandro-matches-selector/-/desandro-matches-selector-2.0.2.tgz#717beed4dc13e7d8f3762f707a6d58a6774218e1" + integrity sha1-cXvu1NwT59jzdi9wem1YpndCGOE= + destroy@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" @@ -4887,6 +4899,11 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +ev-emitter@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ev-emitter/-/ev-emitter-1.1.1.tgz#8f18b0ce5c76a5d18017f71c0a795c65b9138f2a" + integrity sha512-ipiDYhdQSCZ4hSbX4rMW+XzNKMD1prg/sTvoVmSLkuQ1MVlwjJQQA+sW8tMYR3BLUr9KjodFV4pvzunvRhd33Q== + event-source-polyfill@^1.0.26: version "1.0.26" resolved "https://registry.yarnpkg.com/event-source-polyfill/-/event-source-polyfill-1.0.26.tgz#86c04d088ef078279168eefa028f928fec5059a4" @@ -5030,7 +5047,7 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-loader@^6.2.0: +file-loader@^6.0.0, file-loader@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== @@ -5155,6 +5172,13 @@ firebase@^9.6.9: "@firebase/storage-compat" "0.1.11" "@firebase/util" "1.5.0" +fizzy-ui-utils@^2.0.0: + version "2.0.7" + resolved "https://registry.yarnpkg.com/fizzy-ui-utils/-/fizzy-ui-utils-2.0.7.tgz#7df45dcc4eb374a08b65d39bb9a4beedf7330505" + integrity sha512-CZXDVXQ1If3/r8s0T+v+qVeMshhfcuq0rqIFgJnrtd+Bu8GmDmqMjntjUePypVtjHXKJ6V4sw9zeyox34n9aCg== + dependencies: + desandro-matches-selector "^2.0.0" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -5294,6 +5318,11 @@ get-own-enumerable-property-symbols@^3.0.0: resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== +get-size@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/get-size/-/get-size-2.0.3.tgz#54a1d0256b20ea7ac646516756202769941ad2ef" + integrity sha512-lXNzT/h/dTjTxRbm9BXb+SGxxzkm97h/PCIKtlN/CBCxxmkkIVV21udumMS93MuVTDX583gqc94v3RjuHmI+2Q== + get-stream@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" @@ -6488,6 +6517,11 @@ magic-string@^0.25.0, magic-string@^0.25.7: dependencies: sourcemap-codec "^1.4.8" +make-cancellable-promise@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/make-cancellable-promise/-/make-cancellable-promise-1.1.0.tgz#b4e9fcb31db3a27417e44f80cffa598ec9ac9f4e" + integrity sha512-X5Opjm2xcZsOLuJ+Bnhb4t5yfu4ehlA3OKEYLtqUchgVzL/QaqW373ZUVxVHKwvJ38cmYuR4rAHD2yUvAIkTPA== + make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -6500,6 +6534,11 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +make-event-props@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-event-props/-/make-event-props-1.3.0.tgz#2434cb390d58bcf40898d009ef5b1f936de9671b" + integrity sha512-oWiDZMcVB1/A487251hEWza1xzgCzl6MXxe9aF24l5Bt9N9UEbqTqKumEfuuLhmlhRZYnc+suVvW4vUs8bwO7Q== + map-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -6531,6 +6570,14 @@ markdown-it@^12.0.0, markdown-it@^12.2.0: mdurl "^1.0.1" uc.micro "^1.0.5" +masonry-layout@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/masonry-layout/-/masonry-layout-4.2.2.tgz#d57b44af13e601bfcdc423f1dd8348b5524de348" + integrity sha512-iGtAlrpHNyxaR19CvKC3npnEcAwszXoyJiI8ARV2ePi7fmYhIud25MHK8Zx4P0LCC4d3TNO9+rFa1KoK1OEOaA== + dependencies: + get-size "^2.0.2" + outlayer "^2.1.0" + mdast-util-definitions@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-5.1.0.tgz#b6d10ef00a3c4cf191e8d9a5fa58d7f4a366f817" @@ -6644,11 +6691,21 @@ meow@^8.0.0: type-fest "^0.18.0" yargs-parser "^20.2.3" +merge-class-names@^1.1.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/merge-class-names/-/merge-class-names-1.4.2.tgz#78d6d95ab259e7e647252a7988fd25a27d5a8835" + integrity sha512-bOl98VzwCGi25Gcn3xKxnR5p/WrhWFQB59MS/aGENcmUc6iSm96yrFDF0XSNurX9qN4LbJm0R9kfvsQ17i8zCw== + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= +merge-refs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/merge-refs/-/merge-refs-1.0.0.tgz#388348bce22e623782c6df9d3c4fc55888276120" + integrity sha512-WZ4S5wqD9FCR9hxkLgvcHJCBxzXzy3VVE6p8W2OzxRzB+hLRlcadGE2bW9xp2KSzk10rvp4y+pwwKO6JQVguMg== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -7291,6 +7348,15 @@ orderedmap@^1.1.0: resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-1.1.5.tgz#4174c90b61bd7c25294932edf789f3b5677744d0" integrity sha512-/fzlCGKRmfayGoI9UUXvJfc2nMZlJHW30QqEvwPvlg8tsX7jyiUSomYie6mYqx7Z9bOMGoag0H/q1PS/0PjYkg== +outlayer@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/outlayer/-/outlayer-2.1.1.tgz#29863b6de10ea5dadfffcadfa0d728907387e9a2" + integrity sha1-KYY7beEOpdrf/8rfoNcokHOH6aI= + dependencies: + ev-emitter "^1.0.0" + fizzy-ui-utils "^2.0.0" + get-size "^2.0.2" + outline-icons@^1.38.1: version "1.41.1" resolved "https://registry.yarnpkg.com/outline-icons/-/outline-icons-1.41.1.tgz#a56968fb3f955c692dcb0b4aeb17894ff2649ff4" @@ -7477,6 +7543,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pdfjs-dist@2.12.313: + version "2.12.313" + resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-2.12.313.tgz#62f2273737bb956267ae2e02cdfaddcb1099819c" + integrity sha512-1x6iXO4Qnv6Eb+YFdN5JdUzt4pAkxSp3aLAYPX93eQCyg/m7QFzXVWJHJVtoW48CI8HCXju4dSkhQZwoheL5mA== + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -8054,7 +8125,7 @@ pretty-error@^4.0.0: lodash "^4.17.20" renderkid "^3.0.0" -prismjs@^1.25.0, prismjs@~1.27.0: +prismjs@^1.23.0, prismjs@^1.25.0, prismjs@~1.27.0: version "1.27.0" resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== @@ -8077,7 +8148,7 @@ prompts@^2.4.2: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.0.0, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.7.2, prop-types@^15.8.1: +prop-types@^15.0.0, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -8477,6 +8548,22 @@ react-medium-image-zoom@^3.1.3: resolved "https://registry.yarnpkg.com/react-medium-image-zoom/-/react-medium-image-zoom-3.1.3.tgz#b1470abc5a342d65c23021c01bafa8c731821478" integrity sha512-5CoU8whSCz5Xz2xNeGD34dDfZ6jaf/pybdfZh8HNUmA9mbXbLfj0n6bQWfEUwkq9lsNg1sEkyeIJq2tcvZY8bw== +react-pdf@^5.7.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/react-pdf/-/react-pdf-5.7.1.tgz#d540cee152b2747763b0173ed70ab69be5b64a5b" + integrity sha512-0G0Yb5Lx/B52+AJcLoJ3181IOet4ug7hgyE/U3/0QHcj5lK8i0DYZJSnE3KowAi0p8FBfUhp6QngUgJZGmuKIQ== + dependencies: + "@babel/runtime" "^7.0.0" + file-loader "^6.0.0" + make-cancellable-promise "^1.0.0" + make-event-props "^1.1.0" + merge-class-names "^1.1.1" + merge-refs "^1.0.0" + pdfjs-dist "2.12.313" + prop-types "^15.6.2" + tiny-invariant "^1.0.0" + tiny-warning "^1.0.0" + react-popper@2.2.5, react-popper@^2.2.4: version "2.2.5" resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.2.5.tgz#1214ef3cec86330a171671a4fbcbeeb65ee58e96" @@ -9857,7 +9944,12 @@ tiny-invariant@1.0.6: resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.0.6.tgz#b3f9b38835e36a41c843a3b0907a5a7b3755de73" integrity sha512-FOyLWWVjG+aC0UqG76V53yAWdXfH8bO6FNmyZOuUrzDzK8DI3/JRY25UD7+g49JWM1LXwymsKERB+DzI0dTEQA== -tiny-warning@^1.0.3: +tiny-invariant@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.2.0.tgz#a1141f86b672a9148c72e978a19a73b9b94a15a9" + integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg== + +tiny-warning@^1.0.0, tiny-warning@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==