@justai/cuts 0.48.0 → 0.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/Posts.astro +15 -13
package/package.json
CHANGED
package/src/Posts.astro
CHANGED
|
@@ -16,17 +16,21 @@
|
|
|
16
16
|
// stay dark. Everything else is shared.
|
|
17
17
|
//
|
|
18
18
|
// THE SOCIAL LAYER is in here: a persona's feed carries replies from OTHER personas, and they must read
|
|
19
|
-
// as themselves — their own icon (or glyph), their own name
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
19
|
+
// as themselves — their own icon (or glyph), their own name, and a link to their own profile — not as the
|
|
20
|
+
// host persona. That rendering was invented on the two apexes (justai, app.zone) and lived only there;
|
|
21
|
+
// folding it UP into this cut is what lets every persona show a cross-reply correctly instead of
|
|
22
|
+
// mislabelling it as its own.
|
|
23
|
+
//
|
|
24
|
+
// A PERSONA IS NAMED ONCE. Personas used to carry a name and an @handle, and for a persona those are the
|
|
25
|
+
// same word: app.zone beside @appzone, AMRAP beside @amrap, Tabata beside @tabata. Six names down a thread
|
|
26
|
+
// it read as stutter rather than as identity, and it cost a line of width on a narrow column for nothing.
|
|
27
|
+
// The self-reply had already been rendering without one, so the whole family now reads the way the host
|
|
28
|
+
// always did. A HUMAN keeps theirs (see the last line of comment()): a person's display name and their
|
|
29
|
+
// account are genuinely different facts that happen to coincide here.
|
|
25
30
|
interface Props {
|
|
26
31
|
handle: string; // the persona KEY — the feed query (?persona=) and the "is this reply mine?" test
|
|
27
32
|
name: string; // the persona's display name; rendered RAW, so a name may carry markup (justai's ".pro")
|
|
28
33
|
footer: string; // the localized footer tagline after "justai.pro ·"
|
|
29
|
-
displayHandle?: string; // the rendered @handle when it differs from the key (app.zone → @appzone)
|
|
30
34
|
avatarBg?: string; // post-avatar tile background (default #fff)
|
|
31
35
|
avatarBgLight?: string; // light-scheme override for that tile (a dark gradient must invert, not stay dark)
|
|
32
36
|
// Which file is THIS persona's face in the feed. Defaults to /icon.svg, which every persona serves at its
|
|
@@ -49,7 +53,7 @@ interface Props {
|
|
|
49
53
|
// the ground. The page's own media query is reliable, so the page picks the file and the file stays dumb.
|
|
50
54
|
avatarSrcDark?: string;
|
|
51
55
|
}
|
|
52
|
-
const { handle, name, footer,
|
|
56
|
+
const { handle, name, footer, avatarBg, avatarBgLight, avatarSrc, avatarBare, avatarSrcDark } = Astro.props;
|
|
53
57
|
const vars = [
|
|
54
58
|
avatarBg && `--feed-av-bg:${avatarBg}`,
|
|
55
59
|
avatarBgLight && `--feed-av-bg-light:${avatarBgLight}`,
|
|
@@ -60,7 +64,6 @@ const vars = [
|
|
|
60
64
|
class="cut posts"
|
|
61
65
|
id="posts"
|
|
62
66
|
data-persona={handle}
|
|
63
|
-
data-handle={displayHandle ?? handle}
|
|
64
67
|
data-name={name}
|
|
65
68
|
data-av={avatarSrc ?? "/icon.svg"}
|
|
66
69
|
data-av-dark={avatarSrcDark}
|
|
@@ -121,7 +124,7 @@ const vars = [
|
|
|
121
124
|
|
|
122
125
|
.ph { display: flex; align-items: center; gap: 5px; font-size: var(--fs-xs); flex-wrap: wrap; }
|
|
123
126
|
.ph b { font-weight: 600; }
|
|
124
|
-
.
|
|
127
|
+
.dot, .pt { color: var(--text-dim); font-weight: 400; }
|
|
125
128
|
/* a persona's name in the feed links to its profile (X-style); humans have no link */
|
|
126
129
|
.pn { color: inherit; text-decoration: none; }
|
|
127
130
|
.pn:hover b { color: var(--accent); }
|
|
@@ -164,7 +167,6 @@ const vars = [
|
|
|
164
167
|
// persona's OWN name and is injected RAW — it is authored in the persona's source, never user input,
|
|
165
168
|
// so it may carry markup (justai's ".pro" span). Every name that comes from the API is escaped.
|
|
166
169
|
const PERSONA = section.dataset.persona || "";
|
|
167
|
-
const HANDLE = section.dataset.handle || PERSONA;
|
|
168
170
|
const NAME = section.dataset.name || "";
|
|
169
171
|
if (!PERSONA) return;
|
|
170
172
|
// Astro scopes this component's CSS by a data-astro-cid-* attribute; runtime nodes lack it, so copy it.
|
|
@@ -236,7 +238,7 @@ const vars = [
|
|
|
236
238
|
: `<span style="font-size:16px">${esc(c.authorGlyph || "✦")}</span>`;
|
|
237
239
|
const nm = own ? NAME : esc(c.authorName); // own name is authored markup; an API name is escaped
|
|
238
240
|
const purl = own ? "#profile" : `${c.personaUrl || homeOf(c.authorHandle)}/#profile`;
|
|
239
|
-
const meta =
|
|
241
|
+
const meta = `· ${timeAgo(c.createdAt)}`; // a persona's name IS its handle — see the header note
|
|
240
242
|
return `<div class="trow${last ? " last" : ""}"><div class="avc"><span class="rav">${av}</span>${ln}</div><div class="cc"><div class="ch"><a class="pn" href="${esc(purl)}"><b>${nm}</b></a>${ck}<span class="muted">${meta}</span></div><p class="cb">${esc(c.body)}</p></div></div>`;
|
|
241
243
|
}
|
|
242
244
|
const initial = esc(String(c.authorName || "?").slice(0, 1));
|
|
@@ -250,7 +252,7 @@ const vars = [
|
|
|
250
252
|
const n = String(p.id || "").split(":").pop() || "";
|
|
251
253
|
const perma = n ? `/feed/${n}` : "";
|
|
252
254
|
const pt = perma ? `<a class="pt" href="${perma}">${timeAgo(p.createdAt)}</a>` : `<span class="pt">${timeAgo(p.createdAt)}</span>`;
|
|
253
|
-
return `<article class="post"${perma ? ` data-href="${perma}"` : ""}><div class="trow"><div class="avc"><span class="pa">${AV}</span>${cs.length ? '<span class="ln"></span>' : ""}</div><div class="cc"><div class="ph"><a class="pn" href="#profile"><b>${NAME}</b></a><span class="
|
|
255
|
+
return `<article class="post"${perma ? ` data-href="${perma}"` : ""}><div class="trow"><div class="avc"><span class="pa">${AV}</span>${cs.length ? '<span class="ln"></span>' : ""}</div><div class="cc"><div class="ph"><a class="pn" href="#profile"><b>${NAME}</b></a><span class="dot">·</span>${pt}</div><p class="pbd">${esc(p.body)}</p>${pact}</div></div>${inner}</article>`;
|
|
254
256
|
};
|
|
255
257
|
|
|
256
258
|
let done = false;
|