diff --git a/packages/app/src/pages/account/index.jsx b/packages/app/src/pages/account/index.jsx index af06042e..10a3d565 100755 --- a/packages/app/src/pages/account/index.jsx +++ b/packages/app/src/pages/account/index.jsx @@ -1,12 +1,11 @@ import React from "react" import * as antd from "antd" import classnames from "classnames" -import Loadable from "react-loadable" import { Translation } from "react-i18next" -import { Icons, createIconRender } from "components/Icons" -import { Image, Skeleton, FollowButton } from "components" -import { Session, User } from "models" +import { Icons } from "components/Icons" +import { Skeleton, FollowButton, UserCard } from "components" +import { Session } from "models" import DetailsTab from "./tabs/details" import PostsTab from "./tabs/posts" @@ -52,35 +51,6 @@ const TabRender = React.memo((props, ref) => { }) -const UserBadges = React.memo((props) => { - return React.createElement(Loadable({ - loader: async () => { - let { user_id } = props - - const badgesData = await User.getUserBadges(user_id).catch((err) => { - console.error(err) - - app.message.error("Failed to fetch user badges") - - return null - }) - - if (!badgesData) { - return null - } - - return () => badgesData.map((badge, index) => { - return - - {badge.label} - - - }) - }, - loading: antd.Skeleton, - })) -}) - export default class Account extends React.Component { state = { requestedUser: null, @@ -100,7 +70,9 @@ export default class Account extends React.Component { coverComponent = React.createRef() - tabNavigatorRef = React.createRef() + leftPanelRef = React.createRef() + + actionsRef = React.createRef() api = window.app.api.withEndpoints("main") @@ -131,6 +103,8 @@ export default class Account extends React.Component { return false } + console.log(`Loaded User [${user.username}] >`, user) + if (!isSelf) { const followedResult = await this.api.get.isFollowed(undefined, { user_id: user._id }).catch(() => false) @@ -154,11 +128,25 @@ export default class Account extends React.Component { followers, }) - app.eventBus.emit("style.compactMode", true) + // create intersection observer for cover + this.coverIntersectionObserver = new IntersectionObserver((e) => { + if (e[0].intersectionRatio > 0) { + this.leftPanelRef.current.style.transform = "translate(0, -100px)" + this.actionsRef.current.style.opacity = "1" + } else { + this.leftPanelRef.current.style.transform = "translate(0, 0)" + this.actionsRef.current.style.opacity = "0" + } + }, { + root: document.querySelector("#root"), + threshold: 0 + }) + + this.coverIntersectionObserver.observe(this.coverComponent.current) } componentWillUnmount = () => { - app.eventBus.emit("style.compactMode", false) + this.coverIntersectionObserver.disconnect() } fetchData = async (username) => { @@ -210,29 +198,6 @@ export default class Account extends React.Component { }) } - handleScroll = (e) => { - if (!this.state.user?.cover) { - return false - } - - // if component scrolled foward set cover height to 0 - if (e.target.scrollTop > 0) { - this.coverComponent.current.style.height = "0px" - - if (window.isMobile) { - this.tabNavigatorRef.current.style.overflow = "hidden" - this.tabNavigatorRef.current.style.height = "0px" - } - } else { - this.coverComponent.current.style.height = "" - - if (window.isMobile) { - this.tabNavigatorRef.current.style.overflow = "" - this.tabNavigatorRef.current.style.height = "" - } - } - } - render() { const user = this.state.user @@ -249,65 +214,55 @@ export default class Account extends React.Component { return } - return
- {user.cover &&
this.toogleCoverExpanded()} - />} -
-
-
-
-
-
- ProfileImage -
-
+ return
+ { + user.cover &&
this.toogleCoverExpanded()} + id="profile-cover" + /> + } -
-
-

{user.fullName ?? user.username}

- {user.verified && } -
+
+
+ - @{user.username} -
-
- -
- -
+
+
- -
-

- {user.description} -

-
-
-
- }> - - +
+
-
-
-
+
- -
- -
} diff --git a/packages/app/src/pages/account/index.less b/packages/app/src/pages/account/index.less index e95fd2d3..08e9b415 100755 --- a/packages/app/src/pages/account/index.less +++ b/packages/app/src/pages/account/index.less @@ -1,208 +1,107 @@ @borderRadius: 12px; .accountProfile { + display: flex; + + flex-direction: column; + width: 100%; - height: 100vh; - - overflow: hidden; - - padding: 10px 20px; - - // max-width: 70vw; - // min-width: 900px; - - transition: all 0.3s ease-in-out; + height: 100%; .cover { z-index: 50; position: relative; - border-radius: @borderRadius @borderRadius 0 0; outline: 1px solid var(--border-color); + border-radius: @borderRadius; content: ""; width: 100%; + height: 25vh; + + margin-bottom: 10px; background-position: center; background-size: cover; - height: 25vh; - - transform: translate(0, 10px); transition: all 0.3s ease-in-out; &.expanded { height: 70vh; - transform: translate(0, 0); background-size: cover; background-repeat: no-repeat; - border-radius: @borderRadius; - margin-bottom: 10px; } } - .profileCardWrapper { - position: sticky; - top: 0; - z-index: 150; - } - - .profileCard { + .panels { position: relative; - z-index: 150; - display: flex; - flex-direction: column; - - color: var(--background-color-contrast); - background-color: var(--background-color-primary); - - border: 1px solid var(--border-color); - border-radius: @borderRadius @borderRadius 0 @borderRadius; - - padding: 20px 15px; - - height: 15vh; - min-height: 175px; - - .basicData { - display: inline-flex; - flex-direction: row; - justify-content: space-between; - - margin-bottom: 15px; - - .avatar { - width: 100px; - height: 100px; - - img { - width: 100%; - height: 100%; - border-radius: 8px; - } - } - - svg { - fill: var(--appColor); - } - - .title { - display: inline-flex; - flex-direction: row; - align-items: center; - } - - .field { - display: inline-flex; - flex-direction: column; - - margin-right: 15px; - - h1 { - margin: 0; - - font-size: 35px; - line-height: 37px; - } - - >div { - display: inline-flex; - } - } - } - - .description { - max-height: 5vh; - overflow: hidden; - - p { - height: 100%; - overflow: hidden; - - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - - margin: 0; - } - } - - h1, - h2, - h3, - h4, - h5, - h6, - span, - p { - user-select: text; - } - } - - .badgesTab { - position: relative; - z-index: 140; - - display: flex; - flex-direction: row; - - padding: 30px 10px 10px 10px; - - background-color: var(--background-color-accent); - - border-radius: 0 0 @borderRadius @borderRadius; - transform: translate(0, -20px); - - border: 1px solid var(--border-color); - - .badge { - margin-left: 10px; - height: fit-content; - } - } - - .tabMenuWrapper { - position: sticky !important; - top: 20px; - - height: fit-content; - - .tabMenu { - width: fit-content; - min-width: 10vw; - - padding: 10px; - background-color: var(--background-color-accent) !important; - border-radius: @borderRadius; - } - } - - .contents { display: grid; - grid-template-columns: 10vw 1fr 10vw; + grid-template-columns: repeat(3, 1fr); grid-template-rows: 1fr; - grid-column-gap: 50px; + grid-column-gap: 20px; grid-row-gap: 0px; - width: 100%; - height: 100%; + padding-top: 20px; - overflow: hidden; - overflow-y: hidden; - - margin-top: -1.5vh; - - transition: all 0.3s ease-in-out; - - .tabContent { + .leftPanel { position: sticky; - border-radius: @borderRadius; + top: 0; - padding: 20px 10px 20vh 10px; + z-index: 55; - overflow-y: overlay; + display: flex; + flex-direction: column; + + align-items: center; + + transition: all 0.3s ease-in-out; + + .userCard { + position: sticky; + top: 0; + z-index: 55; + } + + .actions { + display: flex; + flex-direction: column; + + height: fit-content; + width: 20vw; + min-width: 400px; + + padding: 20px; + margin-top: 20px; + + background-color: var(--background-color-accent); + border-radius: 12px; + + transition: all 0.3s ease-in-out; + + .followButton { + width: fit-content; + } + } + } + + .tabMenuWrapper { + position: sticky; + top: 0; + + display: flex; + flex-direction: column; + + background-color: var(--background-color-accent); + border-radius: 12px; + padding: 20px; + + height: fit-content; + width: 20vw; + min-width: 400px; + + justify-self: center; } } @@ -210,18 +109,11 @@ background-color: var(--background-color-accent); padding: 20px; border-radius: @borderRadius; + } - font-family: "DM Mono", monospace; - - h1, - h2, - h3, - h4, - h5, - h6, - p, - span { - user-select: text; - } + .followersList { + background-color: var(--background-color-accent); + padding: 20px; + border-radius: @borderRadius; } } \ No newline at end of file