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