mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-25 12:56:41 +07:00
displaying profile backdrop
This commit is contained in:
parent
0eae79ec08
commit
327272a08a
5 changed files with 99 additions and 6 deletions
35
src/components/profile/ProfileBackdrop/index.tsx
Normal file
35
src/components/profile/ProfileBackdrop/index.tsx
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import React, { FC, useState, useCallback, useEffect } from 'react';
|
||||||
|
import { IUser } from '~/redux/auth/types';
|
||||||
|
import styles from './styles.scss';
|
||||||
|
import { getURL } from '~/utils/dom';
|
||||||
|
import { PRESETS } from '~/constants/urls';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
cover: IUser['cover'];
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProfileBackdrop: FC<IProps> = ({ cover }) => {
|
||||||
|
const [is_loaded, setIsLoaded] = useState(false);
|
||||||
|
|
||||||
|
const onLoad = useCallback(() => setIsLoaded(true), [setIsLoaded]);
|
||||||
|
|
||||||
|
const image = getURL(cover, PRESETS.cover);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setIsLoaded(false);
|
||||||
|
}, [cover]);
|
||||||
|
|
||||||
|
if (!cover) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={classNames(styles.cover, { [styles.active]: is_loaded })}
|
||||||
|
style={{ backgroundImage: `url("${image}")` }}
|
||||||
|
>
|
||||||
|
<img src={image} onLoad={onLoad} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { ProfileBackdrop };
|
30
src/components/profile/ProfileBackdrop/styles.scss
Normal file
30
src/components/profile/ProfileBackdrop/styles.scss
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
.cover {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background: 50% 50% no-repeat/cover;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 1s;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background: url('~/sprites/stripes.svg') transparentize($color: #000000, $amount: 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ interface IProps {
|
||||||
children: React.ReactChild;
|
children: React.ReactChild;
|
||||||
header?: JSX.Element;
|
header?: JSX.Element;
|
||||||
footer?: JSX.Element;
|
footer?: JSX.Element;
|
||||||
|
backdrop?: JSX.Element;
|
||||||
size?: 'medium' | 'big';
|
size?: 'medium' | 'big';
|
||||||
width?: number;
|
width?: number;
|
||||||
error?: string;
|
error?: string;
|
||||||
|
@ -20,6 +21,7 @@ const BetterScrollDialog: FC<IProps> = ({
|
||||||
children,
|
children,
|
||||||
header,
|
header,
|
||||||
footer,
|
footer,
|
||||||
|
backdrop,
|
||||||
width = 600,
|
width = 600,
|
||||||
error,
|
error,
|
||||||
onClose,
|
onClose,
|
||||||
|
@ -34,6 +36,8 @@ const BetterScrollDialog: FC<IProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.wrap} ref={ref}>
|
<div className={styles.wrap} ref={ref}>
|
||||||
|
{backdrop && <div className={styles.backdrop}>{backdrop}</div>}
|
||||||
|
|
||||||
<div className={styles.container} style={{ maxWidth: width }}>
|
<div className={styles.container} style={{ maxWidth: width }}>
|
||||||
{onClose && (
|
{onClose && (
|
||||||
<div className={styles.close} onClick={onClose}>
|
<div className={styles.close} onClick={onClose}>
|
||||||
|
|
|
@ -97,3 +97,11 @@
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
background: linear-gradient($red, transparentize($red, 1));
|
background: linear-gradient($red, transparentize($red, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.backdrop {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
|
@ -3,17 +3,24 @@ import { BetterScrollDialog } from '../BetterScrollDialog';
|
||||||
import { ProfileInfo } from '~/containers/profile/ProfileInfo';
|
import { ProfileInfo } from '~/containers/profile/ProfileInfo';
|
||||||
import { IDialogProps } from '~/redux/types';
|
import { IDialogProps } from '~/redux/types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { selectAuthProfile } from '~/redux/auth/selectors';
|
import { selectAuthProfile, selectAuthUser } from '~/redux/auth/selectors';
|
||||||
import { ProfileMessages } from '~/containers/profile/ProfileMessages';
|
import { ProfileMessages } from '~/containers/profile/ProfileMessages';
|
||||||
import { ProfileDescription } from '~/components/profile/ProfileDescription';
|
import { ProfileDescription } from '~/components/profile/ProfileDescription';
|
||||||
import * as AUTH_ACTIONS from '~/redux/auth/actions';
|
import * as AUTH_ACTIONS from '~/redux/auth/actions';
|
||||||
import { IAuthState } from '~/redux/auth/types';
|
import { IAuthState } from '~/redux/auth/types';
|
||||||
|
import pick from 'ramda/es/pick';
|
||||||
|
import { ProfileBackdrop } from '~/components/profile/ProfileBackdrop';
|
||||||
|
|
||||||
const TAB_CONTENT = {
|
const TAB_CONTENT = {
|
||||||
profile: <ProfileDescription />,
|
profile: <ProfileDescription />,
|
||||||
messages: <ProfileMessages />,
|
messages: <ProfileMessages />,
|
||||||
};
|
};
|
||||||
const mapStateToProps = selectAuthProfile;
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
profile: selectAuthProfile(state),
|
||||||
|
user: pick(['id'], selectAuthUser(state)),
|
||||||
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
authSetProfile: AUTH_ACTIONS.authSetProfile,
|
authSetProfile: AUTH_ACTIONS.authSetProfile,
|
||||||
};
|
};
|
||||||
|
@ -23,9 +30,9 @@ type IProps = IDialogProps & ReturnType<typeof mapStateToProps> & typeof mapDisp
|
||||||
const ProfileDialogUnconnected: FC<IProps> = ({
|
const ProfileDialogUnconnected: FC<IProps> = ({
|
||||||
onRequestClose,
|
onRequestClose,
|
||||||
authSetProfile,
|
authSetProfile,
|
||||||
is_loading,
|
|
||||||
user,
|
profile: { is_loading, user, tab },
|
||||||
tab,
|
user: { id },
|
||||||
}) => {
|
}) => {
|
||||||
const setTab = useCallback((val: IAuthState['profile']['tab']) => authSetProfile({ tab: val }), [
|
const setTab = useCallback((val: IAuthState['profile']['tab']) => authSetProfile({ tab: val }), [
|
||||||
authSetProfile,
|
authSetProfile,
|
||||||
|
@ -33,7 +40,16 @@ const ProfileDialogUnconnected: FC<IProps> = ({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BetterScrollDialog
|
<BetterScrollDialog
|
||||||
header={<ProfileInfo is_loading={is_loading} user={user} tab={tab} setTab={setTab} />}
|
header={
|
||||||
|
<ProfileInfo
|
||||||
|
is_own={user && user.id === id}
|
||||||
|
is_loading={is_loading}
|
||||||
|
user={user}
|
||||||
|
tab={tab}
|
||||||
|
setTab={setTab}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
backdrop={<ProfileBackdrop cover={user && user.cover} />}
|
||||||
onClose={onRequestClose}
|
onClose={onRequestClose}
|
||||||
>
|
>
|
||||||
{TAB_CONTENT[tab] || null}
|
{TAB_CONTENT[tab] || null}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue