pl-fe: display animated emojis on hover unless specified otherwise
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
a6deb34558
commit
7c3cb6a6eb
5 changed files with 29 additions and 9 deletions
|
@ -45,7 +45,7 @@ const SidebarNavigationLink = React.forwardRef((props: ISidebarNavigationLink, r
|
|||
ref={ref}
|
||||
onClick={handleClick}
|
||||
className={clsx({
|
||||
'flex items-center py-2 text-sm font-semibold space-x-4 rtl:space-x-reverse transition-colors duration-200': true,
|
||||
'group flex items-center py-2 text-sm font-semibold space-x-4 rtl:space-x-reverse transition-colors duration-200': true,
|
||||
'text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200': !isActive,
|
||||
'text-gray-900 dark:text-white': isActive,
|
||||
})}
|
||||
|
@ -53,7 +53,7 @@ const SidebarNavigationLink = React.forwardRef((props: ISidebarNavigationLink, r
|
|||
<span
|
||||
className={clsx({
|
||||
'relative rounded-lg inline-flex p-2.5 transition-colors duration-200': true,
|
||||
'bg-primary-50 hover:bg-primary-100 dark:bg-slate-700 dark:hover:bg-slate-600 black:bg-gray-900 black:hover:bg-gray-800': !isActive,
|
||||
'bg-primary-50 group-hover:bg-primary-100 dark:bg-slate-700 dark:group-hover:bg-slate-600 black:bg-gray-900 black:group-hover:bg-gray-800': !isActive,
|
||||
'bg-primary-600': isActive,
|
||||
})}
|
||||
>
|
||||
|
|
|
@ -59,7 +59,7 @@ const StatusReaction: React.FC<IStatusReaction> = ({ reaction, status, obfuscate
|
|||
|
||||
return (
|
||||
<button
|
||||
className={clsx('flex cursor-pointer items-center gap-2 rounded-md border border-gray-400 p-1.5 transition-colors', {
|
||||
className={clsx('group flex cursor-pointer items-center gap-2 rounded-md border border-gray-400 p-1.5 transition-colors', {
|
||||
'bg-primary-100 dark:border-primary-400 dark:bg-primary-400 black:border-primary-600 black:bg-primary-600': reaction.me,
|
||||
'bg-transparent dark:border-primary-700 dark:bg-primary-700 black:border-primary-800 black:bg-primary-800': !reaction.me,
|
||||
'cursor-pointer': !disabled,
|
||||
|
|
|
@ -18,17 +18,23 @@ interface IStillImage {
|
|||
showExt?: boolean;
|
||||
/** Callback function if the image fails to load */
|
||||
onError?(): void;
|
||||
/** Treat as animated, no matter the extension */
|
||||
isGif?: boolean;
|
||||
/** Specify that the group is defined by the parent */
|
||||
noGroup?: boolean;
|
||||
}
|
||||
|
||||
/** Renders images on a canvas, only playing GIFs if autoPlayGif is enabled. */
|
||||
const StillImage: React.FC<IStillImage> = ({ alt, className, src, style, letterboxed = false, showExt = false, onError }) => {
|
||||
const StillImage: React.FC<IStillImage> = ({
|
||||
alt, className, src, style, letterboxed = false, showExt = false, onError, isGif, noGroup,
|
||||
}) => {
|
||||
const { autoPlayGif } = useSettings();
|
||||
|
||||
const canvas = useRef<HTMLCanvasElement>(null);
|
||||
const img = useRef<HTMLImageElement>(null);
|
||||
|
||||
const hoverToPlay = (
|
||||
src && !autoPlayGif && (src.endsWith('.gif') || src.startsWith('blob:'))
|
||||
src && !autoPlayGif && (isGif || src.endsWith('.gif') || src.startsWith('blob:'))
|
||||
);
|
||||
|
||||
const handleImageLoad = () => {
|
||||
|
@ -48,7 +54,7 @@ const StillImage: React.FC<IStillImage> = ({ alt, className, src, style, letterb
|
|||
return (
|
||||
<div
|
||||
data-testid='still-image-container'
|
||||
className={clsx(className, 'group relative isolate overflow-hidden')}
|
||||
className={clsx(className, 'relative isolate overflow-hidden', { 'group': !noGroup })}
|
||||
style={style}
|
||||
>
|
||||
<img
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import React from 'react';
|
||||
|
||||
import StillImage from 'pl-fe/components/still-image';
|
||||
import { removeVS16s, toCodePoints } from 'pl-fe/utils/emoji';
|
||||
import { joinPublicPath } from 'pl-fe/utils/static';
|
||||
|
||||
interface IEmoji extends React.ImgHTMLAttributes<HTMLImageElement> {
|
||||
interface IEmoji extends Pick<React.ImgHTMLAttributes<HTMLImageElement>, 'alt' | 'className' | 'src' | 'title'> {
|
||||
/** Unicode emoji character. */
|
||||
emoji?: string;
|
||||
noGroup?: boolean;
|
||||
}
|
||||
|
||||
/** A single emoji image. */
|
||||
const Emoji: React.FC<IEmoji> = (props): JSX.Element | null => {
|
||||
const { emoji, alt, src, ...rest } = props;
|
||||
const { emoji, alt, src, noGroup, ...rest } = props;
|
||||
|
||||
let filename;
|
||||
|
||||
|
@ -21,6 +23,18 @@ const Emoji: React.FC<IEmoji> = (props): JSX.Element | null => {
|
|||
|
||||
if (!filename && !src) return null;
|
||||
|
||||
if (src) {
|
||||
return (
|
||||
<StillImage
|
||||
alt={alt || emoji}
|
||||
src={src}
|
||||
isGif
|
||||
noGroup={noGroup}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<img
|
||||
draggable='false'
|
||||
|
|
|
@ -58,7 +58,7 @@ const EmojiPicker: React.FC<IEmojiPicker> = ({ emoji, emojiUrl, ...props }) => {
|
|||
tabIndex={0}
|
||||
>
|
||||
{emoji
|
||||
? <Emoji height={20} width={20} emoji={emoji} />
|
||||
? <Emoji className='h-5 w-5' emoji={emoji} src={emojiUrl} />
|
||||
: <Icon className='h-5 w-5 text-gray-600 hover:text-gray-700 dark:hover:text-gray-500' src={require('@tabler/icons/outline/mood-happy.svg')} />}
|
||||
</button>
|
||||
|
||||
|
|
Loading…
Reference in a new issue