update evite initialization & post rendering

This commit is contained in:
SrGooglo 2023-08-02 20:41:26 +00:00
parent ae0a480314
commit 6c4724201c
19 changed files with 174 additions and 173 deletions

1
evite Submodule

@ -0,0 +1 @@
Subproject commit eeb7f4f8f0714a38669953875d55a30855fe79bc

View File

@ -17,6 +17,7 @@ const aliases = {
utils: path.join(__dirname, "src/utils"), utils: path.join(__dirname, "src/utils"),
layouts: path.join(__dirname, "src/layouts"), layouts: path.join(__dirname, "src/layouts"),
hooks: path.join(__dirname, "src/hooks"), hooks: path.join(__dirname, "src/hooks"),
classes: path.join(__dirname, "src/classes"),
"comty.js": path.join(__dirname, "../", "comty.js", "src"), "comty.js": path.join(__dirname, "../", "comty.js", "src"),
models: path.join(__dirname, "../comty.js/src/models"), models: path.join(__dirname, "../comty.js/src/models"),
} }

View File

@ -43,9 +43,9 @@
"@ionic/react": "^7.0.12", "@ionic/react": "^7.0.12",
"@loadable/component": "5.15.2", "@loadable/component": "5.15.2",
"@mui/material": "^5.11.9", "@mui/material": "^5.11.9",
"@paciolan/remote-component": "^2.13.0",
"@ragestudio/cordova-nfc": "^1.2.0", "@ragestudio/cordova-nfc": "^1.2.0",
"@react-spring/web": "^9.7.2", "@react-spring/web": "^9.7.2",
"@tanstack/react-virtual": "^3.0.0-beta.54",
"@tsmx/human-readable": "^1.0.7", "@tsmx/human-readable": "^1.0.7",
"antd": "^5.6.4", "antd": "^5.6.4",
"antd-mobile": "^5.31.0", "antd-mobile": "^5.31.0",
@ -56,16 +56,11 @@
"classnames": "2.3.1", "classnames": "2.3.1",
"dexie": "^3.2.3", "dexie": "^3.2.3",
"dompurify": "^3.0.0", "dompurify": "^3.0.0",
"electron-is": "^3.0.0",
"electron-log": "^4.4.8",
"electron-squirrel-startup": "^1.0.0",
"evite": "^0.15.6", "evite": "^0.15.6",
"fast-average-color": "^9.2.0", "fast-average-color": "^9.2.0",
"faye": "1.4.0",
"feather-reactjs": "2.0.13", "feather-reactjs": "2.0.13",
"framer-motion": "^10.12.17", "framer-motion": "^10.12.17",
"fuse.js": "6.5.3", "fuse.js": "6.5.3",
"global": "4.4.0",
"hls.js": "^1.1.5", "hls.js": "^1.1.5",
"howler": "2.2.3", "howler": "2.2.3",
"i18next": "21.6.6", "i18next": "21.6.6",
@ -74,11 +69,10 @@
"jwt-decode": "3.1.2", "jwt-decode": "3.1.2",
"less": "4.1.2", "less": "4.1.2",
"linebridge": "0.15.7", "linebridge": "0.15.7",
"localforage": "^1.10.0",
"lottie-react": "^2.4.0", "lottie-react": "^2.4.0",
"lru-cache": "^10.0.0", "lru-cache": "^10.0.0",
"luxon": "^3.0.4", "luxon": "^3.0.4",
"match-sorter": "^6.3.1", "million": "^2.5.4-beta.1",
"mime": "^3.0.0", "mime": "^3.0.0",
"moment": "2.29.4", "moment": "2.29.4",
"moment-timezone": "^0.5.37", "moment-timezone": "^0.5.37",
@ -89,53 +83,40 @@
"plyr": "^3.6.12", "plyr": "^3.6.12",
"plyr-react": "^3.2.1", "plyr-react": "^3.2.1",
"prop-types": "^15.8.1", "prop-types": "^15.8.1",
"qrcode": "1.5.0", "react": "^18.2.0",
"rc-animate": "^3.1.1",
"rc-util": "^5.19.3",
"rc-virtual-list": "^3.4.4",
"react": "17.0.2",
"react-beautiful-dnd": "^13.1.1", "react-beautiful-dnd": "^13.1.1",
"react-color": "2.19.3", "react-color": "2.19.3",
"react-contexify": "5.0.0",
"react-countup": "^6.4.1", "react-countup": "^6.4.1",
"react-dom": "^17.0.2", "react-dom": "^18.2.0",
"react-draggable": "4.4.4",
"react-fast-marquee": "^1.3.5", "react-fast-marquee": "^1.3.5",
"react-helmet": "6.1.0", "react-helmet": "6.1.0",
"react-i18next": "11.15.3", "react-i18next": "11.15.3",
"react-icons": "^4.8.0", "react-icons": "^4.8.0",
"react-infinite-scroller": "^1.2.6",
"react-inlinesvg": "^3.0.1", "react-inlinesvg": "^3.0.1",
"react-intersection-observer": "8.33.1", "react-intersection-observer": "8.33.1",
"react-json-view": "1.21.3", "react-json-view": "1.21.3",
"react-lazy-load-image-component": "^1.5.4", "react-lazy-load-image-component": "^1.5.4",
"react-loadable": "^5.5.0",
"react-markdown": "^8.0.3", "react-markdown": "^8.0.3",
"react-modal-image": "^2.6.0", "react-modal-image": "^2.6.0",
"react-motion": "0.5.2", "react-motion": "0.5.2",
"react-query": "^3.39.3",
"react-responsive-carousel": "^3.2.23",
"react-reveal": "1.2.2",
"react-rnd": "10.3.5", "react-rnd": "10.3.5",
"react-router-dom": "^6.6.2", "react-router-dom": "^6.6.2",
"react-spring": "^9.7.1",
"react-staggered-list": "^1.0.2",
"react-ticker": "^1.3.2", "react-ticker": "^1.3.2",
"react-transition-group": "^4.4.5", "react-transition-group": "^4.4.5",
"react-useanimations": "^2.10.0", "react-useanimations": "^2.10.0",
"react-viewport-list": "^7.0.0-beta.4", "react-viewport-list": "^7.0.0-beta.4",
"react-virtualized": "^9.22.3", "react-virtualized": "^9.22.3",
"react-virtualized-auto-sizer": "^1.0.7", "react-virtualized-auto-sizer": "^1.0.7",
"react-window": "^1.8.8", "realtime-bpm-analyzer": "^3.2.1",
"react-window-infinite-loader": "^1.0.8",
"realtime-bpm-analyzer": "^3.1.2",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"rxjs": "^7.5.5", "rxjs": "^7.5.5",
"sort-by": "^1.2.0", "sort-by": "^1.2.0",
"store": "^2.0.12", "store": "^2.0.12",
"supertokens-web-js": "^0.6.0", "supertokens-web-js": "^0.6.0",
"tone": "^14.7.77", "tone": "^14.7.77",
"tseep": "^1.1.1",
"uuid": "^9.0.0", "uuid": "^9.0.0",
"virtual-scroller": "^1.12.3",
"wait-on": "^6.0.1" "wait-on": "^6.0.1"
}, },
"devDependencies": { "devDependencies": {
@ -159,6 +140,9 @@
"cors": "2.8.5", "cors": "2.8.5",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"electron": "^21.0.1", "electron": "^21.0.1",
"electron-is": "^3.0.0",
"electron-log": "^4.4.8",
"electron-squirrel-startup": "^1.0.0",
"express": "^4.17.1", "express": "^4.17.1",
"typescript": "^4.3.5", "typescript": "^4.3.5",
"vite": "3.2.5" "vite": "3.2.5"
@ -190,4 +174,4 @@
] ]
} }
} }
} }

View File

@ -80,7 +80,6 @@ import {
UserRegister, UserRegister,
Searcher, Searcher,
NotificationsCenter, NotificationsCenter,
PostViewer,
PostCreator, PostCreator,
} from "components" } from "components"
import { DOMWindow } from "components/RenderWindow" import { DOMWindow } from "components/RenderWindow"
@ -94,8 +93,6 @@ import * as Router from "./router"
import "theme/index.less" import "theme/index.less"
console.log(`REACT VERSION: ${React.version}`)
CapacitorUpdater.notifyAppReady() CapacitorUpdater.notifyAppReady()
class ComtyApp extends React.Component { class ComtyApp extends React.Component {
@ -107,9 +104,6 @@ class ComtyApp extends React.Component {
}) })
} }
sessionController = new SessionModel()
userController = new UserModel()
state = { state = {
session: null, session: null,
initialized: false, initialized: false,
@ -222,7 +216,7 @@ class ComtyApp extends React.Component {
}) })
} }
return app.layout.modal.open("searcher", () => <Searcher renderResults />) return app.layout.modal.open("searcher", (props) => <Searcher renderResults {...props} />)
}, },
openFullImageViewer: (src) => { openFullImageViewer: (src) => {
const win = new DOMWindow({ const win = new DOMWindow({
@ -238,11 +232,9 @@ class ComtyApp extends React.Component {
showRotate showRotate
/>) />)
}, },
openPostViewer: (post) => {
app.layout.modal.open("post_viewer", () => <PostViewer post={post} />)
},
openPostCreator: () => { openPostCreator: () => {
app.layout.modal.open("post_creator", () => <PostCreator />) app.layout.modal.open("post_creator", (props) => <PostCreator {...props} />)
} }
}, },
navigation: { navigation: {
@ -452,12 +444,8 @@ class ComtyApp extends React.Component {
}) })
} }
app.eventBus.emit("app.initialization.start")
await this.initialization() await this.initialization()
app.eventBus.emit("app.initialization.finish")
app.cores.sound.useUIAudio("splash_out") app.cores.sound.useUIAudio("splash_out")
this.setState({ initialized: true }) this.setState({ initialized: true })
@ -470,18 +458,15 @@ class ComtyApp extends React.Component {
} }
initialization = async () => { initialization = async () => {
app.eventBus.emit("app.initialization.start")
console.debug(`[App] Initializing app`) console.debug(`[App] Initializing app`)
const initializationTasks = [ const initializationTasks = [
async () => { async () => {
try { try {
await this.__SessionInit() await this.__SessionInit()
await this.__UserInit()
app.eventBus.emit("app.initialization.session_success")
} catch (error) { } catch (error) {
app.eventBus.emit("app.initialization.session_error", error)
console.error(`[App] Error while initializing session`, error) console.error(`[App] Error while initializing session`, error)
throw { throw {
@ -500,6 +485,8 @@ class ComtyApp extends React.Component {
details: reason.details, details: reason.details,
}) })
}) })
app.eventBus.emit("app.initialization.finish")
} }
__SessionInit = async () => { __SessionInit = async () => {
@ -510,31 +497,23 @@ class ComtyApp extends React.Component {
return false return false
} }
const session = await SessionModel.getCurrentSession().catch((error) => { const user = await UserModel.data().catch((err) => {
console.error(`[App] Cannot get current session: ${error.message}`)
return false return false
}) })
await this.setState({ session }) if (!user) {
} app.eventBus.emit("app.no_session")
__UserInit = async () => {
if (!this.state.session) {
return false return false
} }
const user = await UserModel.data()
app.userData = user app.userData = user
this.setState({ user }) await this.setState({
user
})
} }
render() { render() {
if (!this.state.initialized) {
return <></>
}
return <React.Fragment> return <React.Fragment>
<Helmet> <Helmet>
<title>{config.app.siteName}</title> <title>{config.app.siteName}</title>
@ -547,14 +526,12 @@ class ComtyApp extends React.Component {
user={this.state.user} user={this.state.user}
staticRenders={ComtyApp.staticRenders} staticRenders={ComtyApp.staticRenders}
bindProps={{ bindProps={{
staticRenders: ComtyApp.staticRenders,
user: this.state.user, user: this.state.user,
session: this.state.session,
sessionController: this.sessionController,
userController: this.userController,
}} }}
> >
<Router.PageRender /> {
this.state.initialized && <Router.PageRender />
}
</Layout> </Layout>
</ThemeProvider> </ThemeProvider>
</Router.InternalRouter> </Router.InternalRouter>

View File

@ -60,11 +60,11 @@ export default React.forwardRef((props, ref) => {
{loadingComponent && React.createElement(loadingComponent)} {loadingComponent && React.createElement(loadingComponent)}
</div> </div>
<div {/* <div
className="no-result" className="no-result"
style={{ display: hasMore ? "none" : "block" }} style={{ display: hasMore ? "none" : "block" }}
> >
{noResultComponent ? React.createElement(noResultComponent) : "No more result"} {noResultComponent ? React.createElement(noResultComponent) : "No more result"}
</div> </div> */}
</div> </div>
}) })

View File

@ -1,5 +1,8 @@
.infinite-scroll { .infinite-scroll {
min-height: 32vw; min-height: 32vw;
width: 100%;
position: relative; position: relative;
.no-result { .no-result {

View File

@ -9,7 +9,6 @@ import ContentFailed from "../contentFailed"
import BearCarousel from "bear-react-carousel" import BearCarousel from "bear-react-carousel"
import "bear-react-carousel/dist/index.css" import "bear-react-carousel/dist/index.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"

View File

@ -46,9 +46,9 @@
justify-content: center; justify-content: center;
width: 100%; width: 100%;
height: 100%; height: 50vh;
max-height: 50vh; max-height: 700px;
.plyr { .plyr {
width: 100%; width: 100%;

View File

@ -198,9 +198,10 @@ export default class PostCard extends React.PureComponent {
</div> </div>
{ {
this.props.data.attachments && this.props.data.attachments.length > 0 && <PostAttachments !this.props.disableAttachments && this.props.data.attachments && this.props.data.attachments.length > 0 && <PostAttachments
attachments={this.props.data.attachments} attachments={this.props.data.attachments}
/> />
} }
</div> </div>

View File

@ -4,14 +4,19 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
//max-height: 500px;
//height: fit-content;
width: 100%; width: 100%;
max-width: 800px; max-width: 700px;
gap: 15px; gap: 15px;
padding: 17px 17px 0px 17px; padding: 17px 17px 0px 17px;
background-color: var(--background-color-accent); background-color: var(--background-color-accent);
border-bottom: 2px solid var(--border-color);
//border-bottom: 2px solid var(--border-color);
border-radius: 8px;
color: rgba(var(--background-color-contrast)); color: rgba(var(--background-color-contrast));
@ -68,16 +73,4 @@
} }
} }
} }
&:first-child {
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
&:last-child {
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
border-bottom: none;
}
} }

View File

@ -28,7 +28,7 @@ export default class PostCreator extends React.Component {
postAttachments: [], postAttachments: [],
fileList: [], fileList: [],
postingPolicy: DEFAULT_POST_POLICY postingPolicy: DEFAULT_POST_POLICY,
} }
creatorRef = React.createRef() creatorRef = React.createRef()

View File

@ -6,29 +6,28 @@ import PostCard from "components/PostCard"
import PlaylistTimelineEntry from "components/Music/PlaylistTimelineEntry" import PlaylistTimelineEntry from "components/Music/PlaylistTimelineEntry"
import LoadMore from "components/LoadMore" import LoadMore from "components/LoadMore"
//import { ViewportList } from "react-viewport-list" import { For } from "million/react"
import AutoSizer from "react-virtualized-auto-sizer"
import PostModel from "models/post" import PostModel from "models/post"
import "./index.less" import "./index.less"
const LoadingComponent = () => { const LoadingComponent = () => {
return <antd.Skeleton avatar return <antd.Skeleton
avatar
style={{ style={{
padding: "20px", width: "100%"
width: "100%",
height: "160px",
}} }}
/> />
} }
const NoResultComponent = () => { const NoResultComponent = () => {
return <div className="postCard"> return <antd.Empty
<antd.Empty description="No more post here"
description="No more post here" style={{
/> width: "100%"
</div> }}
/>
} }
const typeToComponent = { const typeToComponent = {
@ -36,9 +35,27 @@ const typeToComponent = {
"playlist": (args) => <PlaylistTimelineEntry {...args} />, "playlist": (args) => <PlaylistTimelineEntry {...args} />,
} }
const Entry = React.memo((props) => {
const { data } = props
return React.createElement(typeToComponent[data.type ?? "post"] ?? PostCard, {
key: data._id,
data: data,
//disableAttachments: true,
events: {
onClickLike: props.onLikePost,
onClickSave: props.onSavePost,
onClickDelete: props.onDeletePost,
onClickEdit: props.onEditPost,
},
})
})
const PostList = (props) => { const PostList = (props) => {
const parentRef = React.useRef()
return <LoadMore return <LoadMore
ref={props.listRef} ref={parentRef}
className="post-list" className="post-list"
loadingComponent={LoadingComponent} loadingComponent={LoadingComponent}
noResultComponent={NoResultComponent} noResultComponent={NoResultComponent}
@ -59,20 +76,26 @@ const PostList = (props) => {
</antd.Button> </antd.Button>
</div> </div>
} }
{
props.list.map((data) => { <For
return React.createElement(typeToComponent[data.type ?? "post"] ?? PostCard, { each={props.list}
key: data._id, style={{
data: data, height: `100%`,
events: { width: `100%`,
onClickLike: props.onLikePost, }}
onClickSave: props.onSavePost, as="div"
onClickDelete: props.onDeletePost, >
onClickEdit: props.onEditPost, {
} (data) => <Entry
}) key={data._id}
}) data={data}
} onLikePost={props.onLikePost}
onSavePost={props.onSavePost}
onDeletePost={props.onDeletePost}
onEditPost={props.onEditPost}
/>
}
</For>
</LoadMore> </LoadMore>
} }

View File

@ -73,6 +73,58 @@ html {
//margin: auto; //margin: auto;
z-index: 150; z-index: 150;
slot {
slot {
.post_card {
border-radius: 0;
border-bottom: 2px solid var(--border-color);
}
.playlistTimelineEntry {
border-radius: 0;
border-bottom: 2px solid var(--border-color);
}
}
&:first-child {
slot {
.post_card {
border-radius: 8px;
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
}
.playlistTimelineEntry {
border-radius: 8px;
border-bottom-left-radius: 0px;
border-bottom-right-radius: 0px;
}
}
}
&:last-child {
slot {
.post_card {
border-top-left-radius: 0px;
border-top-right-radius: 0px;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
.playlistTimelineEntry {
border-top-left-radius: 0px;
border-top-right-radius: 0px;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
}
}
}
}
.postCard { .postCard {
width: 100%; width: 100%;
min-width: 0; min-width: 0;

View File

@ -19,11 +19,14 @@ const ResultsTypeDecorators = {
users: { users: {
icon: "Users", icon: "Users",
label: "Users", label: "Users",
onClick: (item) => {
app.navigation.goToAccount(item.username)
},
renderItem: (props) => { renderItem: (props) => {
const { item, onClick } = props const { item, onClick } = props
return <div className="suggestion"> return <div className="suggestion">
<UserPreview onClick={onClick} user={item} /> <UserPreview onClick={() => onClick(item)} user={item} />
</div> </div>
} }
}, },
@ -73,9 +76,13 @@ const Results = (props) => {
</div> </div>
} }
const handleClick = (props) => { const handleClick = async (decorator, data) => {
if (props.close) { if (typeof decorator.onClick === "function") {
props.close() await decorator.onClick(data)
}
if (typeof props.onClose === "function") {
return props.onClose()
} }
} }
@ -116,7 +123,7 @@ const Results = (props) => {
return decorator.renderItem({ return decorator.renderItem({
key: index, key: index,
item, item,
onClick: handleClick, onClick: (...data) => handleClick(decorator, ...data),
...decorator.props, ...decorator.props,
}) })
}) })
@ -199,28 +206,6 @@ export default (props) => {
} }
} }
const handleResultClick = (type, value) => {
switch (type) {
case "users": {
app.navigation.goToAccount(value.username)
break
}
case "posts": {
app.navigation.goToPost(value)
break
}
default: {
console.warn("Searcher: cannot handle clicks on result of type :", type)
break
}
}
if (typeof props.close === "function") {
props.close()
}
}
React.useEffect(() => { React.useEffect(() => {
if (props.useUrlQuery) { if (props.useUrlQuery) {
if (typeof query === "string") { if (typeof query === "string") {
@ -244,7 +229,7 @@ export default (props) => {
onChange={handleOnSearch} onChange={handleOnSearch}
value={searchValue} value={searchValue}
prefix={<Icons.Search />} prefix={<Icons.Search />}
autoFocus={props.autoFocus ?? false} autoFocus={props.autoFocus ?? true}
onFocus={props.onFocus} onFocus={props.onFocus}
onBlur={props.onUnfocus} onBlur={props.onUnfocus}
/> />
@ -254,7 +239,8 @@ export default (props) => {
{ {
!loading && <Results !loading && <Results
results={searchResult} results={searchResult}
onClick={handleResultClick} /> onClose={props.close}
/>
} }
</div>} </div>}
</div> </div>

View File

@ -32,14 +32,11 @@ const DesktopLayout = (props) => {
className={classnames( className={classnames(
...props.contentClassnames ?? [], ...props.contentClassnames ?? [],
"content_layout", "content_layout",
{
["floating-sidebar"]: window.app?.cores.settings.get("sidebar.floating")
},
"fade-transverse-active", "fade-transverse-active",
)} )}
> >
{ {
React.cloneElement(props.children, props) props.children && React.cloneElement(props.children, props)
} }
</Layout.Content> </Layout.Content>
<ToolsBar /> <ToolsBar />
@ -60,7 +57,7 @@ const MobileLayout = (props) => {
)} )}
> >
{ {
React.cloneElement(props.children, props) props.children && React.cloneElement(props.children, props)
} }
</Layout.Content> </Layout.Content>

View File

@ -79,7 +79,7 @@ export default (props) => {
</div> </div>
{ {
props.user && <div app.userData && <div
className="actions" className="actions"
style={{ style={{
marginBottom: "50px" marginBottom: "50px"
@ -92,7 +92,7 @@ export default (props) => {
app.navigation.goMain() app.navigation.goMain()
}} }}
> >
Continue as {props.user.username} Continue as {app.userData.username}
</antd.Button> </antd.Button>
</div> </div>
} }
@ -131,7 +131,7 @@ export default (props) => {
<p> <p>
<Icons.Info /> <Icons.Info />
Registering a new account accepts the <a>Terms and Conditions</a> and <a>Privacy policy</a> for the services provided by {config.author} Registering a new account accepts the <a onClick={() => app.location.push("/terms")}>Terms and Conditions</a> and <a onClick={() => app.location.push("/privacy")}>Privacy policy</a> for the services provided by {config.author}
</p> </p>
</div> </div>
</div> </div>

View File

@ -93,19 +93,6 @@ function generatePageElementWrapper(route, element, bindProps) {
} }
} }
if (typeof routeDeclaration.requiredRoles !== "undefined") {
const isAdmin = bindProps.user?.roles?.includes("admin") ?? false
if (!isAdmin && !routeDeclaration.requiredRoles.some((role) => bindProps.user?.roles?.includes(role))) {
return <Result
status="403"
title="403"
subTitle="Sorry, you are not authorized to access this page."
extra={<Button type="primary" onClick={() => window.app.location.push("/")}>Back Home</Button>}
/>
}
}
if (routeDeclaration.useLayout) { if (routeDeclaration.useLayout) {
app.layout.set(routeDeclaration.useLayout) app.layout.set(routeDeclaration.useLayout)
} }

View File

@ -114,8 +114,6 @@ html {
&.centered-content { &.centered-content {
.content_layout { .content_layout {
container-type: inline-size;
margin: auto; margin: auto;
min-width: 400px; min-width: 400px;
@ -124,22 +122,22 @@ html {
padding-left: 0; padding-left: 0;
padding-right: 0; padding-right: 0;
.post_card { .post-list {
max-width: 900px; max-width: 700px;
} }
@media screen and (max-width: 2000px) { @media screen and (max-width: 2000px) {
max-width: 1100px; max-width: 1100px;
.post_card { .post-list {
max-width: 750px; max-width: 700px;
} }
} }
@media screen and (max-width: 1444px) { @media screen and (max-width: 1444px) {
max-width: 800px; max-width: 800px;
.post_card { .post-list {
max-width: 550px; max-width: 550px;
} }
} }
@ -147,7 +145,7 @@ html {
@media screen and (max-width: 1170px) { @media screen and (max-width: 1170px) {
max-width: 700px; max-width: 700px;
.post_card { .post-list {
max-width: 450px; max-width: 450px;
} }
} }
@ -155,7 +153,7 @@ html {
@media screen and (max-width: 1024px) { @media screen and (max-width: 1024px) {
max-width: 600px; max-width: 600px;
.post_card { .post-list {
max-width: 350px; max-width: 350px;
} }
} }

View File

@ -1,5 +1,4 @@
import { defineConfig } from "vite" import { defineConfig } from "vite"
import react from "@vitejs/plugin-react" import react from "@vitejs/plugin-react"
import getConfig from "./.config.js" import getConfig from "./.config.js"