From bc4fa6b198557a7f3989eb0865e2c77ac7451d29 Mon Sep 17 00:00:00 2001 From: kibigo! Date: Sun, 3 Dec 2017 23:26:40 -0800 Subject: Rename themes -> flavours ? ? --- .../glitch/features/ui/components/actions_modal.js | 74 --- .../glitch/features/ui/components/boost_modal.js | 84 --- .../themes/glitch/features/ui/components/bundle.js | 102 ---- .../features/ui/components/bundle_column_error.js | 44 -- .../features/ui/components/bundle_modal_error.js | 53 -- .../themes/glitch/features/ui/components/column.js | 74 --- .../glitch/features/ui/components/column_header.js | 35 -- .../glitch/features/ui/components/column_link.js | 39 -- .../features/ui/components/column_loading.js | 30 - .../features/ui/components/column_subheading.js | 16 - .../glitch/features/ui/components/columns_area.js | 174 ------ .../features/ui/components/confirmation_modal.js | 53 -- .../glitch/features/ui/components/doodle_modal.js | 614 --------------------- .../features/ui/components/drawer_loading.js | 11 - .../glitch/features/ui/components/embed_modal.js | 84 --- .../glitch/features/ui/components/image_loader.js | 152 ----- .../glitch/features/ui/components/media_modal.js | 126 ----- .../glitch/features/ui/components/modal_loading.js | 20 - .../glitch/features/ui/components/modal_root.js | 131 ----- .../glitch/features/ui/components/mute_modal.js | 105 ---- .../features/ui/components/onboarding_modal.js | 323 ----------- .../glitch/features/ui/components/report_modal.js | 105 ---- .../glitch/features/ui/components/tabs_bar.js | 84 --- .../glitch/features/ui/components/upload_area.js | 52 -- .../glitch/features/ui/components/video_modal.js | 33 -- .../features/ui/containers/bundle_container.js | 19 - .../ui/containers/columns_area_container.js | 8 - .../ui/containers/loading_bar_container.js | 8 - .../features/ui/containers/modal_container.js | 16 - .../ui/containers/notifications_container.js | 18 - .../ui/containers/status_list_container.js | 73 --- app/javascript/themes/glitch/features/ui/index.js | 442 --------------- 32 files changed, 3202 deletions(-) delete mode 100644 app/javascript/themes/glitch/features/ui/components/actions_modal.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/boost_modal.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/bundle.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/bundle_column_error.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/bundle_modal_error.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/column.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/column_header.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/column_link.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/column_loading.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/column_subheading.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/columns_area.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/confirmation_modal.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/doodle_modal.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/drawer_loading.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/embed_modal.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/image_loader.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/media_modal.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/modal_loading.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/modal_root.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/mute_modal.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/onboarding_modal.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/report_modal.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/tabs_bar.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/upload_area.js delete mode 100644 app/javascript/themes/glitch/features/ui/components/video_modal.js delete mode 100644 app/javascript/themes/glitch/features/ui/containers/bundle_container.js delete mode 100644 app/javascript/themes/glitch/features/ui/containers/columns_area_container.js delete mode 100644 app/javascript/themes/glitch/features/ui/containers/loading_bar_container.js delete mode 100644 app/javascript/themes/glitch/features/ui/containers/modal_container.js delete mode 100644 app/javascript/themes/glitch/features/ui/containers/notifications_container.js delete mode 100644 app/javascript/themes/glitch/features/ui/containers/status_list_container.js delete mode 100644 app/javascript/themes/glitch/features/ui/index.js (limited to 'app/javascript/themes/glitch/features/ui') diff --git a/app/javascript/themes/glitch/features/ui/components/actions_modal.js b/app/javascript/themes/glitch/features/ui/components/actions_modal.js deleted file mode 100644 index 7a2b78b63..000000000 --- a/app/javascript/themes/glitch/features/ui/components/actions_modal.js +++ /dev/null @@ -1,74 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import StatusContent from 'themes/glitch/components/status_content'; -import Avatar from 'themes/glitch/components/avatar'; -import RelativeTimestamp from 'themes/glitch/components/relative_timestamp'; -import DisplayName from 'themes/glitch/components/display_name'; -import IconButton from 'themes/glitch/components/icon_button'; -import classNames from 'classnames'; - -export default class ActionsModal extends ImmutablePureComponent { - - static propTypes = { - status: ImmutablePropTypes.map, - actions: PropTypes.array, - onClick: PropTypes.func, - }; - - renderAction = (action, i) => { - if (action === null) { - return
  • ; - } - - const { icon = null, text, meta = null, active = false, href = '#' } = action; - - return ( -
  • - - {icon && } -
    -
    {text}
    -
    {meta}
    -
    -
    -
  • - ); - } - - render () { - const status = this.props.status && ( -
    -
    -
    - - - -
    - - -
    - -
    - - -
    -
    - - -
    - ); - - return ( -
    - {status} - - -
    - ); - } - -} diff --git a/app/javascript/themes/glitch/features/ui/components/boost_modal.js b/app/javascript/themes/glitch/features/ui/components/boost_modal.js deleted file mode 100644 index 49781db10..000000000 --- a/app/javascript/themes/glitch/features/ui/components/boost_modal.js +++ /dev/null @@ -1,84 +0,0 @@ -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import PropTypes from 'prop-types'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; -import Button from 'themes/glitch/components/button'; -import StatusContent from 'themes/glitch/components/status_content'; -import Avatar from 'themes/glitch/components/avatar'; -import RelativeTimestamp from 'themes/glitch/components/relative_timestamp'; -import DisplayName from 'themes/glitch/components/display_name'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -const messages = defineMessages({ - reblog: { id: 'status.reblog', defaultMessage: 'Boost' }, -}); - -@injectIntl -export default class BoostModal extends ImmutablePureComponent { - - static contextTypes = { - router: PropTypes.object, - }; - - static propTypes = { - status: ImmutablePropTypes.map.isRequired, - onReblog: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - }; - - componentDidMount() { - this.button.focus(); - } - - handleReblog = () => { - this.props.onReblog(this.props.status); - this.props.onClose(); - } - - handleAccountClick = (e) => { - if (e.button === 0) { - e.preventDefault(); - this.props.onClose(); - this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`); - } - } - - setRef = (c) => { - this.button = c; - } - - render () { - const { status, intl } = this.props; - - return ( -
    -
    -
    -
    -
    - -
    - - -
    - -
    - - -
    -
    - - -
    -
    - -
    -
    Shift + }} />
    -
    -
    - ); - } - -} diff --git a/app/javascript/themes/glitch/features/ui/components/bundle.js b/app/javascript/themes/glitch/features/ui/components/bundle.js deleted file mode 100644 index fc88e0c70..000000000 --- a/app/javascript/themes/glitch/features/ui/components/bundle.js +++ /dev/null @@ -1,102 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -const emptyComponent = () => null; -const noop = () => { }; - -class Bundle extends React.Component { - - static propTypes = { - fetchComponent: PropTypes.func.isRequired, - loading: PropTypes.func, - error: PropTypes.func, - children: PropTypes.func.isRequired, - renderDelay: PropTypes.number, - onFetch: PropTypes.func, - onFetchSuccess: PropTypes.func, - onFetchFail: PropTypes.func, - } - - static defaultProps = { - loading: emptyComponent, - error: emptyComponent, - renderDelay: 0, - onFetch: noop, - onFetchSuccess: noop, - onFetchFail: noop, - } - - static cache = {} - - state = { - mod: undefined, - forceRender: false, - } - - componentWillMount() { - this.load(this.props); - } - - componentWillReceiveProps(nextProps) { - if (nextProps.fetchComponent !== this.props.fetchComponent) { - this.load(nextProps); - } - } - - componentWillUnmount () { - if (this.timeout) { - clearTimeout(this.timeout); - } - } - - load = (props) => { - const { fetchComponent, onFetch, onFetchSuccess, onFetchFail, renderDelay } = props || this.props; - - onFetch(); - - if (Bundle.cache[fetchComponent.name]) { - const mod = Bundle.cache[fetchComponent.name]; - - this.setState({ mod: mod.default }); - onFetchSuccess(); - return Promise.resolve(); - } - - this.setState({ mod: undefined }); - - if (renderDelay !== 0) { - this.timestamp = new Date(); - this.timeout = setTimeout(() => this.setState({ forceRender: true }), renderDelay); - } - - return fetchComponent() - .then((mod) => { - Bundle.cache[fetchComponent.name] = mod; - this.setState({ mod: mod.default }); - onFetchSuccess(); - }) - .catch((error) => { - this.setState({ mod: null }); - onFetchFail(error); - }); - } - - render() { - const { loading: Loading, error: Error, children, renderDelay } = this.props; - const { mod, forceRender } = this.state; - const elapsed = this.timestamp ? (new Date() - this.timestamp) : renderDelay; - - if (mod === undefined) { - return (elapsed >= renderDelay || forceRender) ? : null; - } - - if (mod === null) { - return ; - } - - return children(mod); - } - -} - -export default Bundle; diff --git a/app/javascript/themes/glitch/features/ui/components/bundle_column_error.js b/app/javascript/themes/glitch/features/ui/components/bundle_column_error.js deleted file mode 100644 index daedc6299..000000000 --- a/app/javascript/themes/glitch/features/ui/components/bundle_column_error.js +++ /dev/null @@ -1,44 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { defineMessages, injectIntl } from 'react-intl'; - -import Column from './column'; -import ColumnHeader from './column_header'; -import ColumnBackButtonSlim from 'themes/glitch/components/column_back_button_slim'; -import IconButton from 'themes/glitch/components/icon_button'; - -const messages = defineMessages({ - title: { id: 'bundle_column_error.title', defaultMessage: 'Network error' }, - body: { id: 'bundle_column_error.body', defaultMessage: 'Something went wrong while loading this component.' }, - retry: { id: 'bundle_column_error.retry', defaultMessage: 'Try again' }, -}); - -class BundleColumnError extends React.Component { - - static propTypes = { - onRetry: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - } - - handleRetry = () => { - this.props.onRetry(); - } - - render () { - const { intl: { formatMessage } } = this.props; - - return ( - - - -
    - - {formatMessage(messages.body)} -
    -
    - ); - } - -} - -export default injectIntl(BundleColumnError); diff --git a/app/javascript/themes/glitch/features/ui/components/bundle_modal_error.js b/app/javascript/themes/glitch/features/ui/components/bundle_modal_error.js deleted file mode 100644 index 8cca32ae9..000000000 --- a/app/javascript/themes/glitch/features/ui/components/bundle_modal_error.js +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { defineMessages, injectIntl } from 'react-intl'; - -import IconButton from 'themes/glitch/components/icon_button'; - -const messages = defineMessages({ - error: { id: 'bundle_modal_error.message', defaultMessage: 'Something went wrong while loading this component.' }, - retry: { id: 'bundle_modal_error.retry', defaultMessage: 'Try again' }, - close: { id: 'bundle_modal_error.close', defaultMessage: 'Close' }, -}); - -class BundleModalError extends React.Component { - - static propTypes = { - onRetry: PropTypes.func.isRequired, - onClose: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - } - - handleRetry = () => { - this.props.onRetry(); - } - - render () { - const { onClose, intl: { formatMessage } } = this.props; - - // Keep the markup in sync with - // (make sure they have the same dimensions) - return ( -
    -
    - - {formatMessage(messages.error)} -
    - -
    -
    - -
    -
    -
    - ); - } - -} - -export default injectIntl(BundleModalError); diff --git a/app/javascript/themes/glitch/features/ui/components/column.js b/app/javascript/themes/glitch/features/ui/components/column.js deleted file mode 100644 index 73a5bc15e..000000000 --- a/app/javascript/themes/glitch/features/ui/components/column.js +++ /dev/null @@ -1,74 +0,0 @@ -import React from 'react'; -import ColumnHeader from './column_header'; -import PropTypes from 'prop-types'; -import { debounce } from 'lodash'; -import { scrollTop } from 'themes/glitch/util/scroll'; -import { isMobile } from 'themes/glitch/util/is_mobile'; - -export default class Column extends React.PureComponent { - - static propTypes = { - heading: PropTypes.string, - icon: PropTypes.string, - children: PropTypes.node, - active: PropTypes.bool, - hideHeadingOnMobile: PropTypes.bool, - name: PropTypes.string, - }; - - handleHeaderClick = () => { - const scrollable = this.node.querySelector('.scrollable'); - - if (!scrollable) { - return; - } - - this._interruptScrollAnimation = scrollTop(scrollable); - } - - scrollTop () { - const scrollable = this.node.querySelector('.scrollable'); - - if (!scrollable) { - return; - } - - this._interruptScrollAnimation = scrollTop(scrollable); - } - - - handleScroll = debounce(() => { - if (typeof this._interruptScrollAnimation !== 'undefined') { - this._interruptScrollAnimation(); - } - }, 200) - - setRef = (c) => { - this.node = c; - } - - render () { - const { heading, icon, children, active, hideHeadingOnMobile, name } = this.props; - - const showHeading = heading && (!hideHeadingOnMobile || (hideHeadingOnMobile && !isMobile(window.innerWidth))); - - const columnHeaderId = showHeading && heading.replace(/ /g, '-'); - const header = showHeading && ( - - ); - return ( -
    - {header} - {children} -
    - ); - } - -} diff --git a/app/javascript/themes/glitch/features/ui/components/column_header.js b/app/javascript/themes/glitch/features/ui/components/column_header.js deleted file mode 100644 index af195ea9c..000000000 --- a/app/javascript/themes/glitch/features/ui/components/column_header.js +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -export default class ColumnHeader extends React.PureComponent { - - static propTypes = { - icon: PropTypes.string, - type: PropTypes.string, - active: PropTypes.bool, - onClick: PropTypes.func, - columnHeaderId: PropTypes.string, - }; - - handleClick = () => { - this.props.onClick(); - } - - render () { - const { type, active, columnHeaderId } = this.props; - - let icon = ''; - - if (this.props.icon) { - icon = ; - } - - return ( -
    - {icon} - {type} -
    - ); - } - -} diff --git a/app/javascript/themes/glitch/features/ui/components/column_link.js b/app/javascript/themes/glitch/features/ui/components/column_link.js deleted file mode 100644 index b845d1895..000000000 --- a/app/javascript/themes/glitch/features/ui/components/column_link.js +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { Link } from 'react-router-dom'; - -const ColumnLink = ({ icon, text, to, onClick, href, method }) => { - if (href) { - return ( - - - {text} - - ); - } else if (to) { - return ( - - - {text} - - ); - } else { - return ( - - - {text} - - ); - } -}; - -ColumnLink.propTypes = { - icon: PropTypes.string.isRequired, - text: PropTypes.string.isRequired, - to: PropTypes.string, - onClick: PropTypes.func, - href: PropTypes.string, - method: PropTypes.string, -}; - -export default ColumnLink; diff --git a/app/javascript/themes/glitch/features/ui/components/column_loading.js b/app/javascript/themes/glitch/features/ui/components/column_loading.js deleted file mode 100644 index 75f26218a..000000000 --- a/app/javascript/themes/glitch/features/ui/components/column_loading.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -import Column from 'themes/glitch/components/column'; -import ColumnHeader from 'themes/glitch/components/column_header'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -export default class ColumnLoading extends ImmutablePureComponent { - - static propTypes = { - title: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), - icon: PropTypes.string, - }; - - static defaultProps = { - title: '', - icon: '', - }; - - render() { - let { title, icon } = this.props; - return ( - - -
    - - ); - } - -} diff --git a/app/javascript/themes/glitch/features/ui/components/column_subheading.js b/app/javascript/themes/glitch/features/ui/components/column_subheading.js deleted file mode 100644 index 8160c4aa3..000000000 --- a/app/javascript/themes/glitch/features/ui/components/column_subheading.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -const ColumnSubheading = ({ text }) => { - return ( -
    - {text} -
    - ); -}; - -ColumnSubheading.propTypes = { - text: PropTypes.string.isRequired, -}; - -export default ColumnSubheading; diff --git a/app/javascript/themes/glitch/features/ui/components/columns_area.js b/app/javascript/themes/glitch/features/ui/components/columns_area.js deleted file mode 100644 index 452950363..000000000 --- a/app/javascript/themes/glitch/features/ui/components/columns_area.js +++ /dev/null @@ -1,174 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { injectIntl } from 'react-intl'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; - -import ReactSwipeableViews from 'react-swipeable-views'; -import { links, getIndex, getLink } from './tabs_bar'; - -import BundleContainer from '../containers/bundle_container'; -import ColumnLoading from './column_loading'; -import DrawerLoading from './drawer_loading'; -import BundleColumnError from './bundle_column_error'; -import { Compose, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline, DirectTimeline, FavouritedStatuses } from 'themes/glitch/util/async-components'; - -import detectPassiveEvents from 'detect-passive-events'; -import { scrollRight } from 'themes/glitch/util/scroll'; - -const componentMap = { - 'COMPOSE': Compose, - 'HOME': HomeTimeline, - 'NOTIFICATIONS': Notifications, - 'PUBLIC': PublicTimeline, - 'COMMUNITY': CommunityTimeline, - 'HASHTAG': HashtagTimeline, - 'DIRECT': DirectTimeline, - 'FAVOURITES': FavouritedStatuses, -}; - -@component => injectIntl(component, { withRef: true }) -export default class ColumnsArea extends ImmutablePureComponent { - - static contextTypes = { - router: PropTypes.object.isRequired, - }; - - static propTypes = { - intl: PropTypes.object.isRequired, - columns: ImmutablePropTypes.list.isRequired, - singleColumn: PropTypes.bool, - children: PropTypes.node, - }; - - state = { - shouldAnimate: false, - } - - componentWillReceiveProps() { - this.setState({ shouldAnimate: false }); - } - - componentDidMount() { - if (!this.props.singleColumn) { - this.node.addEventListener('wheel', this.handleWheel, detectPassiveEvents.hasSupport ? { passive: true } : false); - } - this.lastIndex = getIndex(this.context.router.history.location.pathname); - this.setState({ shouldAnimate: true }); - } - - componentWillUpdate(nextProps) { - if (this.props.singleColumn !== nextProps.singleColumn && nextProps.singleColumn) { - this.node.removeEventListener('wheel', this.handleWheel); - } - } - - componentDidUpdate(prevProps) { - if (this.props.singleColumn !== prevProps.singleColumn && !this.props.singleColumn) { - this.node.addEventListener('wheel', this.handleWheel, detectPassiveEvents.hasSupport ? { passive: true } : false); - } - this.lastIndex = getIndex(this.context.router.history.location.pathname); - this.setState({ shouldAnimate: true }); - } - - componentWillUnmount () { - if (!this.props.singleColumn) { - this.node.removeEventListener('wheel', this.handleWheel); - } - } - - handleChildrenContentChange() { - if (!this.props.singleColumn) { - this._interruptScrollAnimation = scrollRight(this.node, this.node.scrollWidth - window.innerWidth); - } - } - - handleSwipe = (index) => { - this.pendingIndex = index; - - const nextLinkTranslationId = links[index].props['data-preview-title-id']; - const currentLinkSelector = '.tabs-bar__link.active'; - const nextLinkSelector = `.tabs-bar__link[data-preview-title-id="${nextLinkTranslationId}"]`; - - // HACK: Remove the active class from the current link and set it to the next one - // React-router does this for us, but too late, feeling laggy. - document.querySelector(currentLinkSelector).classList.remove('active'); - document.querySelector(nextLinkSelector).classList.add('active'); - } - - handleAnimationEnd = () => { - if (typeof this.pendingIndex === 'number') { - this.context.router.history.push(getLink(this.pendingIndex)); - this.pendingIndex = null; - } - } - - handleWheel = () => { - if (typeof this._interruptScrollAnimation !== 'function') { - return; - } - - this._interruptScrollAnimation(); - } - - setRef = (node) => { - this.node = node; - } - - renderView = (link, index) => { - const columnIndex = getIndex(this.context.router.history.location.pathname); - const title = this.props.intl.formatMessage({ id: link.props['data-preview-title-id'] }); - const icon = link.props['data-preview-icon']; - - const view = (index === columnIndex) ? - React.cloneElement(this.props.children) : - ; - - return ( -
    - {view} -
    - ); - } - - renderLoading = columnId => () => { - return columnId === 'COMPOSE' ? : ; - } - - renderError = (props) => { - return ; - } - - render () { - const { columns, children, singleColumn } = this.props; - const { shouldAnimate } = this.state; - - const columnIndex = getIndex(this.context.router.history.location.pathname); - this.pendingIndex = null; - - if (singleColumn) { - return columnIndex !== -1 ? ( - - {links.map(this.renderView)} - - ) :
    {children}
    ; - } - - return ( -
    - {columns.map(column => { - const params = column.get('params', null) === null ? null : column.get('params').toJS(); - - return ( - - {SpecificComponent => } - - ); - })} - - {React.Children.map(children, child => React.cloneElement(child, { multiColumn: true }))} -
    - ); - } - -} diff --git a/app/javascript/themes/glitch/features/ui/components/confirmation_modal.js b/app/javascript/themes/glitch/features/ui/components/confirmation_modal.js deleted file mode 100644 index 3d568aec3..000000000 --- a/app/javascript/themes/glitch/features/ui/components/confirmation_modal.js +++ /dev/null @@ -1,53 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { injectIntl, FormattedMessage } from 'react-intl'; -import Button from 'themes/glitch/components/button'; - -@injectIntl -export default class ConfirmationModal extends React.PureComponent { - - static propTypes = { - message: PropTypes.node.isRequired, - confirm: PropTypes.string.isRequired, - onClose: PropTypes.func.isRequired, - onConfirm: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - }; - - componentDidMount() { - this.button.focus(); - } - - handleClick = () => { - this.props.onClose(); - this.props.onConfirm(); - } - - handleCancel = () => { - this.props.onClose(); - } - - setRef = (c) => { - this.button = c; - } - - render () { - const { message, confirm } = this.props; - - return ( -
    -
    - {message} -
    - -
    - -
    -
    - ); - } - -} diff --git a/app/javascript/themes/glitch/features/ui/components/doodle_modal.js b/app/javascript/themes/glitch/features/ui/components/doodle_modal.js deleted file mode 100644 index 819656dbf..000000000 --- a/app/javascript/themes/glitch/features/ui/components/doodle_modal.js +++ /dev/null @@ -1,614 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import Button from 'themes/glitch/components/button'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import Atrament from 'atrament'; // the doodling library -import { connect } from 'react-redux'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import { doodleSet, uploadCompose } from 'themes/glitch/actions/compose'; -import IconButton from 'themes/glitch/components/icon_button'; -import { debounce, mapValues } from 'lodash'; -import classNames from 'classnames'; - -// palette nicked from MyPaint, CC0 -const palette = [ - ['rgb( 0, 0, 0)', 'Black'], - ['rgb( 38, 38, 38)', 'Gray 15'], - ['rgb( 77, 77, 77)', 'Grey 30'], - ['rgb(128, 128, 128)', 'Grey 50'], - ['rgb(171, 171, 171)', 'Grey 67'], - ['rgb(217, 217, 217)', 'Grey 85'], - ['rgb(255, 255, 255)', 'White'], - ['rgb(128, 0, 0)', 'Maroon'], - ['rgb(209, 0, 0)', 'English-red'], - ['rgb(255, 54, 34)', 'Tomato'], - ['rgb(252, 60, 3)', 'Orange-red'], - ['rgb(255, 140, 105)', 'Salmon'], - ['rgb(252, 232, 32)', 'Cadium-yellow'], - ['rgb(243, 253, 37)', 'Lemon yellow'], - ['rgb(121, 5, 35)', 'Dark crimson'], - ['rgb(169, 32, 62)', 'Deep carmine'], - ['rgb(255, 140, 0)', 'Orange'], - ['rgb(255, 168, 18)', 'Dark tangerine'], - ['rgb(217, 144, 88)', 'Persian orange'], - ['rgb(194, 178, 128)', 'Sand'], - ['rgb(255, 229, 180)', 'Peach'], - ['rgb(100, 54, 46)', 'Bole'], - ['rgb(108, 41, 52)', 'Dark cordovan'], - ['rgb(163, 65, 44)', 'Chestnut'], - ['rgb(228, 136, 100)', 'Dark salmon'], - ['rgb(255, 195, 143)', 'Apricot'], - ['rgb(255, 219, 188)', 'Unbleached silk'], - ['rgb(242, 227, 198)', 'Straw'], - ['rgb( 53, 19, 13)', 'Bistre'], - ['rgb( 84, 42, 14)', 'Dark chocolate'], - ['rgb(102, 51, 43)', 'Burnt sienna'], - ['rgb(184, 66, 0)', 'Sienna'], - ['rgb(216, 153, 12)', 'Yellow ochre'], - ['rgb(210, 180, 140)', 'Tan'], - ['rgb(232, 204, 144)', 'Dark wheat'], - ['rgb( 0, 49, 83)', 'Prussian blue'], - ['rgb( 48, 69, 119)', 'Dark grey blue'], - ['rgb( 0, 71, 171)', 'Cobalt blue'], - ['rgb( 31, 117, 254)', 'Blue'], - ['rgb(120, 180, 255)', 'Bright french blue'], - ['rgb(171, 200, 255)', 'Bright steel blue'], - ['rgb(208, 231, 255)', 'Ice blue'], - ['rgb( 30, 51, 58)', 'Medium jungle green'], - ['rgb( 47, 79, 79)', 'Dark slate grey'], - ['rgb( 74, 104, 93)', 'Dark grullo green'], - ['rgb( 0, 128, 128)', 'Teal'], - ['rgb( 67, 170, 176)', 'Turquoise'], - ['rgb(109, 174, 199)', 'Cerulean frost'], - ['rgb(173, 217, 186)', 'Tiffany green'], - ['rgb( 22, 34, 29)', 'Gray-asparagus'], - ['rgb( 36, 48, 45)', 'Medium dark teal'], - ['rgb( 74, 104, 93)', 'Xanadu'], - ['rgb(119, 198, 121)', 'Mint'], - ['rgb(175, 205, 182)', 'Timberwolf'], - ['rgb(185, 245, 246)', 'Celeste'], - ['rgb(193, 255, 234)', 'Aquamarine'], - ['rgb( 29, 52, 35)', 'Cal Poly Pomona'], - ['rgb( 1, 68, 33)', 'Forest green'], - ['rgb( 42, 128, 0)', 'Napier green'], - ['rgb(128, 128, 0)', 'Olive'], - ['rgb( 65, 156, 105)', 'Sea green'], - ['rgb(189, 246, 29)', 'Green-yellow'], - ['rgb(231, 244, 134)', 'Bright chartreuse'], - ['rgb(138, 23, 137)', 'Purple'], - ['rgb( 78, 39, 138)', 'Violet'], - ['rgb(193, 75, 110)', 'Dark thulian pink'], - ['rgb(222, 49, 99)', 'Cerise'], - ['rgb(255, 20, 147)', 'Deep pink'], - ['rgb(255, 102, 204)', 'Rose pink'], - ['rgb(255, 203, 219)', 'Pink'], - ['rgb(255, 255, 255)', 'White'], - ['rgb(229, 17, 1)', 'RGB Red'], - ['rgb( 0, 255, 0)', 'RGB Green'], - ['rgb( 0, 0, 255)', 'RGB Blue'], - ['rgb( 0, 255, 255)', 'CMYK Cyan'], - ['rgb(255, 0, 255)', 'CMYK Magenta'], - ['rgb(255, 255, 0)', 'CMYK Yellow'], -]; - -// re-arrange to the right order for display -let palReordered = []; -for (let row = 0; row < 7; row++) { - for (let col = 0; col < 11; col++) { - palReordered.push(palette[col * 7 + row]); - } - palReordered.push(null); // null indicates a
    -} - -// Utility for converting base64 image to binary for upload -// https://stackoverflow.com/questions/35940290/how-to-convert-base64-string-to-javascript-file-object-like-as-from-file-input-f -function dataURLtoFile(dataurl, filename) { - let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], - bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); - while(n--){ - u8arr[n] = bstr.charCodeAt(n); - } - return new File([u8arr], filename, { type: mime }); -} - -const DOODLE_SIZES = { - normal: [500, 500, 'Square 500'], - tootbanner: [702, 330, 'Tootbanner'], - s640x480: [640, 480, '640×480 - 480p'], - s800x600: [800, 600, '800×600 - SVGA'], - s720x480: [720, 405, '720x405 - 16:9'], -}; - - -const mapStateToProps = state => ({ - options: state.getIn(['compose', 'doodle']), -}); - -const mapDispatchToProps = dispatch => ({ - /** Set options in the redux store */ - setOpt: (opts) => dispatch(doodleSet(opts)), - /** Submit doodle for upload */ - submit: (file) => dispatch(uploadCompose([file])), -}); - -/** - * Doodling dialog with drawing canvas - * - * Keyboard shortcuts: - * - Delete: Clear screen, fill with background color - * - Backspace, Ctrl+Z: Undo one step - * - Ctrl held while drawing: Use background color - * - Shift held while clicking screen: Use fill tool - * - * Palette: - * - Left mouse button: pick foreground - * - Ctrl + left mouse button: pick background - * - Right mouse button: pick background - */ -@connect(mapStateToProps, mapDispatchToProps) -export default class DoodleModal extends ImmutablePureComponent { - - static propTypes = { - options: ImmutablePropTypes.map, - onClose: PropTypes.func.isRequired, - setOpt: PropTypes.func.isRequired, - submit: PropTypes.func.isRequired, - }; - - //region Option getters/setters - - /** Foreground color */ - get fg () { - return this.props.options.get('fg'); - } - set fg (value) { - this.props.setOpt({ fg: value }); - } - - /** Background color */ - get bg () { - return this.props.options.get('bg'); - } - set bg (value) { - this.props.setOpt({ bg: value }); - } - - /** Swap Fg and Bg for drawing */ - get swapped () { - return this.props.options.get('swapped'); - } - set swapped (value) { - this.props.setOpt({ swapped: value }); - } - - /** Mode - 'draw' or 'fill' */ - get mode () { - return this.props.options.get('mode'); - } - set mode (value) { - this.props.setOpt({ mode: value }); - } - - /** Base line weight */ - get weight () { - return this.props.options.get('weight'); - } - set weight (value) { - this.props.setOpt({ weight: value }); - } - - /** Drawing opacity */ - get opacity () { - return this.props.options.get('opacity'); - } - set opacity (value) { - this.props.setOpt({ opacity: value }); - } - - /** Adaptive stroke - change width with speed */ - get adaptiveStroke () { - return this.props.options.get('adaptiveStroke'); - } - set adaptiveStroke (value) { - this.props.setOpt({ adaptiveStroke: value }); - } - - /** Smoothing (for mouse drawing) */ - get smoothing () { - return this.props.options.get('smoothing'); - } - set smoothing (value) { - this.props.setOpt({ smoothing: value }); - } - - /** Size preset */ - get size () { - return this.props.options.get('size'); - } - set size (value) { - this.props.setOpt({ size: value }); - } - - //endregion - - /** Key up handler */ - handleKeyUp = (e) => { - if (e.target.nodeName === 'INPUT') return; - - if (e.key === 'Delete') { - e.preventDefault(); - this.handleClearBtn(); - return; - } - - if (e.key === 'Backspace' || (e.key === 'z' && (e.ctrlKey || e.metaKey))) { - e.preventDefault(); - this.undo(); - } - - if (e.key === 'Control' || e.key === 'Meta') { - this.controlHeld = false; - this.swapped = false; - } - - if (e.key === 'Shift') { - this.shiftHeld = false; - this.mode = 'draw'; - } - }; - - /** Key down handler */ - handleKeyDown = (e) => { - if (e.key === 'Control' || e.key === 'Meta') { - this.controlHeld = true; - this.swapped = true; - } - - if (e.key === 'Shift') { - this.shiftHeld = true; - this.mode = 'fill'; - } - }; - - /** - * Component installed in the DOM, do some initial set-up - */ - componentDidMount () { - this.controlHeld = false; - this.shiftHeld = false; - this.swapped = false; - window.addEventListener('keyup', this.handleKeyUp, false); - window.addEventListener('keydown', this.handleKeyDown, false); - }; - - /** - * Tear component down - */ - componentWillUnmount () { - window.removeEventListener('keyup', this.handleKeyUp, false); - window.removeEventListener('keydown', this.handleKeyDown, false); - if (this.sketcher) this.sketcher.destroy(); - } - - /** - * Set reference to the canvas element. - * This is called during component init - * - * @param elem - canvas element - */ - setCanvasRef = (elem) => { - this.canvas = elem; - if (elem) { - elem.addEventListener('dirty', () => { - this.saveUndo(); - this.sketcher._dirty = false; - }); - - elem.addEventListener('click', () => { - // sketcher bug - does not fire dirty on fill - if (this.mode === 'fill') { - this.saveUndo(); - } - }); - - // prevent context menu - elem.addEventListener('contextmenu', (e) => { - e.preventDefault(); - }); - - elem.addEventListener('mousedown', (e) => { - if (e.button === 2) { - this.swapped = true; - } - }); - - elem.addEventListener('mouseup', (e) => { - if (e.button === 2) { - this.swapped = this.controlHeld; - } - }); - - this.initSketcher(elem); - this.mode = 'draw'; // Reset mode - it's confusing if left at 'fill' - } - }; - - /** - * Set up the sketcher instance - * - * @param canvas - canvas element. Null if we're just resizing - */ - initSketcher (canvas = null) { - const sizepreset = DOODLE_SIZES[this.size]; - - if (this.sketcher) this.sketcher.destroy(); - this.sketcher = new Atrament(canvas || this.canvas, sizepreset[0], sizepreset[1]); - - if (canvas) { - this.ctx = this.sketcher.context; - this.updateSketcherSettings(); - } - - this.clearScreen(); - } - - /** - * Done button handler - */ - onDoneButton = () => { - const dataUrl = this.sketcher.toImage(); - const file = dataURLtoFile(dataUrl, 'doodle.png'); - this.props.submit(file); - this.props.onClose(); // close dialog - }; - - /** - * Cancel button handler - */ - onCancelButton = () => { - if (this.undos.length > 1 && !confirm('Discard doodle? All changes will be lost!')) { - return; - } - - this.props.onClose(); // close dialog - }; - - /** - * Update sketcher options based on state - */ - updateSketcherSettings () { - if (!this.sketcher) return; - - if (this.oldSize !== this.size) this.initSketcher(); - - this.sketcher.color = (this.swapped ? this.bg : this.fg); - this.sketcher.opacity = this.opacity; - this.sketcher.weight = this.weight; - this.sketcher.mode = this.mode; - this.sketcher.smoothing = this.smoothing; - this.sketcher.adaptiveStroke = this.adaptiveStroke; - - this.oldSize = this.size; - } - - /** - * Fill screen with background color - */ - clearScreen = () => { - this.ctx.fillStyle = this.bg; - this.ctx.fillRect(-1, -1, this.canvas.width+2, this.canvas.height+2); - this.undos = []; - - this.doSaveUndo(); - }; - - /** - * Undo one step - */ - undo = () => { - if (this.undos.length > 1) { - this.undos.pop(); - const buf = this.undos.pop(); - - this.sketcher.clear(); - this.ctx.putImageData(buf, 0, 0); - this.doSaveUndo(); - } - }; - - /** - * Save canvas content into the undo buffer immediately - */ - doSaveUndo = () => { - this.undos.push(this.ctx.getImageData(0, 0, this.canvas.width, this.canvas.height)); - }; - - /** - * Called on each canvas change. - * Saves canvas content to the undo buffer after some period of inactivity. - */ - saveUndo = debounce(() => { - this.doSaveUndo(); - }, 100); - - /** - * Palette left click. - * Selects Fg color (or Bg, if Control/Meta is held) - * - * @param e - event - */ - onPaletteClick = (e) => { - const c = e.target.dataset.color; - - if (this.controlHeld) { - this.bg = c; - } else { - this.fg = c; - } - - e.target.blur(); - e.preventDefault(); - }; - - /** - * Palette right click. - * Selects Bg color - * - * @param e - event - */ - onPaletteRClick = (e) => { - this.bg = e.target.dataset.color; - e.target.blur(); - e.preventDefault(); - }; - - /** - * Handle click on the Draw mode button - * - * @param e - event - */ - setModeDraw = (e) => { - this.mode = 'draw'; - e.target.blur(); - }; - - /** - * Handle click on the Fill mode button - * - * @param e - event - */ - setModeFill = (e) => { - this.mode = 'fill'; - e.target.blur(); - }; - - /** - * Handle click on Smooth checkbox - * - * @param e - event - */ - tglSmooth = (e) => { - this.smoothing = !this.smoothing; - e.target.blur(); - }; - - /** - * Handle click on Adaptive checkbox - * - * @param e - event - */ - tglAdaptive = (e) => { - this.adaptiveStroke = !this.adaptiveStroke; - e.target.blur(); - }; - - /** - * Handle change of the Weight input field - * - * @param e - event - */ - setWeight = (e) => { - this.weight = +e.target.value || 1; - }; - - /** - * Set size - clalback from the select box - * - * @param e - event - */ - changeSize = (e) => { - let newSize = e.target.value; - if (newSize === this.oldSize) return; - - if (this.undos.length > 1 && !confirm('Change size? This will erase your drawing!')) { - return; - } - - this.size = newSize; - }; - - handleClearBtn = () => { - if (this.undos.length > 1 && !confirm('Clear screen? This will erase your drawing!')) { - return; - } - - this.clearScreen(); - }; - - /** - * Render the component - */ - render () { - this.updateSketcherSettings(); - - return ( -
    -
    - -
    - -
    -
    -
    -
    -
    -
    - - - - -
    -
    - - - - -
    -
    - - - - -
    -
    - -
    -
    -
    - - - - -
    -
    - { - palReordered.map((c, i) => - c === null ? -
    : -
    -
    -
    - ); - } - -} diff --git a/app/javascript/themes/glitch/features/ui/components/drawer_loading.js b/app/javascript/themes/glitch/features/ui/components/drawer_loading.js deleted file mode 100644 index 08b0d2347..000000000 --- a/app/javascript/themes/glitch/features/ui/components/drawer_loading.js +++ /dev/null @@ -1,11 +0,0 @@ -import React from 'react'; - -const DrawerLoading = () => ( -
    -
    -
    -
    -
    -); - -export default DrawerLoading; diff --git a/app/javascript/themes/glitch/features/ui/components/embed_modal.js b/app/javascript/themes/glitch/features/ui/components/embed_modal.js deleted file mode 100644 index 1afffb51b..000000000 --- a/app/javascript/themes/glitch/features/ui/components/embed_modal.js +++ /dev/null @@ -1,84 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { FormattedMessage, injectIntl } from 'react-intl'; -import axios from 'axios'; - -@injectIntl -export default class EmbedModal extends ImmutablePureComponent { - - static propTypes = { - url: PropTypes.string.isRequired, - onClose: PropTypes.func.isRequired, - intl: PropTypes.object.isRequired, - } - - state = { - loading: false, - oembed: null, - }; - - componentDidMount () { - const { url } = this.props; - - this.setState({ loading: true }); - - axios.post('/api/web/embed', { url }).then(res => { - this.setState({ loading: false, oembed: res.data }); - - const iframeDocument = this.iframe.contentWindow.document; - - iframeDocument.open(); - iframeDocument.write(res.data.html); - iframeDocument.close(); - - iframeDocument.body.style.margin = 0; - this.iframe.width = iframeDocument.body.scrollWidth; - this.iframe.height = iframeDocument.body.scrollHeight; - }); - } - - setIframeRef = c => { - this.iframe = c; - } - - handleTextareaClick = (e) => { - e.target.select(); - } - - render () { - const { oembed } = this.state; - - return ( -
    -

    - -
    -

    - -

    - - - -

    - -

    - -