westakof

westakof

На Пикабу
7166 рейтинг 6 подписчиков 4 подписки 41 пост 4 в горячем
Награды:
5 лет на Пикабу
4

Каких персонажей добавить в игру?

Сейчас в игре просто пушки-заглушки =)

Сейчас в игре просто пушки-заглушки =)

Хочу заменить их на персонажей, которые визуально стреляют, но геймплей остаётся тем же.

Пока вот такие варанты пришли в голову:

Всего голосов:

Поднимите пост, пожалуйста, чтоб больше людей проголосовало!

Показать полностью 1
2

Муж-геймер - горе семье?

Часто встречаю мнение, что если муж играет семье конец.

Решил проверить, как это выглядит в реальности, а не в стереотипах.

Кто у вас геймер?

Поднимите вверх, чтоб больше людей проголосовало

Всего голосов:
Показать полностью 1
8

Продолжение поста «Добавил иконки в Gmail почту! Красота =)»1

Напомню. Я сделал расширение, которое добавляет иконки в Gmail почту. И в комментариях попросили сделать не расширением, а скриптом для Tampermonkey. Мне было лень, но потом я подумал почему бы и нет. Скинул код в chatGPT и он подогнал его под формат Tampermonkey. Ниже расскажу как поставить чтоб работало.

Выглядит вот так:

Продолжение поста «Добавил иконки в Gmail почту! Красота =)»

Как поставить?

  1. Установить Tampermonkey если у вас его ещё нет https://chromewebstore.google.com/detail/tampermonkey/dhdgff...

  2. Правой кнопкой по иконке расширения и Параметры

  3. В верхнем меню панели Tampermonkey жмём на плюсик и открывается страница создания нового скрипта

  4. Вставляем код скприта сюда и сохраняем

  5. Готово.

Вот сам код скрипта:

// ==UserScript==

// @name Gmail Sender Favicon (base + S2, fallback letter)

// @namespace https://tampermonkey.net/

// @VERSION 2026-01-02

// @Description Gmail: show sender base-domain favicon; fallback to Google S2; then fallback to letter.

// @match https://mail.google.com/*

// @run-at document-idle

// ==/UserScript==

(() => {

'use strict';

const STYLE_ID = 'gm-sender-favicon-style-final';

const BADGE_CLASS = 'gm-sender-badge-final';

function injectStyles() {

if (document.getElementById(STYLE_ID)) return;

const style = document.createElement('style');

style.id = STYLE_ID;

style.textContent = `

.${BADGE_CLASS}{

display:inline-flex;

align-items:center;

margin-right:6px;

vertical-align:middle;

flex: 0 0 auto;

transform: translateY(-0.5px);

}

.${BADGE_CLASS} img{

width:14px;height:14px;border-radius:3px;display:block;

}

.${BADGE_CLASS} .gm-letter{

font-weight:700;

font-size:12px;

line-height:1;

display:inline-block;

}

`;

document.documentElement.appendChild(style);

}

// ---------- domain/email helpers ----------

function extractEmailLike(str) {

if (!str) return '';

const s = String(str);

// <mail@domain>

const m1 = s.match(/<\s*([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,})\s*>/i);

if (m1) return m1[1];

// mail@domain

const m2 = s.match(/([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,})/i);

if (m2) return m2[1];

return '';

}

function getDomainFromEmail(email) {

const at = (email || '').indexOf('@');

if (at === -1) return '';

return email.slice(at + 1).trim().toLowerCase();

}

// Простая нормализация к base-domain: example.com

function baseDomain(domain) {

const parts = (domain || '').split('.').filter(Boolean);

if (parts.length < 2) return domain || '';

return parts.slice(-2).join('.');

}

// стабильный цвет по seed (чтобы буква была “привычного” цвета)

function stableColor(seed) {

let h = 0;

for (let i = 0; i < seed.length; i++) h = (h * 31 + seed.charCodeAt(i)) | 0;

const hue = Math.abs(h) % 360;

return `hsl(${hue}, 70%, 40%)`;

}

function pickLetter(senderText, base) {

const m = (senderText || '').match(/[a-z0-9а-яё]/i);

if (m) return m[0].toUpperCase();

if (base) return base[0].toUpperCase();

return '?';

}

// ---------- locating sender in a row ----------

function findSenderInfo(row) {

// 1) самый надежный: span[email]

const emailSpan = row.querySelector('span[email]');

if (emailSpan) {

const email = emailSpan.getAttribute('email') || '';

const senderText =

(emailSpan.getAttribute('name') || '').trim() ||

(emailSpan.getAttribute('aria-label') || '').trim() ||

(emailSpan.textContent || '').trim();

return { email, senderText, senderNode: emailSpan };

}

// 2) data-hovercard-id часто содержит email

const hcSpan = row.querySelector('span[data-hovercard-id]');

if (hcSpan) {

const hc = hcSpan.getAttribute('data-hovercard-id') || '';

const email = extractEmailLike(hc) || extractEmailLike(hcSpan.getAttribute('aria-label')) || '';

const senderText =

(hcSpan.getAttribute('name') || '').trim() ||

(hcSpan.getAttribute('aria-label') || '').trim() ||

(hcSpan.textContent || '').trim();

return { email, senderText, senderNode: hcSpan };

}

// 3) иногда sender виден как yP/zF

const nameSpan = row.querySelector('span.yP, span.zF');

if (nameSpan) {

const email =

extractEmailLike(nameSpan.getAttribute('aria-label')) ||

extractEmailLike(nameSpan.getAttribute('title')) ||

'';

const senderText =

(nameSpan.getAttribute('aria-label') || '').trim() ||

(nameSpan.getAttribute('title') || '').trim() ||

(nameSpan.textContent || '').trim();

return { email, senderText, senderNode: nameSpan };

}

return null;

}

// ---------- badge creation ----------

function makeBadge(base, letter, fontSizePx) {

const badge = document.createElement('span');

badge.className = BADGE_CLASS;

badge.setAttribute('data-base', base || '');

const img = document.createElement('img');

img.alt = '';

img.referrerPolicy = 'no-referrer';

const sources = base

? [

`https://${base}/favicon.ico`,

`https://www.google.com/s2/favicons?sz=64&amp;domain=%24%7Ben...}`

]

: [];

let idx = 0;

const fallbackToLetter = () => {

img.remove();

const span = document.createElement('span');

span.className = 'gm-letter';

span.textContent = letter;

span.style.color = stableColor(base || letter || 'x');

if (fontSizePx) span.style.fontSize = fontSizePx;

badge.appendChild(span);

};

img.onerror = () => {

idx++;

if (idx < sources.length) {

img.src = sources[idx];

} else {

fallbackToLetter();

}

};

if (sources.length) {

img.src = sources[0];

badge.appendChild(img);

} else {

fallbackToLetter();

}

return badge;

}

// ---------- main enhancer ----------

function enhanceRow(row) {

const info = findSenderInfo(row);

if (!info) return;

const domain = getDomainFromEmail(info.email);

const base = baseDomain(domain);

// текст для буквы

const senderText = info.senderText || (info.senderNode?.textContent || '').trim();

const letter = pickLetter(senderText, base);

// куда вставлять:

// A) предпочитаем контейнер отправителя (как у тебя работало)

let target = row.querySelector('.yX.xY');

// B) если нет — рядом с узлом senderNode

let insertBeforeNode = null;

if (!target && info.senderNode && info.senderNode.parentElement) {

target = info.senderNode.parentElement;

insertBeforeNode = info.senderNode;

}

if (!target) return;

// уже вставлено?

const existing = target.querySelector(`:scope > .${BADGE_CLASS}`);

if (existing) {

const exBase = existing.getAttribute('data-base') || '';

if (exBase === (base || '')) return;

existing.remove();

}

const cs = window.getComputedStyle(target);

const fontSizePx = cs.fontSize ? `calc(${cs.fontSize} - 1px)` : '';

const badge = makeBadge(base, letter, fontSizePx);

if (insertBeforeNode) target.insertBefore(badge, insertBeforeNode);

else target.prepend(badge);

}

function enhanceAll() {

injectStyles();

document.querySelectorAll('.zA').forEach(enhanceRow);

}

// ---------- observer (throttled) ----------

let rafPending = false;

function schedule() {

if (rafPending) return;

rafPending = true;

requestAnimationFrame(() => {

rafPending = false;

enhanceAll();

});

}

const obs = new MutationObserver(schedule);

obs.observe(document.body, { childList: true, subtree: true });

enhanceAll();

})();

Показать полностью
18

Всегда мечтал сделать гоночную игру и вот делаю!

Всем привет и с наступающим Новым Годом!
Я решил, что сейчас самое время, чтобы исполнить мечту детства и попробовать самому сделать гоночную игру =)

Всегда мечтал сделать гоночную игру и вот делаю!

Она ещё пока очень сырая и её нет в интернете, но уже есть машинки соперники и трасса, так что вот пока что фото моего утреннего заезда )


Буду благодарен за поддержку!

Показать полностью 1
68

Добавил иконки в Gmail почту! Красота =)1

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

Мне кажется, что стало красиво!
Скачать можно тут https://chromewebstore.google.com/detail/gmail-email-icons/n...

Стало:

Было:

Работает локально, ничего не собирает, никуда не отправляет, рекламу не показывает.
Всё как мы любим.

Поднимите вверх, чтоб больше людей увидело =)

Показать полностью 1
2

Надо?

Ребята, могу сделать штуку, которая следит за ценой товара на Ozon и пишет в Telegram, если цена упала больше чем на 5%.

📌 Фишка: вы просто с телефона кидаете ссылку боту и товар сразу добавляется в отслеживание.

⚠️ Нюанс: чтобы всё работало, нужно будет поставить небольшое расширение в браузер на компьютере - оно будет периодически проверять цену.

Если идея нужна - плюсуйте пост, и если желающих будет много, сделаю 👍

17

Чужая победа, твой счет за ремонт

Мне вдруг стало ясно: я гораздо сильнее люблю истории не про героев, а про "маленьких людей", таких же как и я сам.

Про тех, кто пытается строить свой быт, ищет деньги на ипотеку, переживает за детей, смотрит в завтра с тревогой, ведь его могут перемолоть в пыль жернова обстоятесльств и очередные поиски правды какого-нибудь Человека Мыши, который живёт на соседней улице.

И при всё этом сюре, что творится вокруг, маленький и простой человек с понятными желаниями и тревогами, умудряется сохранять человечность.

Не про очередную войну за власть и громкие пророчества, а про то, как люди живут “на фоне” всего этого.

Про стражника на воротах, которому мимоходом оторвало руку, пока главный герой пытается доблестно спасти принцессу юга. Что с ним завтра то случилось, как он теперь вообще выживает дальше?

Про девушку, которая 3 месяца училась на права и сдала с первой попытки, кроила бюджет и смогла купить какую-никакую, но машину, а на неё свалился и разрушил в хлам супермен на следующих день. Как у неё нервы после такого, не сдали, куда её дорога дальше заведёт?

Про кассира/продавщицу, у которой магазин оказался “в эпицентре” и витрины вдребезги, товар пропал, охраны нет, начальство требует выйти завтра как ни в чем не бывало. А у неё кредит, аренда, мама на лекарствах. И вот она стоит среди стекла и думает: это мне теперь что всё начинать с нуля? И где взять силы, когда на тебя всем плевать?

Если знаете такие фильмы и особенно книги — киньте рекомендации.
Плюсуйте пост, что больше рекомендаций собрать в комментариях.

Показать полностью
Отличная работа, все прочитано!

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества