update evite initialization & post rendering

This commit is contained in:
SrGooglo 2023-08-02 20:41:26 +00:00
parent 8e306305c0
commit 8480af5cf7
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"),
layouts: path.join(__dirname, "src/layouts"),
hooks: path.join(__dirname, "src/hooks"),
classes: path.join(__dirname, "src/classes"),
"comty.js": path.join(__dirname, "../", "comty.js", "src"),
models: path.join(__dirname, "../comty.js/src/models"),
}

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,6 @@ import ContentFailed from "../contentFailed"
import BearCarousel from "bear-react-carousel"
import "bear-react-carousel/dist/index.css"
import "react-responsive-carousel/lib/styles/carousel.min.css"
import "plyr-react/dist/plyr.css"
import "./index.less"

View File

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

View File

@ -198,9 +198,10 @@ export default class PostCard extends React.PureComponent {
</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}
/>
}
</div>

View File

@ -4,14 +4,19 @@
display: flex;
flex-direction: column;
//max-height: 500px;
//height: fit-content;
width: 100%;
max-width: 800px;
max-width: 700px;
gap: 15px;
padding: 17px 17px 0px 17px;
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));
@ -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: [],
fileList: [],
postingPolicy: DEFAULT_POST_POLICY
postingPolicy: DEFAULT_POST_POLICY,
}
creatorRef = React.createRef()

View File

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

View File

@ -73,6 +73,58 @@ html {
//margin: auto;
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 {
width: 100%;
min-width: 0;

View File

@ -19,11 +19,14 @@ const ResultsTypeDecorators = {
users: {
icon: "Users",
label: "Users",
onClick: (item) => {
app.navigation.goToAccount(item.username)
},
renderItem: (props) => {
const { item, onClick } = props
return <div className="suggestion">
<UserPreview onClick={onClick} user={item} />
<UserPreview onClick={() => onClick(item)} user={item} />
</div>
}
},
@ -73,9 +76,13 @@ const Results = (props) => {
</div>
}
const handleClick = (props) => {
if (props.close) {
props.close()
const handleClick = async (decorator, data) => {
if (typeof decorator.onClick === "function") {
await decorator.onClick(data)
}
if (typeof props.onClose === "function") {
return props.onClose()
}
}
@ -116,7 +123,7 @@ const Results = (props) => {
return decorator.renderItem({
key: index,
item,
onClick: handleClick,
onClick: (...data) => handleClick(decorator, ...data),
...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(() => {
if (props.useUrlQuery) {
if (typeof query === "string") {
@ -244,7 +229,7 @@ export default (props) => {
onChange={handleOnSearch}
value={searchValue}
prefix={<Icons.Search />}
autoFocus={props.autoFocus ?? false}
autoFocus={props.autoFocus ?? true}
onFocus={props.onFocus}
onBlur={props.onUnfocus}
/>
@ -254,7 +239,8 @@ export default (props) => {
{
!loading && <Results
results={searchResult}
onClick={handleResultClick} />
onClose={props.close}
/>
}
</div>}
</div>

View File

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

View File

@ -79,7 +79,7 @@ export default (props) => {
</div>
{
props.user && <div
app.userData && <div
className="actions"
style={{
marginBottom: "50px"
@ -92,7 +92,7 @@ export default (props) => {
app.navigation.goMain()
}}
>
Continue as {props.user.username}
Continue as {app.userData.username}
</antd.Button>
</div>
}
@ -131,7 +131,7 @@ export default (props) => {
<p>
<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>
</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) {
app.layout.set(routeDeclaration.useLayout)
}

View File

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

View File

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