about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/features/ui
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/flavours/glitch/features/ui')
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/actions_modal.js2
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/boost_modal.js4
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/columns_area.js4
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/favourite_modal.js4
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/media_modal.js26
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/onboarding_modal.js21
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/video_modal.js19
-rw-r--r--app/javascript/flavours/glitch/features/ui/index.js19
8 files changed, 80 insertions, 19 deletions
diff --git a/app/javascript/flavours/glitch/features/ui/components/actions_modal.js b/app/javascript/flavours/glitch/features/ui/components/actions_modal.js
index 9ac6dcf49..724f1c764 100644
--- a/app/javascript/flavours/glitch/features/ui/components/actions_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/actions_modal.js
@@ -114,7 +114,7 @@ export default class ActionsModal extends ImmutablePureComponent {
       <div className='modal-root__modal actions-modal'>
         {status}
 
-        <ul>
+        <ul className={classNames({ 'with-status': !!status })}>
           {this.props.actions.map(this.renderAction)}
         </ul>
       </div>
diff --git a/app/javascript/flavours/glitch/features/ui/components/boost_modal.js b/app/javascript/flavours/glitch/features/ui/components/boost_modal.js
index 9652bcb2d..0a914dce2 100644
--- a/app/javascript/flavours/glitch/features/ui/components/boost_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/boost_modal.js
@@ -40,7 +40,9 @@ export default class BoostModal extends ImmutablePureComponent {
     if (e.button === 0) {
       e.preventDefault();
       this.props.onClose();
-      this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
+      let state = {...this.context.router.history.location.state};
+      state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
+      this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`, state);
     }
   }
 
diff --git a/app/javascript/flavours/glitch/features/ui/components/columns_area.js b/app/javascript/flavours/glitch/features/ui/components/columns_area.js
index 83b797305..0fe580b9b 100644
--- a/app/javascript/flavours/glitch/features/ui/components/columns_area.js
+++ b/app/javascript/flavours/glitch/features/ui/components/columns_area.js
@@ -12,13 +12,13 @@ import BundleContainer from '../containers/bundle_container';
 import ColumnLoading from './column_loading';
 import DrawerLoading from './drawer_loading';
 import BundleColumnError from './bundle_column_error';
-import { Drawer, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline, DirectTimeline, FavouritedStatuses, BookmarkedStatuses, ListTimeline } from 'flavours/glitch/util/async-components';
+import { Compose, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline, DirectTimeline, FavouritedStatuses, BookmarkedStatuses, ListTimeline } from 'flavours/glitch/util/async-components';
 
 import detectPassiveEvents from 'detect-passive-events';
 import { scrollRight } from 'flavours/glitch/util/scroll';
 
 const componentMap = {
-  'COMPOSE': Drawer,
+  'COMPOSE': Compose,
   'HOME': HomeTimeline,
   'NOTIFICATIONS': Notifications,
   'PUBLIC': PublicTimeline,
diff --git a/app/javascript/flavours/glitch/features/ui/components/favourite_modal.js b/app/javascript/flavours/glitch/features/ui/components/favourite_modal.js
index 70722411d..e0037a15f 100644
--- a/app/javascript/flavours/glitch/features/ui/components/favourite_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/favourite_modal.js
@@ -40,7 +40,9 @@ export default class FavouriteModal extends ImmutablePureComponent {
     if (e.button === 0) {
       e.preventDefault();
       this.props.onClose();
-      this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`);
+      let state = {...this.context.router.history.location.state};
+      state.mastodonBackSteps = (state.mastodonBackSteps || 0) + 1;
+      this.context.router.history.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`, state);
     }
   }
 
diff --git a/app/javascript/flavours/glitch/features/ui/components/media_modal.js b/app/javascript/flavours/glitch/features/ui/components/media_modal.js
index 1f3ac18ea..ce6660480 100644
--- a/app/javascript/flavours/glitch/features/ui/components/media_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/media_modal.js
@@ -5,7 +5,7 @@ import PropTypes from 'prop-types';
 import Video from 'flavours/glitch/features/video';
 import ExtendedVideoPlayer from 'flavours/glitch/components/extended_video_player';
 import classNames from 'classnames';
-import { defineMessages, injectIntl } from 'react-intl';
+import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import IconButton from 'flavours/glitch/components/icon_button';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import ImageLoader from './image_loader';
@@ -19,8 +19,13 @@ const messages = defineMessages({
 @injectIntl
 export default class MediaModal extends ImmutablePureComponent {
 
+  static contextTypes = {
+    router: PropTypes.object,
+  };
+
   static propTypes = {
     media: ImmutablePropTypes.list.isRequired,
+    status: ImmutablePropTypes.map,
     index: PropTypes.number.isRequired,
     onClose: PropTypes.func.isRequired,
     intl: PropTypes.object.isRequired,
@@ -81,8 +86,15 @@ export default class MediaModal extends ImmutablePureComponent {
     }));
   };
 
+  handleStatusClick = e => {
+    if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
+      e.preventDefault();
+      this.context.router.history.push(`/statuses/${this.props.status.get('id')}`);
+    }
+  }
+
   render () {
-    const { media, intl, onClose } = this.props;
+    const { media, status, intl, onClose } = this.props;
     const { navigationHidden } = this.state;
 
     const index = this.getIndex();
@@ -123,6 +135,7 @@ export default class MediaModal extends ImmutablePureComponent {
         return (
           <Video
             preview={image.get('preview_url')}
+            blurhash={image.get('blurhash')}
             src={image.get('url')}
             width={image.get('width')}
             height={image.get('height')}
@@ -185,10 +198,19 @@ export default class MediaModal extends ImmutablePureComponent {
             {content}
           </ReactSwipeableViews>
         </div>
+
         <div className={navigationClassName}>
           <IconButton className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={40} />
+
           {leftNav}
           {rightNav}
+
+          {status && (
+            <div className={classNames('media-modal__meta', { 'media-modal__meta--shifted': media.size > 1 })}>
+              <a href={status.get('url')} onClick={this.handleStatusClick}><FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a>
+            </div>
+          )}
+
           <ul className='media-modal__pagination'>
             {pagination}
           </ul>
diff --git a/app/javascript/flavours/glitch/features/ui/components/onboarding_modal.js b/app/javascript/flavours/glitch/features/ui/components/onboarding_modal.js
index 293daf77a..3db9ec77d 100644
--- a/app/javascript/flavours/glitch/features/ui/components/onboarding_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/onboarding_modal.js
@@ -6,12 +6,14 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import ReactSwipeableViews from 'react-swipeable-views';
 import classNames from 'classnames';
 import Permalink from 'flavours/glitch/components/permalink';
-import { WrappedComponent as RawComposer } from 'flavours/glitch/features/composer';
-import DrawerAccount from 'flavours/glitch/features/drawer/account';
-import DrawerSearch from 'flavours/glitch/features/drawer/search';
+import ComposeForm from 'flavours/glitch/features/compose/components/compose_form';
+import DrawerAccount from 'flavours/glitch/features/compose/components/navigation_bar';
+import Search from 'flavours/glitch/features/compose/components/search';
 import ColumnHeader from './column_header';
 import { me } from 'flavours/glitch/util/initial_state';
 
+const noop = () => { };
+
 const messages = defineMessages({
   home_title: { id: 'column.home', defaultMessage: 'Home' },
   notifications_title: { id: 'column.notifications', defaultMessage: 'Notifications' },
@@ -43,10 +45,11 @@ const PageTwo = ({ intl, myAccount }) => (
     <div className='figure non-interactive'>
       <div className='pseudo-drawer'>
         <DrawerAccount account={myAccount} />
-        <RawComposer
-          intl={intl}
+        <ComposeForm
           privacy='public'
           text='Awoo! #introductions'
+          spoilerText=''
+          suggestions={ [] }
         />
       </div>
     </div>
@@ -63,7 +66,13 @@ PageTwo.propTypes = {
 const PageThree = ({ intl, myAccount }) => (
   <div className='onboarding-modal__page onboarding-modal__page-three'>
     <div className='figure non-interactive'>
-      <DrawerSearch intl={intl} />
+      <Search
+        value=''
+        onChange={noop}
+        onSubmit={noop}
+        onClear={noop}
+        onShow={noop}
+      />
 
       <div className='pseudo-drawer'>
         <DrawerAccount account={myAccount} />
diff --git a/app/javascript/flavours/glitch/features/ui/components/video_modal.js b/app/javascript/flavours/glitch/features/ui/components/video_modal.js
index 69e0ee46e..3f742c260 100644
--- a/app/javascript/flavours/glitch/features/ui/components/video_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/video_modal.js
@@ -3,26 +3,43 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 import PropTypes from 'prop-types';
 import Video from 'flavours/glitch/features/video';
 import ImmutablePureComponent from 'react-immutable-pure-component';
+import { FormattedMessage } from 'react-intl';
 
 export default class VideoModal extends ImmutablePureComponent {
 
+  static contextTypes = {
+    router: PropTypes.object,
+  };
+
   static propTypes = {
     media: ImmutablePropTypes.map.isRequired,
+    status: ImmutablePropTypes.map,
     time: PropTypes.number,
     onClose: PropTypes.func.isRequired,
   };
 
+  handleStatusClick = e => {
+    if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
+      e.preventDefault();
+      this.context.router.history.push(`/statuses/${this.props.status.get('id')}`);
+    }
+  }
+
   render () {
-    const { media, time, onClose } = this.props;
+    const { media, status, time, onClose } = this.props;
+
+    const link = status && <a href={status.get('url')} onClick={this.handleStatusClick}><FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a>;
 
     return (
       <div className='modal-root__modal video-modal'>
         <div>
           <Video
             preview={media.get('preview_url')}
+            blurhash={media.get('blurhash')}
             src={media.get('url')}
             startTime={time}
             onCloseVideo={onClose}
+            link={link}
             detailed
             alt={media.get('description')}
           />
diff --git a/app/javascript/flavours/glitch/features/ui/index.js b/app/javascript/flavours/glitch/features/ui/index.js
index a19b3abf1..13c71337a 100644
--- a/app/javascript/flavours/glitch/features/ui/index.js
+++ b/app/javascript/flavours/glitch/features/ui/index.js
@@ -19,7 +19,7 @@ import ColumnsAreaContainer from './containers/columns_area_container';
 import classNames from 'classnames';
 import Favico from 'favico.js';
 import {
-  Drawer,
+  Compose,
   Status,
   GettingStarted,
   KeyboardShortcuts,
@@ -68,6 +68,7 @@ const mapStateToProps = state => ({
   dropdownMenuIsOpen: state.getIn(['dropdown_menu', 'openId']) !== null,
   unreadNotifications: state.getIn(['notifications', 'unread']),
   showFaviconBadge: state.getIn(['local_settings', 'notifications', 'favicon_badge']),
+  hicolorPrivacyIcons: state.getIn(['local_settings', 'hicolor_privacy_icons']),
 });
 
 const keyMap = {
@@ -98,6 +99,8 @@ const keyMap = {
   goToMuted: 'g m',
   goToRequests: 'g r',
   toggleSpoiler: 'x',
+  bookmark: 'd',
+  toggleCollapse: 'shift+x',
 };
 
 @connect(mapStateToProps)
@@ -341,11 +344,16 @@ export default class UI extends React.Component {
   handleHotkeyFocusColumn = e => {
     const index  = (e.key * 1) + 1; // First child is drawer, skip that
     const column = this.node.querySelector(`.column:nth-child(${index})`);
+    if (!column) return;
+    const container = column.querySelector('.scrollable');
 
-    if (column) {
-      const status = column.querySelector('.focusable');
+    if (container) {
+      const status = container.querySelector('.focusable');
 
       if (status) {
+        if (container.scrollTop > status.offsetTop) {
+          status.scrollIntoView(true);
+        }
         status.focus();
       }
     }
@@ -439,6 +447,7 @@ export default class UI extends React.Component {
       'wide': isWide,
       'system-font': this.props.systemFontUi,
       'navbar-under': navbarUnder,
+      'hicolor-privacy-icons': this.props.hicolorPrivacyIcons,
     });
 
     const handlers = {
@@ -483,9 +492,9 @@ export default class UI extends React.Component {
               <WrappedRoute path='/bookmarks' component={BookmarkedStatuses} content={children} />
               <WrappedRoute path='/pinned' component={PinnedStatuses} content={children} />
 
-              <WrappedRoute path='/search' component={Drawer} content={children} componentParams={{ isSearchPage: true }} />
+              <WrappedRoute path='/search' component={Compose} content={children} componentParams={{ isSearchPage: true }} />
 
-              <WrappedRoute path='/statuses/new' component={Drawer} content={children} />
+              <WrappedRoute path='/statuses/new' component={Compose} content={children} />
               <WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} />
               <WrappedRoute path='/statuses/:statusId/reblogs' component={Reblogs} content={children} />
               <WrappedRoute path='/statuses/:statusId/favourites' component={Favourites} content={children} />