From 141b9c0d60c937c4c18e7ab0de82661f70e215ed Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Tue, 19 Jul 2022 16:47:03 +0700 Subject: [PATCH] added profile quick info --- .../comment/CommentAvatar/index.tsx | 3 ++- src/components/menu/MenuButton/index.tsx | 12 +++++++-- .../menu/MenuButton/styles.module.scss | 27 +++++++++++-------- .../profile/ProfileQuickInfo/index.tsx | 17 +++++++----- .../ProfileQuickInfo/styles.module.scss | 16 +++++++++++ src/hooks/auth/useUserActiveStatus.ts | 14 ++++++++++ src/hooks/auth/useUserDescription.ts | 11 +++----- src/utils/color.ts | 16 ++++++++--- 8 files changed, 84 insertions(+), 32 deletions(-) create mode 100644 src/hooks/auth/useUserActiveStatus.ts diff --git a/src/components/comment/CommentAvatar/index.tsx b/src/components/comment/CommentAvatar/index.tsx index a3142b91..ea85cb99 100644 --- a/src/components/comment/CommentAvatar/index.tsx +++ b/src/components/comment/CommentAvatar/index.tsx @@ -16,10 +16,11 @@ interface Props { const CommentAvatar: FC = ({ user, className }) => { return ( } + translucentMenu > diff --git a/src/components/menu/MenuButton/index.tsx b/src/components/menu/MenuButton/index.tsx index c8cad64e..71e9625b 100644 --- a/src/components/menu/MenuButton/index.tsx +++ b/src/components/menu/MenuButton/index.tsx @@ -12,6 +12,7 @@ interface MenuButtonProps { position?: 'top-end' | 'bottom-end' | 'top-start' | 'bottom-start' | 'top' | 'bottom'; icon?: ReactNode; className?: string; + translucentMenu?: boolean; } const modifiers = [ @@ -28,8 +29,9 @@ const MenuButton: FC = ({ children, className, icon = , + translucentMenu, }) => { - const { focused, onFocus, onBlur } = useFocusEvent(true, 150); + const { focused, onFocus, onBlur } = useFocusEvent(false, 150); return ( @@ -49,7 +51,13 @@ const MenuButton: FC = ({ {focused && ( {({ style, ref, placement }) => ( -
+
{children}
)} diff --git a/src/components/menu/MenuButton/styles.module.scss b/src/components/menu/MenuButton/styles.module.scss index e5085d60..c8665eed 100644 --- a/src/components/menu/MenuButton/styles.module.scss +++ b/src/components/menu/MenuButton/styles.module.scss @@ -5,19 +5,13 @@ @import "src/styles/variables.scss"; -@keyframes appear { - 0% { opacity: 0 } - 100% { opacity: 1 } -} - .popper { @include outer_shadow; + @include blur($content_bg, 15px, 0.5); - background-color: $menu_bg; box-sizing: border-box; z-index: 12; border-radius: $radius; - animation: appear forwards 250ms; &::after { content: ' '; @@ -27,14 +21,27 @@ border-width: 0 10px 10px 10px; border-color: transparent transparent lighten($menu_bg, 6%) transparent; position: absolute; + } + + &.bottom-end::after { top: -11px; right: 10px; } + &.bottom-start::after { + top: -11px; + left: 10px; + } + + &.bottom::after { + top: -11px; + left: 50%; + margin-left: -15px; + } + &.top-end::after { border-width: 10px 10px 0 10px; border-color: darken($menu_bg, 8%) transparent transparent transparent; - top: auto; bottom: -11px; } @@ -43,7 +50,6 @@ border-color: darken($menu_bg, 8%) transparent transparent transparent; top: auto; bottom: -11px; - right: auto; left: 10px; } @@ -52,8 +58,7 @@ border-color: darken($menu_bg, 8%) transparent transparent transparent; top: auto; bottom: -11px; - right: auto; left: 50%; - margin-left: -10px; + margin-left: -15px; } } diff --git a/src/containers/profile/ProfileQuickInfo/index.tsx b/src/containers/profile/ProfileQuickInfo/index.tsx index 6f106061..54467313 100644 --- a/src/containers/profile/ProfileQuickInfo/index.tsx +++ b/src/containers/profile/ProfileQuickInfo/index.tsx @@ -1,9 +1,13 @@ import React, { FC, useMemo } from 'react'; +import classNames from 'classnames'; + import { Avatar } from '~/components/common/Avatar'; import { Filler } from '~/components/containers/Filler'; import { Group } from '~/components/containers/Group'; import { useRandomPhrase } from '~/constants/phrases'; +import { useUserActiveStatus } from '~/hooks/auth/useUserActiveStatus'; +import { useUserDescription } from '~/hooks/auth/useUserDescription'; import { useColorGradientFromString } from '~/hooks/color/useColorGradientFromString'; import { IUser } from '~/types/auth'; import { generateGradientFromColor } from '~/utils/color'; @@ -16,15 +20,10 @@ interface ProfileQuickInfoProps { } const ProfileQuickInfo: FC = ({ user }) => { - const style = useMemo(() => { - const color = user.photo?.metadata?.dominant_color; - const gradient = color && generateGradientFromColor(color); - - return gradient ? { background: gradient } : undefined; - }, [user]); + const isActive = useUserActiveStatus(user.last_seen); return ( - +
@@ -33,6 +32,10 @@ const ProfileQuickInfo: FC = ({ user }) => {
{user.fullname || user.username}
~{user.username}
+ +
+ {isActive ? 'в сознании' : 'деактивирован'} +
diff --git a/src/containers/profile/ProfileQuickInfo/styles.module.scss b/src/containers/profile/ProfileQuickInfo/styles.module.scss index b4b88585..4b730e11 100644 --- a/src/containers/profile/ProfileQuickInfo/styles.module.scss +++ b/src/containers/profile/ProfileQuickInfo/styles.module.scss @@ -26,3 +26,19 @@ div.top.top { .fullname { margin-bottom: 3px; } + +.status { + font: $font_12_regular; + margin-top: $gap; + + &.active { + color: $olive; + } + + &::before { + content: '●'; + margin-right: 5px; + padding-top: 1px; + font-size: 0.8em; + } +} diff --git a/src/hooks/auth/useUserActiveStatus.ts b/src/hooks/auth/useUserActiveStatus.ts new file mode 100644 index 00000000..ba90caa9 --- /dev/null +++ b/src/hooks/auth/useUserActiveStatus.ts @@ -0,0 +1,14 @@ +import { differenceInDays, parseISO } from 'date-fns'; + +import { INACTIVE_ACCOUNT_DAYS } from '~/constants/user'; + +const today = new Date(); + +export const useUserActiveStatus = (lastSeen?: string) => { + try { + const lastSeenDate = lastSeen ? parseISO(lastSeen) : undefined; + return lastSeenDate && differenceInDays(today, lastSeenDate) < INACTIVE_ACCOUNT_DAYS; + } catch (e) { + return false; + } +}; diff --git a/src/hooks/auth/useUserDescription.ts b/src/hooks/auth/useUserDescription.ts index d9dcc7c6..096831c5 100644 --- a/src/hooks/auth/useUserDescription.ts +++ b/src/hooks/auth/useUserDescription.ts @@ -1,11 +1,7 @@ -import { differenceInDays, parseISO } from 'date-fns'; - import { useRandomPhrase } from '~/constants/phrases'; -import { INACTIVE_ACCOUNT_DAYS } from '~/constants/user'; +import { useUserActiveStatus } from '~/hooks/auth/useUserActiveStatus'; import { IUser } from '~/types/auth'; -const today = new Date(); - export const useUserDescription = (user?: Partial) => { const randomPhrase = useRandomPhrase('USER_DESCRIPTION'); @@ -13,8 +9,9 @@ export const useUserDescription = (user?: Partial) => { return ''; } - const lastSeen = user.last_seen ? parseISO(user.last_seen) : undefined; - if (!lastSeen || differenceInDays(today, lastSeen) > INACTIVE_ACCOUNT_DAYS) { + const isActive = useUserActiveStatus(user.last_seen); + + if (!isActive) { return 'Юнит деактивирован'; } diff --git a/src/utils/color.ts b/src/utils/color.ts index 8169de88..f37a7518 100644 --- a/src/utils/color.ts +++ b/src/utils/color.ts @@ -1,4 +1,4 @@ -import { adjustHue, darken, desaturate, parseToHsla } from 'color2k'; +import { adjustHue, darken, desaturate, parseToHsla, transparentize } from 'color2k'; import { DEFAULT_DOMINANT_COLOR } from '~/constants/node'; import { stringToColour } from '~/utils/dom'; @@ -30,8 +30,16 @@ export const generateGradientFromColor = ( val: string, saturation = 3, lightness = 3, - angle = 155 + angle = 155, + opacity = 1 ) => { - const [color, second, third] = generateColorTriplet(val, saturation, lightness); - return `linear-gradient(${angle}deg, ${color}, ${second}, ${third})`; + const [first, second, third] = generateColorTriplet(val, saturation, lightness).map(it => { + if (opacity > 1 || opacity < 0) { + return it; + } + + return transparentize(it, 1 - opacity); + }); + + return `linear-gradient(${angle}deg, ${first}, ${second}, ${third})`; };