Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(flat-components): change model #1849

Merged
merged 1 commit into from
Mar 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const preventEvent = (ev: React.UIEvent | Event): void => {
export interface AvatarWindowProps {
mode: "normal" | "maximized";
rect: Rectangle;
index?: number;
zIndex?: number;
hidden?: boolean;
readonly?: boolean;
Expand All @@ -37,7 +36,6 @@ export type ResizeHandle = "" | "n" | "s" | "w" | "e" | "nw" | "ne" | "sw" | "se
export const AvatarWindow: React.FC<AvatarWindowProps> = ({
mode,
rect,
index,
zIndex,
hidden,
readonly,
Expand Down Expand Up @@ -184,31 +182,25 @@ export const AvatarWindow: React.FC<AvatarWindowProps> = ({
);
};

const style =
mode === "normal"
? ({
position: "absolute",
// Prevent a rendering issue on Chrome when set transform to sub-pixel values
width: rect.width | 0,
height: rect.height | 0,
transform: `translate(${rect.x | 0}px,${rect.y | 0}px)`,
zIndex: zIndex,
} as React.CSSProperties)
: ({
flex: 1,
order: index,
} as React.CSSProperties);

return (
<div
className={classNames("window", {
"window-readonly": readonly,
"window-maximized": mode === "maximized",
})}
data-index={index}
data-z-index={zIndex}
hidden={hidden}
style={style}
style={
mode === "normal"
? {
position: "absolute",
// Prevent a rendering issue on Chrome when set transform to sub-pixel values
width: rect.width | 0,
height: rect.height | 0,
transform: `translate(${rect.x | 0}px,${rect.y | 0}px)`,
zIndex: zIndex,
}
: undefined
}
>
<div className="window-main" onClick={onClick} onPointerDown={handleTrackStart}>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
}

.window-maximized {
flex: 1;
transition: none;
cursor: default;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const VideoAvatar: React.FC<VideoAvatarProps> = ({
"is-small": small && !portal,
"is-drop-target": isDropTarget,
})}
data-user-uuid={avatarUser.userUUID}
draggable={isCreator && !portal}
onDoubleClick={portal ? undefined : onDoubleClick}
onDragEnd={onDragEnd}
Expand Down Expand Up @@ -140,11 +141,12 @@ export const VideoAvatar: React.FC<VideoAvatarProps> = ({
return portal ? (
<div
className={classnames("video-avatar", "video-avatar-holder", {
"is-small": small && !portal,
"is-small": small,
"is-drop-target": isDropTarget,
})}
data-user-uuid={avatarUser.userUUID}
>
<span className="video-avatar-holder-name">{avatarUser.name}</span>
{createPortal(view, portal)}
</div>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,34 @@
}

.video-avatar-holder {
background: transparent;
background: var(--grey-0);
display: flex;
align-items: center;
justify-content: center;

&::after {
content: none;
}
}

.video-avatar-holder-name {
user-select: none;
pointer-events: none;
padding: 0 12px;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
font-size: 16px;
color: var(--text);
opacity: .5;
}

.video-avatar-holder.is-drop-target {
box-shadow: inset 0 0 0 2px var(--primary);
}

.flat-color-scheme-dark {
.video-avatar-holder {
background: var(--grey-7);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from "react";

export interface SVGPlaceHolderProps {
className?: string;
isDark?: boolean;
}

export const SVGPlaceHolder: React.FC<SVGPlaceHolderProps> = ({ className, isDark }) => {
const stopColor = isDark ? "#33353D" : "#D5D9E0";

return (
<svg
className={className}
fill="none"
height="80"
viewBox="0 0 80 80"
width="80"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 80V71.7607C0 61.8652 6.62305 53.1938 16.1699 50.5898L19.873 49.5801C24.6387 48.2808 28.4375 44.6855 30 40L29.3926 39.3936C26.5801 36.5806 25 32.7651 25 28.7866V26.25C22.3535 23.9341 22.3535 19.8159 25 17.5V15C25 6.71582 31.7148 0 40 0C48.2852 0 55 6.71582 55 15V17.5C57.6465 19.8159 57.6465 23.9341 55 26.25V28.7866C55 32.7651 53.4199 36.5806 50.6074 39.3936L50 40C51.5625 44.6855 55.3613 48.2808 60.127 49.5801L63.8301 50.5898C73.377 53.1938 80 61.8652 80 71.7607V80H0Z"
fill="url(#paint0_linear_4451_134)"
/>
<defs>
<linearGradient
gradientUnits="userSpaceOnUse"
id="paint0_linear_4451_134"
x1="40"
x2="40"
y1="0"
y2="80"
>
<stop stopColor={stopColor} />
<stop offset="1" stopColor={stopColor} stopOpacity="0" />
</linearGradient>
</defs>
</svg>
);
};

export default SVGPlaceHolder;

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import "./style.less";

import placeholderSVG from "./icons/placeholder.svg";
import Placeholder from "./icons/Placeholder";

import React, { FC } from "react";
import React, { FC, useContext } from "react";
import { useTranslate } from "@netless/flat-i18n";
import classnames from "classnames";
import { User } from "../../../types/user";
import { DarkModeContext } from "../../FlatThemeProvider";

export interface VideoAvatarAbsentProps {
avatarUser?: User | null;
Expand All @@ -19,16 +20,23 @@ export const VideoAvatarAbsent: FC<VideoAvatarAbsentProps> = ({
isAvatarUserCreator,
}) => {
const t = useTranslate();
const isDark = useContext(DarkModeContext);

return (
<div className={classnames("video-avatar-absent", { "is-small": small })}>
<img className="video-avatar-absent-img" draggable={false} src={placeholderSVG} />
<span className="video-avatar-absent-content">
{isAvatarUserCreator
? t("teacher-left-temporarily")
: avatarUser
? t("user-left-temporarily", { name: avatarUser.name })
: t("student-left-temporarily")}
</span>
<div
className={classnames("video-avatar-absent", { "is-small": small })}
data-user-uuid="[object Object]"
>
<div className="video-avatar-absent-block">
<Placeholder className="video-avatar-absent-img" isDark={isDark} />
<span className="video-avatar-absent-content">
{isAvatarUserCreator
? t("teacher-left-temporarily")
: avatarUser
? t("user-left-temporarily", { name: avatarUser.name })
: t("student-left-temporarily")}
</span>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,51 @@
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
position: relative;
background: var(--grey-0);
user-select: none;

&.is-small {
font-size: 12px;

.video-avatar-absent-img {
margin-bottom: 8px;
}
border-radius: 6px;
}
}

.video-avatar-absent-block {
position: relative;
pointer-events: none;
}

.video-avatar-absent-img {
width: 100%;
max-width: 75%;
max-height: 60%;
margin-bottom: 16px;
user-select: none;
}

.video-avatar-absent-content {
display: block;
text-align: center;
padding: 0 16px;
font-size: 14px;
color: var(--text);
opacity: .5;
user-select: none;
}

.video-avatar-absent.is-small {
.video-avatar-absent-block {
width: 80px;
height: 80px;
}

.video-avatar-absent-content {
position: absolute;
left: 50%;
bottom: 0;
width: max-content;
transform: translateX(-50%);
}
}

.flat-color-scheme-dark {
.video-avatar-absent {
background: var(--grey-2);
background: var(--grey-7);
}
}
56 changes: 43 additions & 13 deletions packages/flat-pages/src/SmallClassPage/SmallClassPage.less
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
overflow: hidden;
}

.small-class-realtime-avatars-wrap-wrap {
position: relative;
}

.small-class-realtime-avatars-wrap {
overflow-y: hidden;
overflow-x: overlay;
Expand All @@ -61,7 +65,7 @@
.small-class-realtime-avatars {
height: 108px;
flex: 1;
gap: 4px;
gap: 8px;
padding: 0 4px;
display: flex;
justify-content: center;
Expand All @@ -84,12 +88,18 @@

.small-class-scroll-handles {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 100%;
display: flex;
align-items: stretch;
justify-content: space-between;
pointer-events: none;
z-index: 100;
font-size: 0;
opacity: 0;
transition: opacity 0.1s;
}

.small-class-scroll-handle {
Expand All @@ -98,25 +108,41 @@
border: none;
padding: 0;
outline: none;
width: 36px;
background-color: #fff;
width: 72px;
background-color: transparent;
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 0.1s;
cursor: pointer;
}

&.is-left {
border-right: 1px solid var(--grey-0);
}
.small-class-realtime-avatars-wrap:hover+.small-class-scroll-handles {
opacity: .5;
transition: opacity 0.5s;
}

&.is-right {
border-left: 1px solid var(--grey-0);
}
.small-class-scroll-handles:hover {
opacity: 1;
transition: opacity 0.1s;
}

.small-class-scroll-handle-btn {
display: inline-flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
border: 1px solid var(--grey-3);
border-radius: 50%;
background-color: #fff;
font-size: 0;

-webkit-backdrop-filter: blur(2.71828px);
backdrop-filter: blur(2.71828px);

&:hover {
opacity: 1;
>svg {
width: 32px;
height: 32px;
}
}

Expand All @@ -143,6 +169,10 @@
border-color: var(--grey-8);
}

.small-class-scroll-handle-btn {
border-color: var(--grey-8);
}

.small-class-realtime-avatars {
background: linear-gradient(270deg, #383B42 0%, #2B2F38 100%);
}
Expand Down
Loading