about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/flavours/glitch')
-rw-r--r--app/javascript/flavours/glitch/features/account_gallery/components/media_item.js4
-rw-r--r--app/javascript/flavours/glitch/features/account_gallery/index.js4
-rw-r--r--app/javascript/flavours/glitch/features/compose/components/search.js16
-rw-r--r--app/javascript/flavours/glitch/features/direct_timeline/components/conversation.js45
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/audio_modal.js53
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/embed_modal.js17
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/media_modal.js2
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/modal_root.js2
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/mute_modal.js2
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/video_modal.js13
-rw-r--r--app/javascript/flavours/glitch/features/ui/index.js2
-rw-r--r--app/javascript/flavours/glitch/reducers/conversations.js3
-rw-r--r--app/javascript/flavours/glitch/styles/about.scss21
-rw-r--r--app/javascript/flavours/glitch/styles/components/index.scss9
-rw-r--r--app/javascript/flavours/glitch/styles/components/media.scss10
-rw-r--r--app/javascript/flavours/glitch/styles/components/modal.scss4
-rw-r--r--app/javascript/flavours/glitch/styles/components/status.scss4
-rw-r--r--app/javascript/flavours/glitch/styles/containers.scss14
-rw-r--r--app/javascript/flavours/glitch/styles/mastodon-light/diff.scss15
-rw-r--r--app/javascript/flavours/glitch/styles/mastodon-light/variables.scss2
-rw-r--r--app/javascript/flavours/glitch/styles/rtl.scss35
21 files changed, 247 insertions, 30 deletions
diff --git a/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js b/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js
index bd3baa5c3..6d07ec48c 100644
--- a/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js
+++ b/app/javascript/flavours/glitch/features/account_gallery/components/media_item.js
@@ -118,6 +118,7 @@ export default class MediaItem extends ImmutablePureComponent {
       );
     } else if (['gifv', 'video'].indexOf(attachment.get('type')) !== -1) {
       const autoPlay = !isIOS() && autoPlayGif;
+      const label    = attachment.get('type') === 'video' ? <Icon id='play' /> : 'GIF';
 
       thumbnail = (
         <div className={classNames('media-gallery__gifv', { autoplay: autoPlay })}>
@@ -133,7 +134,8 @@ export default class MediaItem extends ImmutablePureComponent {
             loop
             muted
           />
-          <span className='media-gallery__gifv__label'>GIF</span>
+
+          <span className='media-gallery__gifv__label'>{label}</span>
         </div>
       );
     }
diff --git a/app/javascript/flavours/glitch/features/account_gallery/index.js b/app/javascript/flavours/glitch/features/account_gallery/index.js
index 597196567..ff39764bb 100644
--- a/app/javascript/flavours/glitch/features/account_gallery/index.js
+++ b/app/javascript/flavours/glitch/features/account_gallery/index.js
@@ -111,8 +111,10 @@ class AccountGallery extends ImmutablePureComponent {
   }
 
   handleOpenMedia = attachment => {
-    if (['video', 'audio'].includes(attachment.get('type'))) {
+    if (attachment.get('type') === 'video') {
       this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status') }));
+    } else if (attachment.get('type') === 'audio') {
+      this.props.dispatch(openModal('AUDIO', { media: attachment, status: attachment.get('status') }));
     } else {
       const media = attachment.getIn(['status', 'media_attachments']);
       const index = media.findIndex(x => x.get('id') === attachment.get('id'));
diff --git a/app/javascript/flavours/glitch/features/compose/components/search.js b/app/javascript/flavours/glitch/features/compose/components/search.js
index 29d195ecd..12d839637 100644
--- a/app/javascript/flavours/glitch/features/compose/components/search.js
+++ b/app/javascript/flavours/glitch/features/compose/components/search.js
@@ -73,12 +73,17 @@ class Search extends React.PureComponent {
     onShow: PropTypes.func.isRequired,
     openInRoute: PropTypes.bool,
     intl: PropTypes.object.isRequired,
+    singleColumn: PropTypes.bool,
   };
 
   state = {
     expanded: false,
   };
 
+  setRef = c => {
+    this.searchForm = c;
+  }
+
   handleChange = (e) => {
     const { onChange } = this.props;
     if (onChange) {
@@ -103,10 +108,14 @@ class Search extends React.PureComponent {
   }
 
   handleFocus = () => {
-    const { onShow } = this.props;
     this.setState({ expanded: true });
-    if (onShow) {
-      onShow();
+    this.props.onShow();
+
+    if (this.searchForm && !this.props.singleColumn) {
+      const { left, right } = this.searchForm.getBoundingClientRect();
+      if (left < 0 || right > (window.innerWidth || document.documentElement.clientWidth)) {
+        this.searchForm.scrollIntoView();
+      }
     }
   }
 
@@ -135,6 +144,7 @@ class Search extends React.PureComponent {
         <label>
           <span style={{ display: 'none' }}>{intl.formatMessage(messages.placeholder)}</span>
           <input
+            ref={this.setRef}
             className='search__input'
             type='text'
             placeholder={intl.formatMessage(messages.placeholder)}
diff --git a/app/javascript/flavours/glitch/features/direct_timeline/components/conversation.js b/app/javascript/flavours/glitch/features/direct_timeline/components/conversation.js
index 17487b202..a80fa824b 100644
--- a/app/javascript/flavours/glitch/features/direct_timeline/components/conversation.js
+++ b/app/javascript/flavours/glitch/features/direct_timeline/components/conversation.js
@@ -11,6 +11,7 @@ import Permalink from 'flavours/glitch/components/permalink';
 import IconButton from 'flavours/glitch/components/icon_button';
 import RelativeTimestamp from 'flavours/glitch/components/relative_timestamp';
 import { HotKeys } from 'react-hotkeys';
+import { autoPlayGif } from 'flavours/glitch/util/initial_state';
 
 const messages = defineMessages({
   more: { id: 'status.more', defaultMessage: 'More' },
@@ -37,6 +38,7 @@ class Conversation extends ImmutablePureComponent {
     onMoveUp: PropTypes.func,
     onMoveDown: PropTypes.func,
     markRead: PropTypes.func.isRequired,
+    delete: PropTypes.func.isRequired,
     intl: PropTypes.object.isRequired,
   };
 
@@ -63,6 +65,43 @@ class Conversation extends ImmutablePureComponent {
     }
   }
 
+  _updateEmojis () {
+    const node = this.namesNode;
+
+    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');
+  }
+
   handleClick = () => {
     if (!this.context.router) {
       return;
@@ -111,6 +150,10 @@ class Conversation extends ImmutablePureComponent {
     this.setState({ isExpanded: value });
   }
 
+  setNamesRef = (c) => {
+    this.namesNode = c;
+  }
+
   render () {
     const { accounts, lastStatus, unread, intl } = this.props;
     const { isExpanded } = this.state;
@@ -161,7 +204,7 @@ class Conversation extends ImmutablePureComponent {
                 <RelativeTimestamp timestamp={lastStatus.get('created_at')} />
               </div>
 
-              <div className='conversation__content__names'>
+              <div className='conversation__content__names' ref={this.setNamesRef}>
                 <FormattedMessage id='conversation.with' defaultMessage='With {names}' values={{ names: <span>{names}</span> }} />
               </div>
             </div>
diff --git a/app/javascript/flavours/glitch/features/ui/components/audio_modal.js b/app/javascript/flavours/glitch/features/ui/components/audio_modal.js
new file mode 100644
index 000000000..08fbddc91
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/ui/components/audio_modal.js
@@ -0,0 +1,53 @@
+import React from 'react';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import PropTypes from 'prop-types';
+import Audio from 'flavours/glitch/features/audio';
+import ImmutablePureComponent from 'react-immutable-pure-component';
+import { FormattedMessage } from 'react-intl';
+import classNames from 'classnames';
+import Icon from 'flavours/glitch/components/icon';
+
+export default class AudioModal extends ImmutablePureComponent {
+
+  static propTypes = {
+    media: ImmutablePropTypes.map.isRequired,
+    status: ImmutablePropTypes.map,
+    onClose: PropTypes.func.isRequired,
+  };
+
+  static contextTypes = {
+    router: PropTypes.object,
+  };
+
+  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, status } = this.props;
+
+    return (
+      <div className='modal-root__modal audio-modal'>
+        <div className='audio-modal__container'>
+          <Audio
+            src={media.get('url')}
+            alt={media.get('description')}
+            duration={media.getIn(['meta', 'original', 'duration'], 0)}
+            height={135}
+            preload
+          />
+        </div>
+
+        {status && (
+          <div className={classNames('media-modal__meta')}>
+            <a href={status.get('url')} onClick={this.handleStatusClick}><Icon id='comments' /> <FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a>
+          </div>
+        )}
+      </div>
+    );
+  }
+
+}
diff --git a/app/javascript/flavours/glitch/features/ui/components/embed_modal.js b/app/javascript/flavours/glitch/features/ui/components/embed_modal.js
index 47c1c7925..b6f5e628d 100644
--- a/app/javascript/flavours/glitch/features/ui/components/embed_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/embed_modal.js
@@ -1,8 +1,13 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 import ImmutablePureComponent from 'react-immutable-pure-component';
-import { FormattedMessage, injectIntl } from 'react-intl';
+import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
 import api from 'flavours/glitch/util/api';
+import IconButton from 'flavours/glitch/components/icon_button';
+
+const messages = defineMessages({
+  close: { id: 'lightbox.close', defaultMessage: 'Close' },
+});
 
 export default @injectIntl
 class EmbedModal extends ImmutablePureComponent {
@@ -50,13 +55,17 @@ class EmbedModal extends ImmutablePureComponent {
   }
 
   render () {
+    const { intl, onClose } = this.props;
     const { oembed } = this.state;
 
     return (
-      <div className='modal-root__modal embed-modal'>
-        <h4><FormattedMessage id='status.embed' defaultMessage='Embed' /></h4>
+      <div className='modal-root__modal report-modal embed-modal'>
+        <div className='report-modal__target'>
+          <IconButton className='media-modal__close' title={intl.formatMessage(messages.close)} icon='times' onClick={onClose} size={16} />
+          <FormattedMessage id='status.embed' defaultMessage='Embed' />
+        </div>
 
-        <div className='embed-modal__container'>
+        <div className='report-modal__container embed-modal__container' style={{ display: 'block' }}>
           <p className='hint'>
             <FormattedMessage id='embed.instructions' defaultMessage='Embed this status on your website by copying the code below.' />
           </p>
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 5d60c8a08..d61c69f69 100644
--- a/app/javascript/flavours/glitch/features/ui/components/media_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/media_modal.js
@@ -208,7 +208,7 @@ class MediaModal extends ImmutablePureComponent {
 
           {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>
+              <a href={status.get('url')} onClick={this.handleStatusClick}><Icon id='comments' /> <FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a>
             </div>
           )}
 
diff --git a/app/javascript/flavours/glitch/features/ui/components/modal_root.js b/app/javascript/flavours/glitch/features/ui/components/modal_root.js
index 0941ce9c8..117ce4c55 100644
--- a/app/javascript/flavours/glitch/features/ui/components/modal_root.js
+++ b/app/javascript/flavours/glitch/features/ui/components/modal_root.js
@@ -9,6 +9,7 @@ import MediaModal from './media_modal';
 import VideoModal from './video_modal';
 import BoostModal from './boost_modal';
 import FavouriteModal from './favourite_modal';
+import AudioModal from './audio_modal';
 import DoodleModal from './doodle_modal';
 import ConfirmationModal from './confirmation_modal';
 import FocalPointModal from './focal_point_modal';
@@ -28,6 +29,7 @@ const MODAL_COMPONENTS = {
   'MEDIA': () => Promise.resolve({ default: MediaModal }),
   'ONBOARDING': OnboardingModal,
   'VIDEO': () => Promise.resolve({ default: VideoModal }),
+  'AUDIO': () => Promise.resolve({ default: AudioModal }),
   'BOOST': () => Promise.resolve({ default: BoostModal }),
   'FAVOURITE': () => Promise.resolve({ default: FavouriteModal }),
   'DOODLE': () => Promise.resolve({ default: DoodleModal }),
diff --git a/app/javascript/flavours/glitch/features/ui/components/mute_modal.js b/app/javascript/flavours/glitch/features/ui/components/mute_modal.js
index dec6413c3..2aab82751 100644
--- a/app/javascript/flavours/glitch/features/ui/components/mute_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/mute_modal.js
@@ -82,7 +82,7 @@ class MuteModal extends React.PureComponent {
           <p className='mute-modal__explanation'>
             <FormattedMessage
               id='confirmations.mute.explanation'
-              defaultMessage='This will hide posts from them and posts mentioning them, but it will still allow them to see your posts follow you.'
+              defaultMessage='This will hide posts from them and posts mentioning them, but it will still allow them to see your posts and follow you.'
             />
           </p>
           <div className='setting-toggle'>
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 3f742c260..ef69f60f4 100644
--- a/app/javascript/flavours/glitch/features/ui/components/video_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/video_modal.js
@@ -4,6 +4,8 @@ import PropTypes from 'prop-types';
 import Video from 'flavours/glitch/features/video';
 import ImmutablePureComponent from 'react-immutable-pure-component';
 import { FormattedMessage } from 'react-intl';
+import classNames from 'classnames';
+import Icon from 'mastodon/components/icon';
 
 export default class VideoModal extends ImmutablePureComponent {
 
@@ -28,22 +30,25 @@ export default class VideoModal extends ImmutablePureComponent {
   render () {
     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>
+        <div className='video-modal__container'>
           <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')}
           />
         </div>
+
+        {status && (
+          <div className={classNames('media-modal__meta')}>
+            <a href={status.get('url')} onClick={this.handleStatusClick}><Icon id='comments' /> <FormattedMessage id='lightbox.view_context' defaultMessage='View context' /></a>
+          </div>
+        )}
       </div>
     );
   }
diff --git a/app/javascript/flavours/glitch/features/ui/index.js b/app/javascript/flavours/glitch/features/ui/index.js
index 6cc1b1cde..c201cd93d 100644
--- a/app/javascript/flavours/glitch/features/ui/index.js
+++ b/app/javascript/flavours/glitch/features/ui/index.js
@@ -320,7 +320,7 @@ class UI extends React.Component {
   }
 
   dataTransferIsText = (dataTransfer) => {
-    return (dataTransfer && Array.from(dataTransfer.types).includes('text/plain') && dataTransfer.items.length === 1);
+    return (dataTransfer && Array.from(dataTransfer.types).filter((type) => type === 'text/plain').length === 1);
   }
 
   closeUploadModal = () => {
diff --git a/app/javascript/flavours/glitch/reducers/conversations.js b/app/javascript/flavours/glitch/reducers/conversations.js
index 8fcc2cc79..fba0308bc 100644
--- a/app/javascript/flavours/glitch/reducers/conversations.js
+++ b/app/javascript/flavours/glitch/reducers/conversations.js
@@ -7,6 +7,7 @@ import {
   CONVERSATIONS_FETCH_FAIL,
   CONVERSATIONS_UPDATE,
   CONVERSATIONS_READ,
+  CONVERSATIONS_DELETE_SUCCESS,
 } from '../actions/conversations';
 import { ACCOUNT_BLOCK_SUCCESS, ACCOUNT_MUTE_SUCCESS } from 'flavours/glitch/actions/accounts';
 import { DOMAIN_BLOCK_SUCCESS } from 'flavours/glitch/actions/domain_blocks';
@@ -107,6 +108,8 @@ export default function conversations(state = initialState, action) {
     return filterConversations(state, [action.relationship.id]);
   case DOMAIN_BLOCK_SUCCESS:
     return filterConversations(state, action.accounts);
+  case CONVERSATIONS_DELETE_SUCCESS:
+    return state.update('items', list => list.filterNot(item => item.get('id') === action.id));
   default:
     return state;
   }
diff --git a/app/javascript/flavours/glitch/styles/about.scss b/app/javascript/flavours/glitch/styles/about.scss
index 7c129674d..a38ca99b4 100644
--- a/app/javascript/flavours/glitch/styles/about.scss
+++ b/app/javascript/flavours/glitch/styles/about.scss
@@ -145,8 +145,6 @@ $small-breakpoint: 960px;
 
     thead tr,
     tbody tr {
-      break-after: auto;
-      break-inside: avoid;
       border-bottom: 1px solid lighten($ui-base-color, 4%);
       font-size: 1em;
       line-height: 1.625;
@@ -167,12 +165,25 @@ $small-breakpoint: 960px;
       padding: 8px;
       align-self: start;
       align-items: start;
+      word-break: break-all;
 
       &.nowrap {
-        white-space: nowrap;
-        overflow: hidden;
-        text-overflow: ellipsis;
         width: 25%;
+        position: relative;
+
+        &::before {
+          content: '&nbsp;';
+          visibility: hidden;
+        }
+
+        span {
+          position: absolute;
+          left: 8px;
+          right: 8px;
+          white-space: nowrap;
+          overflow: hidden;
+          text-overflow: ellipsis;
+        }
       }
     }
   }
diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss
index 848ef78df..6f0d4c0be 100644
--- a/app/javascript/flavours/glitch/styles/components/index.scss
+++ b/app/javascript/flavours/glitch/styles/components/index.scss
@@ -1454,7 +1454,6 @@
     flex: 1 1 auto;
     padding: 10px 5px;
     padding-right: 15px;
-    word-break: break-all;
     overflow: hidden;
 
     &__info {
@@ -1477,8 +1476,8 @@
       overflow: hidden;
       text-overflow: ellipsis;
       margin-bottom: 4px;
-      flex-basis: 170px;
-      flex-shrink: 1000;
+      flex-basis: 90px;
+      flex-grow: 1;
 
       a {
         color: $primary-text-color;
@@ -1525,6 +1524,10 @@ noscript {
         text-decoration: none;
       }
     }
+
+    a {
+      word-break: break-word;
+    }
   }
 }
 
diff --git a/app/javascript/flavours/glitch/styles/components/media.scss b/app/javascript/flavours/glitch/styles/components/media.scss
index 85982d938..366759847 100644
--- a/app/javascript/flavours/glitch/styles/components/media.scss
+++ b/app/javascript/flavours/glitch/styles/components/media.scss
@@ -179,10 +179,13 @@
   position: absolute;
 }
 
-.video-modal {
+.video-modal__container {
   max-width: 100vw;
   max-height: 100vh;
-  position: relative;
+}
+
+.audio-modal__container {
+  width: 50vw;
 }
 
 .media-modal {
@@ -282,6 +285,7 @@
   }
 
   a {
+    pointer-events: auto;
     text-decoration: none;
     font-weight: 500;
     color: $ui-secondary-color;
@@ -339,6 +343,7 @@
   background: darken($ui-base-color, 8%);
   border-radius: 4px;
   padding-bottom: 44px;
+  direction: ltr;
 
   &.editable {
     border-radius: 0;
@@ -386,6 +391,7 @@
   max-width: 100%;
   border-radius: 4px;
   box-sizing: border-box;
+  direction: ltr;
 
   &.editable {
     border-radius: 0;
diff --git a/app/javascript/flavours/glitch/styles/components/modal.scss b/app/javascript/flavours/glitch/styles/components/modal.scss
index 4f3e5babf..716796af9 100644
--- a/app/javascript/flavours/glitch/styles/components/modal.scss
+++ b/app/javascript/flavours/glitch/styles/components/modal.scss
@@ -736,6 +736,7 @@
   &:focus,
   &:active {
     color: darken($lighter-text-color, 4%);
+    background-color: transparent;
   }
 }
 
@@ -804,6 +805,7 @@
 }
 
 .embed-modal {
+  width: auto;
   max-width: 80vw;
   max-height: 80vh;
 
@@ -834,6 +836,7 @@
       font-size: 14px;
       margin: 0;
       margin-bottom: 15px;
+      border-radius: 4px;
 
       &::-moz-focus-inner {
         border: 0;
@@ -859,6 +862,7 @@
       max-width: 100%;
       overflow: hidden;
       border: 0;
+      border-radius: 4px;
     }
   }
 }
diff --git a/app/javascript/flavours/glitch/styles/components/status.scss b/app/javascript/flavours/glitch/styles/components/status.scss
index ae89ac0a8..ded423afa 100644
--- a/app/javascript/flavours/glitch/styles/components/status.scss
+++ b/app/javascript/flavours/glitch/styles/components/status.scss
@@ -640,6 +640,10 @@ a.status__display-name,
   color: inherit;
 }
 
+.detailed-status .button.logo-button {
+  margin-bottom: 15px;
+}
+
 .detailed-status__display-name {
   color: $secondary-text-color;
   display: block;
diff --git a/app/javascript/flavours/glitch/styles/containers.scss b/app/javascript/flavours/glitch/styles/containers.scss
index 6a48ff354..e2f291b69 100644
--- a/app/javascript/flavours/glitch/styles/containers.scss
+++ b/app/javascript/flavours/glitch/styles/containers.scss
@@ -414,6 +414,20 @@
     }
   }
 
+  .directory__card {
+    border-radius: 4px;
+
+    @media screen and (max-width: $no-gap-breakpoint) {
+      border-radius: 0;
+    }
+  }
+
+  .page-header {
+    @media screen and (max-width: $no-gap-breakpoint) {
+      border-bottom: 0;
+    }
+  }
+
   .public-account-header {
     overflow: hidden;
     margin-bottom: 10px;
diff --git a/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss b/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss
index 5c7fa87da..3b4ffdf3c 100644
--- a/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss
+++ b/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss
@@ -230,8 +230,19 @@
 .report-modal,
 .embed-modal,
 .error-modal,
-.onboarding-modal {
-  background: $ui-base-color;
+.onboarding-modal,
+.report-modal__comment .setting-text__wrapper,
+.report-modal__comment .setting-text {
+  background: $white;
+  border: 1px solid lighten($ui-base-color, 8%);
+}
+
+.report-modal__comment {
+  border-right-color: lighten($ui-base-color, 8%);
+}
+
+.report-modal__container {
+  border-top-color: lighten($ui-base-color, 8%);
 }
 
 .boost-modal__action-bar,
diff --git a/app/javascript/flavours/glitch/styles/mastodon-light/variables.scss b/app/javascript/flavours/glitch/styles/mastodon-light/variables.scss
index 1b060b58d..312f5e314 100644
--- a/app/javascript/flavours/glitch/styles/mastodon-light/variables.scss
+++ b/app/javascript/flavours/glitch/styles/mastodon-light/variables.scss
@@ -18,6 +18,8 @@ $darker-text-color: $classic-base-color !default;
 $dark-text-color: #444b5d;
 $action-button-color: #606984;
 
+$success-green: lighten(#3c754d, 8%);
+
 $base-overlay-background: $white !default;
 
 $inverted-text-color: $black !default;
diff --git a/app/javascript/flavours/glitch/styles/rtl.scss b/app/javascript/flavours/glitch/styles/rtl.scss
index 8a275d82f..2375bac90 100644
--- a/app/javascript/flavours/glitch/styles/rtl.scss
+++ b/app/javascript/flavours/glitch/styles/rtl.scss
@@ -7,6 +7,34 @@ body.rtl {
     padding-right: 15px;
   }
 
+  .radio-button__input {
+    margin-right: 0;
+    margin-left: 10px;
+  }
+
+  .directory__card__bar .display-name {
+    margin-left: 0;
+    margin-right: 15px;
+  }
+
+  .display-name {
+    text-align: right;
+  }
+
+  .notification__message {
+    margin-left: 0;
+    margin-right: 68px;
+  }
+
+  .drawer__inner__mastodon > img {
+    transform: scaleX(-1);
+  }
+
+  .notification__favourite-icon-wrapper {
+    left: auto;
+    right: -26px;
+  }
+
   .landing-page__logo {
     margin-right: 0;
     margin-left: 20px;
@@ -152,7 +180,6 @@ body.rtl {
   }
 
   .status__action-bar {
-
     &__counter {
       margin-right: 0;
       margin-left: 11px;
@@ -345,6 +372,12 @@ body.rtl {
     }
   }
 
+  .columns-area--mobile .column,
+  .columns-area--mobile .drawer {
+    padding-left: 0;
+    padding-right: 0;
+  }
+
   .public-layout {
     .header {
       .nav-button {