Wire Telegram into the post composer (preview, content type, logo)
This commit is contained in:
parent
b504243212
commit
f378469842
9 changed files with 154 additions and 0 deletions
|
|
@ -484,6 +484,10 @@
|
|||
'label' => 'Post',
|
||||
'description' => 'Text post with optional media',
|
||||
],
|
||||
'telegram_post' => [
|
||||
'label' => 'Post',
|
||||
'description' => 'Text post with optional media',
|
||||
],
|
||||
],
|
||||
|
||||
'platforms' => [
|
||||
|
|
@ -586,6 +590,7 @@
|
|||
'bluesky_post' => 'Bluesky Post',
|
||||
'threads_post' => 'Threads Post',
|
||||
'mastodon_post' => 'Mastodon Post',
|
||||
'telegram_post' => 'Telegram Post',
|
||||
'facebook_post' => 'Facebook Post',
|
||||
'pinterest_pin' => 'Pinterest Pin',
|
||||
'instagram_story' => 'Instagram Story',
|
||||
|
|
|
|||
|
|
@ -484,6 +484,10 @@
|
|||
'label' => 'Post',
|
||||
'description' => 'Post de texto con multimedia opcional',
|
||||
],
|
||||
'telegram_post' => [
|
||||
'label' => 'Post',
|
||||
'description' => 'Post de texto con multimedia opcional',
|
||||
],
|
||||
],
|
||||
|
||||
'platforms' => [
|
||||
|
|
@ -587,6 +591,7 @@
|
|||
'bluesky_post' => 'Post en Bluesky',
|
||||
'threads_post' => 'Post en Threads',
|
||||
'mastodon_post' => 'Post en Mastodon',
|
||||
'telegram_post' => 'Post en Telegram',
|
||||
'facebook_post' => 'Post en Facebook',
|
||||
'pinterest_pin' => 'Pin de Pinterest',
|
||||
'instagram_story' => 'Story de Instagram',
|
||||
|
|
|
|||
|
|
@ -484,6 +484,10 @@
|
|||
'label' => 'Post',
|
||||
'description' => 'Post de texto com mídia opcional',
|
||||
],
|
||||
'telegram_post' => [
|
||||
'label' => 'Post',
|
||||
'description' => 'Post de texto com mídia opcional',
|
||||
],
|
||||
],
|
||||
|
||||
'platforms' => [
|
||||
|
|
@ -586,6 +590,7 @@
|
|||
'bluesky_post' => 'Post no Bluesky',
|
||||
'threads_post' => 'Post no Threads',
|
||||
'mastodon_post' => 'Post no Mastodon',
|
||||
'telegram_post' => 'Post no Telegram',
|
||||
'facebook_post' => 'Post no Facebook',
|
||||
'pinterest_pin' => 'Pin no Pinterest',
|
||||
'instagram_story' => 'Story do Instagram',
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ const getProfileUrl = (platform: string, username: string | null, platformUserId
|
|||
'threads': `https://threads.net/@${username}`,
|
||||
'bluesky': `https://bsky.app/profile/${username}`,
|
||||
'pinterest': `https://pinterest.com/${username}`,
|
||||
'telegram': `https://t.me/${username}`,
|
||||
};
|
||||
return urls[platform] || null;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import InstagramPreview from './InstagramPreview.vue';
|
|||
import LinkedInPreview from './LinkedInPreview.vue';
|
||||
import MastodonPreview from './MastodonPreview.vue';
|
||||
import PinterestPreview from './PinterestPreview.vue';
|
||||
import TelegramPreview from './TelegramPreview.vue';
|
||||
import ThreadsPreview from './ThreadsPreview.vue';
|
||||
import TikTokPreview from './TikTokPreview.vue';
|
||||
import XPreview from './XPreview.vue';
|
||||
|
|
@ -65,6 +66,8 @@ const previewComponent = computed(() => {
|
|||
return BlueskyPreview;
|
||||
case 'mastodon':
|
||||
return MastodonPreview;
|
||||
case 'telegram':
|
||||
return TelegramPreview;
|
||||
default:
|
||||
return LinkedInPreview;
|
||||
}
|
||||
|
|
|
|||
130
resources/js/components/posts/previews/TelegramPreview.vue
Normal file
130
resources/js/components/posts/previews/TelegramPreview.vue
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
<script setup lang="ts">
|
||||
import VideoPreview from '@/components/posts/previews/VideoPreview.vue';
|
||||
import { isVideoMedia } from '@/composables/useMedia';
|
||||
import type { MediaItem } from '@/types/media';
|
||||
|
||||
interface SocialAccount {
|
||||
id: string;
|
||||
platform: string;
|
||||
display_name: string;
|
||||
username: string;
|
||||
avatar_url: string | null;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
socialAccount: SocialAccount;
|
||||
content: string;
|
||||
media: MediaItem[];
|
||||
}
|
||||
|
||||
defineProps<Props>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex h-full w-full flex-col overflow-hidden bg-[#a4bce0] dark:bg-[#0e1621]"
|
||||
>
|
||||
<!-- Header -->
|
||||
<div
|
||||
class="flex items-center gap-3 bg-white px-4 py-2.5 dark:bg-[#17212b]"
|
||||
>
|
||||
<img
|
||||
v-if="socialAccount.avatar_url"
|
||||
:src="socialAccount.avatar_url"
|
||||
:alt="socialAccount.display_name"
|
||||
class="h-9 w-9 rounded-full object-cover"
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
class="flex h-9 w-9 items-center justify-center rounded-full bg-gradient-to-br from-[#2aabee] to-[#229ed9] font-semibold text-white"
|
||||
>
|
||||
{{ socialAccount.display_name?.charAt(0) }}
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<div
|
||||
class="truncate text-[15px] font-semibold text-[#1f232b] dark:text-white"
|
||||
>
|
||||
{{ socialAccount.display_name || 'Channel' }}
|
||||
</div>
|
||||
<div class="text-[13px] text-[#707991] dark:text-[#708499]">
|
||||
channel
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Chat area -->
|
||||
<div class="flex-1 overflow-y-auto px-3 py-4">
|
||||
<div
|
||||
class="max-w-[85%] overflow-hidden rounded-2xl rounded-bl-md bg-white shadow-sm dark:bg-[#182533]"
|
||||
>
|
||||
<!-- Media -->
|
||||
<div v-if="media.length > 0">
|
||||
<div
|
||||
class="overflow-hidden"
|
||||
:class="{
|
||||
'grid grid-cols-2 gap-0.5': media.length >= 2,
|
||||
}"
|
||||
>
|
||||
<div
|
||||
v-for="(item, index) in media.slice(0, 4)"
|
||||
:key="item.id"
|
||||
class="relative overflow-hidden"
|
||||
:class="{
|
||||
'aspect-[4/3]': media.length === 1,
|
||||
'aspect-square': media.length > 1,
|
||||
}"
|
||||
>
|
||||
<img
|
||||
v-if="!isVideoMedia(item)"
|
||||
:src="item.url"
|
||||
:alt="item.original_filename"
|
||||
class="h-full w-full object-cover"
|
||||
/>
|
||||
<VideoPreview
|
||||
v-else
|
||||
:src="item.url"
|
||||
video-class="w-full h-full object-cover bg-black"
|
||||
/>
|
||||
<div
|
||||
v-if="media.length > 4 && index === 3"
|
||||
class="absolute inset-0 flex items-center justify-center bg-black/60"
|
||||
>
|
||||
<span class="text-xl font-semibold text-white"
|
||||
>+{{ media.length - 4 }}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Text + meta -->
|
||||
<div class="px-3 py-2">
|
||||
<div
|
||||
v-if="content"
|
||||
class="text-[15px] leading-[20px] whitespace-pre-wrap text-[#1f232b] dark:text-white"
|
||||
>
|
||||
{{ content }}
|
||||
</div>
|
||||
<div
|
||||
class="mt-1 flex items-center justify-end gap-1 text-[12px] text-[#707991] dark:text-[#708499]"
|
||||
>
|
||||
<svg
|
||||
class="h-3.5 w-3.5"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
>
|
||||
<path
|
||||
d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z"
|
||||
/>
|
||||
<circle cx="12" cy="12" r="3" />
|
||||
</svg>
|
||||
<span>0</span>
|
||||
<span class="ml-1">4:30 PM</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -11,6 +11,7 @@ const PLATFORM_LOGOS: Record<string, string> = {
|
|||
bluesky: '/images/accounts/bluesky.png',
|
||||
pinterest: '/images/accounts/pinterest.png',
|
||||
mastodon: '/images/accounts/mastodon.png',
|
||||
telegram: '/images/accounts/telegram.svg',
|
||||
};
|
||||
|
||||
const PLATFORM_LABELS: Record<string, string> = {
|
||||
|
|
@ -26,6 +27,7 @@ const PLATFORM_LABELS: Record<string, string> = {
|
|||
bluesky: 'Bluesky',
|
||||
pinterest: 'Pinterest',
|
||||
mastodon: 'Mastodon',
|
||||
telegram: 'Telegram',
|
||||
};
|
||||
|
||||
const PLATFORM_CONTENT_TYPES: Record<string, string[]> = {
|
||||
|
|
@ -41,6 +43,7 @@ const PLATFORM_CONTENT_TYPES: Record<string, string[]> = {
|
|||
pinterest: ['pinterest_pin', 'pinterest_video_pin', 'pinterest_carousel'],
|
||||
bluesky: ['bluesky_post'],
|
||||
mastodon: ['mastodon_post'],
|
||||
telegram: ['telegram_post'],
|
||||
};
|
||||
|
||||
export interface ContentTypeOption {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ export const ContentType = {
|
|||
PinterestCarousel: 'pinterest_carousel',
|
||||
BlueskyPost: 'bluesky_post',
|
||||
MastodonPost: 'mastodon_post',
|
||||
TelegramPost: 'telegram_post',
|
||||
} as const;
|
||||
|
||||
export type ContentTypeValue = (typeof ContentType)[keyof typeof ContentType];
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ export const Platform = {
|
|||
Pinterest: 'pinterest',
|
||||
Bluesky: 'bluesky',
|
||||
Mastodon: 'mastodon',
|
||||
Telegram: 'telegram',
|
||||
} as const;
|
||||
|
||||
export type PlatformValue = (typeof Platform)[keyof typeof Platform];
|
||||
|
|
|
|||
Loading…
Reference in a new issue