parent
54a11778da
commit
2e9afd711f
|
@ -309,6 +309,10 @@ export default {
|
||||||
true {(follow requested)}
|
true {(follow requested)}
|
||||||
other {}
|
other {}
|
||||||
}`,
|
}`,
|
||||||
|
notifyLabel: `Subscribe`,
|
||||||
|
denotifyLabel: `Unsubscribe`,
|
||||||
|
subscribedAccount: 'Subscribed to account',
|
||||||
|
unsubscribedAccount: 'Unsubscribed to account',
|
||||||
unblock: 'Unblock',
|
unblock: 'Unblock',
|
||||||
nameAndFollowing: 'Name and following',
|
nameAndFollowing: 'Name and following',
|
||||||
clickToSeeAvatar: 'Click to see avatar',
|
clickToSeeAvatar: 'Click to see avatar',
|
||||||
|
@ -631,6 +635,8 @@ export default {
|
||||||
unableToShowReblogs: 'Unable to show boosts: {error}',
|
unableToShowReblogs: 'Unable to show boosts: {error}',
|
||||||
unableToHideReblogs: 'Unable to hide boosts: {error}',
|
unableToHideReblogs: 'Unable to hide boosts: {error}',
|
||||||
unableToShare: 'Unable to share: {error}',
|
unableToShare: 'Unable to share: {error}',
|
||||||
|
unableToSubscribe: 'Unable to subscribe: {error}',
|
||||||
|
unableToUnsubscribe: 'Unable to unsubscribe: {error}',
|
||||||
showingOfflineContent: 'Internet request failed. Showing offline content.',
|
showingOfflineContent: 'Internet request failed. Showing offline content.',
|
||||||
youAreOffline: 'You seem to be offline. You can still read toots while offline.',
|
youAreOffline: 'You seem to be offline. You can still read toots while offline.',
|
||||||
// Snackbar UI
|
// Snackbar UI
|
||||||
|
|
27
src/routes/_actions/notify.js
Normal file
27
src/routes/_actions/notify.js
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
import { store } from '../_store/store.js'
|
||||||
|
import { notifyAccount, denotifyAccount } from '../_api/notify.js'
|
||||||
|
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) {
|
||||||
|
const { currentInstance, accessToken } = store.get()
|
||||||
|
try {
|
||||||
|
let relationship
|
||||||
|
if (notify) {
|
||||||
|
relationship = await notifyAccount(currentInstance, accessToken, accountId)
|
||||||
|
} else {
|
||||||
|
relationship = await denotifyAccount(currentInstance, accessToken, accountId)
|
||||||
|
}
|
||||||
|
await updateLocalRelationship(currentInstance, accountId, relationship)
|
||||||
|
if (toastOnSuccess) {
|
||||||
|
/* no await */ toast.say(follow ? 'intl.subscribedAccount' : 'intl.unsubscribedAccount')
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
/* no await */ toast.say(follow
|
||||||
|
? formatIntl('intl.unableToSubscribe', { error: (e.message || '') })
|
||||||
|
: formatIntl('intl.unableToUnsubscribe', { error: (e.message || '') })
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
16
src/routes/_api/notify.js
Normal file
16
src/routes/_api/notify.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { post, WRITE_TIMEOUT } from '../_utils/ajax.js'
|
||||||
|
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,
|
||||||
|
}, 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
|
||||||
|
}, auth(accessToken), { timeout: WRITE_TIMEOUT })
|
||||||
|
}
|
|
@ -8,6 +8,7 @@
|
||||||
<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} />
|
||||||
|
@ -37,7 +38,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 follow"
|
"avatar note note note notify"
|
||||||
"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;
|
||||||
|
@ -71,7 +72,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 follow"
|
"avatar followed-by notify"
|
||||||
"note note note"
|
"note note note"
|
||||||
"meta meta meta"
|
"meta meta meta"
|
||||||
"details details details";
|
"details details details";
|
||||||
|
@ -97,6 +98,7 @@
|
||||||
"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";
|
||||||
|
@ -108,6 +110,7 @@
|
||||||
</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'
|
||||||
|
@ -144,6 +147,7 @@
|
||||||
AccountProfileHeader,
|
AccountProfileHeader,
|
||||||
AccountProfileFollow,
|
AccountProfileFollow,
|
||||||
AccountProfileNote,
|
AccountProfileNote,
|
||||||
|
AccountProfileNotify,
|
||||||
AccountProfileMeta,
|
AccountProfileMeta,
|
||||||
AccountProfileDetails,
|
AccountProfileDetails,
|
||||||
AccountProfileMovedBanner,
|
AccountProfileMovedBanner,
|
||||||
|
|
92
src/routes/_components/profile/AccountProfileNotify.html
Normal file
92
src/routes/_components/profile/AccountProfileNotify.html
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
<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>
|
Loading…
Reference in a new issue