diff --git a/app/soapbox/components/pullable.js b/app/soapbox/components/pullable.js new file mode 100644 index 000000000..52970dd7d --- /dev/null +++ b/app/soapbox/components/pullable.js @@ -0,0 +1,34 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import PullToRefresh from 'react-simple-pull-to-refresh'; + +/** + * Pullable: + * Basic "pull to refresh" without the refresh. + * Just visual feedback. + */ +export default class Pullable extends React.Component { + + static propTypes = { + children: PropTypes.node.isRequired, + } + + handleRefresh = () => { + return new Promise(resolve => resolve()); + } + + render() { + const { children } = this.props; + + return ( + + {children} + + ); + } + +} diff --git a/app/soapbox/features/account_timeline/index.js b/app/soapbox/features/account_timeline/index.js index 4d4d916ea..8700710a7 100644 --- a/app/soapbox/features/account_timeline/index.js +++ b/app/soapbox/features/account_timeline/index.js @@ -7,7 +7,7 @@ import { expandAccountFeaturedTimeline, expandAccountTimeline } from '../../acti import Icon from 'soapbox/components/icon'; import StatusList from '../../components/status_list'; import LoadingIndicator from '../../components/loading_indicator'; -import Column from '../ui/components/column'; +import Column from 'soapbox/components/column'; // import ColumnSettingsContainer from './containers/column_settings_container'; import SubNavigation from 'soapbox/components/sub_navigation'; import { OrderedSet as ImmutableOrderedSet } from 'immutable'; diff --git a/app/soapbox/features/chats/index.js b/app/soapbox/features/chats/index.js index 73f2630bd..da91543c8 100644 --- a/app/soapbox/features/chats/index.js +++ b/app/soapbox/features/chats/index.js @@ -8,6 +8,7 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import ChatList from './components/chat_list'; import AudioToggle from 'soapbox/features/chats/components/audio_toggle'; import AccountSearch from 'soapbox/components/account_search'; +import Pullable from 'soapbox/components/pullable'; const messages = defineMessages({ title: { id: 'column.chats', defaultMessage: 'Chats' }, @@ -54,10 +55,12 @@ class ChatIndex extends React.PureComponent { onSelected={this.handleSuggestion} /> - } - /> + + } + /> + ); } diff --git a/app/soapbox/features/compose/components/search_results.js b/app/soapbox/features/compose/components/search_results.js index b219ed944..e316123b1 100644 --- a/app/soapbox/features/compose/components/search_results.js +++ b/app/soapbox/features/compose/components/search_results.js @@ -11,6 +11,7 @@ import ScrollableList from 'soapbox/components/scrollable_list'; import PlaceholderAccount from 'soapbox/features/placeholder/components/placeholder_account'; import PlaceholderHashtag from 'soapbox/features/placeholder/components/placeholder_hashtag'; import PlaceholderStatus from 'soapbox/features/placeholder/components/placeholder_status'; +import Pullable from 'soapbox/components/pullable'; export default class SearchResults extends ImmutablePureComponent { @@ -107,18 +108,20 @@ export default class SearchResults extends ImmutablePureComponent { {noResultsMessage || ( - - {searchResults} - + + + {searchResults} + + )} ); diff --git a/app/soapbox/features/notifications/index.js b/app/soapbox/features/notifications/index.js index bea5e82a4..61367bad4 100644 --- a/app/soapbox/features/notifications/index.js +++ b/app/soapbox/features/notifications/index.js @@ -21,6 +21,7 @@ import TimelineQueueButtonHeader from '../../components/timeline_queue_button_h import { getSettings } from 'soapbox/actions/settings'; import PlaceholderNotification from 'soapbox/features/placeholder/components/placeholder_notification'; import SubNavigation from 'soapbox/components/sub_navigation'; +import Pullable from 'soapbox/components/pullable'; const messages = defineMessages({ title: { id: 'column.notifications', defaultMessage: 'Notifications' }, @@ -188,7 +189,9 @@ class Notifications extends React.PureComponent { count={totalQueuedNotificationsCount} message={messages.queue} /> - {scrollContainer} + + {scrollContainer} + ); } diff --git a/app/soapbox/features/search/index.js b/app/soapbox/features/search/index.js index 48398b749..cb1148460 100644 --- a/app/soapbox/features/search/index.js +++ b/app/soapbox/features/search/index.js @@ -1,6 +1,7 @@ import React from 'react'; import { defineMessages, injectIntl } from 'react-intl'; import PropTypes from 'prop-types'; +import Column from 'soapbox/components/column'; import ColumnHeader from 'soapbox/components/column_header'; import SearchContainer from 'soapbox/features/compose/containers/search_container'; import SearchResultsContainer from 'soapbox/features/compose/containers/search_results_container'; @@ -10,11 +11,11 @@ const messages = defineMessages({ }); const Search = ({ intl }) => ( -
+ -
+ ); Search.propTypes = { diff --git a/app/soapbox/features/status/index.js b/app/soapbox/features/status/index.js index 79c5d32d1..1c887da96 100644 --- a/app/soapbox/features/status/index.js +++ b/app/soapbox/features/status/index.js @@ -8,7 +8,7 @@ import { fetchStatus } from '../../actions/statuses'; import MissingIndicator from '../../components/missing_indicator'; import DetailedStatus from './components/detailed_status'; import ActionBar from './components/action_bar'; -import Column from '../ui/components/column'; +import Column from 'soapbox/components/column'; import { favourite, unfavourite, @@ -52,6 +52,7 @@ import ThreadStatus from './components/thread_status'; import PendingStatus from 'soapbox/features/ui/components/pending_status'; import SubNavigation from 'soapbox/components/sub_navigation'; import { launchChat } from 'soapbox/actions/chats'; +import Pullable from 'soapbox/components/pullable'; const messages = defineMessages({ title: { id: 'status.title', defaultMessage: 'Post' }, @@ -626,56 +627,58 @@ class Status extends ImmutablePureComponent { */}
- {ancestors && ( -
{ancestors}
- )} - -
- -
- - - -
-
-
+ + {ancestors && ( +
{ancestors}
+ )} - {descendants && ( -
{descendants}
- )} +
+ +
+ + + +
+
+
+ + {descendants && ( +
{descendants}
+ )} +
); diff --git a/app/soapbox/features/ui/components/column.js b/app/soapbox/features/ui/components/column.js index 19ad84a02..c4a1be2dc 100644 --- a/app/soapbox/features/ui/components/column.js +++ b/app/soapbox/features/ui/components/column.js @@ -2,6 +2,7 @@ import React from 'react'; import ColumnHeader from './column_header'; import PropTypes from 'prop-types'; import Column from 'soapbox/components/column'; +import Pullable from 'soapbox/components/pullable'; export default class UIColumn extends React.PureComponent { @@ -24,7 +25,9 @@ export default class UIColumn extends React.PureComponent { return ( {heading && } - {children} + + {children} + ); } diff --git a/app/soapbox/features/ui/components/column_loading.js b/app/soapbox/features/ui/components/column_loading.js index 7e710f2e3..7ade977e2 100644 --- a/app/soapbox/features/ui/components/column_loading.js +++ b/app/soapbox/features/ui/components/column_loading.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import Column from './column'; +import Column from 'soapbox/components/column'; import ColumnHeader from '../../../components/column_header'; import ImmutablePureComponent from 'react-immutable-pure-component'; import LoadingIndicator from 'soapbox/components/loading_indicator'; diff --git a/app/soapbox/pages/profile_page.js b/app/soapbox/pages/profile_page.js index ae09b4c2c..84f6c4f5e 100644 --- a/app/soapbox/pages/profile_page.js +++ b/app/soapbox/pages/profile_page.js @@ -100,7 +100,7 @@ class ProfilePage extends ImmutablePureComponent {
-
+
{children}
diff --git a/app/styles/components/admin.scss b/app/styles/components/admin.scss index 96dc141b5..3f9ed12da 100644 --- a/app/styles/components/admin.scss +++ b/app/styles/components/admin.scss @@ -127,7 +127,7 @@ display: block; width: 100%; max-width: 600px; - padding: 20px 20px 0; + padding: 10px 0; box-sizing: border-box; .columns-area__panels__pane__inner { diff --git a/app/styles/components/columns.scss b/app/styles/components/columns.scss index 36b172599..1b82cdcfd 100644 --- a/app/styles/components/columns.scss +++ b/app/styles/components/columns.scss @@ -99,6 +99,10 @@ margin: 0 auto; padding-top: 15px; + @media screen and (max-width: 580px) { + padding-top: 0; + } + .column { width: 100%; padding: 0; @@ -124,7 +128,7 @@ @media (max-width: 580px) { .timeline-compose-block { border-radius: 0; - margin-top: -5px; + margin-top: 10px; } } @@ -959,3 +963,18 @@ .sub-navigation + .account__section-headline { background: var(--foreground-color); } + +// Pull to refresh +.columns-area .column { + .ptr, + .ptr__children { + background: var(--foreground-color); + } + + &--transparent { + .ptr, + .ptr__children { + background: transparent; + } + } +} diff --git a/app/styles/components/profile-info-panel.scss b/app/styles/components/profile-info-panel.scss index 699e40924..99bf66c09 100644 --- a/app/styles/components/profile-info-panel.scss +++ b/app/styles/components/profile-info-panel.scss @@ -103,10 +103,6 @@ padding: 10px 0; margin: 5px 0; - @media screen and (max-width: 895px) { - border-bottom: 1px solid var(--brand-color--med); - } - a { color: var(--highlight-text-color); } diff --git a/app/styles/loading.scss b/app/styles/loading.scss index be819b892..c26ec70fe 100644 --- a/app/styles/loading.scss +++ b/app/styles/loading.scss @@ -219,3 +219,13 @@ } } } + +// Pull to refresh +.lds-ellipsis div { + background: var(--primary-text-color--faint) !important; +} + +.ptr, +.ptr__children { + overflow: visible !important; +} diff --git a/app/styles/ui.scss b/app/styles/ui.scss index 62aba1510..b724475e0 100644 --- a/app/styles/ui.scss +++ b/app/styles/ui.scss @@ -765,3 +765,9 @@ background: var(--accent-color); } } + +.page__top + .page__columns .columns-area { + @media screen and (max-width: 580px) { + padding-top: 10px; + } +} diff --git a/package.json b/package.json index be051d030..5f4529840 100644 --- a/package.json +++ b/package.json @@ -132,6 +132,7 @@ "react-redux": "^7.2.5", "react-router-dom": "^4.3.1", "react-router-scroll-4": "^1.0.0-beta.1", + "react-simple-pull-to-refresh": "^1.3.0", "react-sparklines": "^1.7.0", "react-stickynode": "^4.0.0", "react-swipeable-views": "^0.14.0", diff --git a/yarn.lock b/yarn.lock index 06faba1a0..53753d04a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7990,6 +7990,11 @@ react-side-effect@^2.1.0: resolved "https://registry.yarnpkg.com/react-side-effect/-/react-side-effect-2.1.1.tgz#66c5701c3e7560ab4822a4ee2742dee215d72eb3" integrity sha512-2FoTQzRNTncBVtnzxFOk2mCpcfxQpenBMbk5kSVBg5UcPqV9fRbgY2zhb7GTWWOlpFmAxhClBDlIq8Rsubz1yQ== +react-simple-pull-to-refresh@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/react-simple-pull-to-refresh/-/react-simple-pull-to-refresh-1.3.0.tgz#5f7bcd475ea5c33ecd505d097b14f56c3e5e3ce8" + integrity sha512-QPFGFsbroh2WoTcLCh3f6peMRfSettYJKCXMS9FNbFav7GWKD2whqACiNLx+Mi+VkP/I+aerB7kEirk+DQx41A== + react-sparklines@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/react-sparklines/-/react-sparklines-1.7.0.tgz#9b1d97e8c8610095eeb2ad658d2e1fcf91f91a60"