From 28bb2b6ead3eb0e6fe5f2ca24f55f9f161573868 Mon Sep 17 00:00:00 2001 From: admin Date: Sat, 28 Mar 2026 17:31:30 +1000 Subject: [PATCH] =?UTF-8?q?=D0=B0=D0=BA=D1=82=D1=83=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B5=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B8=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80?= =?UTF-8?q?=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Section.vue | 251 +++++++++++++++++++++---------------- src/components/Stat.vue | 88 +++++++------ 2 files changed, 188 insertions(+), 151 deletions(-) diff --git a/src/components/Section.vue b/src/components/Section.vue index ba799fd..8132ea6 100644 --- a/src/components/Section.vue +++ b/src/components/Section.vue @@ -1,4 +1,3 @@ - + +onUnmounted(() => { + stopPolling(); + if (observer) observer.disconnect(); +}); + \ No newline at end of file diff --git a/src/components/Stat.vue b/src/components/Stat.vue index 8ba890f..e63822d 100644 --- a/src/components/Stat.vue +++ b/src/components/Stat.vue @@ -2,22 +2,8 @@ import { ref, onMounted, onBeforeUnmount } from "vue"; import axios from "axios"; -// Реактивная проверка темной темы -const isDarkMode = ref(document.documentElement.classList.contains("dark")); - -// Следим за изменениями класса dark на html -onMounted(() => { - // Инициализация при загрузке (если класс ещё не установлен) - isDarkMode.value = document.documentElement.classList.contains("dark"); - - const observer = new MutationObserver(() => { - isDarkMode.value = document.documentElement.classList.contains("dark"); - }); - observer.observe(document.documentElement, { - attributes: true, - attributeFilter: ["class"], - }); -}); +// ✅ Добавляем emit для уведомления родителя об изменениях +const emit = defineEmits(["update:viewed", "update:status"]); const props = defineProps({ url: String, @@ -33,12 +19,35 @@ const props = defineProps({ status: Boolean, }); -//Код для раскрытия/скрытия карточки +// ✅ Делаем viewed и status реактивными для локального обновления +const localViewed = ref(props.viewed); +const localStatus = ref(props.status); + +// Следим за изменениями props и обновляем локальные значения +import { watch } from "vue"; +watch(() => props.viewed, (val) => { localViewed.value = val; }); +watch(() => props.status, (val) => { localStatus.value = val; }); + +// Тема +const isDarkMode = ref(document.documentElement.classList.contains("dark")); + +onMounted(() => { + isDarkMode.value = document.documentElement.classList.contains("dark"); + const observer = new MutationObserver(() => { + isDarkMode.value = document.documentElement.classList.contains("dark"); + }); + observer.observe(document.documentElement, { + attributes: true, + attributeFilter: ["class"], + }); +}); + +// Карточка const isOpen = ref(false); const cardRef = ref(null); function toggle() { - isOpen.value = true; //!isOpen.value; + isOpen.value = true; } function handleClickOutside(event) { @@ -47,39 +56,42 @@ function handleClickOutside(event) { } } +// ✅ Обновляем локально + отправляем emit const viewed_b = async () => { + const newValue = !localViewed.value; + localViewed.value = newValue; // Локальное обновление сразу + emit("update:viewed", { url: props.url, viewed: newValue }); + try { await axios.post( "https://allowlgroup.ru/api/8002/update_viewed_status", null, - { - params: { - url: props.url, - viewed: !props.viewed, - }, - }, + { params: { url: props.url, viewed: newValue } } ); } catch (err) { console.log(err); + // При ошибке откатываем локальное значение + localViewed.value = !newValue; } }; const status_b = async () => { + const newValue = !localStatus.value; + localStatus.value = newValue; // Локальное обновление сразу + emit("update:status", { url: props.url, status: newValue }); + try { await axios.post( "https://allowlgroup.ru/api/8002/update_status_status", null, - { - params: { - url: props.url, - status: !props.status, - }, - }, + { params: { url: props.url, status: newValue } } ); } catch (err) { console.log(err); + localStatus.value = !newValue; } }; + const download = async () => { try { const rez = await axios.get("https://allowlgroup.ru/api/8001/file_download", { @@ -95,10 +107,9 @@ const download = async () => { }), ); const link = document.createElement("a"); - // Принудительно добавляем .docx к имени файла let filename = props.title + ".docx"; try { - const disposition = rez.headers && rez.headers["content-disposition"]; + const disposition = rez.headers?.["content-disposition"]; if (disposition) { const match = disposition.match(/filename\*?=([^;\n]+)/i); if (match) { @@ -107,9 +118,7 @@ const download = async () => { filename = name; } } - } catch (e) { - /* ignore */ - } + } catch (e) { /* ignore */ } link.href = blobUrl; link.setAttribute("download", filename); document.body.appendChild(link); @@ -124,6 +133,7 @@ const download = async () => { onMounted(() => { document.addEventListener("click", handleClickOutside); }); + onBeforeUnmount(() => { document.removeEventListener("click", handleClickOutside); }); @@ -132,9 +142,8 @@ onBeforeUnmount(() => {