diff options
Diffstat (limited to 'app/javascript/flavours/glitch/reducers')
4 files changed, 74 insertions, 7 deletions
diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js index 594d70ee2..0ddff707e 100644 --- a/app/javascript/flavours/glitch/reducers/compose.js +++ b/app/javascript/flavours/glitch/reducers/compose.js @@ -314,8 +314,12 @@ export default function compose(state = initialState, action) { map.set('idempotencyKey', uuid()); if (action.status.get('spoiler_text').length > 0) { + let spoiler_text = action.status.get('spoiler_text'); + if (!spoiler_text.match(/^re[: ]/i)) { + spoiler_text = 're: '.concat(spoiler_text); + } map.set('spoiler', true); - map.set('spoiler_text', action.status.get('spoiler_text')); + map.set('spoiler_text', spoiler_text); } else { map.set('spoiler', false); map.set('spoiler_text', ''); diff --git a/app/javascript/flavours/glitch/reducers/dropdown_menu.js b/app/javascript/flavours/glitch/reducers/dropdown_menu.js index 5449884cc..36fd4f132 100644 --- a/app/javascript/flavours/glitch/reducers/dropdown_menu.js +++ b/app/javascript/flavours/glitch/reducers/dropdown_menu.js @@ -4,12 +4,12 @@ import { DROPDOWN_MENU_CLOSE, } from '../actions/dropdown_menu'; -const initialState = Immutable.Map({ openId: null, placement: null }); +const initialState = Immutable.Map({ openId: null, placement: null, keyboard: false }); export default function dropdownMenu(state = initialState, action) { switch (action.type) { case DROPDOWN_MENU_OPEN: - return state.merge({ openId: action.id, placement: action.placement }); + return state.merge({ openId: action.id, placement: action.placement, keyboard: action.keyboard }); case DROPDOWN_MENU_CLOSE: return state.get('openId') === action.id ? state.set('openId', null) : state; default: diff --git a/app/javascript/flavours/glitch/reducers/local_settings.js b/app/javascript/flavours/glitch/reducers/local_settings.js index 063ae3943..260a9f08f 100644 --- a/app/javascript/flavours/glitch/reducers/local_settings.js +++ b/app/javascript/flavours/glitch/reducers/local_settings.js @@ -14,6 +14,7 @@ const initialState = ImmutableMap({ show_reply_count : false, always_show_spoilers_field: false, confirm_missing_media_description: false, + preselect_on_reply: true, content_warnings : ImmutableMap({ auto_unfold : false, filter : null, @@ -37,6 +38,10 @@ const initialState = ImmutableMap({ letterbox : true, fullwidth : true, }), + notifications : ImmutableMap({ + favicon_badge : false, + tab_badge : true, + }), }); const hydrate = (state, localSettings) => state.mergeDeep(localSettings); diff --git a/app/javascript/flavours/glitch/reducers/notifications.js b/app/javascript/flavours/glitch/reducers/notifications.js index dc820b476..0b816e85e 100644 --- a/app/javascript/flavours/glitch/reducers/notifications.js +++ b/app/javascript/flavours/glitch/reducers/notifications.js @@ -1,4 +1,7 @@ import { + NOTIFICATIONS_MOUNT, + NOTIFICATIONS_UNMOUNT, + NOTIFICATIONS_SET_VISIBILITY, NOTIFICATIONS_UPDATE, NOTIFICATIONS_EXPAND_SUCCESS, NOTIFICATIONS_EXPAND_REQUEST, @@ -24,9 +27,12 @@ const initialState = ImmutableMap({ items: ImmutableList(), hasMore: true, top: true, + mounted: 0, unread: 0, + lastReadId: '0', isLoading: false, cleaningMode: false, + isTabVisible: true, // notification removal mark of new notifs loaded whilst cleaningMode is true. markNewForDelete: false, }); @@ -40,9 +46,11 @@ const notificationToMap = (state, notification) => ImmutableMap({ }); const normalizeNotification = (state, notification) => { - const top = state.get('top'); + const top = !shouldCountUnreadNotifications(state); - if (!top) { + if (top) { + state = state.set('lastReadId', notification.id); + } else { state = state.update('unread', unread => unread + 1); } @@ -56,6 +64,8 @@ const normalizeNotification = (state, notification) => { }; const expandNormalizedNotifications = (state, notifications, next) => { + const top = !(shouldCountUnreadNotifications(state)); + const lastReadId = state.get('lastReadId'); let items = ImmutableList(); notifications.forEach((n, i) => { @@ -77,6 +87,14 @@ const expandNormalizedNotifications = (state, notifications, next) => { }); } + if (top) { + if (!items.isEmpty()) { + mutable.update('lastReadId', id => compareId(id, items.first().get('id')) > 0 ? id : items.first().get('id')); + } + } else { + mutable.update('unread', unread => unread + items.filter(item => compareId(item.get('id'), lastReadId) > 0).size); + } + if (!next) { mutable.set('hasMore', true); } @@ -89,15 +107,29 @@ const filterNotifications = (state, relationship) => { return state.update('items', list => list.filterNot(item => item !== null && item.get('account') === relationship.id)); }; +const clearUnread = (state) => { + state = state.set('unread', 0); + const lastNotification = state.get('items').find(item => item !== null); + return state.set('lastReadId', lastNotification ? lastNotification.get('id') : '0'); +} + const updateTop = (state, top) => { - if (top) { - state = state.set('unread', 0); + state = state.set('top', top); + + if (!shouldCountUnreadNotifications(state)) { + state = clearUnread(state); } return state.set('top', top); }; const deleteByStatus = (state, statusId) => { + const top = !(shouldCountUnreadNotifications(state)); + if (!top) { + const lastReadId = state.get('lastReadId'); + const deletedUnread = state.get('items').filter(item => item !== null && item.get('status') === statusId && compareId(item.get('id'), lastReadId) > 0); + state = state.update('unread', unread => unread - deletedUnread.size); + } return state.update('items', list => list.filterNot(item => item !== null && item.get('status') === statusId)); }; @@ -129,10 +161,36 @@ const deleteMarkedNotifs = (state) => { return state.update('items', list => list.filterNot(item => item.get('markedForDelete'))); }; +const updateMounted = (state) => { + state = state.update('mounted', count => count + 1); + if (!shouldCountUnreadNotifications(state)) { + state = clearUnread(state); + } + return state; +}; + +const updateVisibility = (state, visibility) => { + state = state.set('isTabVisible', visibility); + if (!shouldCountUnreadNotifications(state)) { + state = clearUnread(state); + } + return state; +}; + +const shouldCountUnreadNotifications = (state) => { + return !(state.get('isTabVisible') && state.get('top') && state.get('mounted') > 0); +}; + export default function notifications(state = initialState, action) { let st; switch(action.type) { + case NOTIFICATIONS_MOUNT: + return updateMounted(state); + case NOTIFICATIONS_UNMOUNT: + return state.update('mounted', count => count - 1); + case NOTIFICATIONS_SET_VISIBILITY: + return updateVisibility(state, action.visibility); case NOTIFICATIONS_EXPAND_REQUEST: case NOTIFICATIONS_DELETE_MARKED_REQUEST: return state.set('isLoading', true); |