mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-10 02:54:15 +00:00
improve component layout
This commit is contained in:
parent
38e88b48a7
commit
63ec7daa7a
@ -1,5 +1,6 @@
|
||||
import React from "react"
|
||||
import * as antd from "antd"
|
||||
import classnames from "classnames"
|
||||
import moment from "moment"
|
||||
|
||||
import { Icons } from "components/Icons"
|
||||
@ -48,11 +49,10 @@ const CommentCard = (props) => {
|
||||
}
|
||||
|
||||
export default (props) => {
|
||||
const [visible, setVisible] = React.useState(props.visible ?? true)
|
||||
const [comments, setComments] = React.useState(null)
|
||||
|
||||
const fetchData = async () => {
|
||||
setComments(null)
|
||||
|
||||
// fetch comments
|
||||
const commentsResult = await PostModel.getPostComments({
|
||||
post_id: props.post_id
|
||||
@ -123,9 +123,19 @@ export default (props) => {
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
fetchData()
|
||||
listenEvents()
|
||||
setVisible(props.visible)
|
||||
}, [props.visible])
|
||||
|
||||
React.useEffect(() => {
|
||||
if (visible) {
|
||||
fetchData()
|
||||
listenEvents()
|
||||
} else {
|
||||
unlistenEvents()
|
||||
}
|
||||
}, [visible])
|
||||
|
||||
React.useEffect(() => {
|
||||
return () => {
|
||||
unlistenEvents()
|
||||
}
|
||||
@ -149,17 +159,23 @@ export default (props) => {
|
||||
})
|
||||
}
|
||||
|
||||
if (!comments) {
|
||||
return <antd.Skeleton active />
|
||||
}
|
||||
|
||||
return <div className="comments">
|
||||
return <div
|
||||
id="comments"
|
||||
className={classnames(
|
||||
"comments",
|
||||
{
|
||||
"hidden": !visible
|
||||
}
|
||||
)}
|
||||
>
|
||||
<div className="header">
|
||||
<h3>
|
||||
<Icons.MessageSquare /> Comments
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
{renderComments()}
|
||||
|
||||
<div className="commentCreatorWrapper">
|
||||
<CommentCreator
|
||||
onSubmit={handleCommentSubmit}
|
||||
|
@ -16,6 +16,18 @@
|
||||
color: var(--text-color);
|
||||
}
|
||||
|
||||
&.hidden {
|
||||
height: 0px;
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
transition: all 150ms ease-in-out;
|
||||
|
||||
.comment {
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
@ -11,7 +11,7 @@ export default (props) => {
|
||||
<Button
|
||||
type="ghost"
|
||||
shape="circle"
|
||||
onClick={props.onClickComments}
|
||||
onClick={props.onClick}
|
||||
icon={<Icons.MessageCircle />}
|
||||
/>
|
||||
{
|
||||
|
@ -8,16 +8,36 @@ import CommentsButton from "./commentsButton"
|
||||
|
||||
import "./index.less"
|
||||
|
||||
const SelfActionsItems = [
|
||||
{
|
||||
key: "onClickEdit",
|
||||
label: <>
|
||||
<Icons.Edit />
|
||||
<span>Edit</span>
|
||||
</>,
|
||||
},
|
||||
{
|
||||
key: "onClickDelete",
|
||||
label: <>
|
||||
<Icons.Trash />
|
||||
<span>Delete</span>
|
||||
</>,
|
||||
},
|
||||
{
|
||||
type: "divider",
|
||||
},
|
||||
]
|
||||
|
||||
const MoreActionsItems = [
|
||||
{
|
||||
key: "repost",
|
||||
key: "onClickRepost",
|
||||
label: <>
|
||||
<Icons.Repeat />
|
||||
<span>Repost</span>
|
||||
</>,
|
||||
},
|
||||
{
|
||||
key: "share",
|
||||
key: "onClickShare",
|
||||
label: <>
|
||||
<Icons.Share />
|
||||
<span>Share</span>
|
||||
@ -27,7 +47,7 @@ const MoreActionsItems = [
|
||||
type: "divider",
|
||||
},
|
||||
{
|
||||
key: "report",
|
||||
key: "onClickReport",
|
||||
label: <>
|
||||
<Icons.AlertTriangle />
|
||||
<span>Report</span>
|
||||
@ -36,33 +56,68 @@ const MoreActionsItems = [
|
||||
]
|
||||
|
||||
export default (props) => {
|
||||
const [isSelf, setIsSelf] = React.useState(false)
|
||||
|
||||
const {
|
||||
onClickLike,
|
||||
onClickSave,
|
||||
onClickComments,
|
||||
} = props.actions ?? {}
|
||||
|
||||
const genItems = () => {
|
||||
let items = MoreActionsItems
|
||||
|
||||
if (isSelf) {
|
||||
items = [...SelfActionsItems, ...items]
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
const handleDropdownClickItem = (e) => {
|
||||
if (typeof props.actions[e.key] === "function") {
|
||||
props.actions[e.key]()
|
||||
}
|
||||
}
|
||||
|
||||
return <div className="post_actions_wrapper">
|
||||
<div className="actions">
|
||||
<div className="action" id="likes">
|
||||
<LikeButton
|
||||
defaultLiked={props.defaultLiked}
|
||||
onClick={props.onClickLike}
|
||||
count={props.likesCount}
|
||||
onClick={onClickLike}
|
||||
/>
|
||||
</div>
|
||||
<div className="action" id="save">
|
||||
<SaveButton
|
||||
defaultActive={props.defaultSaved}
|
||||
onClick={props.onClickSave}
|
||||
onClick={onClickSave}
|
||||
/>
|
||||
</div>
|
||||
<div className="action" id="comments">
|
||||
<CommentsButton
|
||||
onClickComments={props.onClickComments}
|
||||
count={props.commentsCount}
|
||||
onClick={onClickComments}
|
||||
/>
|
||||
</div>
|
||||
<div className="action" id="more">
|
||||
<Dropdown
|
||||
menu={{
|
||||
items: MoreActionsItems
|
||||
items: genItems(),
|
||||
onClick: handleDropdownClickItem,
|
||||
}}
|
||||
trigger={["click"]}
|
||||
onOpenChange={(open) => {
|
||||
if (open && props.user_id) {
|
||||
const isSelf = app.cores.permissions.checkUserIdIsSelf(props.user_id)
|
||||
|
||||
setIsSelf(isSelf)
|
||||
}
|
||||
}}
|
||||
overlayStyle={{
|
||||
minWidth: "200px",
|
||||
}}
|
||||
>
|
||||
<div className="icon">
|
||||
<Icons.MoreHorizontal />
|
||||
|
@ -124,7 +124,7 @@ const Attachment = React.memo((props) => {
|
||||
}
|
||||
})
|
||||
|
||||
export default (props) => {
|
||||
export default React.memo((props) => {
|
||||
const carouselRef = React.useRef(null)
|
||||
const [attachmentIndex, setAttachmentIndex] = React.useState(0)
|
||||
|
||||
@ -174,9 +174,11 @@ export default (props) => {
|
||||
return null
|
||||
}
|
||||
|
||||
return <Attachment index={index} attachment={attachment} />
|
||||
return <React.Fragment key={index}>
|
||||
<Attachment index={index} attachment={attachment} />
|
||||
</React.Fragment>
|
||||
})
|
||||
}
|
||||
</Carousel>
|
||||
</div>
|
||||
}
|
||||
})
|
@ -1,75 +0,0 @@
|
||||
import React from "react"
|
||||
import * as antd from "antd"
|
||||
import Plyr from "plyr-react"
|
||||
import classnames from "classnames"
|
||||
|
||||
import { processString } from "utils"
|
||||
|
||||
import "./index.less"
|
||||
|
||||
export default (props) => {
|
||||
let { message } = props.data
|
||||
|
||||
const [nsfwAccepted, setNsfwAccepted] = React.useState(false)
|
||||
|
||||
// parse message
|
||||
const regexs = [
|
||||
{
|
||||
regex: /https?:\/\/(?:www\.)?youtube\.com\/watch\?v=([a-zA-Z0-9_-]{11})(&[a-zA-Z0-9_-]+=[a-zA-Z0-9_-]+)*/g,
|
||||
fn: (key, result) => {
|
||||
return <Plyr source={{
|
||||
type: "video",
|
||||
sources: [{
|
||||
src: result[1],
|
||||
provider: "youtube",
|
||||
}],
|
||||
}} />
|
||||
}
|
||||
},
|
||||
{
|
||||
regex: /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi,
|
||||
fn: (key, result) => {
|
||||
return <a key={key} href={result[1]} target="_blank" rel="noopener noreferrer">{result[1]}</a>
|
||||
}
|
||||
},
|
||||
{
|
||||
regex: /(@[a-zA-Z0-9_]+)/gi,
|
||||
fn: (key, result) => {
|
||||
return <a key={key} onClick={() => window.app.setLocation(`/@${result[1].substr(1)}`)}>{result[1]}</a>
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
message = processString(regexs)(message)
|
||||
|
||||
return <div
|
||||
className={
|
||||
classnames(
|
||||
"post_content",
|
||||
{
|
||||
["nsfw"]: props.nsfw && !nsfwAccepted
|
||||
}
|
||||
)
|
||||
}
|
||||
>
|
||||
{props.nsfw && !nsfwAccepted &&
|
||||
<div className="nsfw_alert">
|
||||
<h2>
|
||||
This post may contain sensitive content.
|
||||
</h2>
|
||||
|
||||
<antd.Button onClick={() => setNsfwAccepted(true)}>
|
||||
Show anyways
|
||||
</antd.Button>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div className="message">
|
||||
{message}
|
||||
</div>
|
||||
|
||||
{
|
||||
props.children
|
||||
}
|
||||
</div>
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
.post_content {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
||||
padding: 0 10px 10px 10px;
|
||||
border-radius: 8px;
|
||||
|
||||
color: rgba(var(--background-color-contrast));
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
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 {
|
||||
position: absolute;
|
||||
|
||||
padding: 10px 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
// -webkit-backdrop-filter: blur(25px);
|
||||
// backdrop-filter: blur(25px);
|
||||
//background-color: rgba(0, 0, 0, 0.5);
|
||||
|
||||
border-radius: 8px;
|
||||
|
||||
z-index: 200;
|
||||
|
||||
h2 {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.message {
|
||||
width: 100%;
|
||||
|
||||
font-size: 0.9rem;
|
||||
font-weight: 400;
|
||||
|
||||
color: var(--background-color-contrast);
|
||||
|
||||
word-break: break-all;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
>div {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
@ -1,22 +1,48 @@
|
||||
import React from "react"
|
||||
import * as antd from "antd"
|
||||
import classnames from "classnames"
|
||||
import Plyr from "plyr-react"
|
||||
|
||||
import { CommentsCard } from "components"
|
||||
import { Icons } from "components/Icons"
|
||||
|
||||
import { processString } from "utils"
|
||||
|
||||
import PostHeader from "./components/header"
|
||||
import PostContent from "./components/content"
|
||||
import PostActions from "./components/actions"
|
||||
import PostAttachments from "./components/attachments"
|
||||
|
||||
import "./index.less"
|
||||
|
||||
const messageRegexs = [
|
||||
{
|
||||
regex: /https?:\/\/(?:www\.)?youtube\.com\/watch\?v=([a-zA-Z0-9_-]{11})(&[a-zA-Z0-9_-]+=[a-zA-Z0-9_-]+)*/g,
|
||||
fn: (key, result) => {
|
||||
return <Plyr source={{
|
||||
type: "video",
|
||||
sources: [{
|
||||
src: result[1],
|
||||
provider: "youtube",
|
||||
}],
|
||||
}} />
|
||||
}
|
||||
},
|
||||
{
|
||||
regex: /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi,
|
||||
fn: (key, result) => {
|
||||
return <a key={key} href={result[1]} target="_blank" rel="noopener noreferrer">{result[1]}</a>
|
||||
}
|
||||
},
|
||||
{
|
||||
regex: /(@[a-zA-Z0-9_]+)/gi,
|
||||
fn: (key, result) => {
|
||||
return <a key={key} onClick={() => window.app.setLocation(`/@${result[1].substr(1)}`)}>{result[1]}</a>
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
export default class PostCard extends React.PureComponent {
|
||||
state = {
|
||||
loading: true,
|
||||
data: this.props.data ?? {},
|
||||
|
||||
countLikes: this.props.data.countLikes ?? 0,
|
||||
countComments: this.props.data.countComments ?? 0,
|
||||
|
||||
@ -24,6 +50,9 @@ export default class PostCard extends React.PureComponent {
|
||||
hasSaved: this.props.data.isSaved ?? false,
|
||||
|
||||
open: this.props.defaultOpened ?? false,
|
||||
|
||||
isNsfw: this.props.data.flags?.includes("nsfw") ?? false,
|
||||
nsfwAccepted: false,
|
||||
}
|
||||
|
||||
onClickDelete = async () => {
|
||||
@ -32,7 +61,7 @@ export default class PostCard extends React.PureComponent {
|
||||
return
|
||||
}
|
||||
|
||||
return await this.props.events.onClickDelete(this.state.data)
|
||||
return await this.props.events.onClickDelete(this.props.data)
|
||||
}
|
||||
|
||||
onClickLike = async () => {
|
||||
@ -41,7 +70,7 @@ export default class PostCard extends React.PureComponent {
|
||||
return
|
||||
}
|
||||
|
||||
return await this.props.events.onClickLike(this.state.data)
|
||||
return await this.props.events.onClickLike(this.props.data)
|
||||
}
|
||||
|
||||
onClickSave = async () => {
|
||||
@ -50,7 +79,7 @@ export default class PostCard extends React.PureComponent {
|
||||
return
|
||||
}
|
||||
|
||||
return await this.props.events.onClickSave(this.state.data)
|
||||
return await this.props.events.onClickSave(this.props.data)
|
||||
}
|
||||
|
||||
onClickEdit = async () => {
|
||||
@ -59,7 +88,7 @@ export default class PostCard extends React.PureComponent {
|
||||
return
|
||||
}
|
||||
|
||||
return await this.props.events.onClickEdit(this.state.data)
|
||||
return await this.props.events.onClickEdit(this.props.data)
|
||||
}
|
||||
|
||||
onDoubleClick = async () => {
|
||||
@ -76,17 +105,19 @@ export default class PostCard extends React.PureComponent {
|
||||
}
|
||||
|
||||
if (typeof this.props.events?.onToogleOpen === "function") {
|
||||
this.props.events?.onToogleOpen(to, this.state.data)
|
||||
this.props.events?.onToogleOpen(to, this.props.data)
|
||||
}
|
||||
|
||||
this.setState({
|
||||
open: to,
|
||||
})
|
||||
|
||||
//app.controls.openPostViewer(this.state.data)
|
||||
//app.controls.openPostViewer(this.props.data)
|
||||
}
|
||||
|
||||
onLikesUpdate = (data) => {
|
||||
console.log("onLikesUpdate", data)
|
||||
|
||||
if (data.to) {
|
||||
this.setState({
|
||||
countLikes: this.state.countLikes + 1,
|
||||
@ -99,24 +130,13 @@ export default class PostCard extends React.PureComponent {
|
||||
}
|
||||
|
||||
componentDidMount = async () => {
|
||||
app.eventBus.on(`post.${this.state.data._id}.delete`, this.onClickDelete)
|
||||
app.eventBus.on(`post.${this.state.data._id}.update`, this.onClickEdit)
|
||||
|
||||
// first listen to post changes
|
||||
app.cores.api.listenEvent(`post.${this.state.data._id}.likes.update`, this.onLikesUpdate)
|
||||
|
||||
this.setState({
|
||||
isSelf: app.cores.permissions.checkUserIdIsSelf(this.state.data.user_id),
|
||||
loading: false,
|
||||
})
|
||||
app.cores.api.listenEvent(`post.${this.props.data._id}.likes.update`, this.onLikesUpdate)
|
||||
}
|
||||
|
||||
componentWillUnmount = () => {
|
||||
app.eventBus.off(`post.${this.state.data._id}.delete`, this.onClickDelete)
|
||||
app.eventBus.off(`post.${this.state.data._id}.update`, this.onClickEdit)
|
||||
|
||||
// remove the listener
|
||||
app.cores.api.unlistenEvent(`post.${this.state.data._id}.likes.update`, this.onLikesUpdate)
|
||||
app.cores.api.unlistenEvent(`post.${this.props.data._id}.likes.update`, this.onLikesUpdate)
|
||||
}
|
||||
|
||||
componentDidCatch = (error, info) => {
|
||||
@ -133,62 +153,81 @@ export default class PostCard extends React.PureComponent {
|
||||
</div>
|
||||
}
|
||||
|
||||
render = () => {
|
||||
if (this.state.loading) {
|
||||
return <div
|
||||
key={this.state.data.key ?? this.state.data._id}
|
||||
id={this.state.data._id}
|
||||
className="postCard"
|
||||
>
|
||||
<antd.Skeleton active avatar />
|
||||
</div>
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div
|
||||
key={this.props.index ?? this.state.data._id}
|
||||
id={this.state.data._id}
|
||||
key={this.props.index}
|
||||
id={this.props.data._id}
|
||||
className={classnames(
|
||||
"postCard",
|
||||
{
|
||||
["open"]: this.state.open,
|
||||
}
|
||||
)}
|
||||
style={this.props.style}
|
||||
context-menu={"postCard-context"}
|
||||
user-id={this.state.data.user_id}
|
||||
self-post={this.state.isSelf.toString()}
|
||||
user-id={this.props.data.user_id}
|
||||
>
|
||||
<div className="wrapper">
|
||||
<PostHeader
|
||||
postData={this.state.data}
|
||||
isLiked={this.state.hasLiked}
|
||||
postData={this.props.data}
|
||||
onDoubleClick={this.onDoubleClick}
|
||||
/>
|
||||
<PostContent
|
||||
data={this.state.data}
|
||||
nsfw={this.state.data.flags && this.state.data.flags.includes("nsfw")}
|
||||
onDoubleClick={this.onDoubleClick}
|
||||
<div
|
||||
id="post_content"
|
||||
className={classnames(
|
||||
"post_content",
|
||||
{
|
||||
["nsfw"]: this.state.isNsfw && !this.state.nsfwAccepted,
|
||||
}
|
||||
)}
|
||||
>
|
||||
{this.state.data.attachments && this.state.data.attachments.length > 0 && <PostAttachments
|
||||
attachments={this.state.data.attachments}
|
||||
/>}
|
||||
</PostContent>
|
||||
{
|
||||
this.state.isNsfw && !this.state.nsfwAccepted &&
|
||||
<div className="nsfw_alert">
|
||||
<h2>
|
||||
This post may contain sensitive content.
|
||||
</h2>
|
||||
|
||||
<antd.Button onClick={() => this.setState({ nsfwAccepted: true })}>
|
||||
Show anyways
|
||||
</antd.Button>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div className="message">
|
||||
{
|
||||
processString(messageRegexs)(this.props.data.message ?? "")
|
||||
}
|
||||
</div>
|
||||
|
||||
{
|
||||
this.props.data.attachments && this.props.data.attachments.length > 0 && <PostAttachments
|
||||
attachments={this.props.data.attachments}
|
||||
/>
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<PostActions
|
||||
user_id={this.props.data.user_id}
|
||||
likesCount={this.state.countLikes}
|
||||
commentsCount={this.state.countComments}
|
||||
defaultLiked={this.state.hasLiked}
|
||||
defaultSaved={this.state.hasSaved}
|
||||
onClickLike={this.onClickLike}
|
||||
onClickSave={this.onClickSave}
|
||||
onClickComments={this.onClickComments}
|
||||
actions={{
|
||||
delete: this.onClickDelete,
|
||||
onClickLike: this.onClickLike,
|
||||
onClickEdit: this.onClickEdit,
|
||||
onClickDelete: this.onClickDelete,
|
||||
onClickSave: this.onClickSave,
|
||||
onClickComments: this.onClickComments,
|
||||
}}
|
||||
/>
|
||||
|
||||
{
|
||||
this.state.open && <CommentsCard post_id={this.state.data._id} />
|
||||
}
|
||||
<CommentsCard
|
||||
post_id={this.props.data._id}
|
||||
visible={this.state.open}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
}
|
@ -1,19 +1,22 @@
|
||||
.postCard {
|
||||
display: inline-flex;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
width: 100%;
|
||||
width: 35vw;
|
||||
min-width: 300px;
|
||||
max-width: 600px;
|
||||
|
||||
background-color: var(--background-color-accent);
|
||||
|
||||
transition: all 0.2s ease-in-out;
|
||||
transition: all 150ms ease-in-out;
|
||||
|
||||
padding: 17px;
|
||||
|
||||
&.open {
|
||||
height: 100%;
|
||||
}
|
||||
border-bottom: 2px solid var(--border-color);
|
||||
|
||||
padding-bottom: 10px;
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
.wrapper {
|
||||
display: inline-flex;
|
||||
@ -29,9 +32,87 @@
|
||||
}
|
||||
}
|
||||
|
||||
border-bottom: 2px solid var(--border-color);
|
||||
.post_content {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
||||
padding-bottom: 10px;
|
||||
padding: 0 10px 10px 10px;
|
||||
border-radius: 8px;
|
||||
|
||||
color: rgba(var(--background-color-contrast));
|
||||
|
||||
overflow: hidden;
|
||||
|
||||
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 {
|
||||
position: absolute;
|
||||
|
||||
padding: 10px 0;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
// -webkit-backdrop-filter: blur(25px);
|
||||
// backdrop-filter: blur(25px);
|
||||
//background-color: rgba(0, 0, 0, 0.5);
|
||||
|
||||
border-radius: 8px;
|
||||
|
||||
z-index: 200;
|
||||
|
||||
h2 {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.message {
|
||||
width: 100%;
|
||||
|
||||
font-size: 0.9rem;
|
||||
font-weight: 400;
|
||||
|
||||
color: var(--background-color-contrast);
|
||||
|
||||
word-break: break-all;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
>div {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: 8px;
|
||||
|
Loading…
x
Reference in New Issue
Block a user