1
0
Fork 0
mirror of https://github.com/cheeaun/phanpy.git synced 2025-02-03 15:00:50 +03:00

Show author bylines

This commit is contained in:
Lim Chee Aun 2024-09-16 13:25:51 +08:00
parent 3392c169c9
commit 3ebf7af4c3
6 changed files with 250 additions and 143 deletions

View file

@ -60,10 +60,10 @@
}
}
a {
min-width: 240px;
flex-grow: 1;
max-width: 320px;
a.link-block {
width: 240px;
flex-shrink: 0;
/* max-width: 320px; */
text-decoration: none;
color: inherit;
border-radius: 16px;
@ -81,7 +81,7 @@
background-clip: border-box;
background-origin: border-box;
min-height: 160px;
height: 320px;
height: 340px;
max-height: 50vh;
&:not(:active):is(:hover, :focus-visible) {
@ -113,6 +113,12 @@
opacity: 0.5;
mix-blend-mode: luminosity;
}
.byline {
transition-duration: 0.3s;
opacity: 0.75;
mix-blend-mode: luminosity;
}
}
&.active {
@ -217,10 +223,29 @@
-webkit-box-orient: vertical;
overflow: hidden;
font-size: 90%;
&.more-lines {
-webkit-line-clamp: 3;
}
}
hr {
margin: 4px 0;
}
.byline {
white-space: nowrap;
mask-image: linear-gradient(var(--to-backward), transparent, black 32px);
a {
color: inherit;
}
.avatar {
width: 16px !important;
height: 16px !important;
opacity: 0.8;
}
}
}
}

View file

@ -1990,6 +1990,18 @@ a.card:is(:hover, :focus):visited {
.card.large.card-post {
flex-direction: column-reverse;
}
.card-byline-author {
display: inline-block;
color: var(--text-insignificant-color);
padding: 0 8px;
.avatar {
width: 16px !important;
height: 16px !important;
opacity: 0.8;
vertical-align: middle;
}
}
/* POLLS */

View file

@ -2564,6 +2564,25 @@ function isCardPost(domain) {
return ['x.com', 'twitter.com', 'threads.net', 'bsky.app'].includes(domain);
}
function Byline({ authors, children }) {
if (!authors?.[0]?.account?.id) return children;
const author = authors[0].account;
return (
<div class="card-byline">
{children}
<div class="card-byline-author">
<Icon icon="link" size="s" />{' '}
<small>
<Trans comment="More from [Author]">
More from <NameText account={author} showAvatar />
</Trans>
</small>
</div>
</div>
);
}
function Card({ card, selfReferential, instance }) {
const snapStates = useSnapshot(states);
const {
@ -2584,6 +2603,7 @@ function Card({ card, selfReferential, instance }) {
embedUrl,
language,
publishedAt,
authors,
} = card;
/* type
@ -2677,60 +2697,65 @@ function Card({ card, selfReferential, instance }) {
const isPost = isCardPost(domain);
return (
<a
href={cardStatusURL || url}
target={cardStatusURL ? null : '_blank'}
rel="nofollow noopener noreferrer"
class={`card link ${isPost ? 'card-post' : ''} ${
blurhashImage ? '' : size
}`}
style={{
'--average-color':
rgbAverageColor && `rgb(${rgbAverageColor.join(',')})`,
}}
onClick={handleClick}
>
<div class="card-image">
<img
src={image || blurhashImage}
width={width}
height={height}
loading="lazy"
alt={imageDescription || ''}
onError={(e) => {
try {
e.target.style.display = 'none';
} catch (e) {}
}}
style={{
'--anim-duration':
width &&
height &&
`${Math.min(Math.max(Math.max(width, height) / 100, 5), 120)}s`,
}}
/>
</div>
<div class="meta-container" lang={language}>
<p class="meta domain">
<span class="domain">{domain}</span>{' '}
{!!publishedAt && <>&middot; </>}
{!!publishedAt && (
<>
<RelativeTime datetime={publishedAt} format="micro" />
</>
)}
</p>
<p class="title" dir="auto" title={title}>
{title}
</p>
<p class="meta" dir="auto" title={description}>
{description ||
(!!publishedAt && (
<RelativeTime datetime={publishedAt} format="micro" />
))}
</p>
</div>
</a>
<Byline authors={authors}>
<a
href={cardStatusURL || url}
target={cardStatusURL ? null : '_blank'}
rel="nofollow noopener noreferrer"
class={`card link ${isPost ? 'card-post' : ''} ${
blurhashImage ? '' : size
}`}
style={{
'--average-color':
rgbAverageColor && `rgb(${rgbAverageColor.join(',')})`,
}}
onClick={handleClick}
>
<div class="card-image">
<img
src={image || blurhashImage}
width={width}
height={height}
loading="lazy"
alt={imageDescription || ''}
onError={(e) => {
try {
e.target.style.display = 'none';
} catch (e) {}
}}
style={{
'--anim-duration':
width &&
height &&
`${Math.min(
Math.max(Math.max(width, height) / 100, 5),
120,
)}s`,
}}
/>
</div>
<div class="meta-container" lang={language}>
<p class="meta domain">
<span class="domain">{domain}</span>{' '}
{!!publishedAt && <>&middot; </>}
{!!publishedAt && (
<>
<RelativeTime datetime={publishedAt} format="micro" />
</>
)}
</p>
<p class="title" dir="auto" title={title}>
{title}
</p>
<p class="meta" dir="auto" title={description}>
{description ||
(!!publishedAt && (
<RelativeTime datetime={publishedAt} format="micro" />
))}
</p>
</div>
</a>
</Byline>
);
} else if (type === 'photo') {
return (

172
src/locales/en.po generated
View file

@ -33,7 +33,7 @@ msgstr ""
#: src/components/account-block.jsx:166
#: src/components/account-info.jsx:639
#: src/components/status.jsx:440
#: src/pages/catchup.jsx:1470
#: src/pages/catchup.jsx:1471
msgid "Group"
msgstr ""
@ -119,7 +119,7 @@ msgstr ""
#: src/pages/list.jsx:157
#: src/pages/public.jsx:114
#: src/pages/status.jsx:1169
#: src/pages/trending.jsx:437
#: src/pages/trending.jsx:471
msgid "More"
msgstr ""
@ -183,8 +183,8 @@ msgstr ""
#: src/components/account-info.jsx:859
#: src/components/status.jsx:2163
#: src/pages/catchup.jsx:71
#: src/pages/catchup.jsx:1444
#: src/pages/catchup.jsx:2055
#: src/pages/catchup.jsx:1445
#: src/pages/catchup.jsx:2056
#: src/pages/status.jsx:892
#: src/pages/status.jsx:1494
msgid "Replies"
@ -192,8 +192,8 @@ msgstr ""
#: src/components/account-info.jsx:863
#: src/pages/catchup.jsx:72
#: src/pages/catchup.jsx:1446
#: src/pages/catchup.jsx:2067
#: src/pages/catchup.jsx:1447
#: src/pages/catchup.jsx:2068
#: src/pages/settings.jsx:1045
msgid "Boosts"
msgstr ""
@ -289,7 +289,7 @@ msgstr ""
#: src/components/account-info.jsx:1308
#: src/components/shortcuts-settings.jsx:1056
#: src/components/status.jsx:1088
#: src/components/status.jsx:3121
#: src/components/status.jsx:3146
msgid "Copy"
msgstr ""
@ -417,11 +417,11 @@ msgstr ""
#: src/components/shortcuts-settings.jsx:227
#: src/components/shortcuts-settings.jsx:580
#: src/components/shortcuts-settings.jsx:780
#: src/components/status.jsx:2846
#: src/components/status.jsx:3085
#: src/components/status.jsx:3583
#: src/components/status.jsx:2871
#: src/components/status.jsx:3110
#: src/components/status.jsx:3608
#: src/pages/accounts.jsx:36
#: src/pages/catchup.jsx:1580
#: src/pages/catchup.jsx:1581
#: src/pages/filters.jsx:224
#: src/pages/list.jsx:274
#: src/pages/notifications.jsx:840
@ -915,7 +915,7 @@ msgid "No drafts found."
msgstr ""
#: src/components/drafts.jsx:245
#: src/pages/catchup.jsx:1927
#: src/pages/catchup.jsx:1928
msgid "Poll"
msgstr ""
@ -975,7 +975,7 @@ msgstr ""
#: src/components/keyboard-shortcuts-help.jsx:43
#: src/components/nav-menu.jsx:405
#: src/pages/catchup.jsx:1618
#: src/pages/catchup.jsx:1619
msgid "Keyboard shortcuts"
msgstr ""
@ -984,12 +984,12 @@ msgid "Keyboard shortcuts help"
msgstr ""
#: src/components/keyboard-shortcuts-help.jsx:55
#: src/pages/catchup.jsx:1643
#: src/pages/catchup.jsx:1644
msgid "Next post"
msgstr ""
#: src/components/keyboard-shortcuts-help.jsx:59
#: src/pages/catchup.jsx:1651
#: src/pages/catchup.jsx:1652
msgid "Previous post"
msgstr ""
@ -1014,7 +1014,7 @@ msgid "Load new posts"
msgstr ""
#: src/components/keyboard-shortcuts-help.jsx:83
#: src/pages/catchup.jsx:1675
#: src/pages/catchup.jsx:1676
msgid "Open post details"
msgstr ""
@ -1207,12 +1207,12 @@ msgid "Filtered: {filterTitleStr}"
msgstr ""
#: src/components/media-post.jsx:133
#: src/components/status.jsx:3413
#: src/components/status.jsx:3509
#: src/components/status.jsx:3587
#: src/components/status.jsx:3438
#: src/components/status.jsx:3534
#: src/components/status.jsx:3612
#: src/components/timeline.jsx:973
#: src/pages/catchup.jsx:75
#: src/pages/catchup.jsx:1875
#: src/pages/catchup.jsx:1876
msgid "Filtered"
msgstr ""
@ -1252,7 +1252,7 @@ msgstr ""
#: src/pages/mentions.jsx:20
#: src/pages/mentions.jsx:167
#: src/pages/settings.jsx:1037
#: src/pages/trending.jsx:347
#: src/pages/trending.jsx:381
msgid "Mentions"
msgstr ""
@ -1302,8 +1302,8 @@ msgstr ""
#: src/components/nav-menu.jsx:296
#: src/components/shortcuts-settings.jsx:55
#: src/components/shortcuts-settings.jsx:198
#: src/pages/catchup.jsx:1445
#: src/pages/catchup.jsx:2061
#: src/pages/catchup.jsx:1446
#: src/pages/catchup.jsx:2062
#: src/pages/favourites.jsx:11
#: src/pages/favourites.jsx:23
#: src/pages/settings.jsx:1041
@ -1354,7 +1354,7 @@ msgstr ""
#: src/components/nav-menu.jsx:380
#: src/components/shortcuts-settings.jsx:57
#: src/components/shortcuts-settings.jsx:169
#: src/pages/trending.jsx:407
#: src/pages/trending.jsx:441
msgid "Trending"
msgstr ""
@ -2013,11 +2013,11 @@ msgstr ""
#: src/components/status.jsx:716
msgid "Unliked @{0}'s post"
msgstr ""
msgstr "Unliked @{0}'s post"
#: src/components/status.jsx:717
msgid "Liked @{0}'s post"
msgstr ""
msgstr "Liked @{0}'s post"
#: src/components/status.jsx:756
msgid "Unbookmarked @{0}'s post"
@ -2094,7 +2094,7 @@ msgid "Edited: {editedDateText}"
msgstr ""
#: src/components/status.jsx:1123
#: src/components/status.jsx:3090
#: src/components/status.jsx:3115
msgid "Embed post"
msgstr ""
@ -2218,77 +2218,82 @@ msgstr ""
msgid "Comments"
msgstr ""
#: src/components/status.jsx:2851
#. More from [Author]
#: src/components/status.jsx:2577
msgid "More from <0/>"
msgstr "More from <0/>"
#: src/components/status.jsx:2876
msgid "Edit History"
msgstr ""
#: src/components/status.jsx:2855
#: src/components/status.jsx:2880
msgid "Failed to load history"
msgstr ""
#: src/components/status.jsx:2860
#: src/components/status.jsx:2885
msgid "Loading…"
msgstr ""
#: src/components/status.jsx:3095
#: src/components/status.jsx:3120
msgid "HTML Code"
msgstr ""
#: src/components/status.jsx:3112
#: src/components/status.jsx:3137
msgid "HTML code copied"
msgstr ""
#: src/components/status.jsx:3115
#: src/components/status.jsx:3140
msgid "Unable to copy HTML code"
msgstr ""
#: src/components/status.jsx:3127
#: src/components/status.jsx:3152
msgid "Media attachments:"
msgstr ""
#: src/components/status.jsx:3149
#: src/components/status.jsx:3174
msgid "Account Emojis:"
msgstr ""
#: src/components/status.jsx:3180
#: src/components/status.jsx:3225
#: src/components/status.jsx:3205
#: src/components/status.jsx:3250
msgid "static URL"
msgstr ""
#: src/components/status.jsx:3194
#: src/components/status.jsx:3219
msgid "Emojis:"
msgstr ""
#: src/components/status.jsx:3239
#: src/components/status.jsx:3264
msgid "Notes:"
msgstr ""
#: src/components/status.jsx:3243
#: src/components/status.jsx:3268
msgid "This is static, unstyled and scriptless. You may need to apply your own styles and edit as needed."
msgstr ""
#: src/components/status.jsx:3249
#: src/components/status.jsx:3274
msgid "Polls are not interactive, becomes a list with vote counts."
msgstr ""
#: src/components/status.jsx:3254
#: src/components/status.jsx:3279
msgid "Media attachments can be images, videos, audios or any file types."
msgstr ""
#: src/components/status.jsx:3260
#: src/components/status.jsx:3285
msgid "Post could be edited or deleted later."
msgstr ""
#: src/components/status.jsx:3266
#: src/components/status.jsx:3291
msgid "Preview"
msgstr ""
#: src/components/status.jsx:3275
#: src/components/status.jsx:3300
msgid "Note: This preview is lightly styled."
msgstr ""
#. [Name] [Visibility icon] boosted
#: src/components/status.jsx:3517
#: src/components/status.jsx:3542
msgid "<0/> <1/> boosted"
msgstr ""
@ -2315,7 +2320,7 @@ msgstr "Pinned posts"
#: src/components/timeline.jsx:946
#: src/components/timeline.jsx:953
#: src/pages/catchup.jsx:1892
#: src/pages/catchup.jsx:1893
msgid "Thread"
msgstr ""
@ -2439,7 +2444,7 @@ msgstr ""
#: src/pages/account-statuses.jsx:506
#: src/pages/public.jsx:97
#: src/pages/trending.jsx:415
#: src/pages/trending.jsx:449
msgid "Unable to load posts"
msgstr ""
@ -2578,7 +2583,7 @@ msgid "Catch-up <0>beta</0>"
msgstr ""
#: src/pages/catchup.jsx:896
#: src/pages/catchup.jsx:1584
#: src/pages/catchup.jsx:1585
msgid "Help"
msgstr ""
@ -2655,93 +2660,93 @@ msgid "Reset filters"
msgstr ""
#: src/pages/catchup.jsx:1144
#: src/pages/catchup.jsx:1590
#: src/pages/catchup.jsx:1591
msgid "Top links"
msgstr ""
#: src/pages/catchup.jsx:1260
#: src/pages/catchup.jsx:1261
msgid "Shared by {0}"
msgstr ""
#: src/pages/catchup.jsx:1315
#: src/pages/catchup.jsx:1316
#: src/pages/mentions.jsx:147
#: src/pages/search.jsx:222
msgid "All"
msgstr ""
#: src/pages/catchup.jsx:1400
#: src/pages/catchup.jsx:1401
msgid "{0, plural, one {# author} other {# authors}}"
msgstr ""
#: src/pages/catchup.jsx:1412
#: src/pages/catchup.jsx:1413
msgid "Sort"
msgstr ""
#: src/pages/catchup.jsx:1443
#: src/pages/catchup.jsx:1444
msgid "Date"
msgstr ""
#: src/pages/catchup.jsx:1447
#: src/pages/catchup.jsx:1448
msgid "Density"
msgstr ""
#: src/pages/catchup.jsx:1485
#: src/pages/catchup.jsx:1486
msgid "Authors"
msgstr ""
#: src/pages/catchup.jsx:1486
#: src/pages/catchup.jsx:1487
msgid "None"
msgstr ""
#: src/pages/catchup.jsx:1502
#: src/pages/catchup.jsx:1503
msgid "Show all authors"
msgstr ""
#: src/pages/catchup.jsx:1553
#: src/pages/catchup.jsx:1554
msgid "You don't have to read everything."
msgstr ""
#: src/pages/catchup.jsx:1554
#: src/pages/catchup.jsx:1555
msgid "That's all."
msgstr ""
#: src/pages/catchup.jsx:1562
#: src/pages/catchup.jsx:1563
msgid "Back to top"
msgstr ""
#: src/pages/catchup.jsx:1593
#: src/pages/catchup.jsx:1594
msgid "Links shared by followings, sorted by shared counts, boosts and likes."
msgstr ""
#: src/pages/catchup.jsx:1599
#: src/pages/catchup.jsx:1600
msgid "Sort: Density"
msgstr ""
#: src/pages/catchup.jsx:1602
#: src/pages/catchup.jsx:1603
msgid "Posts are sorted by information density or depth. Shorter posts are \"lighter\" while longer posts are \"heavier\". Posts with photos are \"heavier\" than posts without photos."
msgstr ""
#: src/pages/catchup.jsx:1609
#: src/pages/catchup.jsx:1610
msgid "Group: Authors"
msgstr ""
#: src/pages/catchup.jsx:1612
#: src/pages/catchup.jsx:1613
msgid "Posts are grouped by authors, sorted by posts count per author."
msgstr ""
#: src/pages/catchup.jsx:1659
#: src/pages/catchup.jsx:1660
msgid "Next author"
msgstr ""
#: src/pages/catchup.jsx:1667
#: src/pages/catchup.jsx:1668
msgid "Previous author"
msgstr ""
#: src/pages/catchup.jsx:1683
#: src/pages/catchup.jsx:1684
msgid "Scroll to top"
msgstr ""
#: src/pages/catchup.jsx:1874
#: src/pages/catchup.jsx:1875
msgid "Filtered: {0}"
msgstr ""
@ -2986,25 +2991,25 @@ msgstr ""
#: src/pages/hashtag.jsx:486
#: src/pages/public.jsx:139
#: src/pages/trending.jsx:444
#: src/pages/trending.jsx:478
msgid "Enter a new instance e.g. \"mastodon.social\""
msgstr ""
#: src/pages/hashtag.jsx:489
#: src/pages/public.jsx:142
#: src/pages/trending.jsx:447
#: src/pages/trending.jsx:481
msgid "Invalid instance"
msgstr ""
#: src/pages/hashtag.jsx:503
#: src/pages/public.jsx:156
#: src/pages/trending.jsx:459
#: src/pages/trending.jsx:493
msgid "Go to another instance…"
msgstr ""
#: src/pages/hashtag.jsx:516
#: src/pages/public.jsx:169
#: src/pages/trending.jsx:470
#: src/pages/trending.jsx:504
msgid "Go to my instance (<0>{currentInstance}</0>)"
msgstr ""
@ -3621,27 +3626,32 @@ msgstr ""
msgid "View post with its replies"
msgstr ""
#: src/pages/trending.jsx:70
#: src/pages/trending.jsx:71
msgid "Trending ({instance})"
msgstr ""
#: src/pages/trending.jsx:227
#: src/pages/trending.jsx:228
msgid "Trending News"
msgstr ""
#: src/pages/trending.jsx:374
#. By [Author]
#: src/pages/trending.jsx:347
msgid "By {0}"
msgstr "By {0}"
#: src/pages/trending.jsx:408
msgid "Back to showing trending posts"
msgstr ""
#: src/pages/trending.jsx:379
#: src/pages/trending.jsx:413
msgid "Showing posts mentioning <0>{0}</0>"
msgstr ""
#: src/pages/trending.jsx:391
#: src/pages/trending.jsx:425
msgid "Trending posts"
msgstr ""
#: src/pages/trending.jsx:414
#: src/pages/trending.jsx:448
msgid "No trending posts."
msgstr ""

View file

@ -1193,6 +1193,7 @@ function Catchup() {
href={url}
target="_blank"
rel="noopener noreferrer"
class="link-block"
style={
accentColor
? {

View file

@ -13,6 +13,7 @@ import Icon from '../components/icon';
import Link from '../components/link';
import Loader from '../components/loader';
import Menu2 from '../components/menu2';
import NameText from '../components/name-text';
import RelativeTime from '../components/relative-time';
import Timeline from '../components/timeline';
import { api } from '../utils/api';
@ -229,6 +230,7 @@ function Trending({ columnMode, ...props }) {
</header>
{links.map((link) => {
const {
authors,
authorName,
authorUrl,
blurhash,
@ -244,6 +246,11 @@ function Trending({ columnMode, ...props }) {
url,
width,
} = link;
const author = authors?.[0]?.account?.id
? authors[0].account
: null;
const isShortTitle = title.length < 30;
const hasAuthor = !!(authorName || author);
const domain = punycode.toUnicode(
URL.parse(url)
.hostname.replace(/^www\./, '')
@ -267,13 +274,13 @@ function Trending({ columnMode, ...props }) {
href={url}
target="_blank"
rel="noopener noreferrer"
class={
class={`link-block ${
hasCurrentLink
? currentLink === url
? 'active'
: 'inactive'
: ''
}
}`}
style={
accentColor
? {
@ -322,7 +329,9 @@ function Trending({ columnMode, ...props }) {
</header>
{!!description && (
<p
class="description"
class={`description ${
hasAuthor && !isShortTitle ? '' : 'more-lines'
}`}
lang={language}
dir="auto"
title={description}
@ -330,6 +339,31 @@ function Trending({ columnMode, ...props }) {
{description}
</p>
)}
{hasAuthor && (
<>
<hr />
<p class="byline">
<small>
<Trans comment="By [Author]">
By{' '}
{author ? (
<NameText account={author} showAvatar />
) : authorUrl ? (
<a
href={authorUrl}
target="_blank"
rel="noopener noreferrer"
>
{authorName}
</a>
) : (
authorName
)}
</Trans>
</small>
</p>
</>
)}
</div>
</article>
</a>