diff options
author | Reverite <github@reverite.sh> | 2019-07-23 20:54:15 -0700 |
---|---|---|
committer | Reverite <github@reverite.sh> | 2019-07-23 20:54:15 -0700 |
commit | fee3abd1dce8f437e3514cb03816ae50862b3c4c (patch) | |
tree | 72e19e9e748edce7024737cfb70f9088346058bd /app/javascript/flavours | |
parent | 9148c3e8479e59df9f9a4889ef58a959f60f6606 (diff) | |
parent | 08325db62bcc4d5d530513c615bc1c733f166239 (diff) |
Merge branch 'glitch' into production
Diffstat (limited to 'app/javascript/flavours')
6 files changed, 186 insertions, 65 deletions
diff --git a/app/javascript/flavours/glitch/actions/importer/normalizer.js b/app/javascript/flavours/glitch/actions/importer/normalizer.js index c19ca8265..52d85c059 100644 --- a/app/javascript/flavours/glitch/actions/importer/normalizer.js +++ b/app/javascript/flavours/glitch/actions/importer/normalizer.js @@ -22,7 +22,7 @@ export function normalizeAccount(account) { if (account.fields) { account.fields = account.fields.map(pair => ({ ...pair, - name_emojified: emojify(escapeTextContentForBrowser(pair.name)), + name_emojified: emojify(escapeTextContentForBrowser(pair.name), emojiMap), value_emojified: emojify(pair.value, emojiMap), value_plain: unescapeHTML(pair.value), })); diff --git a/app/javascript/flavours/glitch/components/display_name.js b/app/javascript/flavours/glitch/components/display_name.js index 7f6ef5a5d..9d8c4a775 100644 --- a/app/javascript/flavours/glitch/components/display_name.js +++ b/app/javascript/flavours/glitch/components/display_name.js @@ -1,73 +1,111 @@ -// Package imports. -import classNames from 'classnames'; -import PropTypes from 'prop-types'; import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { autoPlayGif } from 'flavours/glitch/util/initial_state'; + +export default class DisplayName extends React.PureComponent { + + static propTypes = { + account: ImmutablePropTypes.map, + className: PropTypes.string, + inline: PropTypes.bool, + localDomain: PropTypes.string, + others: ImmutablePropTypes.list, + handleClick: PropTypes.func, + }; + + _updateEmojis () { + const node = this.node; + + if (!node || autoPlayGif) { + return; + } + + const emojis = node.querySelectorAll('.custom-emoji'); + + for (var i = 0; i < emojis.length; i++) { + let emoji = emojis[i]; + if (emoji.classList.contains('status-emoji')) { + continue; + } + emoji.classList.add('status-emoji'); + + emoji.addEventListener('mouseenter', this.handleEmojiMouseEnter, false); + emoji.addEventListener('mouseleave', this.handleEmojiMouseLeave, false); + } + } -// The component. -export default function DisplayName ({ - account, - className, - inline, - localDomain, - others, - onAccountClick, -}) { - const computedClass = classNames('display-name', { inline }, className); + componentDidMount () { + this._updateEmojis(); + } - if (!account) return null; + componentDidUpdate () { + this._updateEmojis(); + } - let displayName, suffix; + handleEmojiMouseEnter = ({ target }) => { + target.src = target.getAttribute('data-original'); + } - let acct = account.get('acct'); + handleEmojiMouseLeave = ({ target }) => { + target.src = target.getAttribute('data-static'); + } - if (acct.indexOf('@') === -1 && localDomain) { - acct = `${acct}@${localDomain}`; + setRef = (c) => { + this.node = c; } - if (others && others.size > 0) { - displayName = others.take(2).map(a => ( - <a - href={a.get('url')} - target='_blank' - onClick={(e) => onAccountClick(a.get('id'), e)} - title={`@${a.get('acct')}`} - > - <bdi key={a.get('id')}> - <strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /> - </bdi> - </a> - )).reduce((prev, cur) => [prev, ', ', cur]); - - if (others.size - 2 > 0) { - displayName.push(` +${others.size - 2}`); + render() { + const { account, className, inline, localDomain, others, onAccountClick } = this.props; + + const computedClass = classNames('display-name', { inline }, className); + + if (!account) return null; + + let displayName, suffix; + + let acct = account.get('acct'); + + if (acct.indexOf('@') === -1 && localDomain) { + acct = `${acct}@${localDomain}`; } - suffix = ( - <a href={account.get('url')} target='_blank' onClick={(e) => onAccountClick(account.get('id'), e)}> - <span className='display-name__account'>@{acct}</span> - </a> + if (others && others.size > 0) { + displayName = others.take(2).map(a => ( + <a + href={a.get('url')} + target='_blank' + onClick={(e) => onAccountClick(a.get('id'), e)} + title={`@${a.get('acct')}`} + > + <bdi key={a.get('id')}> + <strong className='display-name__html' dangerouslySetInnerHTML={{ __html: a.get('display_name_html') }} /> + </bdi> + </a> + )).reduce((prev, cur) => [prev, ', ', cur]); + + if (others.size - 2 > 0) { + displayName.push(` +${others.size - 2}`); + } + + suffix = ( + <a href={account.get('url')} target='_blank' onClick={(e) => onAccountClick(account.get('id'), e)}> + <span className='display-name__account'>@{acct}</span> + </a> + ); + } else { + displayName = <bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} /></bdi>; + suffix = <span className='display-name__account'>@{acct}</span>; + } + + return ( + <span className={computedClass} ref={this.setRef}> + {displayName} + {inline ? ' ' : null} + {suffix} + </span> ); - } else { - displayName = <bdi><strong className='display-name__html' dangerouslySetInnerHTML={{ __html: account.get('display_name_html') }} /></bdi>; - suffix = <span className='display-name__account'>@{acct}</span>; } - return ( - <span className={computedClass}> - {displayName} - {inline ? ' ' : null} - {suffix} - </span> - ); } - -// Props. -DisplayName.propTypes = { - account: ImmutablePropTypes.map, - className: PropTypes.string, - inline: PropTypes.bool, - localDomain: PropTypes.string, - others: ImmutablePropTypes.list, - handleClick: PropTypes.func, -}; diff --git a/app/javascript/flavours/glitch/components/status_content.js b/app/javascript/flavours/glitch/components/status_content.js index 07a0d1d5d..650b834de 100644 --- a/app/javascript/flavours/glitch/components/status_content.js +++ b/app/javascript/flavours/glitch/components/status_content.js @@ -5,6 +5,7 @@ import { isRtl } from 'flavours/glitch/util/rtl'; import { FormattedMessage } from 'react-intl'; import Permalink from './permalink'; import classnames from 'classnames'; +import { autoPlayGif } from 'flavours/glitch/util/initial_state'; export default class StatusContent extends React.PureComponent { @@ -57,12 +58,35 @@ export default class StatusContent extends React.PureComponent { } } + _updateStatusEmojis () { + const node = this.node; + + if (!node || autoPlayGif) { + return; + } + + const emojis = node.querySelectorAll('.custom-emoji'); + + for (var i = 0; i < emojis.length; i++) { + let emoji = emojis[i]; + if (emoji.classList.contains('status-emoji')) { + continue; + } + emoji.classList.add('status-emoji'); + + emoji.addEventListener('mouseenter', this.handleEmojiMouseEnter, false); + emoji.addEventListener('mouseleave', this.handleEmojiMouseLeave, false); + } + } + componentDidMount () { this._updateStatusLinks(); + this._updateStatusEmojis(); } componentDidUpdate () { this._updateStatusLinks(); + this._updateStatusEmojis(); if (this.props.onUpdate) this.props.onUpdate(); } @@ -86,6 +110,14 @@ export default class StatusContent extends React.PureComponent { } } + handleEmojiMouseEnter = ({ target }) => { + target.src = target.getAttribute('data-original'); + } + + handleEmojiMouseLeave = ({ target }) => { + target.src = target.getAttribute('data-static'); + } + handleMouseDown = (e) => { this.startXY = [e.clientX, e.clientY]; } @@ -194,7 +226,7 @@ export default class StatusContent extends React.PureComponent { } return ( - <div className={classNames} tabIndex='0' onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp}> + <div className={classNames} tabIndex='0' onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp} ref={this.setRef}> <p style={{ marginBottom: hidden && status.get('mentions').isEmpty() ? '0px' : null }} > @@ -209,7 +241,6 @@ export default class StatusContent extends React.PureComponent { <div className={`status__content__spoiler ${!hidden ? 'status__content__spoiler--visible' : ''}`}> <div - ref={this.setRef} style={directionStyle} tabIndex={!hidden ? 0 : null} dangerouslySetInnerHTML={content} @@ -229,9 +260,9 @@ export default class StatusContent extends React.PureComponent { onMouseDown={this.handleMouseDown} onMouseUp={this.handleMouseUp} tabIndex='0' + ref={this.setRef} > <div - ref={this.setRef} dangerouslySetInnerHTML={content} lang={status.get('language')} className='status__content__text' @@ -246,8 +277,9 @@ export default class StatusContent extends React.PureComponent { className='status__content' style={directionStyle} tabIndex='0' + ref={this.setRef} > - <div ref={this.setRef} className='status__content__text' dangerouslySetInnerHTML={content} lang={status.get('language')} tabIndex='0' /> + <div className='status__content__text' dangerouslySetInnerHTML={content} lang={status.get('language')} tabIndex='0' /> {media} </div> ); diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index 43c4f0d32..e9437c0a9 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -71,6 +71,47 @@ class Header extends ImmutablePureComponent { window.open('/settings/profile', '_blank'); } + _updateEmojis () { + const node = this.node; + + if (!node || autoPlayGif) { + return; + } + + const emojis = node.querySelectorAll('.custom-emoji'); + + for (var i = 0; i < emojis.length; i++) { + let emoji = emojis[i]; + if (emoji.classList.contains('status-emoji')) { + continue; + } + emoji.classList.add('status-emoji'); + + emoji.addEventListener('mouseenter', this.handleEmojiMouseEnter, false); + emoji.addEventListener('mouseleave', this.handleEmojiMouseLeave, false); + } + } + + componentDidMount () { + this._updateEmojis(); + } + + componentDidUpdate () { + this._updateEmojis(); + } + + handleEmojiMouseEnter = ({ target }) => { + target.src = target.getAttribute('data-original'); + } + + handleEmojiMouseLeave = ({ target }) => { + target.src = target.getAttribute('data-static'); + } + + setRef = (c) => { + this.node = c; + } + render () { const { account, intl, domain, identity_proofs } = this.props; @@ -193,7 +234,7 @@ class Header extends ImmutablePureComponent { const acct = account.get('acct').indexOf('@') === -1 && domain ? `${account.get('acct')}@${domain}` : account.get('acct'); return ( - <div className={classNames('account__header', { inactive: !!account.get('moved') })}> + <div className={classNames('account__header', { inactive: !!account.get('moved') })} ref={this.setRef}> <div className='account__header__image'> <div className='account__header__info'> {info} diff --git a/app/javascript/flavours/glitch/packs/public.js b/app/javascript/flavours/glitch/packs/public.js index da0b4c8e0..9f88b0e04 100644 --- a/app/javascript/flavours/glitch/packs/public.js +++ b/app/javascript/flavours/glitch/packs/public.js @@ -4,6 +4,7 @@ import ready from 'flavours/glitch/util/ready'; function main() { const IntlMessageFormat = require('intl-messageformat').default; const { timeAgoString } = require('flavours/glitch/components/relative_timestamp'); + const { delegate } = require('rails-ujs'); const emojify = require('flavours/glitch/util/emoji').default; const { getLocale } = require('locales'); const { messages } = getLocale(); @@ -23,6 +24,12 @@ function main() { } }; + const getEmojiAnimationHandler = (swapTo) => { + return ({ target }) => { + target.src = target.getAttribute(swapTo); + }; + }; + ready(() => { const locale = document.documentElement.lang; @@ -94,6 +101,9 @@ function main() { document.head.appendChild(scrollbarWidthStyle); scrollbarWidthStyle.sheet.insertRule(`body.with-modals--active { margin-right: ${scrollbarWidth}px; }`, 0); } + + delegate(document, '.custom-emoji', 'mouseover', getEmojiAnimationHandler('data-original')); + delegate(document, '.custom-emoji', 'mouseout', getEmojiAnimationHandler('data-static')); }); } diff --git a/app/javascript/flavours/glitch/util/emoji/index.js b/app/javascript/flavours/glitch/util/emoji/index.js index e6fcaf0dc..2f40f9b08 100644 --- a/app/javascript/flavours/glitch/util/emoji/index.js +++ b/app/javascript/flavours/glitch/util/emoji/index.js @@ -29,7 +29,7 @@ const emojify = (str, customEmojis = {}) => { // if you want additional emoji handler, add statements below which set replacement and return true. if (shortname in customEmojis) { const filename = autoPlayGif ? customEmojis[shortname].url : customEmojis[shortname].static_url; - replacement = `<img draggable="false" class="emojione" alt="${shortname}" title="${shortname}" src="${filename}" />`; + replacement = `<img draggable="false" class="emojione custom-emoji" alt="${shortname}" title="${shortname}" src="${filename}" data-original="${customEmojis[shortname].url}" data-static="${customEmojis[shortname].static_url}" />`; return true; } return false; |