♻️ 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> <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"> <div class="content">
<img v-if="current.type === 1" :src="getUrl(current)" /> <img v-if="current.type === 1" :src="getUrl(current)" />
<video v-if="current.type === 2" controls class="w-full"> <video v-if="current.type === 2" controls class="w-full">
<source :src="getUrl(current)"></source> <source :src="getUrl(current)" />
</video> </video>
</div> </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"> <vue-easy-lightbox teleport="#app" :visible="lightbox" :imgs="[getUrl(current)]" @hide="lightbox = false">
<template v-slot:close-btn="{ close }"> <template v-slot:close-btn="{ close }">
<v-btn class="fixed left-2 top-2" icon="mdi-close" variant="text" color="white" @click="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 { computed, ref } from "vue"
import VueEasyLightbox from "vue-easy-lightbox" import VueEasyLightbox from "vue-easy-lightbox"
const props = defineProps<{ attachments: any[] }>() const props = defineProps<{ attachments: any[]; overview?: boolean }>()
const lightbox = ref(false) const lightbox = ref(false)
const focus = ref(0) const focus = ref(0)
@ -36,6 +48,18 @@ function openLightbox() {
lightbox.value = true lightbox.value = true
} }
} }
function focusNext() {
if (focus.value + 1 < props.attachments.length) {
focus.value++
}
}
function focusPrev() {
if (focus.value - 1 >= 0) {
focus.value--
}
}
</script> </script>
<style> <style>

View File

@ -18,7 +18,12 @@
<component :is="renderer[props.item?.model_type]" v-bind="props" /> <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 <post-reaction
size="small" size="small"

View File

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

View File

@ -1,6 +1,6 @@
<template> <template>
<v-container class="flex max-md:flex-col gap-3 overflow-auto max-h-[calc(100vh-64px)] no-scrollbar"> <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"> <v-card :loading="loading">
<article> <article>
<v-card-text> <v-card-text>
@ -26,7 +26,7 @@
</v-card> </v-card>
</div> </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"> <v-card title="Comments">
<div class="px-[1rem] pb-[0.825rem] mt-[-12px]"> <div class="px-[1rem] pb-[0.825rem] mt-[-12px]">
<comment-list <comment-list