Changeset 3597763 in Klonkt
- Timestamp:
- 07/26/2026 09:37:48 AM (6 weeks ago)
- Branches:
- main
- Children:
- ef1853c
- Parents:
- b5c2538
- Files:
-
- 3 added
- 3 edited
-
src/middleware/render.js (modified) (2 diffs)
-
src/services/NoteRender.js (added)
-
src/views/pages/news.ejs (modified) (1 diff)
-
src/views/partials/quote-card.ejs (added)
-
src/views/partials/tl-item.ejs (modified) (2 diffs)
-
test/note-render.test.js (added)
Legend:
- Unmodified
- Added
- Removed
-
src/middleware/render.js
rb5c2538 r3597763 19 19 import { getSetting, apEnabled } from '../services/SettingsService.js'; 20 20 import { isPremium as isPremiumInstance, premiumEnabled, premiumUnlocked } from '../services/PatreonService.js'; 21 import { emojiHtml, emojiName, parseQuote } from '../services/NoteRender.js'; 21 22 import ActivityPubService from '../services/ActivityPubService.js'; 22 23 import { imgProxyUrl } from '../services/ThumbnailService.js'; … … 164 165 formatDate, 165 166 formatDateTime, 167 // Render the Shaer-native bits server-side so the web timeline matches the 168 // apps: FEP-9098 custom emojis in content/names, and the FEP-044f quote. 169 emojiHtml, // (html, emoji_json) → HTML with :shortcode: as <img> 170 emojiName, // (text, emoji_json) → escaped name with :shortcode: as <img> 171 noteQuote: parseQuote, // (quote_json) → the resolved quoted-post object or null 166 172 // Rewrite a local /media/<file> cover to its on-demand downscaled thumbnail 167 173 // (crisp grid/list images). External URLs + already-thumb URLs pass through. -
src/views/pages/news.ejs
rb5c2538 r3597763 137 137 .tl-readmore:hover { text-decoration: underline; } 138 138 139 /* FEP-9098 custom emojis: small inline images, never treated as media. */ 140 img.emoji { height: 1.35em; width: auto; margin: 0 .04em; vertical-align: -0.22em; 141 display: inline-block; border-radius: 0; background: none; box-shadow: none; } 142 .tl-content img.emoji, .tl-quote-body img.emoji { max-width: none; } 143 144 /* FEP-044f embedded quote card (mirror of the Shaer QuoteCard). */ 145 .tl-quote { margin: .75rem 0 0; padding: .6rem .7rem; border-radius: 12px; 146 border: 1px solid color-mix(in srgb, var(--ink, #000) 12%, transparent); 147 background: color-mix(in srgb, var(--ink, #000) 3.5%, transparent); } 148 .tl-quote-head { display: flex; align-items: center; gap: .4rem; margin: 0 0 .35rem; min-width: 0; } 149 .tl-quote-avatar { flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%; object-fit: cover; background: #fff; } 150 .tl-quote-name { font-weight: 700; font-size: .85rem; color: var(--ink, inherit); white-space: nowrap; } 151 .tl-quote-handle { color: var(--ink-soft, #888); font-size: .78rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; } 152 .tl-quote-body { line-height: 1.5; font-size: .92rem; color: var(--ink-soft, #555); 153 overflow-wrap: anywhere; max-height: 16em; overflow: hidden; } 154 .tl-quote-body p { margin: .3rem 0; } .tl-quote-body p:first-child { margin-top: 0; } .tl-quote-body p:last-child { margin-bottom: 0; } 155 .tl-quote-body a { color: var(--accent, #06c); } 156 .tl-quote-media { display: block; margin: .45rem 0 0; } 157 .tl-quote-media img { max-width: 100%; height: auto; border-radius: 8px; } 158 139 159 /* Always show the FULL image at its natural ratio — never cropped, no letterbox. */ 140 160 .tl-media { display: flex; flex-direction: column; gap: .4rem; margin: .75rem 0 0; } -
src/views/partials/tl-item.ejs
rb5c2538 r3597763 1 1 <li class="tl-item"> 2 <% if (p.reblog_name) { %><div class="tl-boost-by"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="17 1 21 5 17 9"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><polyline points="7 23 3 19 7 15"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/></svg> <strong><% = p.reblog_name%></strong> <%= t('tl.boosted') %></div><% } %>2 <% if (p.reblog_name) { %><div class="tl-boost-by"><svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="17 1 21 5 17 9"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><polyline points="7 23 3 19 7 15"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/></svg> <strong><%- emojiName(p.reblog_name, p.reblog_emoji_json) %></strong> <%= t('tl.boosted') %></div><% } %> 3 3 <div class="tl-head"> 4 4 <span class="tl-avatar"><% if (p.author_icon) { %><img src="<%= avatar(p.author_icon, 96) %>" alt="" loading="lazy"><% } else { %><%= (p.author_name || '?').charAt(0).toUpperCase() %><% } %></span> 5 5 <span class="tl-id"> 6 <a class="tl-author" href="<%= p.author_url || p.author_uri %>" target="_blank" rel="nofollow noopener"><% = p.author_name%></a>6 <a class="tl-author" href="<%= p.author_url || p.author_uri %>" target="_blank" rel="nofollow noopener"><%- emojiName(p.author_name, p.author_emoji_json) %></a> 7 7 <span class="tl-handle"><%= p.author_handle %></span> 8 8 </span> … … 19 19 %> 20 20 <% if (_nsfwText) { %> 21 <div class="tl-content nsfw-media"><span class="nsfw-veil"><%- include('../partials/nsfw-veil', { cw: p.cw }) %></span><%- p.content%></div>21 <div class="tl-content nsfw-media"><span class="nsfw-veil"><%- include('../partials/nsfw-veil', { cw: p.cw }) %></span><%- emojiHtml(p.content, p.emoji_json) %></div> 22 22 <% } else { %> 23 <div class="tl-content"><%- p.content%></div>23 <div class="tl-content"><%- emojiHtml(p.content, p.emoji_json) %></div> 24 24 <% } %> 25 <% var _quote = noteQuote(p.quote_json); if (_quote) { %><%- include('../partials/quote-card', { q: _quote }) %><% } %> 25 26 <% if (_nsfwVisual) { %><div class="nsfw-media"><% } %> 26 27 <% if (imgs.length) { %>
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)