semaphore/src/routes/_components/profile/AccountProfileFollow.html

136 lines
4.3 KiB
HTML

<div class="account-profile-follow {shown ? 'shown' : ''}">
<!--
This button has a few different states.
- If we're blocking, then it's a normal non-toggle button that unblocks.
- Otherwise it's a pseudo-toggle button that changes whether we're following the account or not.
- If a follow is requested, then the button is pressed but shows as "follow requested" with
a different icon.
-->
<button class="account-profile-follow-button" on:click="onFollowButtonClick(event)">
{pressed ? pressedLabel : label}
</button>
<!-- TODO: re-enable this when we support profile editing -->
{#if account && verifyCredentials && account.id !== verifyCredentials.id}
<IconButton
className="account-profile-more-options-button"
label="{intl.moreOptions}"
href="#fa-ellipsis-v"
muted="true"
on:click="onMoreOptionsClick()"
/>
{/if}
</div>
<style>
.account-profile-follow {
grid-area: follow;
align-self: flex-start;
display: none;
}
.account-profile-follow.shown {
display: flex;
gap: 5px;
}
@media (max-width: 400px) {
.account-profile-follow {
justify-self: flex-end;
}
}
:global(.account-profile-more-options-button),
.account-profile-follow-button {
padding: 10px;
font-size: 1.1em;
}
:global(.icon-button.account-profile-more-options-button) {
border: 1px solid var(--button-border);
padding-left: 6px;
padding-right: 6px;
}
.account-profile-follow-button {
min-width: 10ch;
}
</style>
<script>
import { store } from '../../_store/store.js'
import IconButton from '../IconButton.html'
import { importShowAccountProfileOptionsDialog } from '../dialog/asyncDialogs/importShowAccountProfileOptionsDialog.js'
import { setAccountFollowed } from '../../_actions/follow.js'
import { setAccountBlocked } from '../../_actions/block.js'
import { formatIntl } from '../../_utils/formatIntl.js'
export default {
methods: {
async onMoreOptionsClick () {
const { account, relationship, verifyCredentials } = this.get()
const showAccountProfileOptionsDialog = await importShowAccountProfileOptionsDialog()
showAccountProfileOptionsDialog(account, relationship, verifyCredentials)
},
oncreate () {
if (process.browser) {
window.__button = this
}
},
async onFollowButtonClick (e) {
e.preventDefault()
e.stopPropagation()
const {
account,
accountId,
following,
followRequested,
blocking
} = this.get()
if (blocking) { // unblock
await setAccountBlocked(accountId, false)
} else { // follow/unfollow
const newFollowingValue = !(following || followRequested)
if (!account.locked) { // be optimistic, show the user that it succeeded
this.set({ overrideFollowing: newFollowingValue })
}
await setAccountFollowed(accountId, newFollowingValue)
}
}
},
store: () => store,
data: () => ({
overrideFollowing: undefined
}),
computed: {
accountId: ({ account }) => account.id,
following: ({ relationship, overrideFollowing }) => {
if (typeof overrideFollowing === 'boolean') {
return overrideFollowing
}
return relationship && relationship.following
},
blocking: ({ relationship }) => relationship && relationship.blocking,
followRequested: ({ relationship }) => {
return relationship && relationship.requested
},
requested: ({ following, followRequested }) => !following && followRequested,
label: ({ blocking, requested }) => {
if (blocking) {
return 'intl.unblock'
}
return formatIntl('intl.followLabel', { requested })
},
pressedLabel: ({ requested }) => {
return formatIntl('intl.unfollowLabel', { requested })
},
shown: ({ verifyCredentials, relationship }) => (
verifyCredentials && relationship && verifyCredentials.id !== relationship.id
),
pressable: ({ blocking }) => !blocking,
pressed: ({ blocking, following, followRequested }) => (
!blocking && (following || followRequested)
)
},
components: {
IconButton
}
}
</script>