Many fix and improvements

This commit is contained in:
Jonathan Bourdon
2024-08-03 04:15:55 -04:00
parent 0d94d79c77
commit 78ead7e387
37 changed files with 669 additions and 735 deletions

View File

@@ -1,45 +1,86 @@
<template>
<script setup>
import {computed, reactive, onMounted} from 'vue';
import {time_ago} from "@/internal_time_ago.js";
import MessageList from "@/views/messages/MessageList.vue";
import PostMessage from "@/views/messages/PostMessage.vue";
import YoutubePlayer from './YoutubePlayer.vue';
import ImageViewer from './ImageViewer.vue';
// import VimeoPlayer from '@/components/VimeoPlayer.vue';
// import AudioPlayer from '@/components/AudioPlayer.vue';
// import BlogViewer from '@/components/BlogViewer.vue';
const props = defineProps({
content: {
type: Object,
required: true,
}
});
const hasUrls = computed(() => !!props.content.urls && props.content.urls.length > 0);
const messages = reactive([]);
function addMessage(newMessage) {
messages.unshift(newMessage)
}
function getComponent(url) {
if (url.includes('youtube.com') || url.includes('youtu.be')) {
return YoutubePlayer;
// } else if (url.includes('vimeo.com')) {
// return VimeoPlayer;
} else if (url.match(/\.(jpeg|jpg|gif|png)$/)) {
return ImageViewer;
// } else if (url.match(/\.(mp3|wav|ogg)$/)) {
// return 'AudioPlayer';
// } else {
// return 'BlogViewer';
}
}
</script>
<template>
<div class="shadow-md rounded-lg bg-gray-50">
<div class="text-lg font-bold">
{{ props.content.title }}
<span class="text-md-caption">
{{ time_ago(props.content.createdAt) }}
<v-card
outlined
tile
>
<v-card-title>
{{ props.content.title }}
<span class="text-subtitle-2">
{{ time_ago(props.content.createdAt) }}
</span>
</div>
</v-card-title>
<div v-if="props.content.url !== null || props.content.uri !== null"
class="h-48 object-cover bg-gray-300 rounded-md">
<v-carousel v-if="hasUrls">
<v-img :src="props.content.url"
v-if="!isHttpUrl">
</v-img>
<v-carousel-item
v-for="url in props.content.urls"
:key="url"
>
<component :is="getComponent(url)"
:src="url"
></component>
</v-carousel-item>
<iframe v-if="isHttpUrl"
:src="props?.content?.uri"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen>
</iframe>
</v-carousel>
</div>
<v-card-text>
{{ props.content.description }}
</v-card-text>
<div class="flex flex-row">
<div>
<div class="text-sm text-gray-500">{{ props.content.description }}</div>
</div>
<div>
<router-link :to="'content/' + props?.content?.id">
<v-card-actions>
<router-link :to="'content/' + content.id">
<div class="bg-blue-500 rounded-lg py-1 px-2">Plus ...</div>
</router-link>
</div>
</v-card-actions>
</div>
</v-card>
<div>
@@ -58,28 +99,4 @@
</div>
</template>
<script setup>
import {computed, reactive} from 'vue';
import {time_ago} from "@/internal_time_ago.js";
import MessageList from "@/views/messages/MessageList.vue";
import PostMessage from "@/views/messages/PostMessage.vue";
const isHttpUrl = computed(() => props.content?.uri?.startsWith('http'))
const props = defineProps({
content: {
type: Object,
required: true,
}
});
const messages = reactive([]);
function addMessage(newMessage) {
messages.unshift(newMessage)
}
</script>
</template>

View File

@@ -48,7 +48,6 @@ async function load({done}) {
let uri = `/api/contents/user/${props.creatorId}?page_size=${page_size}`
if (last_id !== null) uri = uri + `&last_id=${last_id}`
console.log(`Fetching content at: ${uri}`)
const response = await client.get(uri)
if (response.status >= 200 && response.status < 300) {

View File

@@ -1,72 +1,8 @@
<template>
<div v-if="creator.id === userStore.getCurrentUser().id">
<button
class="flex items-center text-white transform transition-transform duration-200 hover:text-gray-300 hover:scale-125 px-4"
@click="isDialogActive = true">
<v-icon style="font-size: 35px; height: 35px; width: 55px;">mdi-text-box-plus-outline</v-icon>
</button>
<v-dialog v-model="isDialogActive" max-width="500">
<v-card class="text-center rounded-xl">
<v-card-title class="text-white p-4 rounded-t"
:style="{backgroundColor: creator.profileColors.menu || '#A30E79'}">
Quicky
</v-card-title>
<v-card-text>
<v-text-field v-model="title"
class="p-2"
label="Titre"
density="comfortable"
variant="outlined"
hide-details
clearable>
</v-text-field>
<v-textarea v-model="message"
label="Écrivez votre message ici..."
class="p-2"
density="comfortable"
variant="outlined"
hide-details
clearable
outlined>
</v-textarea>
<v-file-input v-model="files"
label="Ajoutez des fichiers"
class="p-2"
outlined
multiple
dropzone
placeholder="Glissez et déposez des fichiers ici ou cliquez pour sélectionner des fichiers"
></v-file-input>
</v-card-text>
<v-card-actions class="justify-end">
<v-btn color="secondary" @click="cancelPost">Annuler</v-btn>
<v-btn color="primary" @click="publishPost">Publier</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script setup>
<script setup>
import {useClient} from '@/plugins/api.js';
import {ref} from 'vue';
import {useUserStore} from '@/stores/user.js';
import {useUserStore} from '@/stores/userStore.js';
import {v7} from 'uuid'
const props = defineProps({
creator: {type: Object, required: true},
@@ -75,22 +11,34 @@ const props = defineProps({
const userStore = useUserStore();
const isDialogActive = ref(false);
const title = ref('');
const message = ref('');
const files = ref([]);
const client = useClient();
const title = ref('');
const message = ref('');
const files = ref([])
const publishPost = async () => {
async function publishPost() {
const formData = new FormData();
formData.append('id', v7());
formData.append('creatorId', userStore.user.id);
formData.append('title', title.value);
formData.append('description', message.value);
files.value.forEach(file => {
formData.append('files', file);
});
try {
await client.post(
const response = await client.post(
`/api/contents/`,
formData,
{
"title": title.value,
"description": message.value
headers: {
'Content-Type': 'multipart/form-data',
}
})
console.log('Files uploaded successfully:', response.data);
closeDialog()
} catch (error) {
console.error(error)
@@ -110,3 +58,69 @@ const closeDialog = () => {
</script>
<template>
<button
v-if="creator.id === userStore.user.id"
class="flex items-center text-white transform transition-transform duration-200 hover:text-gray-300 hover:scale-125 px-4"
@click="isDialogActive = true">
<v-icon style="font-size: 35px; height: 35px; width: 55px;">mdi-text-box-plus-outline</v-icon>
</button>
<v-dialog v-model="isDialogActive"
max-width="500">
<v-form>
<v-card class="text-center rounded-xl">
<v-card-title class="text-white p-4 rounded-t"
:style="{backgroundColor: creator.profileColors.menu || '#A30E79'}">
Quicky
</v-card-title>
<v-card-text>
<v-text-field v-model="title"
class="p-2"
label="Titre"
density="comfortable"
variant="outlined"
hide-details
clearable
></v-text-field>
<v-textarea v-model="message"
label="Écrivez votre message ici..."
class="p-2"
density="comfortable"
variant="outlined"
hide-details
clearable
outlined
></v-textarea>
<v-file-input v-model="files"
label="Ajoutez des fichiers"
class="p-2"
outlined
multiple
dropzone
placeholder="Glissez et déposez des fichiers ici ou cliquez pour sélectionner des fichiers"
></v-file-input>
</v-card-text>
<v-card-actions class="justify-end">
<v-btn color="secondary" @click="cancelPost">Annuler</v-btn>
<v-btn color="primary" @click="publishPost">Publier</v-btn>
</v-card-actions>
</v-card>
</v-form>
</v-dialog>
</template>

View File

@@ -0,0 +1,31 @@
<template>
<div class="image-container">
<img :src="src" alt="Image" class="image" />
</div>
</template>
<script setup>
const props = defineProps({
src: {
type: String,
required: true,
},
});
</script>
<style scoped>
.image-container {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
overflow: hidden;
}
.image {
max-width: 100%;
max-height: 100%;
object-fit: contain;
}
</style>

View File

@@ -0,0 +1,26 @@
<template>
<iframe
:src="src"
title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen
></iframe>
</template>
<script setup>
const props = defineProps({
src: {
type: String,
required: true,
},
});
</script>
<style scoped>
iframe {
width: 100%;
height: 100%;
border: 0;
}
</style>