♻️ Interactive v2 #1

Merged
LittleSheep merged 30 commits from refactor/v2 into master 2024-03-16 08:22:25 +00:00
4 changed files with 42 additions and 13 deletions
Showing only changes of commit c1fe67bb75 - Show all commits

View File

@ -1,12 +1,24 @@
<template>
<v-card variant="tonal" class="max-w-[540px]" :ripple="canLightbox" @click="openLightbox">
<v-chip size="small" variant="tonal" prepend-icon="mdi-paperclip" v-if="props.overview">
Attached {{ props.attachments.length }} attachment(s)
</v-chip>
<v-card v-else variant="outlined" class="max-w-[540px]" :ripple="canLightbox" @click="openLightbox">
<div class="content">
<img v-if="current.type === 1" :src="getUrl(current)" />
<video v-if="current.type === 2" controls class="w-full">
<source :src="getUrl(current)"></source>
<source :src="getUrl(current)" />
</video>
</div>
<div v-if="props.attachments.length > 1" class="switcher flex justify-between items-center px-5 py-2">
<div>{{ focus + 1 }} of {{ props.attachments.length }}</div>
<div>
<v-btn icon="mdi-arrow-left" variant="text" size="small" @click.stop="focusPrev" />
<v-btn icon="mdi-arrow-right" variant="text" size="small" @click.stop="focusNext" />
</div>
</div>
<vue-easy-lightbox teleport="#app" :visible="lightbox" :imgs="[getUrl(current)]" @hide="lightbox = false">
<template v-slot:close-btn="{ close }">
<v-btn class="fixed left-2 top-2" icon="mdi-close" variant="text" color="white" @click="close" />
@ -19,7 +31,7 @@
import { computed, ref } from "vue"
import VueEasyLightbox from "vue-easy-lightbox"
const props = defineProps<{ attachments: any[] }>()
const props = defineProps<{ attachments: any[]; overview?: boolean }>()
const lightbox = ref(false)
const focus = ref(0)
@ -36,6 +48,18 @@ function openLightbox() {
lightbox.value = true
}
}
function focusNext() {
if (focus.value + 1 < props.attachments.length) {
focus.value++
}
}
function focusPrev() {
if (focus.value - 1 >= 0) {
focus.value--
}
}
</script>
<style>

View File

@ -18,7 +18,12 @@
<component :is="renderer[props.item?.model_type]" v-bind="props" />
<post-attachment v-if="props.item?.attachments" :attachments="props.item?.attachments" />
<post-attachment
v-if="props.item?.attachments"
class="mt-1.5"
:overview="props.item?.model_type !== 'moment'"
:attachments="props.item?.attachments"
/>
<post-reaction
size="small"

View File

@ -94,18 +94,18 @@ const uploading = ref(false)
async function postMoment(evt: SubmitEvent) {
const form = evt.target as HTMLFormElement
const data = new FormData(form)
if (!data.has("content")) return
if (!extras.publishedAt) data.set("published_at", new Date().toISOString())
else data.set("published_at", extras.publishedAt)
const data: any = Object.fromEntries(new FormData(form))
if (!data.hasOwnProperty("content")) return
if (!extras.publishedAt) data["published_at"] = new Date().toISOString()
else data["published_at"] = extras.publishedAt
extras.attachments.forEach((item) => data.append("attachments[]", item))
data["attachments"] = extras.attachments
loading.value = true
const res = await request("/api/p/moments", {
method: "POST",
headers: { Authorization: `Bearer ${getAtk()}` },
body: data
headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` },
body: JSON.stringify(data)
})
if (res.status === 200) {
form.reset()

View File

@ -1,6 +1,6 @@
<template>
<v-container class="flex max-md:flex-col gap-3 overflow-auto max-h-[calc(100vh-64px)] no-scrollbar">
<div class="timeline flex-grow-1 max-w-[75ch]">
<div class="timeline flex-grow-1">
<v-card :loading="loading">
<article>
<v-card-text>
@ -26,7 +26,7 @@
</v-card>
</div>
<div class="aside sticky top-0 w-full h-fit md:min-w-[280px]">
<div class="aside sticky top-0 w-full h-fit md:max-w-[360px] md:min-w-[280px]">
<v-card title="Comments">
<div class="px-[1rem] pb-[0.825rem] mt-[-12px]">
<comment-list