Задать вопрос
  • Не получается установить npm install. требуеться разобрать ошибку?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Все пакеты установились, но есть предупреждения о том, что в некоторых из них обнаружены уязвимости.

    Тут можно либо обновить пакеты до актуальных версий (что опасно на старых проектах и не факт, что поможет), либо заменить пакеты на другие. Ну или просто не обращать внимание.
    Ответ написан
    Комментировать
  • Как выполнение действия в определенное время?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Может что-то на основе обычного таймера.

    В этом примере планировщик задач (таймер) запускается с периодом 1 час. В методе TimerElapsed вы можете подключиться к базе данных и выполнить запрос для получения событий, а затем проверить каждое событие и отправить напоминание пользователю, если текущее время ближе к определенным моментам.
    using System;
    using System.Timers;
    
    public class EventReminder
    {
        private Timer timer;
    
        public EventReminder()
        {
            timer = new Timer();
            timer.Elapsed += TimerElapsed;
            timer.Interval = TimeSpan.FromHours(1).TotalMilliseconds; // Период проверки (1 час)
            timer.AutoReset = true;
            timer.Start();
        }
    
        private void TimerElapsed(object sender, ElapsedEventArgs e)
        {
            // Подключение к базе данных и выполнение запроса для получения событий
            // Проверка каждого события и отправка напоминания, если необходимо
        }
    }
    
    public class Program
    {
        public static void Main()
        {
            // Создание экземпляра EventReminder
            EventReminder eventReminder = new EventReminder();
    
            // Ожидание завершения программы (например, с помощью Console.ReadLine())
            Console.ReadLine();
        }
    }
    Ответ написан
    Комментировать
  • Почему команда работает только на половину?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Может что-то типа этого?
    import telebot
    import time
    import sched
    
    bot = telebot.TeleBot('TOKEN')
    
    # список для хранения id пользователей
    users = {}
    
    # функция для обработки команды /start
    @bot.message_handler(commands=['start'])
    def start(message):
        user_id = message.chat.id
        
        # добавляем user_id в словарь
        users[user_id] = True
        
        bot.send_message(user_id, "Привет! Ты подписался на уведомления.")
    
    # функция для отправки уведомлений
    def send_notifications():
        for user_id in users.keys():
            bot.send_message(user_id, "Уведомление.")
            
        # запускаем функцию через 5 минут
        scheduler.enter(300, 1, send_notifications)
        
    # инициализируем объект scheduler
    scheduler = sched.scheduler(time.time, time.sleep)
    # запускаем функцию send_notifications через 5 минут
    scheduler.enter(300, 1, send_notifications)
    # запускаем цикл планировщика
    scheduler.run()
    
    # запускаем цикл получения сообщений
    bot.polling()
    Ответ написан
  • Уходит вверх контент от GSAP после обновления страницы, как решить?

    scoffs
    @scoffs
    Fullstack | C# | Student
    GSAP не сохраняет последнее положение, поэтому всё улетает.

    Чтобы решить эту проблему, вам нужно сохранить текущее состояние анимации и восстановить его после перезагрузки страницы. Можно хранить в localStorage или sessionStorage.
    import { useEffect, useRef } from 'react';
    import gsap from 'gsap';
    import ScrollTrigger from 'gsap/ScrollTrigger';
    
    gsap.registerPlugin(ScrollTrigger);
    
    export default function HorizontalContent() {
      const itemsRef = useRef(null);
      const triggerRef = useRef(null);
    
      useEffect(() => {
        const items = itemsRef.current;
    
        const savedPosition = sessionStorage.getItem('animationPosition');
        const initialPosition = savedPosition ? JSON.parse(savedPosition) : { translateX: 0 };
    
        const pin = gsap.fromTo(
          items,
          initialPosition,
          {
            translateX: '-300vw',
            ease: 'none',
            duration: 1,
            scrollTrigger: {
              trigger: triggerRef.current,
              start: 'top top',
              end: '2000 top',
              scrub: 0.6,
              pin: true,
            },
          }
        );
    
        ScrollTrigger.addEventListener('refresh', () => {
          // Сохраняем текущую позицию анимации
          sessionStorage.setItem('animationPosition', JSON.stringify({ translateX: pin.progress() * -300 }));
          // Очищаем анимацию
          pin.kill();
          // Восстанавливаем исходное состояние анимации
          pin.progress(0).invalidate().restart();
        });
    
        return () => {
          pin.kill();
        };
      }, []);
    
      return (
        <div className={styles.content}>
          <div className={styles.container}>
            <div ref={triggerRef}>
              <div ref={itemsRef} className={styles.items}>
                <div className={styles.item}>
                  <Efficiency />
                </div>
                <div className={styles.item}>
                  <h3>Section 2</h3>
                </div>
                <div className={styles.item}>
                  <h3>Section 3</h3>
                </div>
                <div className={styles.item}>
                  <h3>Section 4</h3>
                </div>
              </div>
            </div>
          </div>
        </div>
      );
    };
    Ответ написан
  • Как закрывать модальное окно действием назад, избегая возвращения по истории?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Открытие окна не производит смены URL, ты остаешься на той же странице, поэтому достаточно странная необходимость делать закрытие модалки при клике на Назад, но это может выглядеть как-то так
    import { useHistory } from 'react-router-dom';
    
    function ModalComponent() {
      const history = useHistory();
    
      const handleCloseModal = () => {
        // Закрытие модального окна и замена текущего пути новым путем (например, '/')
        history.replace('/');
      };
    
      return (
        <div>
          {/* Ваше содержимое модального окна */}
          <button onClick={handleCloseModal}>Закрыть</button>
        </div>
      );
    }
    Ответ написан
  • Как правильно выполнить динамический vue роутинг?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Возможное решение
    router.beforeEach((to, from, next) => {
      const isAgreementAccepted = agreement.value;
      const isUserLoggedIn = Boolean(store.state.user.token);
    
      if (to.meta.requiresAuth && !isAgreementAccepted) {
        // Если требуется аутентификация и соглашение не принято,
        // перенаправляем на страницу TermsOfUseView
        next({ name: "TermsOfUseView" });
      } else if (to.name === "TermsOfUseView" && isAgreementAccepted) {
        // Если пользователь уже принял соглашение,
        // перенаправляем его на другую страницу, например, HomeView
        next({ name: "HomeView" });
      } else if (to.meta.requiresAuth && !isUserLoggedIn) {
        // Если требуется аутентификация и пользователь не вошел в систему,
        // перенаправляем на страницу AuthorizationView
        next({ name: "AuthorizationView" });
      } else if (to.meta.isGuest && isUserLoggedIn) {
        // Если пользователь вошел в систему, но на страницу доступа только для гостей,
        // перенаправляем на другую страницу, например, HomeView
        next({ name: "HomeView" });
      } else {
        // В остальных случаях просто продолжаем навигацию
        next();
      }
    });
    Ответ написан
  • Почему не работает бот?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Проверьте, что вы настроили параметры доступа к сообщениям в группе. Приложение должно иметь права на чтение и отправку сообщений в группу.

    Кроме этого, убедитесь, что ваш бот имеет права на отправку комментариев к записям на стене группы. Это можно проверить в настройках группы в меню "Управление" -> "Сообщения и сообщества" -> "Настройки ботов".

    Также, вы используете метод vk.wall.createComment, который позволяет создавать комментарии, но не позволяет отвечать на сообщения пользователей в ЛС. Для ответа на сообщения пользователей вам нужно использовать метод vk.messages.send.
    Ответ написан
    Комментировать
  • Как сделать Поиск Wordpress с учетом регистра?

    scoffs
    @scoffs
    Fullstack | C# | Student
    if (!empty($_POST["query_check"])) {
        $args = array(
            'posts_per_page' => 2,
            'post_type' => 'check',
            's' => $query_check,
            'sentence' => true
        );
        $posts = new WP_Query( $args );
        if ( $posts->have_posts() ) {
            echo '<p class="yescode">'.$successmessage.'</p>';
        } else {
            echo '<p class="nocode">'.$notfoundcode.'</p>';
        }
    }
    Ответ написан
    Комментировать
  • Как инвертировать скролл по колесу мыши?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Не это?
    try {
     window.addEventListener("wheel", function(event) {
        if (event.deltaX !== 0) {
            event.preventDefault();
            window.scrollBy(event.deltaX, -event.deltaY);
        }
    });
    }
    catch(e) {
      console.error(e);
    }
    Ответ написан
    Комментировать
  • Есть ли возможность написать скрипт пересылки сообщений из определённого диалога на другой аккаунт?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Через апи нет возможности прямой пересылки, кастыльно это будет выглядеть типа такого
    import vk_api
    
    login = 'log'
    password = 'pass'
    vk_session = vk_api.VkApi(login, password)
    try:
        vk_session.auth()
    except vk_api.AuthError as error_msg:
        print(error_msg)
    
    # Получение истории сообщений
    peer_id = 123456789 # ID диалога
    history = vk_session.method('messages.getHistory', {'peer_id': peer_id})
    
    # Отправка сообщений на другой аккаунт
    new_peer_id = 987654321 # ID другого аккаунта
    for message in history['items']:
        text = message['text']
        vk_session.method('messages.send', {'peer_id': new_peer_id, 'message': text})
    Ответ написан
    Комментировать
  • Можно ли загрузить фотографию в альбом с помощью идентификатора фотографии?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Не?
    const v3 = require('node-hue-api').v3;
    
    async function uploadPhotoToAlbum(photoId, albumId) {
      const username = 'your-username'; // Замените на ваше имя пользователя Hue
      const bridgeIp = 'your-bridge-ip'; // Замените на IP-адрес вашего моста Hue
    
      // Создание экземпляра Hue API
      const api = await v3.api.createLocal(bridgeIp).connect(username);
    
      // Загрузка фотографии в альбом
      const response = await api.groups.createGroupScene(albumId, [photoId]);
    
      console.log('Photo uploaded to album:', response);
    }
    
    // Использование функции для загрузки фотографии в альбом
    uploadPhotoToAlbum('1_43894933', 'your-album-id'); // Замените на ваш идентификатор альбома
    Ответ написан
    Комментировать
  • Почему из-за Suspense в React.js(ts) не срабатывает onLoadedData на видео?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Возможно, что видео не срабатывает или срабатывает не всегда, потому что оно еще не загружено на момент первого рендеринга компонента. Из-за этого обработчик может пропустить событие onLoadedData.

    // может использовать onCanPlayThrough ? Или onCanPlay / onPlay
    const handleOnCanPlayThrough = () => {
      setLoading(false)
      console.log('Video loaded')
    }
    
    <video
      onCanPlayThrough={handleOnCanPlayThrough}
      // ...
    >
    Ответ написан
    1 комментарий
  • Как сделать пунктирные линии в диаграмме?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Вроде как в chart.js нет такой функции

    Но может тебе поможет что-то типа этого
    <div class="chart-container">
      <canvas id="myChart"></canvas>
      <div class="tooltip-line"></div>
    </div>

    .chart-container {
      position: relative;
    }
    
    .tooltip-line {
      position: absolute;
      display: none;
      width: 1px;
      height: 100%;
      background-color: black;
      opacity: 0.5;
      pointer-events: none;
      border: dashed;
    }

    const chart = new Chart(document.getElementById('myChart'), {
      // Конфигурация графика Chart.js
      // ...
    });
    
    const tooltipLine = document.querySelector('.tooltip-line');
    
    chart.canvas.addEventListener('mousemove', function(e) {
      const rect = chart.canvas.getBoundingClientRect();
      const xPos = e.clientX - rect.left;
      
      tooltipLine.style.left = xPos + 'px';
      tooltipLine.style.display = 'block';
    });
    
    chart.canvas.addEventListener('mouseout', function(e) {
      tooltipLine.style.display = 'none';
    });
    Ответ написан
  • Как ограничить количество меток при создании поста?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Конечно, через WordPress Hooks

    function limit_post_tags($postarr) {
        $tags = isset($postarr['tags_input']) ? explode(',', $postarr['tags_input']) : array();
        
        // Установите максимальное количество меток
        $max_tags = 3;
    
        if (count($tags) > $max_tags) {
            // Если количество меток превышает максимальное, удалите лишние
            $postarr['tags_input'] = implode(',', array_slice($tags, 0, $max_tags));
        }
    
        return $postarr;
    }
    add_filter('wp_insert_post_data', 'limit_post_tags');


    Или плагины:
    1. "Tag Limit" (https://wordpress.org/plugins/tag-limit/): Этот плагин позволяет вам установить максимальное количество меток, которые могут быть добавлены к посту.

    2. "Term Management Tools" (https://wordpress.org/plugins/term-management-tools/): Этот плагин предоставляет дополнительные функции управления терминами (включая метки).
    Ответ написан
    Комментировать
  • Как изучать ASP.NET Web Forms?

    scoffs
    @scoffs
    Fullstack | C# | Student
    https://learn.microsoft.com/en-us/aspnet/web-forms/
    https://www.pluralsight.com/ - с VPN

    1. "Beginning ASP.NET 4.5.1: in C# and VB" by Imar Spaanjaars: Эта книга является прекрасным ресурсом для начинающих. Она покрывает основы ASP.NET Web Forms, включая создание страниц, использование элементов управления, работу с базами данных и другие аспекты разработки веб-приложений на ASP.NET Web Forms.

    2. "Professional ASP.NET 4.5 in C# and VB" by Jason N. Gaylord, Christian Wenz, et al.: Это обширное руководство по ASP.NET 4.5 включает в себя различные темы, включая ASP.NET Web Forms. Книга рассматривает множество аспектов, включая создание пользовательского интерфейса, обработку данных, безопасность и тестирование.
    Ответ написан
    2 комментария
  • Как прекрипить футер к самому нижу?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Прежде всего хочу сказать, что в вашем коде есть намёк на БЕМ и вы даже используете SCSS, но при этом вы вообще не используете переиспользование БЭМ-классов. Почитайте, пожалуйста, об этой методологии и избавьтесь от каши в стилях.

    Ответ на ваш вопрос:
    https://dimox.name/press_footer_bottom_with_css/

    <body>
      <header>
        <!-- Ваш хедер -->
      </header>
    
      <main>
        <!-- Основной контент страницы -->
      </main>
    
      <footer>
        <!-- Ваш футер -->
      </footer>
    </body>

    *, *::before, *::after { 
      margin: 0;
      padding: 0;
    }
    html {
      height: 100%;
    }
    
    body {
      height: 100%;
      display: flex;
      flex-direction: column;
    }
    
    body {
      flex: 1; /* Расширяет основной контент на все доступное пространство */
    }
    
    header, footer {
      flex-shrink: 0; /* Предотвращает сжатие хедера и футера */
    }
    Ответ написан
  • Как правильно дать права на папки и подпапки?

    scoffs
    @scoffs
    Fullstack | C# | Student
    777 не лучшая идея, конечно, но вам может помочь атрибут SetGID (установка бита SGID).

    Установите правильные разрешения для директории /var/www/html, чтобы обеспечить безопасность:
    sudo chown -R $USER:www-data /var/www/html
    sudo find /var/www/html -type d -exec chmod 750 {} \;
    sudo find /var/www/html -type f -exec chmod 640 {} \;


    Установите атрибут SetGID на директорию /var/www/html, чтобы новые файлы и папки, созданные внутри, наследовали разрешения:
    sudo chmod g+s /var/www/html

    P.S. я заменил 777 на 750 для директорий и 640 для файлов внутри директории /var/www/html. Это ограничит доступ к директории и файлам только владельцу и группе, в то время как остальные пользователи не будут иметь права на запись или выполнение. Это более безопасный и рекомендуемый подход для настройки разрешений веб-сервера.
    Ответ написан
    1 комментарий
  • Как настроить amp и нужен ли он вообще для сайта на водпресс?

    scoffs
    @scoffs
    Fullstack | C# | Student
    1. По умолчанию, если у вас есть AMP-версия страницы, то она будет отображаться при прямом заходе на сайт или переходе по ссылке с мобильного устройства. Это связано с тем, что AMP-страницы обеспечивают более быструю загрузку и лучший пользовательский опыт на мобильных устройствах. Однако, если вы хотите, чтобы отображалась обычная мобильная версия темы, а не AMP-версия, вам может потребоваться настроить это в вашей теме или плагине AMP.
    2. Ошибка "Заблокировано в файле robots.txt" в Google Search Console указывает на то, что в вашем файле robots.txt есть инструкции, которые блокируют индексацию AMP-страниц. Возможно, вы должны иметь запись Allow: / для разрешения индексации всех страниц вашего сайта, включая AMP-страницы.
    Ответ написан
  • Как отследить когда кеш сбросится?

    scoffs
    @scoffs
    Fullstack | C# | Student
    Может что-то типа этого?

    После вызова self.skipWaiting() в Service Worker можно отправить сообщение об успешном сбросе кеша обратно в клиентскую часть приложения, используя postMessage(). В клиентской части вы можете прослушивать это сообщение и выполнить обновление страницы с помощью location.reload() или другого подходящего метода.

    // Service Worker
    self.addEventListener('message', event => {
        if (event.data && event.data.type === 'SKIP_WAITING') {
            self.skipWaiting();
            event.source.postMessage({ type: 'CACHE_RESET_SUCCESS' });
        }
    });


    // client
    navigator.serviceWorker.addEventListener('message', event => {
        if (event.data && event.data.type === 'CACHE_RESET_SUCCESS') {
            location.reload();
        }
    });


    Либо
    Если вы хотите, чтобы клиентская часть обновляла страницу после сброса кеша, вы можете прослушивать событие controllerchange на объекте navigator.serviceWorker. Когда Service Worker сбрасывается и становится активным контроллером, будет вызвано событие controllerchange, и вы можете выполнить обновление страницы.

    navigator.serviceWorker.addEventListener('controllerchange', () => {
        location.reload();
    });
    Ответ написан
    Комментировать