Fix
This commit is contained in:
@@ -72,7 +72,7 @@ const parseData = computed(() => {
|
||||
</span>
|
||||
<div class="card-audio__type-category" >
|
||||
<div class="card-audio__type" v-if="type">{{ type }}</div>
|
||||
<nuxt-link v-if="parseData.category" to="#" class="card-audio__category" :style="LAYOUT_PARSE['category-article']" :class="LAYOUT_PARSE['category-article_Class']">{{
|
||||
<nuxt-link v-if="parseData?.category" to="#" class="card-audio__category" :style="LAYOUT_PARSE['category-article']" :class="LAYOUT_PARSE['category-article_Class']">{{
|
||||
parseData?.category?.title
|
||||
}}</nuxt-link>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<script setup lang="ts">
|
||||
const emit = defineEmits(["dropData", "selectComponent"]);
|
||||
const _props = defineProps<{
|
||||
dataResult?: any;
|
||||
dataType?: any;
|
||||
dataQuery?: any;
|
||||
layout?: string;
|
||||
label?: string;
|
||||
}>();
|
||||
const { currentArticle } = storeToRefs(useArticleStore())
|
||||
console.log(currentArticle.value, 'currentArticle')
|
||||
</script>
|
||||
<template>
|
||||
<div class="overflow-hidden emagazine">
|
||||
<!-- bổ sung sau -->
|
||||
<!-- <img :src="currentArticle.thumbnail" alt="" class="w-full object-cover">
|
||||
|
||||
<div class="px-44px pb-30px my-30px max-w-660px mx-auto border-b-1px border-#000">
|
||||
|
||||
</div> -->
|
||||
|
||||
<div v-html="currentArticle.detail"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.content {
|
||||
width: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -1,15 +1,14 @@
|
||||
<script setup lang="ts">
|
||||
import { enumPageComponentTemplates } from "@/definitions/enum";
|
||||
import { DEFAULT_QUERY_DROP } from "@/utils/parseSQL";
|
||||
import { isEmpty } from "@/utils/lodash";
|
||||
import { getInputValue } from "@/utils/parseSQL";
|
||||
import { DEFAULT_QUERY_DROP, getInputValue } from "@/utils/parseSQL";
|
||||
const emit = defineEmits(["dropData", "selectComponent"]);
|
||||
|
||||
const _props = defineProps<{
|
||||
dataResult?: any;
|
||||
dataType?: any;
|
||||
dataQuery?: any;
|
||||
layout?: string;
|
||||
label?: any;
|
||||
label?: string;
|
||||
}>();
|
||||
const SETTING_OPTIONS = {
|
||||
BREADCRUMB_MAX_ELEMENT: 3,
|
||||
@@ -18,6 +17,9 @@ const LAYOUT_PARSE = computed(() => {
|
||||
const designObject = _props.label ? getInputValue(_props.label, "OBJECT") : {};
|
||||
return Object.assign({}, designObject);
|
||||
});
|
||||
const selectComponent = () => {
|
||||
emit("selectComponent");
|
||||
};
|
||||
|
||||
const parseData = computed(() => {
|
||||
if (!_props.dataResult) return;
|
||||
@@ -25,20 +27,29 @@ const parseData = computed(() => {
|
||||
return result;
|
||||
});
|
||||
|
||||
const articleStore = useArticleStore();
|
||||
const currentArticle = computed(() => articleStore.currentArticleGeneral);
|
||||
const drop = (e: any) => {
|
||||
if (e.dataTransfer.getData(`${enumPageComponentTemplates.ARTICLE}`)) {
|
||||
const data = e.dataTransfer.getData(`${enumPageComponentTemplates.ARTICLE}`);
|
||||
const { dataType, dataResult } = JSON.parse(data);
|
||||
const dataQuery = DEFAULT_QUERY_DROP(dataType, dataResult.id);
|
||||
emit("dropData", {
|
||||
dataType,
|
||||
dataResult,
|
||||
dataQuery: dataQuery,
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="overflow-hidden">
|
||||
<div @click="selectComponent" class="overflow-hidden" @dragover.prevent @drop.stop.prevent="drop">
|
||||
<div class="breadcrumb" v-if="!LAYOUT_PARSE['HideBreadcrumb']">
|
||||
<ul class="breadcrumb__list">
|
||||
<li
|
||||
class="breadcrumb__list__item"
|
||||
v-for="(item, index) in _props.dataResult && _props.dataResult?.length > 0 ? _props.dataResult : Array(SETTING_OPTIONS.BREADCRUMB_MAX_ELEMENT).fill(null)"
|
||||
:key="index"
|
||||
:class="isEmpty(item) && 'empty'"
|
||||
>
|
||||
<p v-if="!isEmpty(item)" class="breadcrumb__list__item__title">
|
||||
<p class="breadcrumb__list__item__title">
|
||||
{{ item?.title }}
|
||||
</p>
|
||||
</li>
|
||||
|
||||
@@ -1,55 +1,76 @@
|
||||
<script setup lang="ts">
|
||||
import { isEmpty } from "@/utils/lodash";
|
||||
|
||||
const emit = defineEmits(["dropData", "selectComponent"]);
|
||||
const { categoryTree } = storeToRefs(useCategoryStore());
|
||||
const { currentArticle } = storeToRefs(useArticleStore());
|
||||
if (categoryTree.value) {
|
||||
await useCategoryStore().fetchBySiteId();
|
||||
}
|
||||
const _props = defineProps<{
|
||||
dataResult?: any;
|
||||
dataResult?: any[];
|
||||
}>();
|
||||
const SETTING_OPTIONS = {
|
||||
BREADCRUMB_MAX_ELEMENT: 3,
|
||||
};
|
||||
const currentCategoryTree = findElementPathById(categoryTree.value, currentArticle.value.categoryId);
|
||||
function findElementPathById(categories: any[], targetId: number, path: any[] = []) {
|
||||
for (const category of categories) {
|
||||
const currentPath = [...path, { title: category.title, code: category.code }];
|
||||
if (category.id === targetId) {
|
||||
return currentPath;
|
||||
}
|
||||
if (category.children) {
|
||||
const result: any = findElementPathById(category.children, targetId, currentPath);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log(currentArticle.value, "currentArticle");
|
||||
</script>
|
||||
<template>
|
||||
<div class="overflow-hidden">
|
||||
<div class="breadcrumb">
|
||||
<ul class="breadcrumb__list">
|
||||
<li
|
||||
class="breadcrumb__list__item"
|
||||
v-for="(item, index) in _props.dataResult && _props.dataResult?.length > 0 ? _props.dataResult : Array(SETTING_OPTIONS.BREADCRUMB_MAX_ELEMENT).fill(null)"
|
||||
:key="index"
|
||||
:class="isEmpty(item) && 'empty'"
|
||||
>
|
||||
<p v-if="!isEmpty(item)" class="breadcrumb__list__item__title">
|
||||
{{ item?.title }}
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="overflow-hidden w-full max-w-1385px mx-auto px-30px image">
|
||||
<div class="">
|
||||
<div class="category flex justify-between flex-wrap items-center mb-10px">
|
||||
<ul class="flex gap-32px">
|
||||
<li v-for="(category, index) in currentCategoryTree" :key="index" class="first:text-#000 text-#929292 last:after:content-[''] relative after:absolute after:content-['/'] after:text-20px after:right--20px">
|
||||
<nuxt-link class="font-raleway text-18px font-500 leading-180% uppercase" :to="`${category.code}`">{{ category.title }}</nuxt-link>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p class="breakcrumb__time">Ngày tạo image</p>
|
||||
</div>
|
||||
|
||||
<div class="content">Nội dung bài viết sẽ ở đây</div>
|
||||
|
||||
<div class="btn-wrap w-100 max-w">
|
||||
<div class="center-y">
|
||||
<p title="Quay trở lại" class="button--back">
|
||||
<Icon name="fa6-solid:arrow-left" />
|
||||
</p>
|
||||
<button class="button--bookmark">
|
||||
<Icon name="fa6-regular:bookmark" />
|
||||
</button>
|
||||
<div v-if="currentArticle.topics" class="pl-20px relative bg-primary inline-block">
|
||||
<nuxt-link class="h-30px block py-4px px-16px border-1 border-#000 bg-white text-12px leading-180% font-raleway font-400" :to="`/topic/${currentArticle.topics[0].code}`">{{ currentArticle.topics[0].title }}</nuxt-link>
|
||||
</div>
|
||||
</div>
|
||||
<h2 class="font-gelasio text-44px font-bold leading-130%" v-if="currentArticle.title" v-html="currentArticle.title"></h2>
|
||||
<!-- <div class="grid grid-cols-12 gap-20px">
|
||||
<div class="col-span-3"></div>
|
||||
</div> -->
|
||||
|
||||
<div class="center-y">
|
||||
<button title="Copy link" class="button--back copy-link">
|
||||
<Icon name="mdi:link-variant" />
|
||||
</button>
|
||||
<div class="author flex gap-12px my-20px" v-if="currentArticle.authors">
|
||||
<ul class="flex">
|
||||
<li :style="{ 'z-index': index + 1 }" class="relative ml--12px first:ml-0" v-for="(author, index) in currentArticle.authors" :key="index">
|
||||
<nuxt-link :to="`tac-gia/${author.code}`">
|
||||
<img :src="author.thumbnail || `http://picsum.photos/1024/600?random=1`" alt="" class="w-64px p-1px border-1px border-white h-64px object-cover rounded-full" />
|
||||
</nuxt-link>
|
||||
</li>
|
||||
</ul>
|
||||
<div>
|
||||
<div class="mt-10px">
|
||||
<nuxt-link class="font-raleway text-#000" v-for="(author, index) in currentArticle.authors" :key="index" :to="`/tac-gia/${author.code}`">{{ author.title + (index < currentArticle.authors.length - 1 ? ", " : "") }}</nuxt-link>
|
||||
</div>
|
||||
<div class="text-12px">Xuất bản vào {{ formatDate(currentArticle.publishedOn, "DD/MM/YYYY | hh:mm") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-html="currentArticle.detail"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
$max-width: 680px;
|
||||
$max-width: 1276px;
|
||||
|
||||
.breadcrumb {
|
||||
display: flex;
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
<script setup lang="ts">
|
||||
const emit = defineEmits(["dropData", "selectComponent"]);
|
||||
const _props = defineProps<{
|
||||
dataResult?: any;
|
||||
dataType?: any;
|
||||
dataQuery?: any;
|
||||
layout?: string;
|
||||
label?: string;
|
||||
}>();
|
||||
const { currentArticle } = storeToRefs(useArticleStore())
|
||||
console.log(currentArticle.value, 'currentArticle')
|
||||
</script>
|
||||
<template>
|
||||
<div class="overflow-hidden infographic">
|
||||
<!-- bổ sung sau -->
|
||||
<!-- <img :src="currentArticle.thumbnail" alt="" class="w-full object-cover">
|
||||
|
||||
<div class="px-44px pb-30px my-30px max-w-660px mx-auto border-b-1px border-#000">
|
||||
|
||||
</div> -->
|
||||
|
||||
<div v-html="currentArticle.detail"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.center-y {
|
||||
width: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -1,93 +1,254 @@
|
||||
<script setup lang="ts">
|
||||
import { useArticleStore } from "~/stores/articles";
|
||||
import Poll from "~/components/article/immerse/Poll.vue";
|
||||
import Quiz from "~/components/article/immerse/Quiz.vue";
|
||||
import Survey from "~/components/article/immerse/Survey.vue";
|
||||
import Document from "~/components/article/immerse/Document.vue";
|
||||
import Attachment from "@/components/article/immerse/Attachment.vue";
|
||||
import Tag from "@/components/article/immerse/Tag.vue";
|
||||
const { currentArticle } = storeToRefs(useArticleStore());
|
||||
import { useDynamicPageStore } from "~/stores/dynamic-page";
|
||||
import { useCategoryStore } from "~/stores/category";
|
||||
|
||||
const store = reactive({
|
||||
dynamicPage: useDynamicPageStore(),
|
||||
article: useArticleStore(),
|
||||
category: useCategoryStore(),
|
||||
});
|
||||
|
||||
const { categoryTree } = storeToRefs(store.category);
|
||||
|
||||
await store.category.fetchBySiteId();
|
||||
const currentCategoryTree = (store.category.currentCategoryTree = findElementPathById(categoryTree.value, currentArticle.value.categoryId));
|
||||
function findElementPathById(categories: any[], targetId: number, path: any[] = []) {
|
||||
for (const category of categories) {
|
||||
const currentPath = [...path, { title: category.title, code: category.code }];
|
||||
if (category.id === targetId) {
|
||||
return currentPath;
|
||||
}
|
||||
if (category.children) {
|
||||
const result: any = findElementPathById(category.children, targetId, currentPath);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
clickElement("figure", "custom-figure", "data-code");
|
||||
clickElement("author", "author", "data-code");
|
||||
|
||||
let detailEmagazine = document.querySelector('div[layout="ARTICLE_DETAIL_EMAGAZINE"]');
|
||||
let breadcrumb = document.querySelector('div[layout="BREADCRUM_DEFAULT"]');
|
||||
if (detailEmagazine && breadcrumb) {
|
||||
breadcrumb.classList.add("lg:max-w-640px", "mx-auto");
|
||||
}
|
||||
});
|
||||
|
||||
function clickElement(type: string, selector: string, attribute: string) {
|
||||
const elements = document.querySelectorAll(selector);
|
||||
elements.forEach((element) => {
|
||||
element.addEventListener("click", (event) => {
|
||||
event.preventDefault();
|
||||
const url = `${window.location.protocol}//${window.location.host}/${type}/${element.getAttribute(attribute)}`;
|
||||
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const isBookmark = ref(false);
|
||||
const onClickBookmark = () => {
|
||||
isBookmark.value = !isBookmark.value;
|
||||
};
|
||||
async function copyLink() {
|
||||
try {
|
||||
const url = window.location.href;
|
||||
await navigator.clipboard.writeText(url);
|
||||
alert("copy link thành công");
|
||||
} catch (error) {
|
||||
alert(error);
|
||||
}
|
||||
}
|
||||
|
||||
const getSrc = (htmlString: string) => {
|
||||
const srcRegex = /src="([^"]+)"/;
|
||||
return htmlString?.match(srcRegex);
|
||||
};
|
||||
|
||||
const isMoreControl = ref(false);
|
||||
const isPlayed = ref(true);
|
||||
const isVolume = ref(true);
|
||||
const speedList = ref<{ [key: number]: string }>({
|
||||
1: "0.5x",
|
||||
2: "0.75x",
|
||||
3: "1.0x",
|
||||
4: "1.25x",
|
||||
5: "1.50x",
|
||||
});
|
||||
const speedIndexDefault = ref(3);
|
||||
const speedDefault = ref(speedList.value[speedIndexDefault.value]);
|
||||
const volume = ref(1.0);
|
||||
const audioPlayer = ref<HTMLAudioElement | null>(null);
|
||||
const currentTime = ref(0);
|
||||
const duration = ref(0);
|
||||
|
||||
function setUpVolums() {
|
||||
isVolume.value = !isVolume.value;
|
||||
if (audioPlayer.value) {
|
||||
if (isVolume.value) {
|
||||
audioPlayer.value.volume = 1;
|
||||
} else {
|
||||
audioPlayer.value.volume = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const updateVolume = (num?: number) => {
|
||||
if (audioPlayer.value) {
|
||||
if(num) {
|
||||
volume.value += num
|
||||
}
|
||||
// console.log('1231321')
|
||||
audioPlayer.value.volume = volume.value;
|
||||
}
|
||||
};
|
||||
|
||||
function chanageSpeed() {
|
||||
if (speedIndexDefault.value < 5) {
|
||||
speedIndexDefault.value += 1;
|
||||
if (audioPlayer.value) {
|
||||
audioPlayer.value.playbackRate += 0.25;
|
||||
}
|
||||
speedDefault.value = speedList.value[speedIndexDefault.value];
|
||||
} else {
|
||||
if (audioPlayer.value) {
|
||||
audioPlayer.value.playbackRate = 0.5;
|
||||
}
|
||||
speedIndexDefault.value = 1;
|
||||
speedDefault.value = speedList.value[1];
|
||||
}
|
||||
}
|
||||
|
||||
function togglePlayer() {
|
||||
isPlayed.value = !isPlayed.value;
|
||||
if (audioPlayer.value) {
|
||||
if (isPlayed.value) {
|
||||
audioPlayer.value.pause();
|
||||
} else {
|
||||
audioPlayer.value.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function replayAndForward(time: number) {
|
||||
if (audioPlayer.value) {
|
||||
if (audioPlayer.value.currentTime == audioPlayer.value.duration) {
|
||||
isPlayed.value = true;
|
||||
} else {
|
||||
audioPlayer.value.currentTime = audioPlayer.value.currentTime + time;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const seekToTime = () => {
|
||||
if (audioPlayer.value) {
|
||||
audioPlayer.value.currentTime = currentTime.value;
|
||||
}
|
||||
};
|
||||
|
||||
const updateCurrentTime = () => {
|
||||
if (audioPlayer.value) {
|
||||
currentTime.value = audioPlayer.value.currentTime;
|
||||
}
|
||||
};
|
||||
|
||||
const updateDuration = () => {
|
||||
if (audioPlayer.value) {
|
||||
duration.value = audioPlayer.value.duration;
|
||||
}
|
||||
};
|
||||
|
||||
const currrentTimeComputed = computed(() => {
|
||||
return utils.formattedTime(currentTime.value);
|
||||
});
|
||||
|
||||
const durationComputed = computed(() => {
|
||||
return utils.formattedTime(duration.value);
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div
|
||||
class="podcast__wrapper overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="podcast"
|
||||
>
|
||||
<p
|
||||
class="podcast__content__time"
|
||||
>
|
||||
Ngày tạo podcast
|
||||
<div class="lg:p-40px md:p-30px p-5 border-1px border-solid border-black/10 rounded-8px">
|
||||
<div class="flex md:flex-row flex-col md:gap-6 gap-2 justify-between mb-10px">
|
||||
<p class="text-#9f9f9f text-14px mb-2 md:hidden block text-center">
|
||||
{{ utils.dateFormat(currentArticle?.publishedOn, "dddd, DD/MM/YYYY - HH:mm") }}
|
||||
</p>
|
||||
<figure><img src="http://picsum.photos/1024/600?random=1'" alt="Ảnh podcast" title="Ảnh podcast" /></figure>
|
||||
<div
|
||||
class="podcast__content"
|
||||
>
|
||||
<p
|
||||
class="podcast__content__time"
|
||||
>
|
||||
Ngày tạo podcast
|
||||
</p>
|
||||
<h1 class="podcast__content__title">Tiêu đề podcast</h1>
|
||||
<p
|
||||
class="podcast__content__text"
|
||||
>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
<figure class="!w-auto"><img class="w-150px h-150px rounded-8px shadow-md cursor-pointer" :src="currentArticle?.thumbnail" alt="Ảnh podcast" title="Ảnh podcast" /></figure>
|
||||
<div class="flex-1 text-#222 m-0 md:text-left text-center">
|
||||
<p class="text-#9f9f9f text-14px mb-2 md:block hidden">
|
||||
{{ utils.dateFormat(currentArticle?.publishedOn, "dddd, DD/MM/YYYY - HH:mm") }}
|
||||
</p>
|
||||
<h1 class="text-24px md:mb-4 mb-2 font-bold" v-html="currentArticle?.title"></h1>
|
||||
<p class="hidden md:line-clamp-3" v-html="currentArticle?.intro"></p>
|
||||
</div>
|
||||
|
||||
<ul
|
||||
class="buttons"
|
||||
>
|
||||
<li><Icon name="mdi:bookmark-outline" /></li>
|
||||
<li><Icon name="material-symbols:mode-comment-outline" /></li>
|
||||
<ul class="items-start gap-2 m-0 p-0 md:flex hidden">
|
||||
<li class="w-9 h-9 bg-white border-1 border-solid border-[rgb(229, 231, 235)] cursor-pointer shadow-md rounded-50px relative hover:bg-primary-100 hover:text-primary-600">
|
||||
<Icon class="text-18px absolute top-50% left-50% translate-x--50% translate-y--50%" name="mdi:bookmark-outline" />
|
||||
</li>
|
||||
<li class="w-9 h-9 bg-white border-1 border-solid border-[rgb(229, 231, 235)] cursor-pointer shadow-md rounded-50px relative hover:bg-primary-100 hover:text-primary-600">
|
||||
<Icon class="text-18px absolute top-50% left-50% translate-x--50% translate-y--50%" name="material-symbols:mode-comment-outline" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="playlist">
|
||||
<div class="playlist__time">
|
||||
<span>5:00</span>
|
||||
<span>10:00</span>
|
||||
<audio :src="getSrc(currentArticle?.detail)?.[1]" preload="auto" ref="audioPlayer" @timeupdate="updateCurrentTime" @loadedmetadata="updateDuration" />
|
||||
<div class="p-2">
|
||||
<input class="w-full accent-primary-600 cursor-pointer" type="range" v-model="currentTime" @input="seekToTime" :max="duration" />
|
||||
<div class="flex justify-between">
|
||||
<span>{{ currrentTimeComputed }}</span>
|
||||
<span>{{ durationComputed }}</span>
|
||||
</div>
|
||||
<div class="playlist__buttons">
|
||||
<div class="playlist__buttons__left">
|
||||
<div
|
||||
class="button__prev"
|
||||
>
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="md:w-150px text-left">
|
||||
<div class="text-28px text-primary-600 md:hidden block">
|
||||
<Icon name="material-symbols:skip-previous" />
|
||||
</div>
|
||||
<div
|
||||
class="sound"
|
||||
>
|
||||
<Icon name="material-symbols:volume-mute"></Icon>
|
||||
<div></div>
|
||||
<Icon name="material-symbols:volume-up"></Icon>
|
||||
<div class="md:inline-flex hidden items-center gap-2 ml--10px h9 text-primary-600 rounded-8px text-28px cursor-pointer hover:bg-primary-100">
|
||||
<Icon @click="updateVolume(-0.1)" name="material-symbols:volume-mute"></Icon>
|
||||
<input v-if="isVolume" class="accent-primary-600 h-1 w-12 lg:w-20 cursor-pointer" type="range" v-model="volume" @input="updateVolume()" min="0.1" max="1" step="0.1" />
|
||||
<Icon @click="updateVolume(0.1)" name="material-symbols:volume-up"></Icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="play">
|
||||
<Icon name="fluent:skip-back-10-48-filled" />
|
||||
<Icon name="material-symbols:play-arrow" class="button" />
|
||||
<Icon name="fluent:skip-forward-10-48-filled" />
|
||||
<div class="flex items-center justify-center gap-4 flex-1 text-28px text-primary-600">
|
||||
<Icon @click="replayAndForward(-10)" name="fluent:skip-back-10-48-filled" />
|
||||
<button @click="togglePlayer" class="bg-transparent">
|
||||
<Icon v-if="isPlayed" name="material-symbols:play-arrow-rounded" class="text-64px" />
|
||||
<Icon v-if="!isPlayed" name="material-symbols:pause" class="text-64px" />
|
||||
</button>
|
||||
|
||||
<Icon @click="replayAndForward(10)" name="fluent:skip-forward-10-48-filled" />
|
||||
</div>
|
||||
|
||||
<div class="playlist__buttons__right">
|
||||
<div
|
||||
class="button__next"
|
||||
>
|
||||
<div class="md:w-150px text-right">
|
||||
<div class="text-28px text-primary-600 md:hidden block">
|
||||
<Icon name="material-symbols:skip-next" />
|
||||
</div>
|
||||
<div
|
||||
class="speed"
|
||||
>
|
||||
<span>Tốc độ phát: </span>
|
||||
<strong>1x</strong>
|
||||
<div class="text-14px text-primary-600 md:block hidden cursor-pointer" @click="chanageSpeed">
|
||||
<span class="font-300">Tốc độ phát: </span>
|
||||
<strong class="font-bold text-20px ml-1">{{ speedDefault }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p
|
||||
class="podcast__content__text"
|
||||
>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
||||
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
</p>
|
||||
<p class="md:hidden block" v-html="currentArticle?.intro"></p>
|
||||
</div>
|
||||
</template>
|
||||
<style lang="scss">
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
<script setup lang="ts">
|
||||
import Comment from "@/components/dynamic-page/page-component/templates/others/comments/Default.vue";
|
||||
// const store = {
|
||||
// page: useCmsPageStore(),
|
||||
// };
|
||||
// import Comment from "@/components/cms/page-component/templates/others/comments/Default.vue";
|
||||
</script>
|
||||
<template>
|
||||
<div class="container overflow-hidden">
|
||||
video
|
||||
<!-- <div class="container overflow-hidden">
|
||||
<div class="video row">
|
||||
<div
|
||||
class="video__left"
|
||||
:class="
|
||||
store.page.classifyScreenByWidth({
|
||||
computer: 'col-8 px-0',
|
||||
tablet: 'col-8 px-0',
|
||||
smartphone: 'col-12',
|
||||
})
|
||||
"
|
||||
>
|
||||
<video controls="controls" width="100%" height="100%" data-file-id="149" data-resource="https://acp-api.vpress.vn/Resources/Video/983d2f57-7743-472f-b22d-fc73085af6d5.mp4" data-title="Download.mp4">
|
||||
<source src="" type="video/mp4" />
|
||||
@@ -14,13 +25,27 @@ import Comment from "@/components/dynamic-page/page-component/templates/others/c
|
||||
|
||||
<div
|
||||
class="video__right bg-body-tertiary"
|
||||
:class="
|
||||
store.page.classifyScreenByWidth({
|
||||
computer: 'col-4 ps-4 pt-2',
|
||||
tablet: 'col-4 ps-4 pt-2',
|
||||
smartphone: 'col-12 pt-2',
|
||||
})
|
||||
"
|
||||
>
|
||||
<h1
|
||||
class=""
|
||||
:class="
|
||||
store.page.classifyScreenByWidth({
|
||||
computer: 'fs-1',
|
||||
tablet: 'fs-2',
|
||||
smartphone: 'fs-3',
|
||||
})
|
||||
"
|
||||
>
|
||||
Tiêu đề video
|
||||
</h1>
|
||||
<p class="line-clamp-3 fs-5 fw-light">
|
||||
<p class="line-clamp-3 fs-5 fw-light" :class="store.page.classifyScreenByWidth({})">
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
</p>
|
||||
@@ -30,7 +55,7 @@ import Comment from "@/components/dynamic-page/page-component/templates/others/c
|
||||
<Comment />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
.line-clamp-3 {
|
||||
|
||||
@@ -3,4 +3,6 @@
|
||||
export { default as Article_Detail_General } from './General.vue'
|
||||
export { default as Article_Detail_Podcast } from './Podcast.vue'
|
||||
export { default as Article_Detail_Video } from './Video.vue'
|
||||
export { default as Article_Detail_Image } from './Image.vue'
|
||||
export { default as Article_Detail_Image } from './Image.vue'
|
||||
export { default as Article_Detail_Emagazine } from './Emagazine.vue'
|
||||
export { default as Article_Detail_Infographic } from './Infographic.vue'
|
||||
@@ -2,7 +2,7 @@
|
||||
import { enumPageComponentTemplate, enumPageComponentKey, enumPageComponentLayouts } from "@/definitions/enum";
|
||||
|
||||
// import { Article_Card, Article_Detail_Video, Article_Detail_Podcast, Article_Detail_General, Article_Detail_Image } from "./index";
|
||||
import { Article_Detail_General, Article_Detail_Podcast, Article_Detail_Video, Article_Detail_Image } from "./index";
|
||||
import { Article_Detail_General, Article_Detail_Podcast, Article_Detail_Video, Article_Detail_Image, Article_Detail_Emagazine, Article_Detail_Infographic } from "./index";
|
||||
const _props = defineProps<{
|
||||
settings: any;
|
||||
component?: any;
|
||||
@@ -13,6 +13,8 @@ const definedDynamicComponent: Record<string, any> = {
|
||||
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_PODCAST"]]: Article_Detail_Podcast,
|
||||
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_VIDEO"]]: Article_Detail_Video,
|
||||
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_IMAGE"]]: Article_Detail_Image,
|
||||
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_EMAGAZINE"]]: Article_Detail_Emagazine,
|
||||
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_INFOGRAPHIC"]]: Article_Detail_Infographic,
|
||||
};
|
||||
|
||||
const getCurrentComponent = computed(() => `${_props.settings.layout}`);
|
||||
|
||||
Reference in New Issue
Block a user