Compare commits
No commits in common. "2318a645ce17a1273b99493d9777bf10c3acd51f" and "d39b85fbc7147ac7b13d72f3424441eb440d95e6" have entirely different histories.
2318a645ce
...
d39b85fbc7
14 changed files with 5451 additions and 1226 deletions
6455
package-lock.json
generated
6455
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -10,8 +10,8 @@
|
||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"astro": "^2.10.5",
|
"astro": "^2.9.0",
|
||||||
"astro-compress": "^2.0.5",
|
"astro-compress": "^1.1.50",
|
||||||
"intl": "^1.2.5",
|
"intl": "^1.2.5",
|
||||||
"less": "^4.1.3",
|
"less": "^4.1.3",
|
||||||
"reading-time": "^1.5.0",
|
"reading-time": "^1.5.0",
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 17 KiB |
BIN
public/assets/forest.jpg
Normal file
BIN
public/assets/forest.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 229 KiB |
|
@ -19,7 +19,6 @@ const {
|
||||||
<div class="card card-elevated" id={post.slug}>
|
<div class="card card-elevated" id={post.slug}>
|
||||||
<Article
|
<Article
|
||||||
PostContent={PostContent}
|
PostContent={PostContent}
|
||||||
slug={post.slug}
|
|
||||||
title={title}
|
title={title}
|
||||||
description={description}
|
description={description}
|
||||||
readingTime={readingTime}
|
readingTime={readingTime}
|
||||||
|
|
|
@ -35,8 +35,6 @@ const {
|
||||||
@icon-size: 1.5rem;
|
@icon-size: 1.5rem;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
height: fit-content;
|
|
||||||
|
|
||||||
a {
|
a {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
---
|
|
||||||
import Icon from './Icon.astro';
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
btnKind: 'prev' | 'pagenum' | 'next';
|
|
||||||
url?: string | undefined;
|
|
||||||
num?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { btnKind, url, num = 1 } = Astro.props;
|
|
||||||
---
|
|
||||||
|
|
||||||
<a href={url ?? 'javascript:void(0)'} class={btnKind}>
|
|
||||||
{
|
|
||||||
btnKind === 'pagenum' ? <span class="pagenum">{num}</span> :
|
|
||||||
btnKind === 'prev' ? <Icon code="" /> :
|
|
||||||
btnKind === 'next' ? <Icon code="" /> :
|
|
||||||
""
|
|
||||||
}
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<style lang="less">
|
|
||||||
a {
|
|
||||||
@size: 1.1rem;
|
|
||||||
@color: var(--fg);
|
|
||||||
|
|
||||||
width: @size;
|
|
||||||
height: @size;
|
|
||||||
box-sizing: content-box;
|
|
||||||
|
|
||||||
font-size: @size;
|
|
||||||
padding: 0.625rem;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
color: @color;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: @color;
|
|
||||||
|
|
||||||
background: var(--accent-bg);
|
|
||||||
border-radius: var(--bdrs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagenum {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,82 +0,0 @@
|
||||||
---
|
|
||||||
import Icon from "./Icon.astro";
|
|
||||||
---
|
|
||||||
|
|
||||||
<div id="scroll-to-top" data-show="0">
|
|
||||||
<a href="#">
|
|
||||||
<Icon code="" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="less">
|
|
||||||
@size: 2.25rem;
|
|
||||||
@font: 1.50rem;
|
|
||||||
|
|
||||||
div {
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
&[data-show="0"] a {
|
|
||||||
height: 0;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.2s ease, height 0.2s step-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[data-show="1"] a {
|
|
||||||
height: @size;
|
|
||||||
opacity: 1;
|
|
||||||
transition: opacity 0.2s ease, height 0.2s step-start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0.5rem;
|
|
||||||
right: 0.625rem;
|
|
||||||
|
|
||||||
display: inline-flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0.25rem;
|
|
||||||
|
|
||||||
width: @size;
|
|
||||||
height: @size;
|
|
||||||
border-radius: @size;
|
|
||||||
font-size: @font;
|
|
||||||
|
|
||||||
background: var(--accent-bg);
|
|
||||||
color: var(--fg);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: var(--bg-sec);
|
|
||||||
color: var(--fg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const stt = document.getElementById('scroll-to-top')
|
|
||||||
const doc = document.documentElement
|
|
||||||
|
|
||||||
let scrollPos = 0
|
|
||||||
let ticking = false
|
|
||||||
|
|
||||||
const handler = (pos: number) => {
|
|
||||||
if (pos > doc.clientHeight / 2) {
|
|
||||||
stt.dataset.show = '1'
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
stt.dataset.show = '0'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addEventListener('scroll', () => {
|
|
||||||
scrollPos = window.scrollY
|
|
||||||
if (!ticking) {
|
|
||||||
window.requestAnimationFrame(() => {
|
|
||||||
handler(scrollPos)
|
|
||||||
ticking = false
|
|
||||||
})
|
|
||||||
ticking = true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
|
@ -1,19 +0,0 @@
|
||||||
---
|
|
||||||
comments: dcat09/18
|
|
||||||
---
|
|
||||||
|
|
||||||
# Начинающему фронтендеру: margin vs padding
|
|
||||||
|
|
||||||
Раньше я не понимал разницы между margin и padding, и ставил их в CSS наугад, проверяя результат.
|
|
||||||
На StackOverflow объяснение было так себе, да и инглиш я тогда знал тоже так себе.
|
|
||||||
|
|
||||||
Помог мне Chrome, а точнее инструменты разработчика. Внизу вкладки "Стили" есть наглядная визуализация отступов цветными прямоугольниками.
|
|
||||||
|
|
||||||
![](/assets/20220629-mvsp/devtools.jpg)
|
|
||||||
|
|
||||||
- Вокруг содержимого элемента -- **padding**, ограничивающий текст от рамки
|
|
||||||
- После него -- **border**, т.е. сама рамка
|
|
||||||
- После border -- **margin**, ограничивающий элемент от других элементов
|
|
||||||
|
|
||||||
А посмотреть всё это в интерактивном виде можно на [странице на Codeberg Pages](https://darkcat09.codeberg.page/margin-vs-padding).
|
|
||||||
Исходники: [Codeberg](https://codeberg.org/DarkCat09/margin-vs-padding) | [Gitea](https://git.dc09.ru/DarkCat09/margin-vs-padding).
|
|
|
@ -1,28 +0,0 @@
|
||||||
---
|
|
||||||
comments: dcat09/37
|
|
||||||
---
|
|
||||||
|
|
||||||
# Технологии XDT, или YouTube всё знает...
|
|
||||||
|
|
||||||
Смотрел я на СТСе Гарри Поттера.
|
|
||||||
На следующий день в рекомендациях ютуба появились видео на тему вышеуказанного фильма, которые я не искал примерно год.
|
|
||||||
Как? Ведь тогда установлены были не официальные сервисы, а MicroG.
|
|
||||||
|
|
||||||
Где-то на хабре в комментах под статьёй то ли про телеметрию, то ли про рекламу, был такой вариант: генерация высокочастотных звуков при трансляции телепередач, чтобы наши девайсы отслеживали их и понимали, что мы смотрим. И на основе этого предлагать таргетированную рекламу.
|
|
||||||
<s>Лишь бы этим не воспользовались. Или уже?</s>
|
|
||||||
|
|
||||||
**Upd:**
|
|
||||||
Технология называется [Cross-device tracking (CDT, XDT)](https://en.m.wikipedia.org/wiki/Cross-device_tracking).
|
|
||||||
К ней относится аналитика, обычно с целью показа рекламы, которая, вместо сохранения идентификатора в одной сессии браузера или его привязки к одному IP-адресу, может передавать рекламный ID между устройствами.
|
|
||||||
Внедряют почти все, кому не лень.
|
|
||||||
|
|
||||||
- Самый простой способ -- отслеживание **залогиненных пользователей**.
|
|
||||||
На сайте у человека есть аккаунт, в который он входит с разных устройств.
|
|
||||||
Таким образом можно сохранять список устройств, далее - делать что угодно.
|
|
||||||
"Рекламный идентификатор" у Google является ярким примером такого XDT.
|
|
||||||
|
|
||||||
- Способ сложнее, о котором я и рассказывал -- **использование ультразвука** для передачи информации между устройствами.
|
|
||||||
Лидирует в этом варианте XDT комания SilverPush, у которой ещё и патент на эту технологию.
|
|
||||||
Для защиты можно использовать приложение [PilferShushJammer](https://github.com/kaputnikGo/PilferShushJammer).
|
|
||||||
|
|
||||||
За информацию большое спасибо [@nvrm17](https://t.me/nvrm17)
|
|
|
@ -1,5 +1,4 @@
|
||||||
---
|
---
|
||||||
draft: true
|
|
||||||
comments: dcat09/1
|
comments: dcat09/1
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,11 @@ comments: dcat09/338
|
||||||
|
|
||||||
# Коротко о разработке ПО сейчас
|
# Коротко о разработке ПО сейчас
|
||||||
|
|
||||||
|
_[Оригинальный текст](https://factoryfactoryfactory.net)_
|
||||||
|
_Перевод [DarkCat09](https://dc09.ru)_
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
Представим, что я решил сделать подставку для специй.
|
Представим, что я решил сделать подставку для специй.
|
||||||
|
|
||||||
Я уже имел дело с небольшими проектами по работе с деревом, и хорошо представляю, что мне необходимо: древесный материал и несколько основных инструментов: рулетка, уровень, пила и молоток.
|
Я уже имел дело с небольшими проектами по работе с деревом, и хорошо представляю, что мне необходимо: древесный материал и несколько основных инструментов: рулетка, уровень, пила и молоток.
|
||||||
|
@ -60,7 +65,7 @@ comments: dcat09/338
|
||||||
|
|
||||||
— Внимательно слушаю.
|
— Внимательно слушаю.
|
||||||
|
|
||||||
— Когда мы шагнули назад и посмотрели на всю картину инфраструктуры строительных инструментов, мы определили, что люди разочарованы в необходимости управлять фабрикой фабрик, как и производимой ею фабрикой. Это довольно обременительно, когда вы оперируете по такому же сценарию ещё и фабрикой фабрик рулеток, фабрикой фабрик уровней, фабрикой фабрик пил, не говоря уже о холдинге компаний по производству древесного материала. Когда мы здраво оценили ситуацию, мы поняли, что вышеописанное слишком сложно для тех, кому просто хочется сделать подставку для специй.
|
— Когда мы шагнули назад и посмотрели на всю картину инфраструктуры строительных инструментов, мы определили, что люди разочарованы в необходимости управлять фабрикой фабрик, как и производимой ею фабрикой. Что довольно обременительно, когда вы оперируете по такому же сценарию ещё и фабрикой фабрик рулеток, фабрикой фабрик уровней, фабрикой фабрик пил, не говоря уже о холдинге компаний по производству древесного материала. Когда мы здраво оценили ситуацию, мы поняли, что вышеописанное слишком сложно для тех, кому просто хочется сделать подставку для специй.
|
||||||
|
|
||||||
— Да, без шуток, абсолютно верно.
|
— Да, без шуток, абсолютно верно.
|
||||||
|
|
||||||
|
@ -79,8 +84,3 @@ comments: dcat09/338
|
||||||
— Что будет очень полезно для вас!
|
— Что будет очень полезно для вас!
|
||||||
|
|
||||||
— У этой штуки же есть документация, да?
|
— У этой штуки же есть документация, да?
|
||||||
|
|
||||||
***
|
|
||||||
|
|
||||||
_[Оригинальный текст](https://factoryfactoryfactory.net) написан Benji Smith,_
|
|
||||||
_переведён [DarkCat09](https://dc09.ru)_
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
import Layout from "./Layout.astro";
|
import Layout from "./Layout.astro";
|
||||||
import NavMenu from "./NavMenu.astro";
|
import NavMenu from "./NavMenu.astro";
|
||||||
import MenuItem from "../components/MenuItem.astro";
|
import MenuItem from "../components/MenuItem.astro";
|
||||||
import ScrollToTop from "../components/ScrollToTop.astro";
|
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
title: string;
|
title: string;
|
||||||
|
@ -15,7 +14,6 @@ const { title, description, mainpage = false } = Astro.props;
|
||||||
|
|
||||||
<Layout title={"Blog | " + title} description={description}>
|
<Layout title={"Blog | " + title} description={description}>
|
||||||
<slot name="metadata" slot="metadata" />
|
<slot name="metadata" slot="metadata" />
|
||||||
<ScrollToTop />
|
|
||||||
<NavMenu>
|
<NavMenu>
|
||||||
{
|
{
|
||||||
mainpage ?
|
mainpage ?
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
---
|
---
|
||||||
import BlogLayout from "../../layouts/BlogLayout.astro";
|
import BlogLayout from "../../layouts/BlogLayout.astro";
|
||||||
import ArticleCard from "../../components/ArticleCard.astro";
|
import ArticleCard from "../../components/ArticleCard.astro";
|
||||||
import PageCtrlBtn from "../../components/PageCtrlBtn.astro";
|
|
||||||
|
|
||||||
import { getCollection } from "astro:content";
|
import { getCollection } from "astro:content";
|
||||||
import { Page } from "astro";
|
|
||||||
|
|
||||||
export async function getStaticPaths({ paginate }) {
|
export async function getStaticPaths({ paginate }) {
|
||||||
const POSTS_ON_PAGE = 15;
|
const POSTS_ON_PAGE = 15;
|
||||||
|
@ -21,7 +19,7 @@ export async function getStaticPaths({ paginate }) {
|
||||||
return paginate(posts, { pageSize: POSTS_ON_PAGE });
|
return paginate(posts, { pageSize: POSTS_ON_PAGE });
|
||||||
}
|
}
|
||||||
|
|
||||||
const page: Page = Astro.props.page;
|
const { page } = Astro.props;
|
||||||
const description =
|
const description =
|
||||||
"DarkCat09's blog. " +
|
"DarkCat09's blog. " +
|
||||||
"Reading a QR code without a phone, " +
|
"Reading a QR code without a phone, " +
|
||||||
|
@ -37,11 +35,6 @@ const description =
|
||||||
<div id="articles">
|
<div id="articles">
|
||||||
{page.data.map(({ post }) => <ArticleCard post={post} />)}
|
{page.data.map(({ post }) => <ArticleCard post={post} />)}
|
||||||
</div>
|
</div>
|
||||||
<div id="page-ctrl">
|
|
||||||
<PageCtrlBtn btnKind="prev" url={page.url.prev} />
|
|
||||||
<PageCtrlBtn btnKind="pagenum" num={page.currentPage} />
|
|
||||||
<PageCtrlBtn btnKind="next" url={page.url.next} />
|
|
||||||
</div>
|
|
||||||
</BlogLayout>
|
</BlogLayout>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
@ -53,12 +46,4 @@ const description =
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: @body-padding + @main-padding;
|
gap: @body-padding + @main-padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
#page-ctrl {
|
|
||||||
margin-top: 0.5rem;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Add table
Reference in a new issue