ui: move publish widget

zio/stable
Anthony Fu 2022-11-24 15:53:27 +08:00
parent 0dc515647f
commit cd2a06e969
7 changed files with 65 additions and 62 deletions

View File

@ -4,6 +4,8 @@ import type { Account } from 'masto'
const { account } = defineProps<{ const { account } = defineProps<{
account: Account account: Account
}>() }>()
cacheAccount(account)
</script> </script>
<template> <template>

View File

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { Attachment, CreateStatusParams, CreateStatusParamsWithStatus } from 'masto' import type { CreateStatusParams, CreateStatusParamsWithStatus } from 'masto'
const { const {
draftKey, draftKey,
@ -103,26 +103,22 @@ onUnmounted(() => {
</script> </script>
<template> <template>
<div v-if="currentUser" border="t base" p4 flex gap-4>
<AccountAvatar :account="currentUser.account" w-12 h-12 />
<div <div
flex flex-col gap-3 flex flex-col gap-3 flex-auto
:class="isSending ? 'pointer-events-none' : ''" :class="isSending ? 'pointer-events-none' : ''"
> >
<textarea <textarea
v-model="draft.params.status" v-model="draft.params.status"
:placeholder="placeholder" :placeholder="placeholder"
p2 border-rounded w-full h-40 p2 border-rounded w-full bg-transparent
bg-gray:10 outline-none border="~ base" outline-none border="~ base"
@paste="handlePaste" @paste="handlePaste"
/> />
<div flex="~" gap-2>
<button hover:bg-active p2 rounded-5 @click="pickAttachments">
<div i-ri:upload-line />
</button>
</div>
<div flex="~ col gap-2" max-h-50vh overflow-auto> <div flex="~ col gap-2" max-h-50vh overflow-auto>
<publish-attachment <PublishAttachment
v-for="(att, idx) in draft.attachments" :key="att.id" v-for="(att, idx) in draft.attachments" :key="att.id"
:attachment="att" :attachment="att"
@remove="removeAttachment(idx)" @remove="removeAttachment(idx)"
@ -134,9 +130,15 @@ onUnmounted(() => {
Uploading... Uploading...
</div> </div>
<div flex justify-end> <div flex="~ gap-2">
<button btn-action-icon @click="pickAttachments">
<div i-ri:upload-line />
</button>
<div flex-auto />
<button <button
btn-solid btn-solid rounded-full
:disabled="isUploading || (draft.attachments.length === 0 && !draft.params.status)" :disabled="isUploading || (draft.attachments.length === 0 && !draft.params.status)"
@click="publish" @click="publish"
> >
@ -144,4 +146,5 @@ onUnmounted(() => {
</button> </button>
</div> </div>
</div> </div>
</div>
</template> </template>

View File

@ -9,7 +9,8 @@ if (process.dev)
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log({ cache }) console.log({ cache })
export function setCached(key: string, value: any) { export function setCached(key: string, value: any, override = false) {
if (override || !cache.has(key))
cache.set(key, value) cache.set(key, value)
} }
@ -34,7 +35,7 @@ export function fetchAccount(id: string) {
return cached return cached
const promise = masto.accounts.fetch(id) const promise = masto.accounts.fetch(id)
.then((account) => { .then((account) => {
cacheAccount(account) cacheAccount(account, true)
return account return account
}) })
cache.set(key, promise) cache.set(key, promise)
@ -48,18 +49,18 @@ export function fetchAccountByName(acct: string) {
return cached return cached
const account = masto.accounts.lookup({ acct }) const account = masto.accounts.lookup({ acct })
.then((r) => { .then((r) => {
cacheAccount(r) cacheAccount(r, true)
return r return r
}) })
cache.set(key, account) cache.set(key, account)
return account return account
} }
export function cacheStatus(status: Status) { export function cacheStatus(status: Status, override?: boolean) {
setCached(`status:${status.id}`, status) setCached(`status:${status.id}`, status, override)
} }
export function cacheAccount(account: Account) { export function cacheAccount(account: Account, override?: boolean) {
setCached(`account:${account.id}`, account) setCached(`account:${account.id}`, account, override)
setCached(`account:${account.acct}`, account) setCached(`account:${account.acct}`, account, override)
} }

View File

@ -4,10 +4,7 @@
<div class="hidden md:block w-1/4 zen-hide" relative> <div class="hidden md:block w-1/4 zen-hide" relative>
<div sticky top-0 h-screen flex="~ col"> <div sticky top-0 h-screen flex="~ col">
<slot name="left"> <slot name="left">
<template v-if="currentUser"> <UserSignInEntry v-if="!currentUser" />
<PublishWidget px4 mt16 draft-key="home" />
</template>
<UserSignInEntry v-else />
<div flex-auto /> <div flex-auto />
<AccountInfo <AccountInfo
v-if="currentUser" v-if="currentUser"

View File

@ -12,6 +12,7 @@ const paginator = masto.timelines.getHomeIterable()
<span text-lg font-bold>Home</span> <span text-lg font-bold>Home</span>
</template> </template>
<slot> <slot>
<PublishWidget draft-key="home" border="b base" />
<TimelinePaginator :paginator="paginator" /> <TimelinePaginator :paginator="paginator" />
</slot> </slot>
</MainContent> </MainContent>

View File

@ -18,15 +18,12 @@ const { data: context } = useAsyncData(`context:${id}`, () => masto.statuses.fet
</template> </template>
<StatusDetails ref="main" :status="status" border="t base" /> <StatusDetails ref="main" :status="status" border="t base" />
<div v-if="currentUser" border="t base" p6 flex gap-4>
<AccountAvatar :account="currentUser.account" w-10 h-10 />
<PublishWidget <PublishWidget
w-full v-if="currentUser"
:draft-key="`reply-${id}`" :draft-key="`reply-${id}`"
:placeholder="`Reply to ${status?.account ? getDisplayName(status?.account) : 'this thread'}`" :placeholder="`Reply to ${status?.account ? getDisplayName(status?.account) : 'this thread'}`"
:in-reply-to-id="id" :in-reply-to-id="id"
/> />
</div>
<template v-if="context"> <template v-if="context">
<template v-for="comment of context?.descendants" :key="comment.id"> <template v-for="comment of context?.descendants" :key="comment.id">

View File

@ -19,9 +19,11 @@ export default defineConfig({
'text-base': 'text-$c-text-base', 'text-base': 'text-$c-text-base',
'text-secondary': 'text-$c-text-secondary', 'text-secondary': 'text-$c-text-secondary',
'interact-disabled': 'disabled:opacity-50 disabled:pointer-events-none disabled:saturate-0', 'interact-disabled': 'disabled:opacity-50 disabled:pointer-events-none disabled:saturate-0',
'btn-solid': 'px-4 py-2 rounded text-white bg-$c-primary hover:bg-$c-primary-active interact-disabled', 'btn-base': 'interact-disabled cursor-pointer',
'btn-outline': 'px-4 py-2 rounded text-$c-primary border border-$c-primary hover:bg-$c-primary hover:text-white interact-disabled', 'btn-solid': 'btn-base px-4 py-2 rounded text-white bg-$c-primary hover:bg-$c-primary-active',
'btn-text': 'px-4 py-2 text-$c-primary hover:text-$c-primary-active interact-disabled cursor-pointer', 'btn-outline': 'btn-base px-4 py-2 rounded text-$c-primary border border-$c-primary hover:bg-$c-primary hover:text-white',
'btn-text': 'btn-base px-4 py-2 text-$c-primary hover:text-$c-primary-active',
'btn-action-icon': 'btn-base hover:bg-active rounded-full h9 w9 flex items-center justify-center',
}, },
], ],
presets: [ presets: [