forked from Mirrors/elk
feat: support more actions for user
This commit is contained in:
parent
3d7d2ca405
commit
84478984dc
12 changed files with 184 additions and 37 deletions
|
@ -6,11 +6,17 @@ const { account } = defineProps<{
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const isSelf = $computed(() => currentUser.value?.account.id === account.id)
|
const isSelf = $computed(() => currentUser.value?.account.id === account.id)
|
||||||
const relationship = $(useRelationship(account))
|
let relationship = $(useRelationship(account))
|
||||||
|
|
||||||
async function toggleFollow() {
|
async function toggleFollow() {
|
||||||
relationship!.following = !relationship!.following
|
relationship!.following = !relationship!.following
|
||||||
await masto.accounts[relationship!.following ? 'follow' : 'unfollow'](account.id)
|
try {
|
||||||
|
relationship = await masto.accounts[relationship!.following ? 'follow' : 'unfollow'](account.id)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
// TODO error handling
|
||||||
|
relationship!.following = !relationship!.following
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -8,34 +8,29 @@ let relationship = $(useRelationship(account))
|
||||||
|
|
||||||
const isSelf = $computed(() => currentUser.value?.account.id === account.id)
|
const isSelf = $computed(() => currentUser.value?.account.id === account.id)
|
||||||
|
|
||||||
const mute = async () => {
|
const toggleMute = async () => {
|
||||||
// TODO: Add confirmation
|
// TODO: Add confirmation
|
||||||
|
|
||||||
relationship!.muting = true
|
relationship!.muting = !relationship!.muting
|
||||||
relationship = await masto.accounts.mute(account.id, {
|
relationship = relationship!.muting
|
||||||
// TODO support more options
|
? await masto.accounts.mute(account.id, {
|
||||||
})
|
// TODO support more options
|
||||||
|
})
|
||||||
|
: await masto.accounts.unmute(account.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const unmute = async () => {
|
const toggleBlockUser = async () => {
|
||||||
// TODO: Add confirmation
|
// TODO: Add confirmation
|
||||||
|
|
||||||
relationship!.muting = false
|
relationship!.blocking = !relationship!.blocking
|
||||||
relationship = await masto.accounts.unmute(account.id)
|
relationship = await masto.accounts[relationship!.blocking ? 'block' : 'unblock'](account.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const block = async () => {
|
const toggleBlockDomain = async () => {
|
||||||
// TODO: Add confirmation
|
// TODO: Add confirmation
|
||||||
|
|
||||||
relationship!.blocking = true
|
relationship!.domainBlocking = !relationship!.domainBlocking
|
||||||
relationship = await masto.accounts.block(account.id)
|
await masto.domainBlocks[relationship!.domainBlocking ? 'block' : 'unblock'](getServerName(account))
|
||||||
}
|
|
||||||
|
|
||||||
const unblock = async () => {
|
|
||||||
// TODO: Add confirmation
|
|
||||||
|
|
||||||
relationship!.blocking = false
|
|
||||||
relationship = await masto.accounts.unblock(account.id)
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -62,19 +57,58 @@ const unblock = async () => {
|
||||||
Direct message @{{ account.acct }}
|
Direct message @{{ account.acct }}
|
||||||
</CommonDropdownItem>
|
</CommonDropdownItem>
|
||||||
|
|
||||||
<CommonDropdownItem v-if="!relationship?.muting" icon="i-ri:volume-up-fill" @click="mute">
|
<CommonDropdownItem v-if="!relationship?.muting" icon="i-ri:volume-up-fill" @click="toggleMute">
|
||||||
Mute @{{ account.acct }}
|
Mute @{{ account.acct }}
|
||||||
</CommonDropdownItem>
|
</CommonDropdownItem>
|
||||||
<CommonDropdownItem v-else icon="i-ri:volume-mute-line" @click="unmute">
|
<CommonDropdownItem v-else icon="i-ri:volume-mute-line" @click="toggleMute">
|
||||||
Unmute @{{ account.acct }}
|
Unmute @{{ account.acct }}
|
||||||
</CommonDropdownItem>
|
</CommonDropdownItem>
|
||||||
|
|
||||||
<CommonDropdownItem v-if="!relationship?.blocking" icon="i-ri:forbid-2-line" @click="block">
|
<CommonDropdownItem v-if="!relationship?.blocking" icon="i-ri:forbid-2-line" @click="toggleBlockUser">
|
||||||
Block @{{ account.acct }}
|
Block @{{ account.acct }}
|
||||||
</CommonDropdownItem>
|
</CommonDropdownItem>
|
||||||
<CommonDropdownItem v-else icon="i-ri:checkbox-circle-line" @click="unblock">
|
<CommonDropdownItem v-else icon="i-ri:checkbox-circle-line" @click="toggleBlockUser">
|
||||||
Unblock @{{ account.acct }}
|
Unblock @{{ account.acct }}
|
||||||
</CommonDropdownItem>
|
</CommonDropdownItem>
|
||||||
|
|
||||||
|
<CommonDropdownItem
|
||||||
|
v-if="!relationship?.domainBlocking"
|
||||||
|
icon="i-ri:shut-down-line"
|
||||||
|
@click="toggleBlockDomain"
|
||||||
|
>
|
||||||
|
Block domain {{ getServerName(account) }}
|
||||||
|
</CommonDropdownItem>
|
||||||
|
<CommonDropdownItem v-else icon="i-ri:restart-line" @click="toggleBlockDomain">
|
||||||
|
Unblock domain {{ getServerName(account) }}
|
||||||
|
</CommonDropdownItem>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-else>
|
||||||
|
<NuxtLink to="/pinned">
|
||||||
|
<CommonDropdownItem icon="i-ri:pushpin-line">
|
||||||
|
Pinned
|
||||||
|
</CommonDropdownItem>
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink to="/favourites">
|
||||||
|
<CommonDropdownItem icon="i-ri:heart-3-line">
|
||||||
|
Favourites
|
||||||
|
</CommonDropdownItem>
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink to="/mutes">
|
||||||
|
<CommonDropdownItem icon="i-ri:volume-mute-line">
|
||||||
|
Muted users
|
||||||
|
</CommonDropdownItem>
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink to="/blocks">
|
||||||
|
<CommonDropdownItem icon="i-ri:forbid-2-line">
|
||||||
|
Blocked users
|
||||||
|
</CommonDropdownItem>
|
||||||
|
</NuxtLink>
|
||||||
|
<NuxtLink to="/domain_blocks">
|
||||||
|
<CommonDropdownItem icon="i-ri:shut-down-line">
|
||||||
|
Blocked domains
|
||||||
|
</CommonDropdownItem>
|
||||||
|
</NuxtLink>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</CommonDropdown>
|
</CommonDropdown>
|
||||||
|
|
|
@ -19,6 +19,7 @@ const handleClick = (evt: MouseEvent) => {
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
flex gap-3 items-center cursor-pointer px4 py3 hover-bg-active
|
flex gap-3 items-center cursor-pointer px4 py3 hover-bg-active
|
||||||
|
v-bind="$attrs"
|
||||||
@click="handleClick"
|
@click="handleClick"
|
||||||
>
|
>
|
||||||
<div v-if="icon" :class="icon" />
|
<div v-if="icon" :class="icon" />
|
||||||
|
@ -38,5 +39,6 @@ const handleClick = (evt: MouseEvent) => {
|
||||||
<div flex-auto />
|
<div flex-auto />
|
||||||
|
|
||||||
<div v-if="checked" i-ri:check-line />
|
<div v-if="checked" i-ri:check-line />
|
||||||
|
<slot name="actions" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineProps<{
|
||||||
|
back?: boolean
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div relative>
|
<div relative>
|
||||||
<div
|
<div
|
||||||
|
@ -7,13 +13,12 @@
|
||||||
:class="isZenMode ? 'op0 hover:op100 transition duration-300' : ''"
|
:class="isZenMode ? 'op0 hover:op100 transition duration-300' : ''"
|
||||||
>
|
>
|
||||||
<div flex justify-between px5 py4>
|
<div flex justify-between px5 py4>
|
||||||
<div flex gap-1>
|
<div flex gap-3>
|
||||||
<slot name="title">
|
<NuxtLink v-if="back" flex="~ gap1" items-center btn-text p-0 @click="$router.go(-1)">
|
||||||
<NuxtLink flex="~ gap1" items-center btn-text p-0 @click="$router.go(-1)">
|
<div i-ri-arrow-left-line />
|
||||||
<div i-ri-arrow-left-line />
|
</NuxtLink>
|
||||||
Back
|
<slot name="title" />
|
||||||
</NuxtLink>
|
<div h-7 w-1px />
|
||||||
</slot>
|
|
||||||
</div>
|
</div>
|
||||||
<div flex items-center>
|
<div flex items-center>
|
||||||
<slot name="actions" />
|
<slot name="actions" />
|
||||||
|
|
|
@ -10,7 +10,7 @@ const { data: context } = useAsyncData(`context:${id}`, () => masto.statuses.fet
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MainContent>
|
<MainContent back>
|
||||||
<template v-if="status">
|
<template v-if="status">
|
||||||
<template v-if="context">
|
<template v-if="context">
|
||||||
<template v-for="comment of context?.ancestors" :key="comment.id">
|
<template v-for="comment of context?.ancestors" :key="comment.id">
|
||||||
|
|
|
@ -12,7 +12,11 @@ if (account) {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MainContent>
|
<MainContent back>
|
||||||
|
<template #title>
|
||||||
|
<span text-lg font-bold>{{ account ? getDisplayName(account) : 'Profile' }}</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-if="account">
|
<template v-if="account">
|
||||||
<AccountHeader :account="account" border="b base" />
|
<AccountHeader :account="account" border="b base" />
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
|
|
20
pages/blocks.vue
Normal file
20
pages/blocks.vue
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
middleware: 'auth',
|
||||||
|
})
|
||||||
|
|
||||||
|
const paginator = masto.blocks.getIterator()
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: 'Blocked users',
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<MainContent back>
|
||||||
|
<template #title>
|
||||||
|
<span text-lg font-bold>Blocked users</span>
|
||||||
|
</template>
|
||||||
|
<AccountPaginator :paginator="paginator" />
|
||||||
|
</MainContent>
|
||||||
|
</template>
|
34
pages/domain_blocks.vue
Normal file
34
pages/domain_blocks.vue
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
middleware: 'auth',
|
||||||
|
})
|
||||||
|
|
||||||
|
const paginator = masto.domainBlocks.getIterator()
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: 'Blocked domains',
|
||||||
|
})
|
||||||
|
|
||||||
|
const unblock = async (domain: string) => {
|
||||||
|
await masto.domainBlocks.unblock(domain)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<MainContent back>
|
||||||
|
<template #title>
|
||||||
|
<span text-lg font-bold>Blocked domains</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<CommonPaginator :paginator="paginator">
|
||||||
|
<template #default="{ item }">
|
||||||
|
<CommonDropdownItem class="!cursor-auto">
|
||||||
|
{{ item }}
|
||||||
|
<template #actions>
|
||||||
|
<div i-ri:lock-unlock-line text-primary cursor-pointer @click="unblock(item)" />
|
||||||
|
</template>
|
||||||
|
</CommonDropdownItem>
|
||||||
|
</template>
|
||||||
|
</CommonPaginator>
|
||||||
|
</MainContent>
|
||||||
|
</template>
|
20
pages/mutes.vue
Normal file
20
pages/mutes.vue
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
middleware: 'auth',
|
||||||
|
})
|
||||||
|
|
||||||
|
const paginator = masto.mutes.getIterator()
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: 'Muted users',
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<MainContent back>
|
||||||
|
<template #title>
|
||||||
|
<span text-lg font-bold>Muted users</span>
|
||||||
|
</template>
|
||||||
|
<AccountPaginator :paginator="paginator" />
|
||||||
|
</MainContent>
|
||||||
|
</template>
|
22
pages/pinned.vue
Normal file
22
pages/pinned.vue
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
middleware: 'auth',
|
||||||
|
})
|
||||||
|
|
||||||
|
const paginator = masto.accounts.getStatusesIterable(currentUser.value!.account.id, { pinned: true })
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: 'Pinned',
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<MainContent>
|
||||||
|
<template #title>
|
||||||
|
<div i-ri:pushpin-line h-6 mr-1 />
|
||||||
|
<span>Pinned</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<TimelinePaginator :paginator="paginator" />
|
||||||
|
</MainContent>
|
||||||
|
</template>
|
|
@ -2,16 +2,16 @@
|
||||||
const paginator = masto.timelines.getPublicIterable()
|
const paginator = masto.timelines.getPublicIterable()
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
title: 'Federated'
|
title: 'Federated',
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MainContent>
|
<MainContent>
|
||||||
<template #title>
|
<template #title>
|
||||||
<span text-lg font-bold>Federated Timeline</span>
|
<span text-lg font-bold>Federated Timeline</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<slot>
|
<slot>
|
||||||
<TimelinePaginator :paginator="paginator" />
|
<TimelinePaginator :paginator="paginator" />
|
||||||
</slot>
|
</slot>
|
||||||
|
|
|
@ -10,7 +10,7 @@ useHead({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<MainContent>
|
<MainContent back>
|
||||||
<template #title>
|
<template #title>
|
||||||
<span text-lg font-bold>#{{ tag }}</span>
|
<span text-lg font-bold>#{{ tag }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in a new issue