diff --git a/app/gabsocial/actions/markers.js b/app/gabsocial/actions/markers.js new file mode 100644 index 000000000..3bf623fde --- /dev/null +++ b/app/gabsocial/actions/markers.js @@ -0,0 +1,33 @@ +import api from '../api'; + +export const FETCH_MARKERS_REQUEST = 'FETCH_MARKERS_REQUEST'; +export const FETCH_MARKERS_SUCCESS = 'FETCH_MARKERS_SUCCESS'; +export const FETCH_MARKERS_FAIL = 'FETCH_MARKERS_FAIL'; + +export const SAVE_MARKERS_REQUEST = 'SAVE_MARKERS_REQUEST'; +export const SAVE_MARKERS_SUCCESS = 'SAVE_MARKERS_SUCCESS'; +export const SAVE_MARKERS_FAIL = 'SAVE_MARKERS_FAIL'; + +export function fetchMarkers(timeline) { + return (dispatch, getState) => { + dispatch({ type: FETCH_MARKERS_REQUEST }); + return api(getState).get('/api/v1/markers', { + params: { timeline }, + }).then(response => { + dispatch({ type: FETCH_MARKERS_SUCCESS, markers: response.data }); + }).catch(error => { + dispatch({ type: FETCH_MARKERS_FAIL, error }); + }); + }; +} + +export function saveMarkers(params) { + return (dispatch, getState) => { + dispatch({ type: SAVE_MARKERS_REQUEST }); + return api(getState).post('/api/v1/markers', params).then(response => { + dispatch({ type: SAVE_MARKERS_SUCCESS, markers: response.data }); + }).catch(error => { + dispatch({ type: SAVE_MARKERS_FAIL, error }); + }); + }; +} diff --git a/app/gabsocial/actions/notifications.js b/app/gabsocial/actions/notifications.js index 9024d2ea6..d34cacd25 100644 --- a/app/gabsocial/actions/notifications.js +++ b/app/gabsocial/actions/notifications.js @@ -13,8 +13,8 @@ import { defineMessages } from 'react-intl'; import { List as ImmutableList } from 'immutable'; import { unescapeHTML } from '../utils/html'; import { getFilters, regexFromFilters } from '../selectors'; +import { fetchMarkers, saveMarkers } from './markers'; -export const NOTIFICATIONS_INITIALIZE = 'NOTIFICATIONS_INITIALIZE'; export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE'; export const NOTIFICATIONS_UPDATE_NOOP = 'NOTIFICATIONS_UPDATE_NOOP'; export const NOTIFICATIONS_UPDATE_QUEUE = 'NOTIFICATIONS_UPDATE_QUEUE'; @@ -27,9 +27,12 @@ export const NOTIFICATIONS_EXPAND_FAIL = 'NOTIFICATIONS_EXPAND_FAIL'; export const NOTIFICATIONS_FILTER_SET = 'NOTIFICATIONS_FILTER_SET'; export const NOTIFICATIONS_CLEAR = 'NOTIFICATIONS_CLEAR'; -export const NOTIFICATIONS_MARK_READ = 'NOTIFICATIONS_MARK_READ'; export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP'; +export const NOTIFICATIONS_MARK_READ_REQUEST = 'NOTIFICATIONS_MARK_READ_REQUEST'; +export const NOTIFICATIONS_MARK_READ_SUCCESS = 'NOTIFICATIONS_MARK_READ_SUCCESS'; +export const NOTIFICATIONS_MARK_READ_FAIL = 'NOTIFICATIONS_MARK_READ_FAIL'; + export const MAX_QUEUED_NOTIFICATIONS = 40; defineMessages({ @@ -45,12 +48,6 @@ const fetchRelatedRelationships = (dispatch, notifications) => { } }; -export function initializeNotifications() { - return { - type: NOTIFICATIONS_INITIALIZE, - }; -} - export function updateNotifications(notification, intlMessages, intlLocale) { return (dispatch, getState) => { const showInColumn = getState().getIn(['settings', 'notifications', 'shows', notification.type], true); @@ -176,6 +173,7 @@ export function expandNotifications({ maxId } = {}, done = noOp) { params.since_id = notifications.getIn(['items', 0, 'id']); } + dispatch(fetchMarkers(['notifications'])); dispatch(expandNotificationsRequest(isLoadingMore)); api(getState).get('/api/v1/notifications', { params }).then(response => { @@ -255,19 +253,24 @@ export function setFilter(filterType) { export function markReadNotifications() { return (dispatch, getState) => { if (!getState().get('me')) return; - const top_notification = parseInt(getState().getIn(['notifications', 'items', 0, 'id'])); - const last_read = getState().getIn(['notifications', 'lastRead']); + const topNotification = parseInt(getState().getIn(['notifications', 'items', 0, 'id'])); + const lastRead = getState().getIn(['notifications', 'lastRead']); + if (!(topNotification && topNotification > lastRead)) return; - if (top_notification && top_notification > last_read) { - api(getState).post('/api/v1/notifications/mark_read', { id: top_notification }).then(response => { - dispatch({ - type: NOTIFICATIONS_MARK_READ, - notification: top_notification, - }); - }).catch(e => { - console.error(e); - console.error('Could not mark notifications read.'); + dispatch({ + type: NOTIFICATIONS_MARK_READ_REQUEST, + lastRead: topNotification, + }); + + api(getState).post('/api/v1/pleroma/notifications/read', { + max_id: topNotification, + }).then(response => { + dispatch({ + type: NOTIFICATIONS_MARK_READ_SUCCESS, + notifications: response.data, }); - } + }).catch(e => { + dispatch({ type: NOTIFICATIONS_MARK_READ_FAIL }); + }); }; } diff --git a/app/gabsocial/features/ui/index.js b/app/gabsocial/features/ui/index.js index d737e1d10..be53d955d 100644 --- a/app/gabsocial/features/ui/index.js +++ b/app/gabsocial/features/ui/index.js @@ -15,7 +15,7 @@ import { isMobile } from '../../is_mobile'; import { debounce } from 'lodash'; import { uploadCompose, resetCompose } from '../../actions/compose'; import { expandHomeTimeline } from '../../actions/timelines'; -import { initializeNotifications, expandNotifications } from '../../actions/notifications'; +import { expandNotifications } from '../../actions/notifications'; import { fetchFilters } from '../../actions/filters'; import { clearHeight } from '../../actions/height_cache'; import { openModal } from '../../actions/modal'; @@ -404,7 +404,6 @@ class UI extends React.PureComponent { if (me) { this.props.dispatch(expandHomeTimeline()); this.props.dispatch(expandNotifications()); - this.props.dispatch(initializeNotifications()); // this.props.dispatch(fetchGroups('member')); setTimeout(() => this.props.dispatch(fetchFilters()), 500); diff --git a/app/gabsocial/reducers/notifications.js b/app/gabsocial/reducers/notifications.js index 3ac0e042d..4b2267e5a 100644 --- a/app/gabsocial/reducers/notifications.js +++ b/app/gabsocial/reducers/notifications.js @@ -1,25 +1,28 @@ import { - NOTIFICATIONS_INITIALIZE, NOTIFICATIONS_UPDATE, NOTIFICATIONS_EXPAND_SUCCESS, NOTIFICATIONS_EXPAND_REQUEST, NOTIFICATIONS_EXPAND_FAIL, NOTIFICATIONS_FILTER_SET, NOTIFICATIONS_CLEAR, - NOTIFICATIONS_MARK_READ, NOTIFICATIONS_SCROLL_TOP, NOTIFICATIONS_UPDATE_QUEUE, NOTIFICATIONS_DEQUEUE, + NOTIFICATIONS_MARK_READ_REQUEST, MAX_QUEUED_NOTIFICATIONS, } from '../actions/notifications'; import { ACCOUNT_BLOCK_SUCCESS, ACCOUNT_MUTE_SUCCESS, } from '../actions/accounts'; +import { + FETCH_MARKERS_SUCCESS, + SAVE_MARKERS_SUCCESS, +} from '../actions/markers'; import { TIMELINE_DELETE, TIMELINE_DISCONNECT } from '../actions/timelines'; import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; import compareId from '../compare_id'; -import { unreadCount } from 'gabsocial/initial_state'; +import { fromJS } from 'immutable'; const initialState = ImmutableMap({ items: ImmutableList(), @@ -130,8 +133,13 @@ const updateNotificationsQueue = (state, notification, intlMessages, intlLocale) export default function notifications(state = initialState, action) { switch(action.type) { - case NOTIFICATIONS_INITIALIZE: - return state.set('unread', unreadCount); + case FETCH_MARKERS_SUCCESS: + case SAVE_MARKERS_SUCCESS: + const prevRead = state.get('lastRead'); + const marker = fromJS(action.markers); + const unread = marker.getIn(['notifications', 'pleroma', 'unread_count'], 0); + const lastRead = marker.getIn(['notifications', 'last_read_id'], prevRead); + return state.merge({ unread, lastRead }); case NOTIFICATIONS_EXPAND_REQUEST: return state.set('isLoading', true); case NOTIFICATIONS_EXPAND_FAIL: @@ -157,8 +165,8 @@ export default function notifications(state = initialState, action) { return action.relationship.muting_notifications ? filterNotifications(state, action.relationship) : state; case NOTIFICATIONS_CLEAR: return state.set('items', ImmutableList()).set('hasMore', false); - case NOTIFICATIONS_MARK_READ: - return state.set('lastRead', action.notification); + case NOTIFICATIONS_MARK_READ_REQUEST: + return state.set('lastRead', action.lastRead); case TIMELINE_DELETE: return deleteByStatus(state, action.id); case TIMELINE_DISCONNECT: