Pull to Refresh: Notifications, Chats, Bookmarks

merge-requests/854/head
Alex Gleason 2021-11-04 14:07:20 -05:00
rodzic f61845b876
commit 65a2a40cb2
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
5 zmienionych plików z 48 dodań i 20 usunięć

Wyświetl plik

@ -9,15 +9,17 @@ export const BOOKMARKED_STATUSES_EXPAND_REQUEST = 'BOOKMARKED_STATUSES_EXPAND_RE
export const BOOKMARKED_STATUSES_EXPAND_SUCCESS = 'BOOKMARKED_STATUSES_EXPAND_SUCCESS';
export const BOOKMARKED_STATUSES_EXPAND_FAIL = 'BOOKMARKED_STATUSES_EXPAND_FAIL';
const noOp = () => new Promise(f => f());
export function fetchBookmarkedStatuses() {
return (dispatch, getState) => {
if (getState().getIn(['status_lists', 'bookmarks', 'isLoading'])) {
return;
return dispatch(noOp);
}
dispatch(fetchBookmarkedStatusesRequest());
api(getState).get('/api/v1/bookmarks').then(response => {
return api(getState).get('/api/v1/bookmarks').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedStatuses(response.data));
dispatch(fetchBookmarkedStatusesSuccess(response.data, next ? next.uri : null));
@ -53,12 +55,12 @@ export function expandBookmarkedStatuses() {
const url = getState().getIn(['status_lists', 'bookmarks', 'next'], null);
if (url === null || getState().getIn(['status_lists', 'bookmarks', 'isLoading'])) {
return;
return dispatch(noOp);
}
dispatch(expandBookmarkedStatusesRequest());
api(getState).get(url).then(response => {
return api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(importFetchedStatuses(response.data));
dispatch(expandBookmarkedStatusesSuccess(response.data, next ? next.uri : null));

Wyświetl plik

@ -2,7 +2,8 @@ import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import Column from '../ui/components/column';
import Column from 'soapbox/components/column';
import SubNavigation from 'soapbox/components/sub_navigation';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import StatusList from '../../components/status_list';
@ -38,15 +39,22 @@ class Bookmarks extends ImmutablePureComponent {
isLoading: PropTypes.bool,
};
componentDidMount() {
fetchData = () => {
const { dispatch } = this.props;
dispatch(fetchBookmarkedStatuses());
return dispatch(fetchBookmarkedStatuses());
}
componentDidMount() {
this.fetchData();
}
handleLoadMore = debounce(() => {
this.props.dispatch(expandBookmarkedStatuses());
}, 300, { leading: true })
handleRefresh = () => {
return this.fetchData();
}
render() {
const { intl, shouldUpdateScroll, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props;
@ -55,7 +63,8 @@ class Bookmarks extends ImmutablePureComponent {
const emptyMessage = <FormattedMessage id='empty_column.bookmarks' defaultMessage="You don't have any bookmarks yet. When you add one, it will show up here." />;
return (
<Column heading={intl.formatMessage(messages.heading)} transparent>
<Column transparent>
<SubNavigation message={intl.formatMessage(messages.heading)} />
<StatusList
trackScroll={!pinned}
statusIds={statusIds}
@ -63,6 +72,7 @@ class Bookmarks extends ImmutablePureComponent {
hasMore={hasMore}
isLoading={isLoading}
onLoadMore={this.handleLoadMore}
onRefresh={this.handleRefresh}
shouldUpdateScroll={shouldUpdateScroll}
emptyMessage={emptyMessage}
bindToDocument={!multiColumn}

Wyświetl plik

@ -3,12 +3,12 @@ import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Column from '../../components/column';
import ColumnHeader from '../../components/column_header';
import { launchChat } from 'soapbox/actions/chats';
import { fetchChats, launchChat } from 'soapbox/actions/chats';
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';
import PullToRefresh from 'soapbox/components/pull_to_refresh';
const messages = defineMessages({
title: { id: 'column.chats', defaultMessage: 'Chats' },
@ -36,6 +36,11 @@ class ChatIndex extends React.PureComponent {
this.context.router.history.push(`/chats/${chat.get('id')}`);
}
handleRefresh = () => {
const { dispatch } = this.props;
return dispatch(fetchChats());
}
render() {
const { intl } = this.props;
@ -55,12 +60,12 @@ class ChatIndex extends React.PureComponent {
onSelected={this.handleSuggestion}
/>
<Pullable>
<PullToRefresh onRefresh={this.handleRefresh}>
<ChatList
onClickChat={this.handleClickChat}
emptyMessage={<FormattedMessage id='chat_panels.main_window.empty' defaultMessage="No chats found. To start a chat, visit a user's profile." />}
/>
</Pullable>
</PullToRefresh>
</Column>
);
}

Wyświetl plik

@ -21,7 +21,6 @@ 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' },
@ -129,6 +128,11 @@ class Notifications extends React.PureComponent {
this.props.dispatch(dequeueNotifications());
};
handleRefresh = () => {
const { dispatch } = this.props;
return dispatch(expandNotifications());
}
render() {
const { intl, notifications, isLoading, hasMore, showFilterBar, totalQueuedNotificationsCount } = this.props;
const emptyMessage = <FormattedMessage id='empty_column.notifications' defaultMessage="You don't have any notifications yet. Interact with others to start the conversation." />;
@ -173,6 +177,7 @@ class Notifications extends React.PureComponent {
placeholderComponent={PlaceholderNotification}
placeholderCount={20}
onLoadMore={this.handleLoadOlder}
onRefresh={this.handleRefresh}
onScrollToTop={this.handleScrollToTop}
onScroll={this.handleScroll}
>
@ -189,9 +194,7 @@ class Notifications extends React.PureComponent {
count={totalQueuedNotificationsCount}
message={messages.queue}
/>
<Pullable>
{scrollContainer}
</Pullable>
{scrollContainer}
</Column>
);
}

Wyświetl plik

@ -934,10 +934,18 @@
}
// Make MaterialStatus flush against SubNavigation
.sub-navigation ~ .slist .item-list > article:first-child .material-status__status,
.sub-navigation ~ .material-status:not(.material-status + .material-status) .material-status__status {
border-top-left-radius: 0;
border-top-right-radius: 0;
.sub-navigation ~,
.sub-navigation ~ .ptr > .ptr__children > {
// ScrollableList
.slist .item-list > article:first-child,
// Thread
.material-status:not(.material-status + .material-status) {
// MaterialStatus
.material-status__status {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
}
}
// Display background for loading indicator