fix: fix bell notifications, add tests
This commit is contained in:
parent
2e9afd711f
commit
c67be9acc2
|
@ -1,6 +1,7 @@
|
|||
export default [
|
||||
{ id: 'pinafore-logo', src: 'src/static/sailboat.svg', inline: true },
|
||||
{ id: 'fa-bell', src: 'src/thirdparty/font-awesome-svg-png/white/svg/bell.svg', inline: true },
|
||||
{ id: 'fa-bell-o', src: 'src/thirdparty/font-awesome-svg-png/white/svg/bell-o.svg' },
|
||||
{ id: 'fa-users', src: 'src/thirdparty/font-awesome-svg-png/white/svg/users.svg', inline: true },
|
||||
{ id: 'fa-globe', src: 'src/thirdparty/font-awesome-svg-png/white/svg/globe.svg' },
|
||||
{ id: 'fa-gear', src: 'src/thirdparty/font-awesome-svg-png/white/svg/gear.svg', inline: true },
|
||||
|
@ -22,6 +23,7 @@ export default [
|
|||
{ id: 'fa-user-plus', src: 'src/thirdparty/font-awesome-svg-png/white/svg/user-plus.svg' },
|
||||
{ id: 'fa-external-link', src: 'src/thirdparty/font-awesome-svg-png/white/svg/external-link.svg' },
|
||||
{ id: 'fa-search', src: 'src/thirdparty/font-awesome-svg-png/white/svg/search.svg', inline: true },
|
||||
{ id: 'fa-comment', src: 'src/thirdparty/font-awesome-svg-png/white/svg/comment.svg' },
|
||||
{ id: 'fa-comments', src: 'src/thirdparty/font-awesome-svg-png/white/svg/comments.svg', inline: true },
|
||||
{ id: 'fa-paperclip', src: 'src/thirdparty/font-awesome-svg-png/white/svg/paperclip.svg' },
|
||||
{ id: 'fa-thumb-tack', src: 'src/thirdparty/font-awesome-svg-png/white/svg/thumb-tack.svg' },
|
||||
|
|
|
@ -309,10 +309,10 @@ export default {
|
|||
true {(follow requested)}
|
||||
other {}
|
||||
}`,
|
||||
notifyLabel: `Subscribe`,
|
||||
denotifyLabel: `Unsubscribe`,
|
||||
notify: 'Subscribe to {account}',
|
||||
denotify: 'Unsubscribe from {account}',
|
||||
subscribedAccount: 'Subscribed to account',
|
||||
unsubscribedAccount: 'Unsubscribed to account',
|
||||
unsubscribedAccount: 'Unsubscribed from account',
|
||||
unblock: 'Unblock',
|
||||
nameAndFollowing: 'Name and following',
|
||||
clickToSeeAvatar: 'Click to see avatar',
|
||||
|
@ -474,6 +474,7 @@ export default {
|
|||
newFollowers: 'New followers',
|
||||
reblogs: 'Boosts',
|
||||
pollResults: 'Poll results',
|
||||
subscriptions: 'Subscribed toots',
|
||||
needToReauthenticate: 'You need to reauthenticate in order to enable push notification. Log out of {instance}?',
|
||||
failedToUpdatePush: 'Failed to update push notification settings: {error}',
|
||||
// Themes
|
||||
|
@ -508,6 +509,7 @@ export default {
|
|||
rebloggedYou: 'boosted your toot',
|
||||
favoritedYou: 'favorited your toot',
|
||||
followedYou: 'followed you',
|
||||
posted: 'posted',
|
||||
pollYouCreatedEnded: 'A poll you created has ended',
|
||||
pollYouVotedEnded: 'A poll you voted on has ended',
|
||||
reblogged: 'boosted',
|
||||
|
|
|
@ -4,7 +4,7 @@ import { toast } from '../_components/toast/toast.js'
|
|||
import { updateLocalRelationship } from './accounts.js'
|
||||
import { formatIntl } from '../_utils/formatIntl.js'
|
||||
|
||||
export async function setAccountNotify (accountId, notify, toastOnSuccess) {
|
||||
export async function setAccountNotified (accountId, notify, toastOnSuccess) {
|
||||
const { currentInstance, accessToken } = store.get()
|
||||
try {
|
||||
let relationship
|
||||
|
@ -15,11 +15,11 @@ export async function setAccountNotify (accountId, notify, toastOnSuccess) {
|
|||
}
|
||||
await updateLocalRelationship(currentInstance, accountId, relationship)
|
||||
if (toastOnSuccess) {
|
||||
/* no await */ toast.say(follow ? 'intl.subscribedAccount' : 'intl.unsubscribedAccount')
|
||||
/* no await */ toast.say(notify ? 'intl.subscribedAccount' : 'intl.unsubscribedAccount')
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
/* no await */ toast.say(follow
|
||||
/* no await */ toast.say(notify
|
||||
? formatIntl('intl.unableToSubscribe', { error: (e.message || '') })
|
||||
: formatIntl('intl.unableToUnsubscribe', { error: (e.message || '') })
|
||||
)
|
|
@ -4,13 +4,13 @@ import { auth, basename } from './utils.js'
|
|||
export async function notifyAccount (instanceName, accessToken, accountId) {
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/${accountId}/follow`
|
||||
return post(url, {
|
||||
"notify": true,
|
||||
notify: true
|
||||
}, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
||||
export async function denotifyAccount (instanceName, accessToken, accountId) {
|
||||
const url = `${basename(instanceName)}/api/v1/accounts/${accountId}/follow`
|
||||
return post(url, {
|
||||
"notify": false
|
||||
notify: false
|
||||
}, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import { composeNewStatusMentioning } from '../../../_actions/mention.js'
|
|||
import { toggleMute } from '../../../_actions/toggleMute.js'
|
||||
import { reportStatusOrAccount } from '../../../_actions/report.js'
|
||||
import { formatIntl } from '../../../_utils/formatIntl.js'
|
||||
import { setAccountNotified } from '../../../_actions/setAccountNotified.js'
|
||||
|
||||
export default {
|
||||
oncreate,
|
||||
|
@ -39,6 +40,7 @@ export default {
|
|||
username: ({ account }) => account.username,
|
||||
muting: ({ relationship }) => relationship && relationship.muting,
|
||||
blocking: ({ relationship }) => relationship && relationship.blocking,
|
||||
notifying: ({ relationship }) => relationship && relationship.notifying,
|
||||
followLabel: ({ following, followRequested, account, username }) => {
|
||||
if (typeof following === 'undefined' || !account) {
|
||||
return ''
|
||||
|
@ -86,7 +88,7 @@ export default {
|
|||
blockLabel, blocking, blockIcon, muteLabel, muteIcon,
|
||||
followLabel, followIcon, following, followRequested,
|
||||
accountId, verifyCredentialsId, username, isUser, showReblogsLabel,
|
||||
domain, blockDomainLabel, reportLabel
|
||||
domain, blockDomainLabel, reportLabel, notifying
|
||||
}) => ([
|
||||
!isUser && {
|
||||
key: 'mention',
|
||||
|
@ -98,6 +100,16 @@ export default {
|
|||
label: followLabel,
|
||||
icon: followIcon
|
||||
},
|
||||
!isUser && following && notifying === false && { // notifying could be undefined for old servers
|
||||
key: 'notify',
|
||||
label: formatIntl('intl.notify', { account: `@${username}` }),
|
||||
icon: '#fa-bell'
|
||||
},
|
||||
!isUser && following && notifying === true && { // notifying could be undefined for old servers
|
||||
key: 'denotify',
|
||||
label: formatIntl('intl.denotify', { account: `@${username}` }),
|
||||
icon: '#fa-bell-o'
|
||||
},
|
||||
!isUser && {
|
||||
key: 'block',
|
||||
label: blockLabel,
|
||||
|
@ -151,6 +163,10 @@ export default {
|
|||
return this.onCopyClicked()
|
||||
case 'report':
|
||||
return this.onReport()
|
||||
case 'notify':
|
||||
return this.onNotifyClicked()
|
||||
case 'denotify':
|
||||
return this.onDenotifyClicked()
|
||||
}
|
||||
},
|
||||
async onMentionClicked () {
|
||||
|
@ -193,6 +209,16 @@ export default {
|
|||
const { account } = this.get()
|
||||
this.close()
|
||||
await reportStatusOrAccount({ account })
|
||||
},
|
||||
async onNotifyClicked () {
|
||||
const { accountId } = this.get()
|
||||
this.close()
|
||||
await setAccountNotified(accountId, /* notify */ true, /* toastOnSuccess */ true)
|
||||
},
|
||||
async onDenotifyClicked () {
|
||||
const { accountId } = this.get()
|
||||
this.close()
|
||||
await setAccountNotified(accountId, /* notify */ false, /* toastOnSuccess */ true)
|
||||
}
|
||||
},
|
||||
components: {
|
||||
|
|
|
@ -26,6 +26,7 @@ import { shareStatus } from '../../../_actions/share.js'
|
|||
import { toggleMute } from '../../../_actions/toggleMute.js'
|
||||
import { reportStatusOrAccount } from '../../../_actions/report.js'
|
||||
import { formatIntl } from '../../../_utils/formatIntl.js'
|
||||
import { setAccountNotified } from '../../../_actions/setAccountNotified.js'
|
||||
|
||||
export default {
|
||||
oncreate,
|
||||
|
@ -53,6 +54,7 @@ export default {
|
|||
username: ({ account }) => account.username,
|
||||
muting: ({ relationship }) => relationship.muting,
|
||||
blocking: ({ relationship }) => relationship.blocking,
|
||||
notifying: ({ relationship }) => relationship && relationship.notifying,
|
||||
followLabel: ({ following, followRequested, account, username }) => {
|
||||
if (typeof following === 'undefined' || !account) {
|
||||
return ''
|
||||
|
@ -96,7 +98,8 @@ export default {
|
|||
items: ({
|
||||
blockLabel, blocking, blockIcon, muteLabel, muteIcon, followLabel, followIcon,
|
||||
following, followRequested, pinLabel, isUser, visibility, mentionsUser, mutingConversation,
|
||||
muteConversationLabel, muteConversationIcon, supportsWebShare, isPublicOrUnlisted, bookmarkLabel
|
||||
muteConversationLabel, muteConversationIcon, supportsWebShare, isPublicOrUnlisted, bookmarkLabel,
|
||||
username, notifying
|
||||
}) => ([
|
||||
isUser && {
|
||||
key: 'delete',
|
||||
|
@ -113,6 +116,16 @@ export default {
|
|||
label: followLabel,
|
||||
icon: followIcon
|
||||
},
|
||||
!isUser && following && notifying === false && { // notifying could be undefined for old servers
|
||||
key: 'notify',
|
||||
label: formatIntl('intl.notify', { account: `@${username}` }),
|
||||
icon: '#fa-bell'
|
||||
},
|
||||
!isUser && following && notifying === true && { // notifying could be undefined for old servers
|
||||
key: 'denotify',
|
||||
label: formatIntl('intl.denotify', { account: `@${username}` }),
|
||||
icon: '#fa-bell-o'
|
||||
},
|
||||
!isUser && {
|
||||
key: 'block',
|
||||
label: blockLabel,
|
||||
|
@ -187,6 +200,10 @@ export default {
|
|||
return this.onReport()
|
||||
case 'bookmark':
|
||||
return this.onBookmark()
|
||||
case 'notify':
|
||||
return this.onNotifyClicked()
|
||||
case 'denotify':
|
||||
return this.onDenotifyClicked()
|
||||
}
|
||||
},
|
||||
async onDeleteClicked () {
|
||||
|
@ -244,6 +261,16 @@ export default {
|
|||
const { status } = this.get()
|
||||
this.close()
|
||||
await setStatusBookmarkedOrUnbookmarked(status.id, !status.bookmarked)
|
||||
},
|
||||
async onNotifyClicked () {
|
||||
const { accountId } = this.get()
|
||||
this.close()
|
||||
await setAccountNotified(accountId, /* notify */ true, /* toastOnSuccess */ true)
|
||||
},
|
||||
async onDenotifyClicked () {
|
||||
const { accountId } = this.get()
|
||||
this.close()
|
||||
await setAccountNotified(accountId, /* notify */ false, /* toastOnSuccess */ true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
<div class="account-profile-grid-wrapper">
|
||||
<div class="account-profile-grid">
|
||||
<AccountProfileHeader {account} {relationship} {verifyCredentials} />
|
||||
<AccountProfileNotify {account} {relationship} {verifyCredentials} />
|
||||
<AccountProfileFollow {account} {relationship} {verifyCredentials} />
|
||||
<AccountProfileNote {account} />
|
||||
<AccountProfileMeta {account} />
|
||||
|
@ -38,7 +37,7 @@
|
|||
display: grid;
|
||||
grid-template-areas: "avatar name label followed-by follow"
|
||||
"avatar username username username follow"
|
||||
"avatar note note note notify"
|
||||
"avatar note note note follow"
|
||||
"meta meta meta meta meta"
|
||||
"details details details details details";
|
||||
grid-template-columns: min-content auto 1fr 1fr min-content;
|
||||
|
@ -72,7 +71,7 @@
|
|||
grid-template-areas: "avatar name follow"
|
||||
"avatar label follow"
|
||||
"avatar username follow"
|
||||
"avatar followed-by notify"
|
||||
"avatar followed-by follow"
|
||||
"note note note"
|
||||
"meta meta meta"
|
||||
"details details details";
|
||||
|
@ -98,7 +97,6 @@
|
|||
"username username"
|
||||
"followed-by followed-by"
|
||||
"follow follow"
|
||||
"notify notify"
|
||||
"note note"
|
||||
"meta meta"
|
||||
"details details";
|
||||
|
@ -110,7 +108,6 @@
|
|||
</style>
|
||||
<script>
|
||||
import AccountProfileHeader from './AccountProfileHeader.html'
|
||||
import AccountProfileNotify from './AccountProfileNotify.html'
|
||||
import AccountProfileFollow from './AccountProfileFollow.html'
|
||||
import AccountProfileNote from './AccountProfileNote.html'
|
||||
import AccountProfileMeta from './AccountProfileMeta.html'
|
||||
|
@ -147,7 +144,6 @@
|
|||
AccountProfileHeader,
|
||||
AccountProfileFollow,
|
||||
AccountProfileNote,
|
||||
AccountProfileNotify,
|
||||
AccountProfileMeta,
|
||||
AccountProfileDetails,
|
||||
AccountProfileMovedBanner,
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
<div class="account-profile-notify {shown ? 'shown' : ''}">
|
||||
<!--
|
||||
The bell notification button (Mastodon 3.3+)
|
||||
Shows if we're getting notifications or not.
|
||||
It is not possible to turn on notifications for accounts you don't follow.
|
||||
Also the instance can just have no support for this feature.
|
||||
-->
|
||||
<IconButton
|
||||
className="account-profile-notify-icon-button"
|
||||
{label}
|
||||
pressedLabel="{intl.denotifyLabel}"
|
||||
{href}
|
||||
big={!$isVeryTinyMobileSize}
|
||||
on:click="onNotifyButtonClick(event)"
|
||||
ref:icon
|
||||
/>
|
||||
</div>
|
||||
<style>
|
||||
.account-profile-notify {
|
||||
grid-area: notify;
|
||||
align-self: flex-start;
|
||||
display: none;
|
||||
}
|
||||
.account-profile-notify.shown {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (max-width: 240px) {
|
||||
.account-profile-notify {
|
||||
justify-self: flex-end;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import IconButton from '../IconButton.html'
|
||||
import { FOLLOW_BUTTON_ANIMATION } from '../../_static/animations.js'
|
||||
import { store } from '../../_store/store.js'
|
||||
import { setAccountNotify } from '../../_actions/notify.js'
|
||||
import { formatIntl } from '../../_utils/formatIntl.js'
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
oncreate () {
|
||||
if (process.browser) {
|
||||
window.__button = this
|
||||
}
|
||||
},
|
||||
async onNotifyButtonClick (e) {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
const {
|
||||
account,
|
||||
accountId,
|
||||
notifying
|
||||
} = this.get()
|
||||
if (notifying) { // unblock
|
||||
await setAccountNotify(accountId, false)
|
||||
} else { // follow/unfollow
|
||||
this.refs.icon.animate(FOLLOW_BUTTON_ANIMATION)
|
||||
await setAccountNotify(accountId, true)
|
||||
}
|
||||
}
|
||||
},
|
||||
store: () => store,
|
||||
data: () => ({
|
||||
}),
|
||||
computed: {
|
||||
accountId: ({ account }) => account.id,
|
||||
notifying: ({ relationship }) => {
|
||||
return relationship && relationship.notifying
|
||||
},
|
||||
href: ({ notifying }) => {
|
||||
if (notifying) {
|
||||
return '#fa-bell-ringing'
|
||||
}
|
||||
return '#fa-bell-o'
|
||||
},
|
||||
label: ({ notifying }) => {
|
||||
if (notifying) {
|
||||
return formatIntl('intl.notifyLabel')
|
||||
}
|
||||
return formatIntl('intl.denotifyLabel')
|
||||
},
|
||||
shown: ({ verifyCredentials, relationship }) => (
|
||||
verifyCredentials && relationship && verifyCredentials.id !== relationship.id && relationship.following
|
||||
),
|
||||
},
|
||||
components: {
|
||||
IconButton
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -10,7 +10,8 @@
|
|||
NOTIFICATION_FAVORITES,
|
||||
NOTIFICATION_FOLLOWS,
|
||||
NOTIFICATION_MENTIONS,
|
||||
NOTIFICATION_POLLS
|
||||
NOTIFICATION_POLLS,
|
||||
NOTIFICATION_SUBSCRIPTIONS
|
||||
} from '../../../_static/instanceSettings.js'
|
||||
|
||||
export default {
|
||||
|
@ -40,6 +41,11 @@
|
|||
key: NOTIFICATION_POLLS,
|
||||
label: 'intl.pollResults',
|
||||
defaultValue: true
|
||||
},
|
||||
{
|
||||
key: NOTIFICATION_SUBSCRIPTIONS,
|
||||
label: 'intl.subscriptions',
|
||||
defaultValue: true
|
||||
}
|
||||
]
|
||||
}),
|
||||
|
|
|
@ -76,6 +76,10 @@
|
|||
{
|
||||
key: 'poll',
|
||||
label: 'intl.pollResults'
|
||||
},
|
||||
{
|
||||
key: 'status',
|
||||
label: 'intl.subscriptions'
|
||||
}
|
||||
]
|
||||
}),
|
||||
|
|
|
@ -295,7 +295,7 @@
|
|||
)
|
||||
),
|
||||
showHeader: ({ notification, status, timelineType }) => (
|
||||
(notification && ['reblog', 'favourite', 'poll'].includes(notification.type)) ||
|
||||
(notification && ['reblog', 'favourite', 'poll', 'status'].includes(notification.type)) ||
|
||||
status.reblog ||
|
||||
timelineType === 'pinned'
|
||||
),
|
||||
|
|
|
@ -125,6 +125,8 @@
|
|||
return '#fa-user-plus'
|
||||
} else if (notificationType === 'poll') {
|
||||
return '#fa-bar-chart'
|
||||
} else if (notificationType === 'status') {
|
||||
return '#fa-comment'
|
||||
}
|
||||
return '#fa-star'
|
||||
},
|
||||
|
@ -135,6 +137,8 @@
|
|||
return 'intl.favoritedYou'
|
||||
} else if (notificationType === 'follow') {
|
||||
return 'intl.followedYou'
|
||||
} else if (notificationType === 'status') {
|
||||
return 'intl.posted'
|
||||
} else if (notificationType === 'poll') {
|
||||
if ($currentVerifyCredentials && status && $currentVerifyCredentials.id === status.account.id) {
|
||||
return 'intl.pollYouCreatedEnded'
|
||||
|
|
|
@ -6,3 +6,4 @@ export const NOTIFICATION_FAVORITES = 'notificationFavs'
|
|||
export const NOTIFICATION_FOLLOWS = 'notificationFollows'
|
||||
export const NOTIFICATION_MENTIONS = 'notificationMentions'
|
||||
export const NOTIFICATION_POLLS = 'notificationPolls'
|
||||
export const NOTIFICATION_SUBSCRIPTIONS = 'notificationSubscriptions'
|
||||
|
|
|
@ -3,7 +3,7 @@ import {
|
|||
HOME_REPLIES,
|
||||
NOTIFICATION_FAVORITES,
|
||||
NOTIFICATION_FOLLOWS, NOTIFICATION_MENTIONS, NOTIFICATION_POLLS,
|
||||
NOTIFICATION_REBLOGS
|
||||
NOTIFICATION_REBLOGS, NOTIFICATION_SUBSCRIPTIONS
|
||||
} from '../../_static/instanceSettings.js'
|
||||
import {
|
||||
WORD_FILTER_CONTEXT_ACCOUNT,
|
||||
|
@ -46,12 +46,14 @@ export function timelineFilterComputations (store) {
|
|||
computeTimelineFilter(store, 'timelineShowFavs', { notifications: NOTIFICATION_FAVORITES })
|
||||
computeTimelineFilter(store, 'timelineShowMentions', { notifications: NOTIFICATION_MENTIONS })
|
||||
computeTimelineFilter(store, 'timelineShowPolls', { notifications: NOTIFICATION_POLLS })
|
||||
computeTimelineFilter(store, 'timelineShowSubscriptions', { notifications: NOTIFICATION_SUBSCRIPTIONS })
|
||||
|
||||
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)
|
||||
computeNotificationFilter(store, 'timelineNotificationShowSubscriptions', NOTIFICATION_SUBSCRIPTIONS)
|
||||
|
||||
store.compute(
|
||||
'timelineWordFilterContext',
|
||||
|
@ -85,10 +87,10 @@ export function timelineFilterComputations (store) {
|
|||
[
|
||||
'timelineShowReblogs', 'timelineShowReplies', 'timelineShowFollows',
|
||||
'timelineShowFavs', 'timelineShowMentions', 'timelineShowPolls',
|
||||
'timelineWordFilterContext'
|
||||
'timelineShowSubscriptions', 'timelineWordFilterContext'
|
||||
],
|
||||
(showReblogs, showReplies, showFollows, showFavs, showMentions, showPolls, wordFilterContext) => (
|
||||
createFilterFunction(showReblogs, showReplies, showFollows, showFavs, showMentions, showPolls, wordFilterContext)
|
||||
(showReblogs, showReplies, showFollows, showFavs, showMentions, showPolls, showSubscriptions, wordFilterContext) => (
|
||||
createFilterFunction(showReblogs, showReplies, showFollows, showFavs, showMentions, showPolls, showSubscriptions, wordFilterContext)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -99,10 +101,10 @@ export function timelineFilterComputations (store) {
|
|||
[
|
||||
'timelineNotificationShowReblogs', 'timelineNotificationShowFollows',
|
||||
'timelineNotificationShowFavs', 'timelineNotificationShowMentions',
|
||||
'timelineNotificationShowPolls'
|
||||
'timelineNotificationShowPolls', 'timelineNotificationShowSubscriptions'
|
||||
],
|
||||
(showReblogs, showFollows, showFavs, showMentions, showPolls) => (
|
||||
createFilterFunction(showReblogs, true, showFollows, showFavs, showMentions, showPolls, WORD_FILTER_CONTEXT_NOTIFICATIONS)
|
||||
(showReblogs, showFollows, showFavs, showMentions, showPolls, showSubscriptions) => (
|
||||
createFilterFunction(showReblogs, true, showFollows, showFavs, showMentions, showPolls, showSubscriptions, WORD_FILTER_CONTEXT_NOTIFICATIONS)
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// create a function for filtering timeline item summaries
|
||||
|
||||
export const createFilterFunction = (
|
||||
showReblogs, showReplies, showFollows, showFavs, showMentions, showPolls, wordFilterContext
|
||||
showReblogs, showReplies, showFollows, showFavs, showMentions, showPolls,
|
||||
showSubscriptions, wordFilterContext
|
||||
) => {
|
||||
return item => {
|
||||
if (item.filterContexts && item.filterContexts.includes(wordFilterContext)) {
|
||||
|
@ -19,6 +20,8 @@ export const createFilterFunction = (
|
|||
return showMentions
|
||||
case 'follow':
|
||||
return showFollows
|
||||
case 'status':
|
||||
return showSubscriptions
|
||||
}
|
||||
if (item.reblogId) {
|
||||
return showReblogs
|
||||
|
|
|
@ -214,6 +214,7 @@ async function showRichNotification (data, notification) {
|
|||
}
|
||||
case 'reblog':
|
||||
case 'favourite':
|
||||
case 'status':
|
||||
case 'poll': {
|
||||
await self.registration.showNotification(data.title, {
|
||||
badge,
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
import { favoriteStatus } from '../src/routes/_api/favorite'
|
||||
import { favoriteStatus } from '../src/routes/_api/favorite.js'
|
||||
import fetch from 'node-fetch'
|
||||
import FileApi from 'file-api'
|
||||
import { users } from './users'
|
||||
import { postStatus } from '../src/routes/_api/statuses'
|
||||
import { deleteStatus } from '../src/routes/_api/delete'
|
||||
import { authorizeFollowRequest, getFollowRequests } from '../src/routes/_api/followRequests'
|
||||
import { followAccount, unfollowAccount } from '../src/routes/_api/follow'
|
||||
import { updateCredentials } from '../src/routes/_api/updateCredentials'
|
||||
import { reblogStatus } from '../src/routes/_api/reblog'
|
||||
import { users } from './users.js'
|
||||
import { postStatus } from '../src/routes/_api/statuses.js'
|
||||
import { deleteStatus } from '../src/routes/_api/delete.js'
|
||||
import { authorizeFollowRequest, getFollowRequests } from '../src/routes/_api/followRequests.js'
|
||||
import { followAccount, unfollowAccount } from '../src/routes/_api/follow.js'
|
||||
import { updateCredentials } from '../src/routes/_api/updateCredentials.js'
|
||||
import { reblogStatus } from '../src/routes/_api/reblog.js'
|
||||
import { submitMedia } from './submitMedia.js'
|
||||
import { voteOnPoll } from '../src/routes/_api/polls'
|
||||
import { POLL_EXPIRY_DEFAULT } from '../src/routes/_static/polls'
|
||||
import { createList, getLists } from '../src/routes/_api/lists'
|
||||
import { createFilter, deleteFilter, getFilters } from '../src/routes/_api/filters'
|
||||
import { voteOnPoll } from '../src/routes/_api/polls.js'
|
||||
import { POLL_EXPIRY_DEFAULT } from '../src/routes/_static/polls.js'
|
||||
import { createList, getLists } from '../src/routes/_api/lists.js'
|
||||
import { createFilter, deleteFilter, getFilters } from '../src/routes/_api/filters.js'
|
||||
|
||||
global.fetch = fetch
|
||||
global.File = FileApi.File
|
||||
|
|
|
@ -2,7 +2,7 @@ import {
|
|||
accountProfileFollowButton,
|
||||
accountProfileFollowedBy, accountProfileMoreOptionsButton, communityNavButton, getNthSearchResult,
|
||||
getNthStatus, getNthStatusOptionsButton, getNthDialogOptionsOption, getUrl, modalDialog,
|
||||
sleep
|
||||
sleep, getDialogOptionWithText
|
||||
} from '../utils'
|
||||
import { Selector as $ } from 'testcafe'
|
||||
import { loginAsFoobar } from '../roles'
|
||||
|
@ -21,10 +21,10 @@ test('Can block and unblock an account from a status', async t => {
|
|||
await t
|
||||
.click(getNthStatusOptionsButton(1))
|
||||
.expect(getNthDialogOptionsOption(1).innerText).contains('Unfollow @admin')
|
||||
.expect(getNthDialogOptionsOption(2).innerText).contains('Block @admin')
|
||||
.expect(getNthDialogOptionsOption(3).innerText).contains('Block @admin')
|
||||
await sleep(500)
|
||||
await t
|
||||
.click(getNthDialogOptionsOption(2))
|
||||
.click(getDialogOptionWithText('Block @admin'))
|
||||
.expect(modalDialog.exists).notOk()
|
||||
await sleep(500)
|
||||
await t
|
||||
|
@ -60,12 +60,9 @@ test('Can block and unblock an account from the account profile page', async t =
|
|||
await sleep(500)
|
||||
await t
|
||||
.click(accountProfileMoreOptionsButton)
|
||||
.expect(getNthDialogOptionsOption(1).innerText).contains('Mention @baz')
|
||||
.expect(getNthDialogOptionsOption(2).innerText).contains('Follow @baz')
|
||||
.expect(getNthDialogOptionsOption(3).innerText).contains('Block @baz')
|
||||
await sleep(500)
|
||||
await t
|
||||
.click(getNthDialogOptionsOption(3))
|
||||
.click(getDialogOptionWithText('Block @baz'))
|
||||
.expect(accountProfileFollowedBy.innerText).match(/blocked/i)
|
||||
.expect(accountProfileFollowButton.getAttribute('aria-label')).eql('Unblock')
|
||||
.expect(accountProfileFollowButton.getAttribute('title')).eql('Unblock')
|
||||
|
|
|
@ -5,11 +5,10 @@ import {
|
|||
getNthSearchResult,
|
||||
getNthStatus,
|
||||
getNthStatusOptionsButton,
|
||||
getNthDialogOptionsOption,
|
||||
getUrl,
|
||||
modalDialog,
|
||||
closeDialogButton,
|
||||
confirmationDialogOKButton, sleep
|
||||
confirmationDialogOKButton, sleep, getDialogOptionWithText
|
||||
} from '../utils'
|
||||
import { Selector as $ } from 'testcafe'
|
||||
import { loginAsFoobar } from '../roles'
|
||||
|
@ -25,12 +24,9 @@ test('Can mute and unmute an account', async t => {
|
|||
|
||||
await t.expect(getNthStatus(1).innerText).contains(post, { timeout: 20000 })
|
||||
.click(getNthStatusOptionsButton(1))
|
||||
.expect(getNthDialogOptionsOption(1).innerText).contains('Unfollow @admin')
|
||||
.expect(getNthDialogOptionsOption(2).innerText).contains('Block @admin')
|
||||
.expect(getNthDialogOptionsOption(3).innerText).contains('Mute @admin')
|
||||
await sleep(1000)
|
||||
await t
|
||||
.click(getNthDialogOptionsOption(3))
|
||||
.click(getDialogOptionWithText('Mute @admin'))
|
||||
await sleep(1000)
|
||||
await t
|
||||
.click(confirmationDialogOKButton)
|
||||
|
@ -43,20 +39,13 @@ test('Can mute and unmute an account', async t => {
|
|||
.click(getNthSearchResult(1))
|
||||
.expect(getUrl()).contains('/accounts/1')
|
||||
.click(accountProfileMoreOptionsButton)
|
||||
.expect(getNthDialogOptionsOption(1).innerText).contains('Mention @admin')
|
||||
.expect(getNthDialogOptionsOption(2).innerText).contains('Unfollow @admin')
|
||||
.expect(getNthDialogOptionsOption(3).innerText).contains('Block @admin')
|
||||
.expect(getNthDialogOptionsOption(4).innerText).contains('Unmute @admin')
|
||||
await sleep(1000)
|
||||
await t
|
||||
.click(getNthDialogOptionsOption(4))
|
||||
.click(getDialogOptionWithText('Unmute @admin'))
|
||||
await sleep(1000)
|
||||
await t
|
||||
.click(accountProfileMoreOptionsButton)
|
||||
.expect(getNthDialogOptionsOption(1).innerText).contains('Mention @admin')
|
||||
.expect(getNthDialogOptionsOption(2).innerText).contains('Unfollow @admin')
|
||||
.expect(getNthDialogOptionsOption(3).innerText).contains('Block @admin')
|
||||
.expect(getNthDialogOptionsOption(4).innerText).contains('Mute @admin')
|
||||
.expect(getDialogOptionWithText('Mute @admin').exists).ok()
|
||||
await sleep(1000)
|
||||
await t
|
||||
.click(closeDialogButton)
|
||||
|
|
49
tests/spec/139-notify-denotify.js
Normal file
49
tests/spec/139-notify-denotify.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
import {
|
||||
accountProfileMoreOptionsButton,
|
||||
getNthStatus,
|
||||
getNthStatusOptionsButton,
|
||||
getUrl,
|
||||
modalDialog,
|
||||
sleep, getDialogOptionWithText, getNthStatusAccountLink, notificationsNavButton, getNthStatusHeader
|
||||
} from '../utils'
|
||||
import { loginAsFoobar } from '../roles'
|
||||
import { postAs } from '../serverActions'
|
||||
|
||||
fixture`139-notify-denotify.js`
|
||||
.page`http://localhost:4002`
|
||||
|
||||
test('Can notify and denotify an account', async t => {
|
||||
await loginAsFoobar(t)
|
||||
const post = 'ha ha ha'
|
||||
await postAs('admin', post)
|
||||
|
||||
await t.expect(getNthStatus(1).innerText).contains(post, { timeout: 20000 })
|
||||
.click(getNthStatusOptionsButton(1))
|
||||
await sleep(1000)
|
||||
await t.click(getDialogOptionWithText('Subscribe to @admin'))
|
||||
await sleep(1000)
|
||||
await t
|
||||
.expect(modalDialog.exists).notOk()
|
||||
await sleep(1000)
|
||||
const notificationPost = 'get a notification for this'
|
||||
await postAs('admin', notificationPost)
|
||||
await sleep(1000)
|
||||
await t
|
||||
.expect(notificationsNavButton.getAttribute('aria-label')).eql('Notifications (1 notification)', {
|
||||
timeout: 20000
|
||||
})
|
||||
.click(notificationsNavButton)
|
||||
.expect(getUrl()).contains('/notifications')
|
||||
await t
|
||||
.expect(getNthStatus(1).innerText).contains(notificationPost, { timeout: 20000 })
|
||||
.expect(getNthStatusHeader(1).innerText).contains('posted')
|
||||
.click(getNthStatusAccountLink(1))
|
||||
.expect(getUrl()).contains('/accounts/1')
|
||||
.click(accountProfileMoreOptionsButton)
|
||||
await sleep(1000)
|
||||
await t.click(getDialogOptionWithText('Unsubscribe from @admin'))
|
||||
await sleep(1000)
|
||||
await t.click(accountProfileMoreOptionsButton)
|
||||
await t
|
||||
.expect(getDialogOptionWithText('Subscribe to @admin').exists).ok()
|
||||
})
|
|
@ -522,6 +522,10 @@ export function getNthStatusOptionsButton (n) {
|
|||
return $(`${getNthStatusSelector(n)} .status-toolbar button:nth-child(4)`)
|
||||
}
|
||||
|
||||
export function getNthStatusAccountLink (n) {
|
||||
return $(`${getNthStatusSelector(n)} .status-author-name`)
|
||||
}
|
||||
|
||||
export function getNthFavoritedLabel (n) {
|
||||
return getNthFavoriteButton(n).getAttribute('aria-label')
|
||||
}
|
||||
|
@ -546,6 +550,10 @@ export function getNthDialogOptionsOption (n) {
|
|||
return $(`.modal-dialog li:nth-child(${n}) button`)
|
||||
}
|
||||
|
||||
export function getDialogOptionWithText (text) {
|
||||
return $('.modal-dialog li button').withText(text)
|
||||
}
|
||||
|
||||
export function getReblogsCount () {
|
||||
return reblogsCountElement.innerCount
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue