Merge commit '1b664cf20dbb696cf16a42efcf59ab186cb211eb' into glitch-soc/merge-upstream
This commit is contained in:
commit
6fc9febb47
65 files changed
+903
-197
No files matched your search
@@ -1,7 +1,5 @@
|
||||
import type { ComponentPropsWithoutRef, ElementType } from 'react';
|
||||
|
||||
import { isModernEmojiEnabled } from '@/mastodon/utils/environment';
|
||||
|
||||
import { useEmojify } from './hooks';
|
||||
import type { CustomEmojiMapArg } from './types';
|
||||
|
||||
@@ -12,16 +10,21 @@ type EmojiHTMLProps<Element extends ElementType = 'div'> = Omit<
|
||||
htmlString: string;
|
||||
extraEmojis?: CustomEmojiMapArg;
|
||||
as?: Element;
|
||||
shallow?: boolean;
|
||||
};
|
||||
|
||||
export const ModernEmojiHTML = <Element extends ElementType>({
|
||||
export const EmojiHTML = ({
|
||||
extraEmojis,
|
||||
htmlString,
|
||||
as: asElement, // Rename for syntax highlighting
|
||||
as: Wrapper = 'div', // Rename for syntax highlighting
|
||||
shallow,
|
||||
...props
|
||||
}: EmojiHTMLProps<Element>) => {
|
||||
const Wrapper = asElement ?? 'div';
|
||||
const emojifiedHtml = useEmojify(htmlString, extraEmojis);
|
||||
}: EmojiHTMLProps<ElementType>) => {
|
||||
const emojifiedHtml = useEmojify({
|
||||
text: htmlString,
|
||||
extraEmojis,
|
||||
deep: !shallow,
|
||||
});
|
||||
|
||||
if (emojifiedHtml === null) {
|
||||
return null;
|
||||
@@ -31,14 +34,3 @@ export const ModernEmojiHTML = <Element extends ElementType>({
|
||||
<Wrapper {...props} dangerouslySetInnerHTML={{ __html: emojifiedHtml }} />
|
||||
);
|
||||
};
|
||||
|
||||
export const EmojiHTML = <Element extends ElementType>(
|
||||
props: EmojiHTMLProps<Element>,
|
||||
) => {
|
||||
if (isModernEmojiEnabled()) {
|
||||
return <ModernEmojiHTML {...props} />;
|
||||
}
|
||||
const { as: asElement, htmlString, extraEmojis, ...rest } = props;
|
||||
const Wrapper = asElement ?? 'div';
|
||||
return <Wrapper {...rest} dangerouslySetInnerHTML={{ __html: htmlString }} />;
|
||||
};
|
||||
@@ -8,6 +8,7 @@ import { isModernEmojiEnabled } from '@/mastodon/utils/environment';
|
||||
|
||||
import { toSupportedLocale } from './locale';
|
||||
import { determineEmojiMode } from './mode';
|
||||
import { emojifyElement, emojifyText } from './render';
|
||||
import type {
|
||||
CustomEmojiMapArg,
|
||||
EmojiAppState,
|
||||
@@ -15,7 +16,17 @@ import type {
|
||||
} from './types';
|
||||
import { stringHasAnyEmoji } from './utils';
|
||||
|
||||
export function useEmojify(text: string, extraEmojis?: CustomEmojiMapArg) {
|
||||
interface UseEmojifyOptions {
|
||||
text: string;
|
||||
extraEmojis?: CustomEmojiMapArg;
|
||||
deep?: boolean;
|
||||
}
|
||||
|
||||
export function useEmojify({
|
||||
text,
|
||||
extraEmojis,
|
||||
deep = true,
|
||||
}: UseEmojifyOptions) {
|
||||
const [emojifiedText, setEmojifiedText] = useState<string | null>(null);
|
||||
|
||||
const appState = useEmojiAppState();
|
||||
@@ -36,17 +47,23 @@ export function useEmojify(text: string, extraEmojis?: CustomEmojiMapArg) {
|
||||
|
||||
const emojify = useCallback(
|
||||
async (input: string) => {
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.innerHTML = input;
|
||||
const { emojifyElement } = await import('./render');
|
||||
const result = await emojifyElement(wrapper, appState, extra);
|
||||
let result: string | null = null;
|
||||
if (deep) {
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.innerHTML = input;
|
||||
if (await emojifyElement(wrapper, appState, extra)) {
|
||||
result = wrapper.innerHTML;
|
||||
}
|
||||
} else {
|
||||
result = await emojifyText(text, appState, extra);
|
||||
}
|
||||
if (result) {
|
||||
setEmojifiedText(result.innerHTML);
|
||||
setEmojifiedText(result);
|
||||
} else {
|
||||
setEmojifiedText(input);
|
||||
}
|
||||
},
|
||||
[appState, extra],
|
||||
[appState, deep, extra, text],
|
||||
);
|
||||
useLayoutEffect(() => {
|
||||
if (isModernEmojiEnabled() && !!text.trim() && stringHasAnyEmoji(text)) {
|
||||
|
||||
@@ -33,7 +33,7 @@ const messages = defineMessages({
|
||||
reblog: { id: 'status.reblog', defaultMessage: 'Boost' },
|
||||
reblog_private: {
|
||||
id: 'status.reblog_private',
|
||||
defaultMessage: 'Boost with original visibility',
|
||||
defaultMessage: 'Share again with your followers',
|
||||
},
|
||||
cancel_reblog_private: {
|
||||
id: 'status.cancel_reblog_private',
|
||||
|
||||
@@ -92,8 +92,7 @@ const messages = defineMessages({
|
||||
const mapStateToProps = state => ({
|
||||
layout: state.getIn(['meta', 'layout']),
|
||||
isComposing: state.getIn(['compose', 'is_composing']),
|
||||
hasComposingText: state.getIn(['compose', 'text']).trim().length !== 0,
|
||||
hasMediaAttachments: state.getIn(['compose', 'media_attachments']).size > 0,
|
||||
hasComposingContents: state.getIn(['compose', 'text']).trim().length !== 0 || state.getIn(['compose', 'media_attachments']).size > 0 || state.getIn(['compose', 'poll']) !== null || state.getIn(['compose', 'quoted_status_id']) !== null,
|
||||
canUploadMore: !state.getIn(['compose', 'media_attachments']).some(x => ['audio', 'video'].includes(x.get('type'))) && state.getIn(['compose', 'media_attachments']).size < state.getIn(['server', 'server', 'configuration', 'statuses', 'max_media_attachments']),
|
||||
firstLaunch: state.getIn(['settings', 'introductionVersion'], 0) < INTRODUCTION_VERSION,
|
||||
newAccount: !state.getIn(['accounts', me, 'note']) && !state.getIn(['accounts', me, 'bot']) && state.getIn(['accounts', me, 'following_count'], 0) === 0 && state.getIn(['accounts', me, 'statuses_count'], 0) === 0,
|
||||
@@ -241,8 +240,7 @@ class UI extends PureComponent {
|
||||
dispatch: PropTypes.func.isRequired,
|
||||
children: PropTypes.node,
|
||||
isComposing: PropTypes.bool,
|
||||
hasComposingText: PropTypes.bool,
|
||||
hasMediaAttachments: PropTypes.bool,
|
||||
hasComposingContents: PropTypes.bool,
|
||||
canUploadMore: PropTypes.bool,
|
||||
intl: PropTypes.object.isRequired,
|
||||
layout: PropTypes.string.isRequired,
|
||||
@@ -257,11 +255,11 @@ class UI extends PureComponent {
|
||||
};
|
||||
|
||||
handleBeforeUnload = e => {
|
||||
const { intl, dispatch, isComposing, hasComposingText, hasMediaAttachments } = this.props;
|
||||
const { intl, dispatch, isComposing, hasComposingContents } = this.props;
|
||||
|
||||
dispatch(synchronouslySubmitMarkers());
|
||||
|
||||
if (isComposing && (hasComposingText || hasMediaAttachments)) {
|
||||
if (isComposing && hasComposingContents) {
|
||||
e.preventDefault();
|
||||
// Setting returnValue to any string causes confirmation dialog.
|
||||
// Many browsers no longer display this text to users,
|
||||
|
||||
Reference in new issue
Block a user