mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-10 02:54:15 +00:00
improve posts layout
This commit is contained in:
parent
d0003ca7f2
commit
f038784e78
@ -2,13 +2,10 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
width: 35vw;
|
width: 100%;
|
||||||
min-width: 300px;
|
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
|
|
||||||
//min-height: 165px;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
max-width: 800px;
|
|
||||||
|
|
||||||
background-color: var(--background-color-accent);
|
background-color: var(--background-color-accent);
|
||||||
|
|
||||||
|
@ -7,6 +7,10 @@ import mimetypes from "mime"
|
|||||||
|
|
||||||
import ContentFailed from "../contentFailed"
|
import ContentFailed from "../contentFailed"
|
||||||
|
|
||||||
|
import BearCarousel, { BearSlideCard } from "bear-react-carousel"
|
||||||
|
|
||||||
|
|
||||||
|
import "bear-react-carousel/dist/index.css"
|
||||||
import "react-responsive-carousel/lib/styles/carousel.min.css"
|
import "react-responsive-carousel/lib/styles/carousel.min.css"
|
||||||
import "plyr-react/dist/plyr.css"
|
import "plyr-react/dist/plyr.css"
|
||||||
import "./index.less"
|
import "./index.less"
|
||||||
@ -125,60 +129,40 @@ const Attachment = React.memo((props) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
export default React.memo((props) => {
|
export default React.memo((props) => {
|
||||||
const carouselRef = React.useRef(null)
|
const [controller, setController] = React.useState()
|
||||||
const [attachmentIndex, setAttachmentIndex] = React.useState(0)
|
const [carouselState, setCarouselState] = React.useState()
|
||||||
|
|
||||||
const handleAttachmentChange = (index) => {
|
|
||||||
const currentAttachmentIndex = carouselRef.current.state.selectedItem
|
|
||||||
const currentAttachment = carouselRef.current.itemsRef[currentAttachmentIndex].querySelector("video, audio")
|
|
||||||
|
|
||||||
if (currentAttachmentIndex !== index) {
|
|
||||||
// if the attachment is a video, pause it
|
|
||||||
if (currentAttachment) {
|
|
||||||
currentAttachment.pause()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// else if the attachment is a video, play it
|
|
||||||
if (currentAttachment) {
|
|
||||||
currentAttachment.play()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setAttachmentIndex(index)
|
|
||||||
}
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
// get attachment index from query string
|
// get attachment index from query string
|
||||||
const attachmentIndex = parseInt(new URLSearchParams(window.location.search).get("attachment"))
|
const attachmentIndex = parseInt(new URLSearchParams(window.location.search).get("attachment"))
|
||||||
|
|
||||||
if (attachmentIndex) {
|
if (attachmentIndex) {
|
||||||
setAttachmentIndex(attachmentIndex)
|
controller?.slideToPage(attachmentIndex)
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return <div className="post_attachments">
|
return <div className="post_attachments">
|
||||||
<Carousel
|
{
|
||||||
ref={carouselRef}
|
props.attachments?.length > 0 && <BearCarousel
|
||||||
showArrows={true}
|
data={props.attachments.map((attachment, index) => {
|
||||||
showStatus={false}
|
|
||||||
showThumbs={false}
|
|
||||||
showIndicators={props.attachments?.length > 1 ?? false}
|
|
||||||
selectedItem={attachmentIndex}
|
|
||||||
onChange={handleAttachmentChange}
|
|
||||||
transitionTime={150}
|
|
||||||
stopOnHover={true}
|
|
||||||
>
|
|
||||||
{
|
|
||||||
props.attachments?.length > 0 && props.attachments.map((attachment, index) => {
|
|
||||||
if (typeof attachment !== "object") {
|
if (typeof attachment !== "object") {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return <React.Fragment key={index}>
|
return {
|
||||||
<Attachment index={index} attachment={attachment} />
|
key: index,
|
||||||
</React.Fragment>
|
children: <React.Fragment key={index}>
|
||||||
})
|
<Attachment index={index} attachment={attachment} />
|
||||||
}
|
</React.Fragment>
|
||||||
</Carousel>
|
}
|
||||||
|
})}
|
||||||
|
isEnableNavButton
|
||||||
|
isEnableMouseMove
|
||||||
|
isEnablePagination
|
||||||
|
setController={setController}
|
||||||
|
onSlideChange={setCarouselState}
|
||||||
|
isDebug
|
||||||
|
/>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
})
|
})
|
@ -1,91 +1,44 @@
|
|||||||
.post_attachments {
|
.post_attachments {
|
||||||
display: flex;
|
box-sizing: border-box;
|
||||||
|
|
||||||
width: 100%;
|
position: relative;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
transition: all 0.2s ease-in-out;
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
|
||||||
.carousel-root {
|
overflow-x: hidden;
|
||||||
position: relative;
|
|
||||||
|
|
||||||
|
transition: all 150ms ease-in-out;
|
||||||
|
|
||||||
|
.bear-react-carousel__root {
|
||||||
font-family: "DM Mono", monospace;
|
font-family: "DM Mono", monospace;
|
||||||
|
|
||||||
height: 100%;
|
border-radius: 12px;
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.carousel {
|
overflow: hidden;
|
||||||
display: flex;
|
|
||||||
background-color: black;
|
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
.slider-wrapper {
|
background-color: black;
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-prev,
|
.bear-react-carousel__pagination-group {
|
||||||
.control-next {
|
|
||||||
color: #ffffff;
|
|
||||||
|
|
||||||
height: 100%;
|
|
||||||
width: 30px;
|
|
||||||
|
|
||||||
opacity: 0;
|
|
||||||
|
|
||||||
transition: all 150ms ease-in-out;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
opacity: 1;
|
|
||||||
width: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
transform: scale(0.5);
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
::before {
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-arrow {
|
|
||||||
z-index: 50;
|
|
||||||
}
|
|
||||||
|
|
||||||
.control-dots {
|
|
||||||
top: 0;
|
top: 0;
|
||||||
height: fit-content;
|
bottom: unset;
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
&:hover {
|
margin-top: 10px;
|
||||||
.dot {
|
|
||||||
height: 8px;
|
|
||||||
width: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dot {
|
|
||||||
transition: all 100ms ease-in;
|
|
||||||
|
|
||||||
height: 3px;
|
|
||||||
width: 15px;
|
|
||||||
|
|
||||||
border-radius: 2px;
|
|
||||||
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel-status {
|
.bear-react-carousel__pagination-group:not([data-page-content="true"]) .bear-react-carousel__pagination-button[data-active] {
|
||||||
padding: 10px;
|
background-color: var(--colorPrimary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.attachment {
|
.attachment {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
margin-bottom: 15px;
|
|
||||||
|
|
||||||
.user {
|
.user {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
@ -157,15 +157,15 @@ export default class PostCard extends React.PureComponent {
|
|||||||
return <div
|
return <div
|
||||||
key={this.props.index}
|
key={this.props.index}
|
||||||
id={this.props.data._id}
|
id={this.props.data._id}
|
||||||
|
style={this.props.style}
|
||||||
|
user-id={this.props.data.user_id}
|
||||||
|
context-menu={"postCard-context"}
|
||||||
className={classnames(
|
className={classnames(
|
||||||
"postCard",
|
"post_card",
|
||||||
{
|
{
|
||||||
["open"]: this.state.open,
|
["open"]: this.state.open,
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
style={this.props.style}
|
|
||||||
context-menu={"postCard-context"}
|
|
||||||
user-id={this.props.data.user_id}
|
|
||||||
>
|
>
|
||||||
<PostHeader
|
<PostHeader
|
||||||
postData={this.props.data}
|
postData={this.props.data}
|
||||||
@ -176,9 +176,6 @@ export default class PostCard extends React.PureComponent {
|
|||||||
id="post_content"
|
id="post_content"
|
||||||
className={classnames(
|
className={classnames(
|
||||||
"post_content",
|
"post_content",
|
||||||
{
|
|
||||||
["nsfw"]: this.state.isNsfw && !this.state.nsfwAccepted,
|
|
||||||
}
|
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
@ -205,7 +202,6 @@ export default class PostCard extends React.PureComponent {
|
|||||||
attachments={this.props.data.attachments}
|
attachments={this.props.data.attachments}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<PostActions
|
<PostActions
|
||||||
|
95
packages/app/src/components/PostCard/index.less
Executable file → Normal file
95
packages/app/src/components/PostCard/index.less
Executable file → Normal file
@ -1,69 +1,50 @@
|
|||||||
.postCard {
|
.post_card {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
width: 35vw;
|
width: 100%;
|
||||||
min-width: 300px;
|
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
|
|
||||||
//max-width: 600px;
|
gap: 15px;
|
||||||
//min-height: 165px;
|
padding: 17px 17px 0px 17px;
|
||||||
//height: 100%;
|
|
||||||
|
|
||||||
background-color: var(--background-color-accent);
|
background-color: var(--background-color-accent);
|
||||||
|
|
||||||
transition: all 150ms ease-in-out;
|
|
||||||
|
|
||||||
padding: 17px;
|
|
||||||
|
|
||||||
border-bottom: 2px solid var(--border-color);
|
border-bottom: 2px solid var(--border-color);
|
||||||
|
|
||||||
padding-bottom: 10px;
|
color: rgba(var(--background-color-contrast));
|
||||||
|
|
||||||
overflow: visible;
|
transition: all 0.2s ease-in-out;
|
||||||
|
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4,
|
||||||
|
h5,
|
||||||
|
h6,
|
||||||
|
p,
|
||||||
|
span {
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
.post_content {
|
.post_content {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
|
||||||
|
|
||||||
padding: 0 10px 10px 10px;
|
width: 100%;
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
color: rgba(var(--background-color-contrast));
|
gap: 10px;
|
||||||
|
|
||||||
overflow: hidden;
|
color: var(--text-color);
|
||||||
|
|
||||||
transition: all 0.2s ease-in-out;
|
|
||||||
|
|
||||||
z-index: 190;
|
|
||||||
|
|
||||||
h1,
|
|
||||||
h2,
|
|
||||||
h3,
|
|
||||||
h4,
|
|
||||||
h5,
|
|
||||||
h6,
|
|
||||||
p,
|
|
||||||
span {
|
|
||||||
color: var(--text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.nsfw {
|
|
||||||
.message {
|
|
||||||
filter: blur(10px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.post_attachments {
|
|
||||||
filter: blur(25px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nsfw_alert {
|
.nsfw_alert {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
|
z-index: 200;
|
||||||
|
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -75,36 +56,17 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
// -webkit-backdrop-filter: blur(25px);
|
|
||||||
// backdrop-filter: blur(25px);
|
|
||||||
//background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|
||||||
z-index: 200;
|
backdrop-filter: blur(25px);
|
||||||
|
-webkit-backdrop-filter: blur(25px);
|
||||||
|
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.message {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
font-size: 0.9rem;
|
|
||||||
font-weight: 400;
|
|
||||||
|
|
||||||
color: var(--background-color-contrast);
|
|
||||||
|
|
||||||
word-break: break-all;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
|
|
||||||
user-select: text;
|
|
||||||
}
|
|
||||||
|
|
||||||
>div {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:first-child {
|
&:first-child {
|
||||||
@ -117,6 +79,5 @@
|
|||||||
border-bottom-right-radius: 8px;
|
border-bottom-right-radius: 8px;
|
||||||
|
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,7 +17,7 @@ const LoadingComponent = () => {
|
|||||||
return <antd.Skeleton avatar
|
return <antd.Skeleton avatar
|
||||||
style={{
|
style={{
|
||||||
padding: "20px",
|
padding: "20px",
|
||||||
width: "35vw",
|
width: "100%",
|
||||||
height: "160px",
|
height: "160px",
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -34,6 +34,8 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.post-list_wrapper {
|
.post-list_wrapper {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
@ -42,6 +44,7 @@ html {
|
|||||||
width: fit-content;
|
width: fit-content;
|
||||||
|
|
||||||
//overflow: hidden;
|
//overflow: hidden;
|
||||||
|
overflow-x: hidden;
|
||||||
overflow-y: overlay;
|
overflow-y: overlay;
|
||||||
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -52,7 +55,8 @@ html {
|
|||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
// WARN: Only use if is a performance issue (If is using virtualized list)
|
// WARN: Only use if is a performance issue (If is using virtualized list)
|
||||||
//will-change: transform;
|
will-change: transform;
|
||||||
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
overflow-y: overlay;
|
overflow-y: overlay;
|
||||||
|
|
||||||
@ -66,17 +70,20 @@ html {
|
|||||||
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
|
|
||||||
margin: auto;
|
//margin: auto;
|
||||||
z-index: 150;
|
z-index: 150;
|
||||||
|
|
||||||
.postCard {
|
.postCard {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: none;
|
min-width: 0;
|
||||||
|
// FIXME: This is a walkaround for a bug when a post contains multiple attachments cause a overflow
|
||||||
|
max-width: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playlistTimelineEntry {
|
.playlistTimelineEntry {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: none;
|
min-width: 0;
|
||||||
|
max-width: unset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,8 +110,8 @@ html {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
width: 35vw;
|
width: 100%;
|
||||||
min-width: 300px;
|
//min-width: 300px;
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
@ -124,20 +124,40 @@ html {
|
|||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
|
|
||||||
@media screen and (max-width:2000px) {
|
.post_card {
|
||||||
max-width: 1000px;
|
max-width: 900px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 2000px) {
|
||||||
|
max-width: 1100px;
|
||||||
|
|
||||||
|
.post_card {
|
||||||
|
max-width: 750px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1444px) {
|
@media screen and (max-width: 1444px) {
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
|
|
||||||
|
.post_card {
|
||||||
|
max-width: 550px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1170px) {
|
@media screen and (max-width: 1170px) {
|
||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
|
|
||||||
|
.post_card {
|
||||||
|
max-width: 450px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1024px) {
|
@media screen and (max-width: 1024px) {
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
|
|
||||||
|
.post_card {
|
||||||
|
max-width: 350px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user