parent
8f477eeccb
commit
bf640b9b0f
|
@ -59,22 +59,6 @@
|
||||||
import { observe } from 'svelte-extras'
|
import { observe } from 'svelte-extras'
|
||||||
import { createMakeProps } from '../../_actions/createMakeProps'
|
import { createMakeProps } from '../../_actions/createMakeProps'
|
||||||
import { showMoreAndScrollToTop } from '../../_actions/showMoreAndScrollToTop'
|
import { showMoreAndScrollToTop } from '../../_actions/showMoreAndScrollToTop'
|
||||||
import { get } from '../../_utils/lodash-lite'
|
|
||||||
import {
|
|
||||||
HOME_REBLOGS,
|
|
||||||
HOME_REPLIES,
|
|
||||||
NOTIFICATION_REBLOGS,
|
|
||||||
NOTIFICATION_FOLLOWS,
|
|
||||||
NOTIFICATION_FAVORITES,
|
|
||||||
NOTIFICATION_POLLS,
|
|
||||||
NOTIFICATION_MENTIONS,
|
|
||||||
FILTER_FAVORITE,
|
|
||||||
FILTER_FOLLOW,
|
|
||||||
FILTER_MENTION,
|
|
||||||
FILTER_POLL,
|
|
||||||
FILTER_REBLOG,
|
|
||||||
FILTER_REPLY
|
|
||||||
} from '../../_static/instanceSettings'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
oncreate () {
|
oncreate () {
|
||||||
|
@ -143,59 +127,10 @@
|
||||||
timelineValue !== $firstTimelineItemId &&
|
timelineValue !== $firstTimelineItemId &&
|
||||||
timelineValue
|
timelineValue
|
||||||
),
|
),
|
||||||
currentInstanceSettings: ({ $currentInstance, $instanceSettings }) => (
|
itemIds: ({ $filteredTimelineItemSummaries }) => (
|
||||||
$instanceSettings[$currentInstance] || {}
|
$filteredTimelineItemSummaries && $filteredTimelineItemSummaries.map(_ => _.id)
|
||||||
),
|
|
||||||
timelineFilters: ({ currentInstanceSettings, timeline }) => {
|
|
||||||
if (timeline === 'home') {
|
|
||||||
return {
|
|
||||||
[FILTER_REBLOG]: get(currentInstanceSettings, [HOME_REBLOGS], true),
|
|
||||||
[FILTER_REPLY]: get(currentInstanceSettings, [HOME_REPLIES], true)
|
|
||||||
}
|
|
||||||
} else if (timeline === 'notifications') {
|
|
||||||
return {
|
|
||||||
[FILTER_REBLOG]: get(currentInstanceSettings, [NOTIFICATION_REBLOGS], true),
|
|
||||||
[FILTER_FOLLOW]: get(currentInstanceSettings, [NOTIFICATION_FOLLOWS], true),
|
|
||||||
[FILTER_FAVORITE]: get(currentInstanceSettings, [NOTIFICATION_FAVORITES], true),
|
|
||||||
[FILTER_MENTION]: get(currentInstanceSettings, [NOTIFICATION_MENTIONS], true),
|
|
||||||
[FILTER_POLL]: get(currentInstanceSettings, [NOTIFICATION_POLLS], true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showReblogs: ({ timelineFilters }) => get(timelineFilters, [FILTER_REBLOG], true),
|
|
||||||
showReplies: ({ timelineFilters }) => get(timelineFilters, [FILTER_REPLY], true),
|
|
||||||
showFollows: ({ timelineFilters }) => get(timelineFilters, [FILTER_FOLLOW], true),
|
|
||||||
showMentions: ({ timelineFilters }) => get(timelineFilters, [FILTER_MENTION], true),
|
|
||||||
showPolls: ({ timelineFilters }) => get(timelineFilters, [FILTER_POLL], true),
|
|
||||||
showFavs: ({ timelineFilters }) => get(timelineFilters, [FILTER_FAVORITE], true),
|
|
||||||
itemIds: ({
|
|
||||||
$timelineItemSummaries, showReblogs, showReplies, showFollows, showMentions,
|
|
||||||
showPolls, showFavs
|
|
||||||
}) => (
|
|
||||||
$timelineItemSummaries && $timelineItemSummaries.filter(item => {
|
|
||||||
switch (item.type) {
|
|
||||||
case 'poll':
|
|
||||||
return showPolls
|
|
||||||
case 'favourite':
|
|
||||||
return showFavs
|
|
||||||
case 'reblog':
|
|
||||||
return showReblogs
|
|
||||||
case 'mention':
|
|
||||||
return showMentions
|
|
||||||
case 'follow':
|
|
||||||
return showFollows
|
|
||||||
}
|
|
||||||
if (item.reblogId) {
|
|
||||||
return showReblogs
|
|
||||||
} else if (item.replyId) {
|
|
||||||
return showReplies
|
|
||||||
} else {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}).map(_ => _.id)
|
|
||||||
),
|
),
|
||||||
itemIdsToAdd: ({ $timelineItemSummariesToAdd }) => (
|
itemIdsToAdd: ({ $timelineItemSummariesToAdd }) => (
|
||||||
// TODO: filter
|
|
||||||
$timelineItemSummariesToAdd && $timelineItemSummariesToAdd.map(_ => _.id)
|
$timelineItemSummariesToAdd && $timelineItemSummariesToAdd.map(_ => _.id)
|
||||||
),
|
),
|
||||||
headerProps: ({ itemIdsToAdd }) => {
|
headerProps: ({ itemIdsToAdd }) => {
|
||||||
|
|
|
@ -6,10 +6,3 @@ export const NOTIFICATION_FAVORITES = 'notificationFavs'
|
||||||
export const NOTIFICATION_FOLLOWS = 'notificationFollows'
|
export const NOTIFICATION_FOLLOWS = 'notificationFollows'
|
||||||
export const NOTIFICATION_MENTIONS = 'notificationMentions'
|
export const NOTIFICATION_MENTIONS = 'notificationMentions'
|
||||||
export const NOTIFICATION_POLLS = 'notificationPolls'
|
export const NOTIFICATION_POLLS = 'notificationPolls'
|
||||||
|
|
||||||
export const FILTER_REBLOG = 'reblog'
|
|
||||||
export const FILTER_REPLY = 'reply'
|
|
||||||
export const FILTER_MENTION = 'mention'
|
|
||||||
export const FILTER_FOLLOW = 'follow'
|
|
||||||
export const FILTER_FAVORITE = 'fav'
|
|
||||||
export const FILTER_POLL = 'poll'
|
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
import { get } from '../../_utils/lodash-lite'
|
import { get } from '../../_utils/lodash-lite'
|
||||||
import { getFirstIdFromItemSummaries, getLastIdFromItemSummaries } from '../../_utils/getIdFromItemSummaries'
|
import { getFirstIdFromItemSummaries, getLastIdFromItemSummaries } from '../../_utils/getIdFromItemSummaries'
|
||||||
|
import {
|
||||||
|
HOME_REBLOGS,
|
||||||
|
HOME_REPLIES,
|
||||||
|
NOTIFICATION_REBLOGS,
|
||||||
|
NOTIFICATION_FOLLOWS,
|
||||||
|
NOTIFICATION_FAVORITES,
|
||||||
|
NOTIFICATION_POLLS,
|
||||||
|
NOTIFICATION_MENTIONS
|
||||||
|
} from '../../_static/instanceSettings'
|
||||||
|
|
||||||
function computeForTimeline (store, key, defaultValue) {
|
function computeForTimeline (store, key, defaultValue) {
|
||||||
store.compute(key,
|
store.compute(key,
|
||||||
|
@ -10,6 +19,31 @@ function computeForTimeline (store, key, defaultValue) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute just the boolean, e.g. 'showPolls', so that we can use that boolean as
|
||||||
|
// the input to the timelineFilterFunction computations. This should reduce the need to
|
||||||
|
// re-compute the timelineFilterFunction over and over.
|
||||||
|
function computeTimelineFilter (store, computationName, timelinesToSettingsKeys) {
|
||||||
|
store.compute(
|
||||||
|
computationName,
|
||||||
|
['currentInstance', 'instanceSettings', 'currentTimeline'],
|
||||||
|
(currentInstance, instanceSettings, currentTimeline) => {
|
||||||
|
let settingsKey = timelinesToSettingsKeys[currentTimeline]
|
||||||
|
return settingsKey ? get(instanceSettings, [currentInstance, settingsKey], true) : true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ditto for notifications, which we always have to keep track of due to the notification count.
|
||||||
|
function computeNotificationFilter (store, computationName, key) {
|
||||||
|
store.compute(
|
||||||
|
computationName,
|
||||||
|
['currentInstance', 'instanceSettings'],
|
||||||
|
(currentInstance, instanceSettings) => {
|
||||||
|
return get(instanceSettings, [currentInstance, key], true)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function timelineComputations (store) {
|
export function timelineComputations (store) {
|
||||||
computeForTimeline(store, 'timelineItemSummaries', null)
|
computeForTimeline(store, 'timelineItemSummaries', null)
|
||||||
computeForTimeline(store, 'timelineItemSummariesToAdd', null)
|
computeForTimeline(store, 'timelineItemSummariesToAdd', null)
|
||||||
|
@ -41,11 +75,93 @@ export function timelineComputations (store) {
|
||||||
getLastIdFromItemSummaries(timelineItemSummaries)
|
getLastIdFromItemSummaries(timelineItemSummaries)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
computeTimelineFilter(store, 'timelineShowReblogs', { home: HOME_REBLOGS, notifications: NOTIFICATION_REBLOGS })
|
||||||
|
computeTimelineFilter(store, 'timelineShowReplies', { home: HOME_REPLIES })
|
||||||
|
computeTimelineFilter(store, 'timelineShowFollows', { notifications: NOTIFICATION_FOLLOWS })
|
||||||
|
computeTimelineFilter(store, 'timelineShowFavs', { notifications: NOTIFICATION_FAVORITES })
|
||||||
|
computeTimelineFilter(store, 'timelineShowMentions', { notifications: NOTIFICATION_MENTIONS })
|
||||||
|
computeTimelineFilter(store, 'timelineShowPolls', { notifications: NOTIFICATION_POLLS })
|
||||||
|
|
||||||
|
computeNotificationFilter(store, 'timelineNotificationShowReblogs', NOTIFICATION_REBLOGS)
|
||||||
|
computeNotificationFilter(store, 'timelineNotificationShowFollows', NOTIFICATION_FOLLOWS)
|
||||||
|
computeNotificationFilter(store, 'timelineNotificationShowFavs', NOTIFICATION_FAVORITES)
|
||||||
|
computeNotificationFilter(store, 'timelineNotificationShowMentions', NOTIFICATION_MENTIONS)
|
||||||
|
computeNotificationFilter(store, 'timelineNotificationShowPolls', NOTIFICATION_POLLS)
|
||||||
|
|
||||||
|
function createFilterFunction (showReblogs, showReplies, showFollows, showFavs, showMentions, showPolls) {
|
||||||
|
return item => {
|
||||||
|
switch (item.type) {
|
||||||
|
case 'poll':
|
||||||
|
return showPolls
|
||||||
|
case 'favourite':
|
||||||
|
return showFavs
|
||||||
|
case 'reblog':
|
||||||
|
return showReblogs
|
||||||
|
case 'mention':
|
||||||
|
return showMentions
|
||||||
|
case 'follow':
|
||||||
|
return showFollows
|
||||||
|
}
|
||||||
|
if (item.reblogId) {
|
||||||
|
return showReblogs
|
||||||
|
} else if (item.replyId) {
|
||||||
|
return showReplies
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
store.compute(
|
||||||
|
'timelineFilterFunction',
|
||||||
|
[
|
||||||
|
'timelineShowReblogs', 'timelineShowReplies', 'timelineShowFollows',
|
||||||
|
'timelineShowFavs', 'timelineShowMentions', 'timelineShowPolls'
|
||||||
|
],
|
||||||
|
(showReblogs, showReplies, showFollows, showFavs, showMentions, showPolls) => (
|
||||||
|
createFilterFunction(showReblogs, showReplies, showFollows, showFavs, showMentions, showPolls)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
store.compute(
|
||||||
|
'timelineNotificationFilterFunction',
|
||||||
|
[
|
||||||
|
'timelineNotificationShowReblogs', 'timelineNotificationShowFollows',
|
||||||
|
'timelineNotificationShowFavs', 'timelineNotificationShowMentions',
|
||||||
|
'timelineNotificationShowPolls'
|
||||||
|
],
|
||||||
|
(showReblogs, showFollows, showFavs, showMentions, showPolls) => (
|
||||||
|
createFilterFunction(showReblogs, true, showFollows, showFavs, showMentions, showPolls)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
store.compute(
|
||||||
|
'filteredTimelineItemSummaries',
|
||||||
|
['timelineItemSummaries', 'timelineFilterFunction'],
|
||||||
|
(timelineItemSummaries, timelineFilterFunction) => {
|
||||||
|
return timelineItemSummaries && timelineItemSummaries.filter(timelineFilterFunction)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
store.compute('timelineNotificationItemSummaries',
|
||||||
|
[`timelineData_timelineItemSummariesToAdd`, 'timelineFilterFunction', 'currentInstance'],
|
||||||
|
(root, timelineFilterFunction, currentInstance) => (
|
||||||
|
get(root, [currentInstance, 'notifications'])
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
store.compute(
|
||||||
|
'filteredTimelineNotificationItemSummaries',
|
||||||
|
['timelineNotificationItemSummaries', 'timelineNotificationFilterFunction'],
|
||||||
|
(timelineNotificationItemSummaries, timelineNotificationFilterFunction) => (
|
||||||
|
timelineNotificationItemSummaries && timelineNotificationItemSummaries.filter(timelineNotificationFilterFunction)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
store.compute('numberOfNotifications',
|
store.compute('numberOfNotifications',
|
||||||
[`timelineData_timelineItemSummariesToAdd`, 'currentInstance'],
|
['filteredTimelineNotificationItemSummaries'],
|
||||||
(root, currentInstance) => (
|
(filteredTimelineNotificationItemSummaries) => (
|
||||||
(root && root[currentInstance] && root[currentInstance].notifications &&
|
filteredTimelineNotificationItemSummaries ? filteredTimelineNotificationItemSummaries.length : 0
|
||||||
root[currentInstance].notifications.length) || 0
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
93
tests/spec/125-notification-timeline-filters.js
Normal file
93
tests/spec/125-notification-timeline-filters.js
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
import {
|
||||||
|
settingsNavButton,
|
||||||
|
getNthStatusContent,
|
||||||
|
instanceSettingNotificationReblogs,
|
||||||
|
notificationBadge,
|
||||||
|
instanceSettingNotificationFavs,
|
||||||
|
instanceSettingNotificationMentions, instanceSettingNotificationFollows
|
||||||
|
} from '../utils'
|
||||||
|
import { loginAsFoobar } from '../roles'
|
||||||
|
import { Selector as $ } from 'testcafe'
|
||||||
|
import { favoriteStatusAs, followAs, postAs, reblogStatusAs, unfollowAs } from '../serverActions'
|
||||||
|
|
||||||
|
fixture`125-notification-timeline-filters.js`
|
||||||
|
.page`http://localhost:4002`
|
||||||
|
|
||||||
|
test('Notification timeline filters correctly affect counts - boosts', async t => {
|
||||||
|
let timeout = 20000
|
||||||
|
let { id: statusId } = await postAs('foobar', 'I do not care if you boost this')
|
||||||
|
await loginAsFoobar(t)
|
||||||
|
await t
|
||||||
|
.expect(getNthStatusContent(1).innerText).contains('I do not care if you boost this')
|
||||||
|
await reblogStatusAs('admin', statusId)
|
||||||
|
await t
|
||||||
|
.expect(notificationBadge.innerText).eql('1', { timeout })
|
||||||
|
.click(settingsNavButton)
|
||||||
|
.click($('a').withText('Instances'))
|
||||||
|
.click($('a').withText('localhost:3000'))
|
||||||
|
.click(instanceSettingNotificationReblogs)
|
||||||
|
.expect(instanceSettingNotificationReblogs.checked).notOk()
|
||||||
|
.expect(notificationBadge.exists).notOk({ timeout })
|
||||||
|
.click(instanceSettingNotificationReblogs)
|
||||||
|
.expect(instanceSettingNotificationReblogs.checked).ok()
|
||||||
|
.expect(notificationBadge.innerText).eql('1', { timeout })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Notification timeline filters correctly affect counts - favs', async t => {
|
||||||
|
let timeout = 20000
|
||||||
|
let { id: statusId } = await postAs('foobar', 'I do not care if you fav this')
|
||||||
|
await loginAsFoobar(t)
|
||||||
|
await t
|
||||||
|
.expect(getNthStatusContent(1).innerText).contains('I do not care if you fav this')
|
||||||
|
await favoriteStatusAs('admin', statusId)
|
||||||
|
await t
|
||||||
|
.expect(notificationBadge.innerText).eql('1', { timeout })
|
||||||
|
.click(settingsNavButton)
|
||||||
|
.click($('a').withText('Instances'))
|
||||||
|
.click($('a').withText('localhost:3000'))
|
||||||
|
.click(instanceSettingNotificationFavs)
|
||||||
|
.expect(instanceSettingNotificationFavs.checked).notOk()
|
||||||
|
.expect(notificationBadge.exists).notOk({ timeout })
|
||||||
|
.click(instanceSettingNotificationFavs)
|
||||||
|
.expect(instanceSettingNotificationFavs.checked).ok()
|
||||||
|
.expect(notificationBadge.innerText).eql('1', { timeout })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Notification timeline filters correctly affect counts - favs', async t => {
|
||||||
|
let timeout = 20000
|
||||||
|
await loginAsFoobar(t)
|
||||||
|
await t
|
||||||
|
.expect(getNthStatusContent(1).exists).ok()
|
||||||
|
await postAs('admin', 'hey yo @foobar')
|
||||||
|
await t
|
||||||
|
.expect(notificationBadge.innerText).eql('1', { timeout })
|
||||||
|
.click(settingsNavButton)
|
||||||
|
.click($('a').withText('Instances'))
|
||||||
|
.click($('a').withText('localhost:3000'))
|
||||||
|
.click(instanceSettingNotificationMentions)
|
||||||
|
.expect(instanceSettingNotificationMentions.checked).notOk()
|
||||||
|
.expect(notificationBadge.exists).notOk({ timeout })
|
||||||
|
.click(instanceSettingNotificationMentions)
|
||||||
|
.expect(instanceSettingNotificationMentions.checked).ok()
|
||||||
|
.expect(notificationBadge.innerText).eql('1', { timeout })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Notification timeline filters correctly affect counts - follows', async t => {
|
||||||
|
let timeout = 20000
|
||||||
|
await loginAsFoobar(t)
|
||||||
|
await t
|
||||||
|
.expect(getNthStatusContent(1).exists).ok()
|
||||||
|
await followAs('ExternalLinks', 'foobar')
|
||||||
|
await t
|
||||||
|
.expect(notificationBadge.innerText).eql('1', { timeout })
|
||||||
|
.click(settingsNavButton)
|
||||||
|
.click($('a').withText('Instances'))
|
||||||
|
.click($('a').withText('localhost:3000'))
|
||||||
|
.click(instanceSettingNotificationFollows)
|
||||||
|
.expect(instanceSettingNotificationFollows.checked).notOk()
|
||||||
|
.expect(notificationBadge.exists).notOk({ timeout })
|
||||||
|
.click(instanceSettingNotificationFollows)
|
||||||
|
.expect(instanceSettingNotificationMentions.checked).ok()
|
||||||
|
.expect(notificationBadge.innerText).eql('1', { timeout })
|
||||||
|
await unfollowAs('ExternalLinks', 'foobar')
|
||||||
|
})
|
|
@ -73,6 +73,8 @@ export const instanceSettingNotificationFavs = $('#instance-option-notificationF
|
||||||
export const instanceSettingNotificationReblogs = $('#instance-option-notificationReblogs')
|
export const instanceSettingNotificationReblogs = $('#instance-option-notificationReblogs')
|
||||||
export const instanceSettingNotificationMentions = $('#instance-option-notificationMentions')
|
export const instanceSettingNotificationMentions = $('#instance-option-notificationMentions')
|
||||||
|
|
||||||
|
export const notificationBadge = $('#main-nav li:nth-child(2) .nav-link-badge')
|
||||||
|
|
||||||
export function getComposeModalNthMediaAltInput (n) {
|
export function getComposeModalNthMediaAltInput (n) {
|
||||||
return $(`.modal-dialog .compose-media:nth-child(${n}) .compose-media-alt input`)
|
return $(`.modal-dialog .compose-media:nth-child(${n}) .compose-media-alt input`)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue