• Как можно определить устройство?

    @Sayto
    Смотреть User-Agent.
    mobile-detect
    Ответ написан
    Комментировать
  • Нужны ли препроцессоры CSS в 2022/2023?

    vabka
    @vabka
    Токсичный шарпист
    Переменные давно реализованы в нативном CSS

    В препроцессорах другие переменные.
    вложенность также.

    Разве?

    Вообще препроцессоры много удобного сахара добавляют. (https://sass-scss.ru/guide/)

    Если вы не видите нужных фич, значит вам не нужны.
    Ответ написан
    Комментировать
  • Как работает деструктуризация в этом примере?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Может, так понятнее. Примерно то же:
    const arr = [0, 1, 2, 3, 4, 5];
    const index = 3;
    [ ...arr.slice(0, index), 'Habr', ...arr.slice(index + 1) ]
    // [ 0, 1, 2, "Habr", 4, 5 ]
    Делается новый массив, в котором сначала идут элементы исходного от 0 до index (не включая index);
    затем вставляется некий новый элемент;
    затем добиваются элементы исходного начиная со следующего после index'ного.

    Фактически заменяется элемент под индексом index на некий новый. В отличие от метода splice(), которым можно было бы сделать тоже самое arr.splice(index, 1, 'Habr'), вариант в вопросе не изменяет исходный массив, а создаёт новый – что, в общем-то, «правильно».
    Ответ написан
    Комментировать
  • Как зашифровать http запрос?

    Использовать https, тогда можно будет зашифровать в том числе урл.
    Если делать свое шифрование поверх http, то во-первых, это будет сильно сложнее сделать правильно и надежно, во-вторых, не получится зашифровать урл, потому что по стандарту http он должен быть в открытом виде.
    Ответ написан
    Комментировать
  • Как типизировать в ts?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Вопрос конечно в духе "я его того, а он мне нихрна, чаво это он". Где конкретика блин? Что именно за ошибка? Любая ошибка TS - это "ошибка типов", он для этого и существует. Что у тебя в route?

    Но окей, предположим, что route у тебя - это текущий роут vue-рутера, тогда ошибка у тебя скорее всего выглядит как-то так:
    TS7053: Element implicitly has an 'any' type because expression of type 'RouteRecordName' can't be used to index type '{ first: string; second: string; }'.   No index signature with a parameter of type 'string' was found on type '{ first: string; second: string; }'.

    Собственно прочитав текст ошибки можно уже догадаться, в чём проблема: у (неявно выведенного за отсутствием явного объявления) типа объекта pages есть ключи типа 'first' | 'second' | ..., но нет index signature типа string, т.е. не указано, что ключом может быть любая строка, а не только конкретные'first' | 'second' | ....
    route.name же после проверки на пустоту имеет тип string | symbol. Ты не можешь у объекта с чётко ограниченным набором ключей брать значение по произвольному строковому/символьному.

    Прямое решение в лоб:
    Задать тип pages позволяющий рандомные ключи, например
    const pages: Record<PropertyKey, string> = {
      first: 'Первая',
      second: 'Вторая',
      ...
    }

    Всё сразу заработает, но это не спасёт тебя от ошибок(например опечаток).


    Не менее прямой вариант
    (но с другой стороны):
    Кастануть нужный тип руками: ... = pages[route.name as keyof typeof pages]
    Ведь мы уверены, что name в route всегда будет одним из ключей pages. Уверены же?..

    Энтерпрайз решение(ничем не лучше предыдущих, зато выглядит солидно):
    Твой файл routes.ts:
    export enum ERoutes {
      FIRST = 'first',
      SECOND = 'second'
    }
    
    const routes = [
      {
         name: ERoutes.FIRST,
         ...
      },
      {
         name: ERoutes.SECOND,
         ...
      },
      ...
    ]

    В коде:
    const pages: Record<ERoutes, string> = {
      [ERoutes.FIRST]: 'Первая',
      [ERoutes.SECOND]: 'Вторая',
      ...
    }
    
    ... = pages[route.name as ERoutes]


    Надмозговое решение("как батька"):
    Твой файл routes.ts:
    const routes = [
      {
         name: 'first',
         ...
      },
      {
         name: 'second',
         ...
      },
      ...
    ] as const satisfies ReadonlyArray<ReadonlyRouteRecordRaw>;
    
    type ReadonlyRouteRecordRaw = Omit<RouteRecordRaw, 'children'> & {
      children?: ReadonlyArray<ReadonlyRouteRecordRaw>;
    };
    
    type ExtractNames<Route> = Route extends { name: infer Name } ? Name : never;
    type FlattenChildren<Route> = Route extends { children: ReadonlyArray<infer Children> }
      ? FlattenChildren<Children> | Route
      : Route;
    
    // с помощью магии ts вытаскиваем в тип RouteNames все заданные у нас имена маршрутов
    export type RouteNames = ExtractNames<FlattenChildren<typeof routes[number]>>;
    
    // с помощью магии же прокидывем их прямо в декларацию vue-router
    declare module 'vue-router' {
      export interface RouteLocationNormalizedLoaded {
        name: RouteNames | null | undefined;
      }
    }

    satisfies
    satisfies - новая фича ts 4.9, в предыдущих версиях того же можно добиться сделав обёртку вида:
    const narrowRoutesTypeWrapper = <T extends ReadonlyArray<ReadonlyRouteRecordRaw>>(routes: T) => routes;
    const routes = narrowRoutesTypeWrapper([ ... ] as const);

    И твой код заработает вообще без изменений (если в pages есть все нужные ключи).)
    Однако для удобства можно написать так:
    const pages: Record<RouteNames, string> = {
      first: 'Первая',
      second: 'Вторая',
      ...
    }
    Ответ написан
    Комментировать
  • Как работает оператор &?

    vabka
    @vabka
    Токсичный шарпист
    То что вы написали в вопросе и в комментарии к моему встречному вопросу - это две совершенно разные вещи.

    То что в вопросе:
    const myVar = ClassCat & ClassDog;
    Тут работа идёт со значениями и & - это побитовое И.

    А вот кусок кода из вашего пояснения:
    export type CatDocument = Cat & Document;
    1. Это Typescript. В JS нет никакого Export type
    2. Тут работа идёт уже с типами (Не со значениями!). & - это пересечение типов
    CatDocument - это пересечение типов Cat и Document.

    На практике это значит, что переменная, которая имеет тип CatDocument должна иметь все поля из Cat и из Document, если Cat и Document - это объекты.
    Ответ написан
    Комментировать
  • Насколько хорошо бэкенд-разработчик должен знать SQL?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Ожидаю уверенного владения SQL как минимум в стандарте 2003, а также понимание реляционной теории. Ну и надо понимать, что кандидатов джунского уровня сотня в неделю, чтобы пробиться на место, нужно выделяться среди других, поэтому чем больше знаешь, тем лучше. Покажешь умение читать планы выполнения - плюс, показал владение оконными функциями - ещё плюс, рассказал про WAL при обсуждении транзакций - снова плюс, смог к этому ещё и объяснить про MVCC - совсем молодец. И т.д. и т.п.
    Ответ написан
    Комментировать
  • Почему после сборки приложения картинки не сохраняются?

    @falconandy
    1. Можно использовать embed, чтобы вшить картинку в бинарник.
    2. Но если посмотреть исходники beeep, то окажется, что библиотека работает с файлами и пока не умеет работать с массивом байт (Support for supplying image-data as a blob).
    3. Поэтому вы можете вшить картинку, но перед вызовом beeep.Notify вам надо будет сохранить вшитую картинку во временный файл и передать в beeep.Notify путь к нему.
    Ответ написан
    52 комментария
  • Как задать задержку для fetch при скачивании более 4000 фото?

    RAX7
    @RAX7
    Помимо случайной задержки нужно еще ограничить количество одновременных запросов, примерно так:
    function randomDelay(min = 250, max = 750) {
      return new Promise((resolve) => {
        const ms = Math.random() * (max - min) + min;
        setTimeout(resolve, ms);
      });
    }
    
    function downloadAll(urls, limit = 4) {
      return new Promise((resolveAll, rejectAll) => {
        const result = [];
        const iter = urls.entries();
        let fulfilled = 0;
    
        const next = () => {
          const { done, value } = iter.next();
    
          if (done) {
            if (fulfilled === urls.length) {
              resolveAll(result);
              return;
            }
    
            return;
          }
    
          const [index, url] = value;
          const onFulfilled = (val) => {
            result[index] = val;
            fulfilled += 1;
            next();
          };
    
          randomDelay()
            .then(() => fetch(url))
            .then(onFulfilled, rejectAll);
        };
    
        for (let i = 0, l = Math.min(limit, urls.length); i < l; i++) {
          next();
        }
      });
    }
    
    const urls = Array.from(
      { length: 100 },
      (_, i) => `https://jsonplaceholder.typicode.com/todos/${i + 1}`
    );
    
    (async () => {
      const responses = await downloadAll(urls, 2);
      const data = await Promise.all(responses.map((r) => r.json()));
      console.log(data);
    })();
    Ответ написан
    1 комментарий
  • Как задать задержку для fetch при скачивании более 4000 фото?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно в N параллельных «потоков» скачивать. В каждом случайная пауза перед очередным URL:
    const N = 3;
    
    const delay = ms => new Promise(res => setTimeout(res, ms));
    
    const next = () => {
      if (items.length > 0) {
        return download(items.shift())
          .then(delay(500 + Math.floor(Math.random() * 500))) // случайная пауза между закачками
          .then(next);
      }
    };
    
    const works = Array.from({ length: N }, () =>
      Promise.resolve()
        .then(next)
        .catch(console.error)
    );
    
    Promise.all(works).then(() => console.log('All Done'));
    Ответ написан
    1 комментарий
  • Как проверить открытие письма?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Из соображений безопасности открытие ресурсов по внешним ссылкам многие почтовые клиенты и почтовые сервисы не делают вообще. Тем более когда речь явно идёт о картинке размера 1x1, которую могут игнорировать намеренно (лучше уж тогда не указывать размеры, пусть клиент скачает картинку эту 1x1 и узнает размер только после этого).

    Надо понимать, что E-mail - это канал с негарантированной доставкой до получателя без шансов проверить факт доставки/прочтения. Письмо может вообще не дойти до получателя, может дойти до "Спама", может дойти но сразу пойти в под нож - но мы об этом не узнаем. Все эти пиксельные картинки, оборачивания ссылок в персонально трекируемые, "запрос подтверждения" - всё эти попытки хоть как-то обойти эти ограничения всё равно ни к чему получателя не обязывают. Получатель может всё это полностью проигнорировать.

    Или, как вариант, картинку почтовый сервис получателя может скачать заранее и положить в кэш, что также ничего не означает о получении письма. Её также может скачать антивирус почтового сервиса или получателя, чтобы проверить.

    Я всегда принципиально отказываюсь от всех подтверждающих получение действий и фокусов, потому что если отправитель ПОЛЕНИЛСЯ приаттачить все картинки к письму - то значит я посмотрю на его письмо без картинок и по ссылкам переходить не буду вообще. Не заслужил. Ничего ценного в таких письмах я ещё ни разу не видел.

    Единственное, для чего все эти средства помогают - примерно оценивать степень прочтения в сравнении с предыдущим опытом. Скажем, вчера письмо прочитало 30% получателей, это может означать что его прочитало, например,на самом деле 60%, но лишь половина подвержена трекингу. А если сегодня прочитало 10%, значит, что-то случилось: письмо хуже дошло до получателей, письмо хуже привлекло их внимание... (Все цифры, конечно, от балды, они имеют иллюстративный характер)

    Да и вообще, в наше время почту читает всё меньше людей.
    Ответ написан
    Комментировать
  • Какие существуют сервисы для интернет-аквайринга в 2022 для физлиц РФ?

    svob
    @svob
    Фрилансер, текстовик широкого профиля
    Самозанятый может просто на банковский счет принимать. Во многих банках есть услуга автоматического формирования чеков о доходах самозанятого на все поступления по номеру конкретной карты. В смысле, эта опция к карте привязывается.
    Ответ написан
    1 комментарий
  • Не хожу на работу, но меня не увольняют и не платят зарплату, как быть?

    BasiC2k
    @BasiC2k
    .NET developer (open to job offers)
    У Вас отличный кейс! Отличный в плане того, что есть возможность получить всю заработную плату с дня заключения трудового договора, до его расторжения. Перечитайте трудовой договор, проконсултируйтесь с юристом. И если Вас что-то не устраивает - всегда можно уволиться )
    Ответ написан
    2 комментария
  • Что должен знать Middle+ разработчик Go?

    dimonchik2013
    @dimonchik2013
    non progredi est regredi
    3-5 коммитов в популярные либы достаточно
    Ответ написан
    4 комментария
  • Что должен знать Middle+ разработчик Go?

    opium
    @opium
    Просто люблю качественно работать
    так ты ж мидл мы у тебя должны спрашивать
    Ответ написан
    Комментировать
  • Дефолтное значение, пока полностью не загрузился Vue?

    Fragster
    @Fragster
    помогло? отметь решением!
    Теоретически можно сделать как-то так:
    <div id="app">
      <div v-cloak>{{ price }}</div>
      <div class="uncloak">0</div>
    </div>

    [v-cloak] { display: none }
    [v-cloak] + .uncloak { display: block }
    .uncloak { display: none }

    но скорее всего будет немного моргать в момент переключения. Как-то так: https://codepen.io/FragsterAt/pen/wvXNYax
    Ответ написан
    2 комментария
  • Как создать собственную тему для чужих сайтов?

    MrDecoy
    @MrDecoy Куратор тега CSS
    Верставший фронтендер
    Внедряться в сайт оно не будет.
    Можно только локально, то есть конкретно у вас в браузере переопределить стили. Такое расширение уже есть. Вы ставите себе это расширение, пишите в нем стили и они применяются к сайту.
    Всё что нужно сделать - написать эти стили.
    Но работать это будет до ближайшего обновления сайта. Я так писал свои стили для вк, когда он на новый дизайн перешёл, чтоб старый дизайн вернуть. Держалось в среднем несколько недель. Потом что то нужно было править. А если сайт как инстаграм, например, когда имена классов генерируются, то полагаться можно только на иерархию разметки, а это адище такие стили писать.

    Если просто цветовую гамму сменить - это можно. Если серьёзно что-то менять хотите, то гиблое дело.
    Ответ написан
    Комментировать
  • На чем делать UI для Windows в 2022 году?

    vabka
    @vabka Куратор тега .NET
    Токсичный шарпист
    MAUI - это масштабное обновления xamarin-а по сути. ИМХО без поддержки Linux его кроссплатформенность мало чего стоит.
    WPF - это нативная технология при этом с WPF тебе доступны всякие сторонние и родные контролы. В том числе самые новые от WinUI 3.
    UWP превратился в WinUI 3
    Avalonia - кроссплатформа. "Как WPF но лучше", но без поддержки контролов от WPF или WinUI, но есть много свободных вполне неплохих. Да и система стилей достаточно удобная

    Если тебе не нравится Winforms из-за внешнего вида стандартных контролов, то всегда можно использовать сторонние.

    На втором месте наверное AvaloniaUI смущает что на нем каких то больших проектов.

    Есть много разных проектов, в том числе крупных и коммерческих, и от именитых компаний.
    https://avaloniaui.net/Showcase

    Так как программа небольшая я склоняюсь все быстро сделать на Windows Forms, в 2022 году кто то стартует на нем новые проекты?

    Если ты делаешь что-то небольшое и чисто для себя, и ты не умеешь работать с XAML и нет времени на освоение - нет причин не использовать Winforms. Да, он имеет проблемы с производительностью, да он не очень красивый, да винформы не очень легко поддерживать. Но является ли это реальной проблемой для вашего проекта?

    В общем вот мой топ-чарт:
    1. Если дёшево и сердито - Winforms (остальное - если нужен нормальный дизайн)
    2. Если кроссплатформу - Avalonia
    3. Если нужно на телефоны - MAUI (хотя Avalonia уже можно заставить работать на Android)
    4. Если хочется в новый дизайн винды - WinUI 3
    Ответ написан
    6 комментариев