mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 05:25:40 +09:00
82 lines
2.6 KiB
TypeScript
82 lines
2.6 KiB
TypeScript
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
import type {AutocompleteOption} from '@app/features/channel/components/Autocomplete';
|
|
import {isSticker} from '@app/features/channel/components/Autocomplete';
|
|
import styles from '@app/features/channel/components/AutocompleteEmoji.module.css';
|
|
import {AutocompleteItem} from '@app/features/channel/components/AutocompleteItem';
|
|
import {useStickerAnimation} from '@app/features/emoji/hooks/useStickerAnimation';
|
|
import * as AvatarUtils from '@app/features/user/utils/AvatarUtils';
|
|
import {observer} from 'mobx-react-lite';
|
|
import type React from 'react';
|
|
|
|
const AutocompleteStickerIcon = observer(
|
|
({id, name, isInteracting}: {id: string; name: string; isInteracting: boolean}) => {
|
|
const {shouldAnimate} = useStickerAnimation({isInteracting});
|
|
return (
|
|
<div className={styles.stickerIconWrapper} data-flx="channel.autocomplete-sticker.sticker-icon-wrapper">
|
|
<img
|
|
draggable={false}
|
|
className={styles.stickerIcon}
|
|
src={AvatarUtils.getStickerURL({id, animated: shouldAnimate, size: 320})}
|
|
alt={name}
|
|
data-flx="channel.autocomplete-sticker.sticker-icon"
|
|
/>
|
|
</div>
|
|
);
|
|
},
|
|
);
|
|
export const AutocompleteSticker = observer(
|
|
({
|
|
onSelect,
|
|
keyboardFocusIndex,
|
|
hoverIndex,
|
|
options,
|
|
onMouseEnter,
|
|
onMouseLeave,
|
|
rowRefs,
|
|
getOptionId,
|
|
}: {
|
|
onSelect: (option: AutocompleteOption) => void;
|
|
keyboardFocusIndex: number;
|
|
hoverIndex: number;
|
|
options: Array<AutocompleteOption>;
|
|
onMouseEnter: (index: number) => void;
|
|
onMouseLeave: () => void;
|
|
rowRefs?: React.MutableRefObject<Array<HTMLButtonElement | null>>;
|
|
getOptionId?: (index: number) => string;
|
|
}) => {
|
|
const stickers = options.filter(isSticker);
|
|
return stickers.map((option, index) => (
|
|
<AutocompleteItem
|
|
key={option.sticker.id}
|
|
id={getOptionId?.(index)}
|
|
name={option.sticker.name}
|
|
description={
|
|
option.sticker.tags.length > 0 ? option.sticker.tags.join(', ') : option.sticker.description || undefined
|
|
}
|
|
icon={
|
|
<AutocompleteStickerIcon
|
|
id={option.sticker.id}
|
|
name={option.sticker.name}
|
|
isInteracting={index === keyboardFocusIndex || index === hoverIndex}
|
|
data-flx="channel.autocomplete-sticker.autocomplete-sticker-icon"
|
|
/>
|
|
}
|
|
isKeyboardSelected={index === keyboardFocusIndex}
|
|
isHovered={index === hoverIndex}
|
|
onSelect={() => onSelect(option)}
|
|
onMouseEnter={() => onMouseEnter(index)}
|
|
onMouseLeave={onMouseLeave}
|
|
innerRef={
|
|
rowRefs
|
|
? (node) => {
|
|
rowRefs.current[index] = node;
|
|
}
|
|
: undefined
|
|
}
|
|
data-flx="channel.autocomplete-sticker.autocomplete-item.select"
|
|
/>
|
|
));
|
|
},
|
|
);
|