mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 18:44:16 +00:00
support for disable element
This commit is contained in:
parent
379838d0f7
commit
37ab0184c2
@ -4,68 +4,73 @@ import classnames from "classnames"
|
|||||||
import "./index.less"
|
import "./index.less"
|
||||||
|
|
||||||
export default (props) => {
|
export default (props) => {
|
||||||
const [liked, setLiked] = React.useState(props.liked)
|
const [liked, setLiked] = React.useState(
|
||||||
const [clicked, setClicked] = React.useState(false)
|
typeof props.liked === "function" ? false : props.liked,
|
||||||
|
)
|
||||||
|
const [clicked, setClicked] = React.useState(false)
|
||||||
|
|
||||||
// TODO: Support handle like change on websocket event
|
// TODO: Support handle like change on websocket event
|
||||||
if (typeof props.watchWs === "object") {
|
if (typeof props.watchWs === "object") {
|
||||||
// useWsEvents({
|
// useWsEvents({
|
||||||
// [props.watchWs.event]: (data) => {
|
// [props.watchWs.event]: (data) => {
|
||||||
// handleUpdateTrackLike(data.track_id, data.action === "liked")
|
// handleUpdateTrackLike(data.track_id, data.action === "liked")
|
||||||
// }
|
// }
|
||||||
// }, {
|
// }, {
|
||||||
// socketName: props.watchWs.socket,
|
// socketName: props.watchWs.socket,
|
||||||
// })
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
async function computeLikedState() {
|
async function computeLikedState() {
|
||||||
if (typeof props.liked === "function") {
|
if (props.disabled) {
|
||||||
let result = await props.liked()
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
result = result.liked ?? result
|
if (typeof props.liked === "function") {
|
||||||
|
let result = await props.liked()
|
||||||
|
|
||||||
return setLiked(result)
|
result = result.liked ?? result
|
||||||
}
|
|
||||||
|
|
||||||
return setLiked(props.liked)
|
return setLiked(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleClick = () => {
|
return setLiked(props.liked)
|
||||||
setClicked(true)
|
}
|
||||||
|
|
||||||
setTimeout(() => {
|
const handleClick = () => {
|
||||||
setClicked(false)
|
if (props.disabled) {
|
||||||
}, 500)
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof props.onClick === "function") {
|
setClicked(true)
|
||||||
props.onClick()
|
|
||||||
}
|
|
||||||
|
|
||||||
setLiked(!liked)
|
setTimeout(() => {
|
||||||
}
|
setClicked(false)
|
||||||
|
}, 500)
|
||||||
|
|
||||||
React.useEffect(() => {
|
if (typeof props.onClick === "function") {
|
||||||
computeLikedState()
|
props.onClick()
|
||||||
}, [props.liked])
|
}
|
||||||
|
|
||||||
return <button
|
setLiked(!liked)
|
||||||
className={classnames(
|
}
|
||||||
"likeButton",
|
|
||||||
{
|
React.useEffect(() => {
|
||||||
["liked"]: liked,
|
computeLikedState()
|
||||||
["clicked"]: clicked,
|
}, [props.liked])
|
||||||
}
|
|
||||||
)}
|
return (
|
||||||
onClick={handleClick}
|
<button
|
||||||
>
|
className={classnames("likeButton", {
|
||||||
{
|
["liked"]: liked,
|
||||||
!!props.ripple && <div className="ripple" />
|
["clicked"]: clicked,
|
||||||
}
|
["disabled"]: props.disabled,
|
||||||
<svg
|
})}
|
||||||
className="heart"
|
onClick={handleClick}
|
||||||
viewBox="0 0 24 24"
|
>
|
||||||
>
|
{!!props.ripple && <div className="ripple" />}
|
||||||
<path d="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"></path>
|
<svg className="heart" viewBox="0 0 24 24">
|
||||||
</svg>
|
<path d="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z"></path>
|
||||||
</button>
|
</svg>
|
||||||
|
</button>
|
||||||
|
)
|
||||||
}
|
}
|
@ -1,158 +1,161 @@
|
|||||||
@likeAnimationDuration : .5s;
|
@likeAnimationDuration: 0.5s;
|
||||||
@likeAnimationEasing : cubic-bezier(.7, 0, .3, 1);
|
@likeAnimationEasing: cubic-bezier(0.7, 0, 0.3, 1);
|
||||||
|
|
||||||
.likeButton {
|
.likeButton {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
|
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
||||||
transition: all @likeAnimationDuration @likeAnimationEasing;
|
transition: all @likeAnimationDuration @likeAnimationEasing;
|
||||||
|
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
content: '';
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
transition: inherit;
|
transition: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
content: '';
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
height: 1em;
|
height: 1em;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.liked {
|
&.liked {
|
||||||
.heart {
|
.heart {
|
||||||
>path {
|
> path {
|
||||||
stroke: var(--colorPrimary);
|
stroke: var(--colorPrimary);
|
||||||
fill: var(--colorPrimary);
|
fill: var(--colorPrimary);
|
||||||
}
|
}
|
||||||
|
|
||||||
filter: drop-shadow(0px 0px 2px var(--colorPrimary));
|
filter: drop-shadow(0px 0px 2px var(--colorPrimary));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.clicked {
|
&.clicked {
|
||||||
.heart {
|
.heart {
|
||||||
animation: heart-bounce @likeAnimationDuration @likeAnimationEasing;
|
animation: heart-bounce @likeAnimationDuration @likeAnimationEasing;
|
||||||
|
|
||||||
@keyframes heart-bounce {
|
@keyframes heart-bounce {
|
||||||
40% {
|
40% {
|
||||||
transform: scale(0.7);
|
transform: scale(0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
0%,
|
0%,
|
||||||
80%,
|
80%,
|
||||||
100% {
|
100% {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.heart {
|
&.disabled {
|
||||||
position: relative;
|
pointer-events: none;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
cursor: pointer;
|
.heart {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
>path {
|
cursor: pointer;
|
||||||
stroke-width: 2;
|
|
||||||
transition: fill @likeAnimationDuration @likeAnimationEasing;
|
|
||||||
stroke: currentColor;
|
|
||||||
fill: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
animation: none;
|
> path {
|
||||||
|
stroke-width: 2;
|
||||||
|
transition: fill @likeAnimationDuration @likeAnimationEasing;
|
||||||
|
stroke: currentColor;
|
||||||
|
fill: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
width: 1em;
|
animation: none;
|
||||||
height: 1em;
|
|
||||||
|
|
||||||
margin: 0;
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
|
||||||
transition: all @likeAnimationDuration @likeAnimationEasing;
|
margin: 0;
|
||||||
}
|
|
||||||
|
|
||||||
.ripple {
|
transition: all @likeAnimationDuration @likeAnimationEasing;
|
||||||
position: absolute;
|
}
|
||||||
|
|
||||||
height: 1em;
|
.ripple {
|
||||||
width: 1em;
|
position: absolute;
|
||||||
|
|
||||||
border-radius: 50%;
|
height: 1em;
|
||||||
overflow: hidden;
|
width: 1em;
|
||||||
|
|
||||||
z-index: 1;
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
&:before {
|
z-index: 1;
|
||||||
content: '';
|
|
||||||
position: absolute;
|
&:before {
|
||||||
top: 0;
|
content: "";
|
||||||
left: 0;
|
position: absolute;
|
||||||
width: 100%;
|
top: 0;
|
||||||
height: 100%;
|
left: 0;
|
||||||
border: .4em solid var(--colorPrimary);
|
width: 100%;
|
||||||
border-radius: inherit;
|
height: 100%;
|
||||||
transform: scale(0);
|
border: 0.4em solid var(--colorPrimary);
|
||||||
}
|
border-radius: inherit;
|
||||||
}
|
transform: scale(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes ripple-out {
|
@keyframes ripple-out {
|
||||||
from {
|
from {
|
||||||
transform: scale(0);
|
transform: scale(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
to {
|
to {
|
||||||
transform: scale(5);
|
transform: scale(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes depress {
|
@keyframes depress {
|
||||||
|
from,
|
||||||
|
to {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
from,
|
50% {
|
||||||
to {
|
transform: translateY(5%) scale(0.9);
|
||||||
transform: none;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: translateY(5%) scale(0.9);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes depress-shadow {
|
@keyframes depress-shadow {
|
||||||
|
from,
|
||||||
|
to {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
from,
|
50% {
|
||||||
to {
|
transform: scale(0.5);
|
||||||
transform: none;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
50% {
|
|
||||||
transform: scale(0.5);
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user