fix ui bugs in session tab

This commit is contained in:
sylenien 2022-05-12 14:53:20 +02:00 committed by Delirium
parent 923fce97fb
commit 7005c046b8
7 changed files with 148 additions and 19 deletions

View file

@ -0,0 +1,42 @@
import React, { useState, useEffect } from 'react'
import {
Link,
Icon,
} from 'UI';
import { session as sessionRoute, liveSession as liveSessionRoute } from 'App/routes';
const PLAY_ICON_NAMES = {
notPlayed: 'play-fill',
played: 'play-circle-light',
hovered: 'play-hover'
}
const getDefaultIconName = (isViewed) => !isViewed ? PLAY_ICON_NAMES.notPlayed : PLAY_ICON_NAMES.played
interface Props {
isAssist: boolean;
viewed: boolean;
sessionId: string;
}
export default function PlayLink(props: Props) {
const { isAssist, viewed, sessionId } = props
const defaultIconName = getDefaultIconName(viewed)
const [isHovered, toggleHover] = useState(false)
const [iconName, setIconName] = useState(defaultIconName)
useEffect(() => {
if (isHovered) setIconName(PLAY_ICON_NAMES.hovered)
else setIconName(getDefaultIconName(viewed))
}, [isHovered, viewed])
return (
<Link
to={ isAssist ? liveSessionRoute(sessionId) : sessionRoute(sessionId) }
onMouseEnter={() => toggleHover(true)}
onMouseLeave={() => toggleHover(false)}
>
<Icon name={iconName} size="42" color={isAssist ? "tealx" : "teal"} />
</Link>
)
}

View file

@ -0,0 +1 @@
export { default } from './PlayLink'

View file

@ -15,6 +15,7 @@ import stl from './sessionItem.css';
import Counter from './Counter'
import { withRouter } from 'react-router-dom';
import SessionMetaList from './SessionMetaList';
import PlayLink from './PlayLink';
import ErrorBars from './ErrorBars';
import { assist as assistRoute, liveSession, sessions as sessionsRoute, isRoute } from "App/routes";
import { capitalize } from 'App/utils';
@ -76,7 +77,7 @@ export default class SessionItem extends React.PureComponent {
});
return (
<div className={ cn(stl.sessionItem, "flex flex-col bg-white p-3 mb-3") } id="session-item" >
<div className={ cn(stl.sessionItem, "flex flex-col p-3 mb-3") } id="session-item" >
<div className="flex items-start">
<div className={ cn('flex items-center w-full')}>
<div className="flex items-center pr-2" style={{ width: "30%"}}>
@ -144,9 +145,11 @@ export default class SessionItem extends React.PureComponent {
)}
</div>
)}
<Link to={ isAssist ? liveSessionRoute(sessionId) : sessionRoute(sessionId) }>
<Icon name={ !viewed && !isAssist ? 'play-fill' : 'play-circle-light' } size="42" color={isAssist ? "tealx" : "teal"} />
</Link>
<PlayLink
isAssist={isAssist}
sessionId={sessionId}
viewed={viewed}
/>
</div>
</div>
</div>

View file

@ -1,5 +1,8 @@
@import 'mixins.css';
.sessionItem {
background-color: #fff;
@mixin defaultHover;
user-select: none;
border-radius: 3px;
border: solid thin #EEEEEE;

View file

@ -1,7 +1,42 @@
import { useState, useRef, useEffect, forwardRef } from 'react';
import cn from 'classnames';
import { Popup } from 'UI';
import styles from './textEllipsis.css';
/** calculates text width in pixels
+ * by creating a hidden element with t
+ * ext and counting its width
+ * @param text String - text string
+ * @param fontProp String - font properties
+ * @returns width number
+ */
function findTextWidth(text, fontProp) {
const tag = document.createElement('div')
tag.style.position = 'absolute'
tag.style.left = '-99in'
tag.style.whiteSpace = 'nowrap'
tag.style.font = fontProp
tag.innerHTML = text
document.body.appendChild(tag)
const result = tag.clientWidth
document.body.removeChild(tag)
return result;
}
const Trigger = forwardRef(({ textOrChildren, maxWidth, style, className, ...rest }, ref) => (
<div
className={ cn(styles.textEllipsis, className) }
style={{ maxWidth, ...style }}
ref={ref}
{ ...rest }
>
{ textOrChildren }
</div>
))
const TextEllipsis = ({
text,
hintText = text,
@ -14,23 +49,51 @@ const TextEllipsis = ({
hintProps={},
...props
}) => {
const [showPopup, setShowPopup] = useState(false)
const textRef = useRef(null);
const textOrChildren = text || children;
const trigger = (
<div
className={ cn(styles.textEllipsis, className) }
style={{ maxWidth, ...style }}
{ ...props }
>
{ textOrChildren }
</div>
);
if (noHint) return trigger;
const popupId = (Math.random() + 1).toString(36).substring(7);
useEffect(() => {
const element = textRef.current;
const fontSize = window.getComputedStyle(element, null).getPropertyValue('font-size');
const textWidth = findTextWidth(element.innerText, fontSize)
console.log(textWidth, element.clientWidth)
if (textWidth > element.clientWidth) setShowPopup(true)
else setShowPopup(false)
}, [textRef.current])
if (noHint || !showPopup) return (
<Trigger
className={className}
maxWidth={maxWidth}
style={style}
textOrChildren={textOrChildren}
ref={textRef}
{...props}
/>
)
return (
<Popup
trigger={ trigger }
content={ <div className="customPopupText" { ...hintProps } >{ hintText || textOrChildren }</div> }
{ ...popupProps }
/>
trigger={
<Trigger
className={className}
maxWidth={maxWidth}
style={style}
textOrChildren={textOrChildren}
id={popupId}
ref={textRef}
{...props}
/>
}
content={ <div className="customPopupText" { ...hintProps } >{ hintText || textOrChildren }</div> }
{ ...popupProps }
/>
);
};

View file

@ -5,8 +5,13 @@ import stl from './timezoneDropdown.css';
import { connect } from 'react-redux';
import { setTimezone } from 'Duck/sessions';
const localMachineFormat = new Date().toString().match(/([A-Z]+[\+-][0-9]+)/)[1]
const middlePoint = localMachineFormat.length - 2
const readableLocalTimezone =
`${localMachineFormat.substring(0, 3)} ${localMachineFormat.substring(3, middlePoint)}:${localMachineFormat.substring(middlePoint)}`
const timezoneOptions = {
'local': new Date().toString().match(/([A-Z]+[\+-][0-9]+)/)[1],
'local': readableLocalTimezone,
'UTC': 'UTC'
};

View file

@ -0,0 +1,12 @@
<svg width="42" height="42" viewBox="0 0 42 42" fill="inherit" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_47)">
<path d="M21 0C25.1534 0 29.2135 1.23163 32.667 3.53914C36.1204 5.84665 38.812 9.1264 40.4015 12.9636C41.9909 16.8009 42.4068 21.0233 41.5965 25.0969C40.7862 29.1705 38.7861 32.9123 35.8492 35.8492C32.9123 38.7861 29.1705 40.7862 25.0969 41.5965C21.0233 42.4068 16.8009 41.9909 12.9636 40.4015C9.1264 38.812 5.84665 36.1204 3.53914 32.667C1.23163 29.2135 0 25.1534 0 21C0 15.4305 2.21249 10.089 6.15076 6.15076C10.089 2.21249 15.4305 0 21 0ZM21 1.27615C17.099 1.27615 13.2856 2.43294 10.042 4.60022C6.79845 6.76751 4.27039 9.84795 2.77754 13.452C1.28469 17.0561 0.894093 21.0219 1.65514 24.8479C2.41619 28.674 4.29471 32.1884 7.05313 34.9469C9.81156 37.7053 13.326 39.5838 17.1521 40.3449C20.9781 41.1059 24.9439 40.7153 28.548 39.2225C32.1521 37.7296 35.2325 35.2015 37.3998 31.958C39.5671 28.7144 40.7238 24.901 40.7238 21C40.7238 18.4098 40.2137 15.845 39.2225 13.452C38.2312 11.059 36.7784 8.88466 34.9469 7.05313C33.1153 5.22161 30.941 3.76876 28.548 2.77754C26.155 1.78633 23.5902 1.27615 21 1.27615Z" />
<circle cx="21" cy="21" r="20" fill="inherit" />
<path d="M29.3192 23.0838C31.1527 21.9531 31.1527 20.1438 29.3192 19.0454L18.6819 12.6565C16.8485 11.5258 15.3462 12.2608 15.3462 14.2719V27.7604C15.3462 29.7312 16.8485 30.4742 18.69 29.3758L29.3192 23.0838Z" fill="white"/>
</g>
<defs>
<clipPath id="clip0_1_47">
<rect width="42" height="42" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB