kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
Restore icon picker
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>environments/review-update-emo-25jnc5/deployments/2714
rodzic
01a4e7370f
commit
dfa5d3ec8e
|
@ -13,7 +13,7 @@ const getImageURL = (set: string, name: string) => {
|
||||||
return joinPublicPath(`/packs/emoji/${name}.svg`);
|
return joinPublicPath(`/packs/emoji/${name}.svg`);
|
||||||
};
|
};
|
||||||
|
|
||||||
function Picker(props: any) {
|
const Picker = (props: any) => {
|
||||||
const ref = useRef(null);
|
const ref = useRef(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -23,7 +23,7 @@ function Picker(props: any) {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return <div ref={ref} />;
|
return <div ref={ref} />;
|
||||||
}
|
};
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Picker,
|
Picker,
|
||||||
|
|
|
@ -40,6 +40,7 @@ export const addCustomToPool = (customEmojis: any[]) => {
|
||||||
const search = (str: string, { maxResults = 5, custom }: searchOptions = {}, custom_emojis?: any): Emoji[] => {
|
const search = (str: string, { maxResults = 5, custom }: searchOptions = {}, custom_emojis?: any): Emoji[] => {
|
||||||
return index.search(str, maxResults)
|
return index.search(str, maxResults)
|
||||||
.flatMap((id: string) => {
|
.flatMap((id: string) => {
|
||||||
|
console.log(id);
|
||||||
if (id[0] === 'c') {
|
if (id[0] === 'c') {
|
||||||
const { shortcode, static_url } = custom_emojis.get((id as string).slice(1)).toJS();
|
const { shortcode, static_url } = custom_emojis.get((id as string).slice(1)).toJS();
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ const search = (str: string, { maxResults = 5, custom }: searchOptions = {}, cus
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: (id as string).slice(1),
|
id: (id as string).slice(1),
|
||||||
colons: ':' + id + ':',
|
colons: ':' + id.slice(1) + ':',
|
||||||
unified: skins[0].unified,
|
unified: skins[0].unified,
|
||||||
native: skins[0].native,
|
native: skins[0].native,
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,10 +13,10 @@ const messages = defineMessages({
|
||||||
|
|
||||||
interface IIconPickerDropdown {
|
interface IIconPickerDropdown {
|
||||||
value: string
|
value: string
|
||||||
onPickEmoji: React.ChangeEventHandler
|
onPickIcon: (icon: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const IconPickerDropdown: React.FC<IIconPickerDropdown> = ({ value, onPickEmoji }) => {
|
const IconPickerDropdown: React.FC<IIconPickerDropdown> = ({ value, onPickIcon }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const [active, setActive] = useState(false);
|
const [active, setActive] = useState(false);
|
||||||
|
@ -73,9 +73,9 @@ const IconPickerDropdown: React.FC<IIconPickerDropdown> = ({ value, onPickEmoji
|
||||||
|
|
||||||
<Overlay show={active} placement={placement} target={target.current}>
|
<Overlay show={active} placement={placement} target={target.current}>
|
||||||
<IconPickerMenu
|
<IconPickerMenu
|
||||||
customEmojis={forkAwesomeIcons}
|
icons={forkAwesomeIcons}
|
||||||
onClose={onHideDropdown}
|
onClose={onHideDropdown}
|
||||||
onPick={onPickEmoji}
|
onPick={onPickIcon}
|
||||||
/>
|
/>
|
||||||
</Overlay>
|
</Overlay>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,30 +1,25 @@
|
||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { supportsPassiveEvents } from 'detect-passive-events';
|
import { supportsPassiveEvents } from 'detect-passive-events';
|
||||||
import React, { useCallback, useEffect, useRef } from 'react';
|
import React, { useCallback, useEffect, useRef } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
import { Text } from 'soapbox/components/ui';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
emoji: { id: 'icon_button.label', defaultMessage: 'Select icon' },
|
emoji: { id: 'icon_button.label', defaultMessage: 'Select icon' },
|
||||||
emoji_search: { id: 'emoji_button.search', defaultMessage: 'Search…' },
|
|
||||||
emoji_not_found: { id: 'icon_button.not_found', defaultMessage: 'No icons!! (╯°□°)╯︵ ┻━┻' },
|
|
||||||
custom: { id: 'icon_button.icons', defaultMessage: 'Icons' },
|
|
||||||
search_results: { id: 'emoji_button.search_results', defaultMessage: 'Search results' },
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const backgroundImageFn = () => '';
|
|
||||||
const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
|
const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
|
||||||
|
|
||||||
const categoriesSort = ['custom'];
|
|
||||||
|
|
||||||
interface IIconPickerMenu {
|
interface IIconPickerMenu {
|
||||||
customEmojis: Record<string, Array<string>>
|
icons: Record<string, Array<string>>
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
onPick: any
|
onPick: (icon: string) => void
|
||||||
style?: React.CSSProperties
|
style?: React.CSSProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
const IconPickerMenu: React.FC<IIconPickerMenu> = ({ customEmojis, onClose, onPick, style }) => {
|
const IconPickerMenu: React.FC<IIconPickerMenu> = ({ icons, onClose, onPick, style }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const node = useRef<HTMLDivElement | null>(null);
|
const node = useRef<HTMLDivElement | null>(null);
|
||||||
|
@ -59,70 +54,42 @@ const IconPickerMenu: React.FC<IIconPickerMenu> = ({ customEmojis, onClose, onPi
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getI18n = () => {
|
const handleClick = (icon: string) => {
|
||||||
|
|
||||||
return {
|
|
||||||
search: intl.formatMessage(messages.emoji_search),
|
|
||||||
notfound: intl.formatMessage(messages.emoji_not_found),
|
|
||||||
categories: {
|
|
||||||
search: intl.formatMessage(messages.search_results),
|
|
||||||
custom: intl.formatMessage(messages.custom),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleClick = (emoji: Record<string, any>) => {
|
|
||||||
emoji.native = emoji.colons;
|
|
||||||
|
|
||||||
onClose();
|
onClose();
|
||||||
onPick(emoji);
|
onPick(icon);
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildIcons = () => {
|
const renderIcon = (icon: string) => {
|
||||||
const emojis: Record<string, any> = [];
|
|
||||||
|
|
||||||
Object.values(customEmojis).forEach((category) => {
|
|
||||||
category.forEach((icon) => {
|
|
||||||
const name = icon.replace('fa fa-', '');
|
const name = icon.replace('fa fa-', '');
|
||||||
if (icon !== 'email' && icon !== 'memo') {
|
|
||||||
emojis.push({
|
|
||||||
id: name,
|
|
||||||
name,
|
|
||||||
short_names: [name],
|
|
||||||
emoticons: [],
|
|
||||||
keywords: [name],
|
|
||||||
imageUrl: '',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return emojis;
|
return (
|
||||||
|
<li key={icon} className='col-span-1 inline-block'>
|
||||||
|
<button
|
||||||
|
className='flex items-center justify-center rounded-full p-1.5 hover:bg-gray-50 dark:hover:bg-primary-800'
|
||||||
|
aria-label={name}
|
||||||
|
title={name}
|
||||||
|
onClick={() => handleClick(name)}
|
||||||
|
>
|
||||||
|
<i className={clsx(icon, 'h-[1.375rem] w-[1.375rem] text-lg leading-[1.15]')} />
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const data = { compressed: true, categories: [], aliases: [], emojis: [] };
|
|
||||||
const title = intl.formatMessage(messages.emoji);
|
const title = intl.formatMessage(messages.emoji);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={clsx('font-icon-picker emoji-picker-dropdown__menu')} style={style} ref={setRef}>
|
<div
|
||||||
{/* <Picker
|
className={clsx('absolute z-[101] -my-0.5')}
|
||||||
perLine={8}
|
style={{ transform: 'translateX(calc(-1 * env(safe-area-inset-right)))', ...style }}
|
||||||
emojiSize={22}
|
ref={setRef}
|
||||||
include={categoriesSort}
|
>
|
||||||
sheetSize={32}
|
<div className='h-[270px] overflow-x-hidden overflow-y-scroll rounded bg-white p-1.5 text-gray-900 dark:bg-primary-900 dark:text-gray-100' aria-label={title}>
|
||||||
custom={buildIcons()}
|
<Text className='px-1.5 py-1'><FormattedMessage id='icon_button.icons' defaultMessage='Icons' /></Text>
|
||||||
color=''
|
<ul className='grid grid-cols-8'>
|
||||||
emoji=''
|
{Object.values(icons).flat().map(icon => renderIcon(icon))}
|
||||||
set=''
|
</ul>
|
||||||
title={title}
|
</div>
|
||||||
i18n={getI18n()}
|
|
||||||
onClick={handleClick}
|
|
||||||
showPreview={false}
|
|
||||||
backgroundImageFn={backgroundImageFn}
|
|
||||||
emojiTooltip
|
|
||||||
noShowAnchors
|
|
||||||
data={data}
|
|
||||||
/> */}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,15 +4,13 @@ import IconPickerDropdown from './icon-picker-dropdown';
|
||||||
|
|
||||||
interface IIconPicker {
|
interface IIconPicker {
|
||||||
value: string
|
value: string
|
||||||
onChange: React.ChangeEventHandler
|
onChange: (icon: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
const IconPicker: React.FC<IIconPicker> = ({ value, onChange }) => {
|
const IconPicker: React.FC<IIconPicker> = ({ value, onChange }) => (
|
||||||
return (
|
|
||||||
<div className='relative mt-1 rounded-md border border-solid border-gray-300 shadow-sm dark:border-gray-600 dark:bg-gray-800'>
|
<div className='relative mt-1 rounded-md border border-solid border-gray-300 shadow-sm dark:border-gray-600 dark:bg-gray-800'>
|
||||||
<IconPickerDropdown value={value} onPickEmoji={onChange} />
|
<IconPickerDropdown value={value} onPickIcon={onChange} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
export default IconPicker;
|
export default IconPicker;
|
||||||
|
|
|
@ -17,8 +17,8 @@ const messages = defineMessages({
|
||||||
const PromoPanelInput: StreamfieldComponent<PromoPanelItem> = ({ value, onChange }) => {
|
const PromoPanelInput: StreamfieldComponent<PromoPanelItem> = ({ value, onChange }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const handleIconChange = (icon: any) => {
|
const handleIconChange = (icon: string) => {
|
||||||
onChange(value.set('icon', icon.id));
|
onChange(value.set('icon', icon));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChange = (key: 'text' | 'url'): React.ChangeEventHandler<HTMLInputElement> => {
|
const handleChange = (key: 'text' | 'url'): React.ChangeEventHandler<HTMLInputElement> => {
|
||||||
|
|
Ładowanie…
Reference in New Issue