your personal website on atproto - mirror
blento.app
1/**
2 * Simulate what checkData() does to a user's layout on load.
3 * Uses react-grid-layout directly to avoid Svelte import chain.
4 *
5 * Usage: npx tsx scripts/atproto.ts listRecords <handle> app.blento.card 2>/dev/null | npx tsx scripts/simulate-load.ts
6 */
7import {
8 correctBounds,
9 verticalCompactor,
10 type LayoutItem
11} from 'react-grid-layout/core';
12import * as fs from 'fs';
13
14const COLUMNS = 8;
15
16type Item = {
17 id: string;
18 x: number; y: number; w: number; h: number;
19 mobileX: number; mobileY: number; mobileW: number; mobileH: number;
20 cardType: string;
21};
22
23function toLayout(items: Item[], mobile: boolean): LayoutItem[] {
24 return items.map((item) =>
25 mobile
26 ? { x: item.mobileX, y: item.mobileY, w: item.mobileW, h: item.mobileH, i: item.id }
27 : { x: item.x, y: item.y, w: item.w, h: item.h, i: item.id }
28 );
29}
30
31function applyLayout(items: Item[], layout: LayoutItem[], mobile: boolean) {
32 const map = new Map(items.map((i) => [i.id, i]));
33 for (const l of layout) {
34 const item = map.get(l.i);
35 if (!item) continue;
36 if (mobile) { item.mobileX = l.x; item.mobileY = l.y; }
37 else { item.x = l.x; item.y = l.y; }
38 }
39}
40
41function fixAllCollisions(items: Item[], mobile: boolean) {
42 let layout = toLayout(items, mobile);
43 correctBounds(layout as any, { cols: COLUMNS });
44 layout = verticalCompactor.compact(layout, COLUMNS) as LayoutItem[];
45 applyLayout(items, layout, mobile);
46}
47
48function compactItems(items: Item[], mobile: boolean) {
49 const layout = toLayout(items, mobile);
50 const compacted = verticalCompactor.compact(layout, COLUMNS) as LayoutItem[];
51 applyLayout(items, compacted, mobile);
52}
53
54// ---
55
56const input = fs.readFileSync('/dev/stdin', 'utf8');
57const records = JSON.parse(input);
58
59const cards: Item[] = records
60 .filter((r: any) => r.value.cardType && (!r.value.page || r.value.page === 'blento.self'))
61 .map((r: any) => ({
62 id: r.value.id,
63 x: r.value.x, y: r.value.y, w: r.value.w, h: r.value.h,
64 mobileX: r.value.mobileX, mobileY: r.value.mobileY,
65 mobileW: r.value.mobileW, mobileH: r.value.mobileH,
66 cardType: r.value.cardType
67 }));
68
69// Save original positions
70const originals = cards.map((c) => ({ ...c }));
71
72// Simulate checkData — fixAllCollisions only (no separate compactItems)
73fixAllCollisions(cards, false);
74fixAllCollisions(cards, true);
75
76// Compare
77let desktopChanges = 0;
78let mobileChanges = 0;
79
80for (const card of cards) {
81 const orig = originals.find((o) => o.id === card.id)!;
82 const dChanged = card.x !== orig.x || card.y !== orig.y;
83 const mChanged = card.mobileX !== orig.mobileX || card.mobileY !== orig.mobileY;
84
85 if (dChanged || mChanged) {
86 console.log(
87 `${orig.cardType.padEnd(20)} id=${orig.id}` +
88 (dChanged ? ` DESKTOP: (${orig.x},${orig.y}) → (${card.x},${card.y})` : '') +
89 (mChanged ? ` MOBILE: (${orig.mobileX},${orig.mobileY}) → (${card.mobileX},${card.mobileY})` : '')
90 );
91 if (dChanged) desktopChanges++;
92 if (mChanged) mobileChanges++;
93 }
94}
95
96if (desktopChanges === 0 && mobileChanges === 0) {
97 console.log('No layout changes on load — checkData is not the culprit.');
98} else {
99 console.log(`\n${desktopChanges} desktop changes, ${mobileChanges} mobile changes on load.`);
100}
101
102// Check for ORDER changes in mobile layout
103console.log('\n=== Mobile reading order (y, then x) ===');
104const sortByMobile = (items: { id: string; mobileX: number; mobileY: number; cardType: string }[]) =>
105 [...items].sort((a, b) => a.mobileY - b.mobileY || a.mobileX - b.mobileX);
106
107const origOrder = sortByMobile(originals);
108const newOrder = sortByMobile(cards);
109
110let orderChanges = 0;
111for (let i = 0; i < origOrder.length; i++) {
112 const same = origOrder[i].id === newOrder[i].id;
113 if (!same) orderChanges++;
114 const orig = originals.find(o => o.id === newOrder[i].id)!;
115 const card = cards.find(c => c.id === newOrder[i].id)!;
116 console.log(
117 `${i.toString().padStart(2)}: ${same ? ' ' : '!!'} ` +
118 `${card.cardType.padEnd(20)} ` +
119 `was (${orig.mobileX},${orig.mobileY}) → now (${card.mobileX},${card.mobileY})` +
120 (!same ? ` [was #${origOrder.findIndex(o => o.id === newOrder[i].id)}]` : '')
121 );
122}
123console.log(`\n${orderChanges} order changes in mobile layout.`);